diff --git a/Makefile b/Makefile index 31b2f3843b..81233f2a03 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ TEST_DIR="$(shell pwd)/_build/default/test" HTML_DIR="$(shell pwd)/_build/default/src/web/www" -SERVER="http://0.0.0.0:8000/" +SERVER="http://0.0.0.0:8009/" .PHONY: all deps change-deps setup-instructor setup-student dev dev-helper dev-student fmt watch watch-release release release-student grade echo-html-dir serve serve2 repl test clean setup-zarith @@ -30,7 +30,7 @@ change-deps: setup-instructor: cp src/web/exercises/settings/ExerciseSettings_instructor.re src/web/exercises/settings/ExerciseSettings.re -setup-student: +setup-student: cp src/web/exercises/settings/ExerciseSettings_student.re src/web/exercises/settings/ExerciseSettings.re dev-helper: setup-zarith @@ -66,7 +66,7 @@ echo-html-dir: @echo $(HTML_DIR) serve: - cd $(HTML_DIR); python3 -m http.server 8000 --bind 0.0.0.0 + cd $(HTML_DIR); python3 -m http.server 8014 --bind 0.0.0.0 hot: npx vite @@ -97,7 +97,7 @@ coverage: ci: setup-zarith dune build --profile dev dune runtest --instrument-with bisect_ppx --force - + generate-coverage-html: bisect-ppx-report html diff --git a/package-lock.json b/package-lock.json index 16bfb7be00..e066e65b8c 100644 --- a/package-lock.json +++ b/package-lock.json @@ -8,20 +8,274 @@ "name": "hazel", "license": "MIT", "dependencies": { + "@automerge/automerge-repo-keyhive": "^0.0.0-alpha.53", + "@automerge/vanillajs": "^2.5.0", "@esbuild-plugins/node-resolve": "^0.2.2", + "@inkandswitch/patchwork-bootloader": "^0.0.4", + "@inkandswitch/patchwork-elements": "^0.0.5", + "@inkandswitch/patchwork-filesystem": "^0.0.3", + "@inkandswitch/patchwork-plugins": "^0.0.5", "@observablehq/plot": "^0.6.17", "algebrite": "^1.4.0", "hotkeys-js": "^3.8.7", "ninja-keys": "^1.2.2", + "resolve.exports": "^2.0.3", "web-worker": "^1.5.0" }, "devDependencies": { "@types/node": "^22.14.0", "esbuild": "^0.25.1", + "esbuild-plugin-wasm": "^1.1.0", "vite": "^6.4.1", "vite-plugin-static-copy": "^2.3.0" } }, + "node_modules/@automerge/automerge": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/@automerge/automerge/-/automerge-3.2.2.tgz", + "integrity": "sha512-A6E2MDnX+IWmFV2GydrkJEf4ClO2hucROJkGmX3bWYoZfgvmCz3QFqew126/uXQAJxWq8WMFf34PuKa7c/cJfg==", + "license": "MIT" + }, + "node_modules/@automerge/automerge-repo": { + "version": "2.5.0-alpha.2", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.0-alpha.2.tgz", + "integrity": "sha512-Sjl1CaD4IpmboNIG9/EL9Run+AKrL8/1h3Om1NZp9syBnJN8OWjeG4ttpQce6k8HdPyl8sllAHYy8/Q4Ukh39w==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@automerge/automerge-repo-keyhive": { + "version": "0.0.0-alpha.71", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-keyhive/-/automerge-repo-keyhive-0.0.0-alpha.71.tgz", + "integrity": "sha512-bDP6QPNTG9eCYVnLW/PuODLFmGrOe4rwaOSAWLgW9VrHg/5aBlP0PmrzeJ58loYvGlqYeN6PWrV+GFDqCPUcug==", + "peer": true, + "dependencies": { + "@automerge/automerge-repo": "2.5.0-alpha.2", + "@automerge/automerge-repo-network-websocket": "2.5.0-alpha.2", + "@keyhive/keyhive": "^0.0.0-alpha.40", + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@automerge/automerge-repo-network-broadcastchannel": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-broadcastchannel/-/automerge-repo-network-broadcastchannel-2.5.1.tgz", + "integrity": "sha512-htjVAPOzWvaal7jXkXhMBWW1OLHBAmGJp3fujdxgMmHa6/KUmhmHsn7VGvVqrU3vCfbfdu5PAupcla95AwlEbA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.1" + } + }, + "node_modules/@automerge/automerge-repo-network-broadcastchannel/node_modules/@automerge/automerge-repo": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.1.tgz", + "integrity": "sha512-w242TXb2TaGHFux7dDtJIUVJMqSSq1iYvNia8FVYgVTUDvbm8chaGMe1kVdKMEINFiB/BNYPtsoJIPjJhQArLg==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@automerge/automerge-repo-network-messagechannel": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-messagechannel/-/automerge-repo-network-messagechannel-2.5.1.tgz", + "integrity": "sha512-C2GKMoiGlyp7KQCwMt1Az/tJMYa+UtlrLtZ6WHT+PN3RQ9D/c/f5CkSNQSHgJRwFW/c2sU6PI3zcRasgrYaUOA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.1", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@automerge/automerge-repo-network-messagechannel/node_modules/@automerge/automerge-repo": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.1.tgz", + "integrity": "sha512-w242TXb2TaGHFux7dDtJIUVJMqSSq1iYvNia8FVYgVTUDvbm8chaGMe1kVdKMEINFiB/BNYPtsoJIPjJhQArLg==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@automerge/automerge-repo-network-websocket": { + "version": "2.5.0-alpha.2", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-2.5.0-alpha.2.tgz", + "integrity": "sha512-EtdsSA9PhuiWWbvT36DGylBeGCL7Aop8nSe4FrBYchBCWpqqZOBLdbxD0crwbCUwTBTJy76pXhSHjObQi0y4zQ==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0-alpha.2", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "isomorphic-ws": "^5.0.0", + "ws": "^8.7.0" + } + }, + "node_modules/@automerge/automerge-repo-storage-indexeddb": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-storage-indexeddb/-/automerge-repo-storage-indexeddb-2.5.1.tgz", + "integrity": "sha512-klyemjiwEn2+PW+NTjvBtjmykjJVoaBbQgk5P02jIgvAO7KH8OACldFzPrJdO0o6WAxkiOdtte8RHFKrDPkBlw==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.1" + } + }, + "node_modules/@automerge/automerge-repo-storage-indexeddb/node_modules/@automerge/automerge-repo": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.1.tgz", + "integrity": "sha512-w242TXb2TaGHFux7dDtJIUVJMqSSq1iYvNia8FVYgVTUDvbm8chaGMe1kVdKMEINFiB/BNYPtsoJIPjJhQArLg==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@automerge/vanillajs": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/vanillajs/-/vanillajs-2.5.1.tgz", + "integrity": "sha512-UWhesAYxkZdlsN1M7grFgsjXL/3XUEkiZsBfv0icTLKGEiuNf6uK2s+wkFWgtoWnVNv0qO8jm/V8ljYlwvG1kQ==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.1", + "@automerge/automerge-repo-network-broadcastchannel": "2.5.1", + "@automerge/automerge-repo-network-messagechannel": "2.5.1", + "@automerge/automerge-repo-network-websocket": "2.5.1", + "@automerge/automerge-repo-storage-indexeddb": "2.5.1" + } + }, + "node_modules/@automerge/vanillajs/node_modules/@automerge/automerge-repo": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.1.tgz", + "integrity": "sha512-w242TXb2TaGHFux7dDtJIUVJMqSSq1iYvNia8FVYgVTUDvbm8chaGMe1kVdKMEINFiB/BNYPtsoJIPjJhQArLg==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@automerge/vanillajs/node_modules/@automerge/automerge-repo-network-websocket": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-2.5.1.tgz", + "integrity": "sha512-urvhlmTZ6VoJi5o0T2mtkVd4X1cuUdBC5/C/UY5FFgWczEq7PwCdNhUndv1CQSn8ePPsT59z7ZnRzZJbqqu22Q==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "isomorphic-ws": "^5.0.0", + "ws": "^8.7.0" + } + }, + "node_modules/@cbor-extract/cbor-extract-darwin-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-arm64/-/cbor-extract-darwin-arm64-2.2.0.tgz", + "integrity": "sha512-P7swiOAdF7aSi0H+tHtHtr6zrpF3aAq/W9FXx5HektRvLTM2O89xCyXF3pk7pLc7QpaY7AoaE8UowVf9QBdh3w==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-darwin-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-darwin-x64/-/cbor-extract-darwin-x64-2.2.0.tgz", + "integrity": "sha512-1liF6fgowph0JxBbYnAS7ZlqNYLf000Qnj4KjqPNW4GViKrEql2MgZnAsExhY9LSy8dnvA4C0qHEBgPrll0z0w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "darwin" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm/-/cbor-extract-linux-arm-2.2.0.tgz", + "integrity": "sha512-QeBcBXk964zOytiedMPQNZr7sg0TNavZeuUCD6ON4vEOU/25+pLhNN6EDIKJ9VLTKaZ7K7EaAriyYQ1NQ05s/Q==", + "cpu": [ + "arm" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-arm64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-arm64/-/cbor-extract-linux-arm64-2.2.0.tgz", + "integrity": "sha512-rQvhNmDuhjTVXSPFLolmQ47/ydGOFXtbR7+wgkSY0bdOxCFept1hvg59uiLPT2fVDuJFuEy16EImo5tE2x3RsQ==", + "cpu": [ + "arm64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-linux-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-linux-x64/-/cbor-extract-linux-x64-2.2.0.tgz", + "integrity": "sha512-cWLAWtT3kNLHSvP4RKDzSTX9o0wvQEEAj4SKvhWuOVZxiDAeQazr9A+PSiRILK1VYMLeDml89ohxCnUNQNQNCw==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "linux" + ] + }, + "node_modules/@cbor-extract/cbor-extract-win32-x64": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/@cbor-extract/cbor-extract-win32-x64/-/cbor-extract-win32-x64-2.2.0.tgz", + "integrity": "sha512-l2M+Z8DO2vbvADOBNLbbh9y5ST1RY5sqkWOg/58GkUPBYou/cuNZ68SGQ644f1CvZ8kcOxyZtw06+dxWHIoN/w==", + "cpu": [ + "x64" + ], + "license": "MIT", + "optional": true, + "os": [ + "win32" + ] + }, "node_modules/@esbuild-plugins/node-resolve": { "version": "0.2.2", "resolved": "https://registry.npmjs.org/@esbuild-plugins/node-resolve/-/node-resolve-0.2.2.tgz", @@ -437,6 +691,233 @@ "node": ">=18" } }, + "node_modules/@inkandswitch/patchwork-bootloader": { + "version": "0.0.4", + "resolved": "https://registry.npmjs.org/@inkandswitch/patchwork-bootloader/-/patchwork-bootloader-0.0.4.tgz", + "integrity": "sha512-3VWkDYPTiY4H2+877tYHptRGQcCg22uoa0NG+7cgwbmETcBhnXheoLh/cv3clPf2mcMiglhY1Htt7ezkgKa17g==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "3.2.1", + "@automerge/automerge-repo": "2.5.0", + "@automerge/vanillajs": "2.5.0", + "@types/debug": "^4.1.12", + "debug": "^4.4.3", + "resolve.exports": "^2.0.3", + "service-worker-types": "npm:@types/serviceworker@^0.0.153", + "tinyargs": "^0.1.4" + }, + "peerDependencies": { + "@automerge/automerge": "3.2.1", + "@automerge/automerge-repo": "2.5.0", + "@automerge/automerge-repo-keyhive": "0.0.0-alpha.71", + "@automerge/vanillajs": "2.5.0", + "@keyhive/keyhive": "0.0.0-alpha.40" + } + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/automerge": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge/-/automerge-3.2.1.tgz", + "integrity": "sha512-xsEZlZe8lWyVCbD7Z7roH4X6ZKlRxMmmumb0M5CuxJWptUEfYsf+1z9lFEJh4aDBbWTLAgxsXd+TBi6jKTj0+g==", + "license": "MIT" + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/automerge-repo": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.0.tgz", + "integrity": "sha512-bdxuMuKmxw0ZjwQXecrIX1VrHXf445bYCftNJJ5vqgGWVvINB5ZKFYAbtgPIyu1Y0TXQKvc6eqESaDeL+g8MmA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/automerge-repo-network-broadcastchannel": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-broadcastchannel/-/automerge-repo-network-broadcastchannel-2.5.0.tgz", + "integrity": "sha512-57rUTYf0W6kL9DXwjRtyGLqeyz65tDIpiNQdc1nXHnN4VkNMvNo0xzb37nyFKWHEqPWA0DGCcBA8HRlbVHHyHw==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0" + } + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/automerge-repo-network-messagechannel": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-messagechannel/-/automerge-repo-network-messagechannel-2.5.0.tgz", + "integrity": "sha512-G7m161tId4djPMzDPlP7nIEsDY7ddbKfKvpJP7kkVqv3OA/Ml8fzyKaU7C1++s/g0FSNCTiN6hOhFCbSkb6/Dw==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1" + } + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/automerge-repo-network-websocket": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-network-websocket/-/automerge-repo-network-websocket-2.5.0.tgz", + "integrity": "sha512-zrwbkW8hk3fWkXdeaH+YDfGG63WaB9WLfWYyinZx2AQv4mr6D6UhIhviIjweMmRxMLen6NlIcdu3toHV33ZuKg==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "isomorphic-ws": "^5.0.0", + "ws": "^8.7.0" + } + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/automerge-repo-storage-indexeddb": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo-storage-indexeddb/-/automerge-repo-storage-indexeddb-2.5.0.tgz", + "integrity": "sha512-7MJYJ5S6K7dHlbvs5/u/v9iexqOeprU/qQonup28r2IoVqwzjuN5ezaoVk6JRBMDI/ZxWfU4rNrqVrVlB49yXA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0" + } + }, + "node_modules/@inkandswitch/patchwork-bootloader/node_modules/@automerge/vanillajs": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/vanillajs/-/vanillajs-2.5.0.tgz", + "integrity": "sha512-18Z179fBkRYhfJOvzcz5NU+TSJOfOBez1ZQqjNnRlmHB0xwaC9P/MFuuc9ujWtJSiRAh6jzB3HxUZpCIjEfXFw==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0", + "@automerge/automerge-repo-network-broadcastchannel": "2.5.0", + "@automerge/automerge-repo-network-messagechannel": "2.5.0", + "@automerge/automerge-repo-network-websocket": "2.5.0", + "@automerge/automerge-repo-storage-indexeddb": "2.5.0" + } + }, + "node_modules/@inkandswitch/patchwork-elements": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@inkandswitch/patchwork-elements/-/patchwork-elements-0.0.5.tgz", + "integrity": "sha512-4MugOD0opAXa5c3OgsUDVq/yVwp8xe/CEXYWHt2LGPyl5AhMLKQa3t8Rk8qEZe13qMUkfR4kVKp2YdIcI9ghjw==", + "license": "MIT", + "dependencies": { + "@automerge/automerge-repo": "2.5.0", + "@inkandswitch/patchwork-filesystem": "^0.0.3", + "@inkandswitch/patchwork-plugins": "^0.0.5" + } + }, + "node_modules/@inkandswitch/patchwork-elements/node_modules/@automerge/automerge-repo": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.0.tgz", + "integrity": "sha512-bdxuMuKmxw0ZjwQXecrIX1VrHXf445bYCftNJJ5vqgGWVvINB5ZKFYAbtgPIyu1Y0TXQKvc6eqESaDeL+g8MmA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@inkandswitch/patchwork-filesystem": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@inkandswitch/patchwork-filesystem/-/patchwork-filesystem-0.0.3.tgz", + "integrity": "sha512-x6yqX1Xyr05ug4YfRyfKJ7jSm/zjhMxU7g/e70nz4QbxfLmcG98LHB9qAkFI2zd+VvKLnTvSpPGu2UvJzXGciw==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "3.2.1", + "@automerge/automerge-repo": "2.5.0", + "@types/debug": "^4.1.12", + "@types/node": "^20.17.57", + "debug": "^4.4.3", + "resolve.exports": "^2.0.3" + } + }, + "node_modules/@inkandswitch/patchwork-filesystem/node_modules/@automerge/automerge": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge/-/automerge-3.2.1.tgz", + "integrity": "sha512-xsEZlZe8lWyVCbD7Z7roH4X6ZKlRxMmmumb0M5CuxJWptUEfYsf+1z9lFEJh4aDBbWTLAgxsXd+TBi6jKTj0+g==", + "license": "MIT" + }, + "node_modules/@inkandswitch/patchwork-filesystem/node_modules/@automerge/automerge-repo": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.0.tgz", + "integrity": "sha512-bdxuMuKmxw0ZjwQXecrIX1VrHXf445bYCftNJJ5vqgGWVvINB5ZKFYAbtgPIyu1Y0TXQKvc6eqESaDeL+g8MmA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@inkandswitch/patchwork-filesystem/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@inkandswitch/patchwork-plugins": { + "version": "0.0.5", + "resolved": "https://registry.npmjs.org/@inkandswitch/patchwork-plugins/-/patchwork-plugins-0.0.5.tgz", + "integrity": "sha512-pQv5M7asDdN8J2moTmLoSnqA8FC/vcOuNJnKveL3MzjEhH0GQdIl6vV3k5jxs83ZpB8stwceE85Zsve/QRnVSA==", + "license": "ISC", + "dependencies": { + "@automerge/automerge": "3.2.1", + "@automerge/automerge-repo": "2.5.0", + "@inkandswitch/patchwork-filesystem": "^0.0.3", + "@types/debug": "^4.1.12", + "@types/node": "^20.17.57", + "debug": "^4.4.3", + "eventemitter3": "^5.0.1", + "resolve.exports": "^2.0.3" + } + }, + "node_modules/@inkandswitch/patchwork-plugins/node_modules/@automerge/automerge": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/@automerge/automerge/-/automerge-3.2.1.tgz", + "integrity": "sha512-xsEZlZe8lWyVCbD7Z7roH4X6ZKlRxMmmumb0M5CuxJWptUEfYsf+1z9lFEJh4aDBbWTLAgxsXd+TBi6jKTj0+g==", + "license": "MIT" + }, + "node_modules/@inkandswitch/patchwork-plugins/node_modules/@automerge/automerge-repo": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/@automerge/automerge-repo/-/automerge-repo-2.5.0.tgz", + "integrity": "sha512-bdxuMuKmxw0ZjwQXecrIX1VrHXf445bYCftNJJ5vqgGWVvINB5ZKFYAbtgPIyu1Y0TXQKvc6eqESaDeL+g8MmA==", + "license": "MIT", + "dependencies": { + "@automerge/automerge": "2.2.8 - 3", + "bs58check": "^3.0.1", + "cbor-x": "^1.3.0", + "debug": "^4.3.4", + "eventemitter3": "^5.0.1", + "fast-sha256": "^1.3.0", + "uuid": "^9.0.0", + "xstate": "^5.9.1" + } + }, + "node_modules/@inkandswitch/patchwork-plugins/node_modules/@types/node": { + "version": "20.19.30", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.19.30.tgz", + "integrity": "sha512-WJtwWJu7UdlvzEAUm484QNg5eAoq5QR08KDNx7g45Usrs2NtOPiX8ugDqmKdXkyL03rBqU5dYNYVQetEpBHq2g==", + "license": "MIT", + "dependencies": { + "undici-types": "~6.21.0" + } + }, + "node_modules/@keyhive/keyhive": { + "version": "0.0.0-alpha.40", + "resolved": "https://registry.npmjs.org/@keyhive/keyhive/-/keyhive-0.0.0-alpha.40.tgz", + "integrity": "sha512-FlvtX6ZK2q47OqqJZ/8G+SAevKJxjSdldhwJPlhUT9QTIv0LNmJO17pkEtLJ0VVrmPryP0tKQDIaQtmcE1f7Tg==", + "license": "Apache-2.0", + "peer": true + }, "node_modules/@lit-labs/ssr-dom-shim": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/@lit-labs/ssr-dom-shim/-/ssr-dom-shim-1.3.0.tgz", @@ -463,6 +944,18 @@ "tslib": "^2.0.1" } }, + "node_modules/@noble/hashes": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/@noble/hashes/-/hashes-1.8.0.tgz", + "integrity": "sha512-jCs9ldd7NwzpgXDIf6P3+NrHh9/sD6CQdxHyjQI+h/6rDNo88ypBxxz45UDuZHz9r3tNz7N/VInSVoVdtXEI4A==", + "license": "MIT", + "engines": { + "node": "^14.21.3 || >=16" + }, + "funding": { + "url": "https://paulmillr.com/funding/" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -794,6 +1287,15 @@ "win32" ] }, + "node_modules/@types/debug": { + "version": "4.1.12", + "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", + "integrity": "sha512-vIChWdVG3LG1SMxEvI/AK+FWJthlrqlTu7fbrlywTkkaONwk/UAGaULXRlf8vkzFBLVm0zkMdCquhL5aOjhXPQ==", + "license": "MIT", + "dependencies": { + "@types/ms": "*" + } + }, "node_modules/@types/estree": { "version": "1.0.7", "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz", @@ -801,6 +1303,12 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/ms": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/@types/ms/-/ms-2.1.0.tgz", + "integrity": "sha512-GsCCIZDE/p3i96vtEqx+7dBUGXrc7zeSK3wwPHIaRThS+9OhWIXRqzs4d6k1SVU8g91DrNRWxWUGhp5KXQb2VA==", + "license": "MIT" + }, "node_modules/@types/node": { "version": "22.14.0", "resolved": "https://registry.npmjs.org/@types/node/-/node-22.14.0.tgz", @@ -847,6 +1355,12 @@ "node": ">= 8" } }, + "node_modules/base-x": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/base-x/-/base-x-4.0.1.tgz", + "integrity": "sha512-uAZ8x6r6S3aUM9rbHGVOIsR15U/ZSc82b3ymnCPsT45Gk1DDvhDPdIgB5MrhirZWt+5K0EEPQH985kNqZgNPFw==", + "license": "MIT" + }, "node_modules/big-integer": { "version": "1.6.52", "resolved": "https://registry.npmjs.org/big-integer/-/big-integer-1.6.52.tgz", @@ -887,6 +1401,56 @@ "node": ">=8" } }, + "node_modules/bs58": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/bs58/-/bs58-5.0.0.tgz", + "integrity": "sha512-r+ihvQJvahgYT50JD05dyJNKlmmSlMoOGwn1lCcEzanPglg7TxYjioQUYehQ9mAR/+hOSd2jRc/Z2y5UxBymvQ==", + "license": "MIT", + "dependencies": { + "base-x": "^4.0.0" + } + }, + "node_modules/bs58check": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/bs58check/-/bs58check-3.0.1.tgz", + "integrity": "sha512-hjuuJvoWEybo7Hn/0xOrczQKKEKD63WguEjlhLExYs2wUBcebDC1jDNK17eEAD2lYfw82d5ASC1d7K3SWszjaQ==", + "license": "MIT", + "dependencies": { + "@noble/hashes": "^1.2.0", + "bs58": "^5.0.0" + } + }, + "node_modules/cbor-extract": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cbor-extract/-/cbor-extract-2.2.0.tgz", + "integrity": "sha512-Ig1zM66BjLfTXpNgKpvBePq271BPOvu8MR0Jl080yG7Jsl+wAZunfrwiwA+9ruzm/WEdIV5QF/bjDZTqyAIVHA==", + "hasInstallScript": true, + "license": "MIT", + "optional": true, + "dependencies": { + "node-gyp-build-optional-packages": "5.1.1" + }, + "bin": { + "download-cbor-prebuilds": "bin/download-prebuilds.js" + }, + "optionalDependencies": { + "@cbor-extract/cbor-extract-darwin-arm64": "2.2.0", + "@cbor-extract/cbor-extract-darwin-x64": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm": "2.2.0", + "@cbor-extract/cbor-extract-linux-arm64": "2.2.0", + "@cbor-extract/cbor-extract-linux-x64": "2.2.0", + "@cbor-extract/cbor-extract-win32-x64": "2.2.0" + } + }, + "node_modules/cbor-x": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/cbor-x/-/cbor-x-1.6.0.tgz", + "integrity": "sha512-0kareyRwHSkL6ws5VXHEf8uY1liitysCVJjlmhaLG+IXLqhSaOO+t63coaso7yjwEzWZzLy8fJo06gZDVQM9Qg==", + "license": "MIT", + "optionalDependencies": { + "cbor-extract": "^2.2.0" + } + }, "node_modules/chokidar": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-3.6.0.tgz", @@ -1292,9 +1856,9 @@ } }, "node_modules/debug": { - "version": "4.4.0", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.0.tgz", - "integrity": "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA==", + "version": "4.4.3", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.3.tgz", + "integrity": "sha512-RGwwWnwQvkVfavKVt22FGLw+xYSdzARwm0ru6DhTVA3umU5hZc28V3kO4stgYryrTlLpuvgI9GiijltAjNbcqA==", "license": "MIT", "dependencies": { "ms": "^2.1.3" @@ -1316,6 +1880,16 @@ "robust-predicates": "^3.0.2" } }, + "node_modules/detect-libc": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-2.1.2.tgz", + "integrity": "sha512-Btj2BOOO83o3WyH59e8MgXsxEQVcarkUOpEYrubB0urwnN10yQ364rsiByU11nZlqWYZm05i/of7io4mzihBtQ==", + "license": "Apache-2.0", + "optional": true, + "engines": { + "node": ">=8" + } + }, "node_modules/esbuild": { "version": "0.25.1", "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.1.tgz", @@ -1357,6 +1931,20 @@ "@esbuild/win32-x64": "0.25.1" } }, + "node_modules/esbuild-plugin-wasm": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/esbuild-plugin-wasm/-/esbuild-plugin-wasm-1.1.0.tgz", + "integrity": "sha512-0bQ6+1tUbySSnxzn5jnXHMDvYnT0cN/Wd4Syk8g/sqAIJUg7buTIi22svS3Qz6ssx895NT+TgLPb33xi1OkZig==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=0.10.0" + }, + "funding": { + "type": "individual", + "url": "https://ko-fi.com/tschrock" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -1369,6 +1957,12 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/eventemitter3": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-5.0.1.tgz", + "integrity": "sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==", + "license": "MIT" + }, "node_modules/fast-glob": { "version": "3.3.3", "resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.3.tgz", @@ -1386,6 +1980,12 @@ "node": ">=8.6.0" } }, + "node_modules/fast-sha256": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/fast-sha256/-/fast-sha256-1.3.0.tgz", + "integrity": "sha512-n11RGP/lrWEFI/bWdygLxhI+pVeo1ZYIVwvvPkW7azl/rOy+F3HYRZ2K5zeE9mmkhQppyv9sQFx0JM9UabnpPQ==", + "license": "Unlicense" + }, "node_modules/fastq": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.19.1.tgz", @@ -1579,6 +2179,15 @@ "resolved": "https://registry.npmjs.org/isoformat/-/isoformat-0.2.1.tgz", "integrity": "sha512-tFLRAygk9NqrRPhJSnNGh7g7oaVWDwR0wKh/GM2LgmPa50Eg4UfyaCO4I8k6EqJHl1/uh2RAD6g06n5ygEnrjQ==" }, + "node_modules/isomorphic-ws": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/isomorphic-ws/-/isomorphic-ws-5.0.0.tgz", + "integrity": "sha512-muId7Zzn9ywDsyXgTIafTry2sV3nySZeUDe6YedVd1Hvuuep5AsIlqK+XefWpYTyJG5e503F2xIuT2lcU6rCSw==", + "license": "MIT", + "peerDependencies": { + "ws": "*" + } + }, "node_modules/jsonfile": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-6.1.0.tgz", @@ -1683,6 +2292,21 @@ "lit": "2.2.6" } }, + "node_modules/node-gyp-build-optional-packages": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/node-gyp-build-optional-packages/-/node-gyp-build-optional-packages-5.1.1.tgz", + "integrity": "sha512-+P72GAjVAbTxjjwUmwjVrqrdZROD4nf8KgpBoDxqXXTiYZZt/ud60dE5yvCSr9lRO8e8yv6kgJIC0K0PfZFVQw==", + "license": "MIT", + "optional": true, + "dependencies": { + "detect-libc": "^2.0.1" + }, + "bin": { + "node-gyp-build-optional-packages": "bin.js", + "node-gyp-build-optional-packages-optional": "optional.js", + "node-gyp-build-optional-packages-test": "build-test.js" + } + }, "node_modules/normalize-path": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", @@ -1815,6 +2439,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve.exports": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-2.0.3.tgz", + "integrity": "sha512-OcXjMsGdhL4XnbShKpAcSqPMzQoYkYyhbEaeSko47MjRP9NfEQMhZkXL1DoFlt9LWQn4YttrdnV6X2OiyzBi+A==", + "license": "MIT", + "engines": { + "node": ">=10" + } + }, "node_modules/reusify": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.1.0.tgz", @@ -1865,6 +2498,13 @@ "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==" }, + "node_modules/service-worker-types": { + "name": "@types/serviceworker", + "version": "0.0.153", + "resolved": "https://registry.npmjs.org/@types/serviceworker/-/serviceworker-0.0.153.tgz", + "integrity": "sha512-/cg6dFEkNchJLyRCGo4Gb8mF200qr3xskM5dCPgbtK0OzXxcFcXa6BEBdyG7JksRsTrvCR+V6aFPncoOYAwYhQ==", + "license": "Apache-2.0" + }, "node_modules/source-map-js": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", @@ -1887,6 +2527,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/tinyargs": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/tinyargs/-/tinyargs-0.1.4.tgz", + "integrity": "sha512-5OpdhMRRE70j0zT7mrBpx12FJI+y0EGx8zMe8Vl2/aiwGgpW3X70OVHlsHmHeeG0ncnnWdq1o+k/S5d9ONgzGA==", + "license": "MIT", + "engines": { + "node": ">=14" + } + }, "node_modules/tinyglobby": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.13.tgz", @@ -1956,7 +2605,6 @@ "version": "6.21.0", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz", "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==", - "dev": true, "license": "MIT" }, "node_modules/universalify": { @@ -1969,6 +2617,19 @@ "node": ">= 10.0.0" } }, + "node_modules/uuid": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-9.0.1.tgz", + "integrity": "sha512-b+1eJOlsR9K8HJpow9Ok3fiWOWSIcIzXodvv0rQjVoOVNpWMpxf1wZNpt4y9h10odCNrqnYp1OBzRktckBe3sA==", + "funding": [ + "https://github.com/sponsors/broofa", + "https://github.com/sponsors/ctavan" + ], + "license": "MIT", + "bin": { + "uuid": "dist/bin/uuid" + } + }, "node_modules/vite": { "version": "6.4.1", "resolved": "https://registry.npmjs.org/vite/-/vite-6.4.1.tgz", @@ -2138,6 +2799,38 @@ "resolved": "https://registry.npmjs.org/web-worker/-/web-worker-1.5.0.tgz", "integrity": "sha512-RiMReJrTAiA+mBjGONMnjVDP2u3p9R1vkcGz6gDIrOMT3oGuYwX2WRMYI9ipkphSuE5XKEhydbhNEJh4NY9mlw==", "license": "Apache-2.0" + }, + "node_modules/ws": { + "version": "8.19.0", + "resolved": "https://registry.npmjs.org/ws/-/ws-8.19.0.tgz", + "integrity": "sha512-blAT2mjOEIi0ZzruJfIhb3nps74PRWTCz1IjglWEEpQl5XS/UNama6u2/rjFkDDouqr4L67ry+1aGIALViWjDg==", + "license": "MIT", + "peer": true, + "engines": { + "node": ">=10.0.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": ">=5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, + "node_modules/xstate": { + "version": "5.25.1", + "resolved": "https://registry.npmjs.org/xstate/-/xstate-5.25.1.tgz", + "integrity": "sha512-oyvsNH5pF2qkHmiHEMdWqc3OjDtoZOH2MTAI35r01f/ZQWOD+VLOiYqo65UgQET0XMA5s9eRm8fnsIo+82biEw==", + "license": "MIT", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/xstate" + } } } } diff --git a/package.json b/package.json index b21d10b01e..1b86ac6e0a 100644 --- a/package.json +++ b/package.json @@ -10,16 +10,24 @@ }, "homepage": "https://hazel.org", "dependencies": { + "@automerge/automerge-repo-keyhive": "^0.0.0-alpha.53", + "@automerge/vanillajs": "^2.5.0", "@esbuild-plugins/node-resolve": "^0.2.2", + "@inkandswitch/patchwork-bootloader": "^0.0.4", + "@inkandswitch/patchwork-elements": "^0.0.5", + "@inkandswitch/patchwork-filesystem": "^0.0.3", + "@inkandswitch/patchwork-plugins": "^0.0.5", "@observablehq/plot": "^0.6.17", "algebrite": "^1.4.0", "hotkeys-js": "^3.8.7", "ninja-keys": "^1.2.2", + "resolve.exports": "^2.0.3", "web-worker": "^1.5.0" }, "devDependencies": { "@types/node": "^22.14.0", "esbuild": "^0.25.1", + "esbuild-plugin-wasm": "^1.1.0", "vite": "^6.4.1", "vite-plugin-static-copy": "^2.3.0" } diff --git a/src/haz3lcore/ExternalProjectorBridge.re b/src/haz3lcore/ExternalProjectorBridge.re index 667e8df2e6..e3a8477527 100644 --- a/src/haz3lcore/ExternalProjectorBridge.re +++ b/src/haz3lcore/ExternalProjectorBridge.re @@ -267,7 +267,9 @@ let listener = (event: _) => { | Some(entry) => dispatch(msg, entry) | None => prerr_endline("listener: projector not found") } - | None => prerr_endline("listener: invalid message format") + | None => + //prerr_endline("listener: invalid message format") + () }; Js._true; }; diff --git a/src/haz3lcore/HazelProtocol.re b/src/haz3lcore/HazelProtocol.re index 926a55b9b2..fbf7ebdf0a 100644 --- a/src/haz3lcore/HazelProtocol.re +++ b/src/haz3lcore/HazelProtocol.re @@ -98,8 +98,8 @@ let parse_to_hazel_message = (data: Js.t(_)): option(to_hazel_message) => None; } | None => - prerr_endline("parse_to_hazel_message: missing id or wrong id format"); - None; + //prerr_endline("parse_to_hazel_message: missing id or wrong id format"); + None }; /* Convert from_hazel_message to JavaScript object */ diff --git a/src/haz3lcore/projectors/ProjectorInit.re b/src/haz3lcore/projectors/ProjectorInit.re index 1ab25acad1..9137e6cb5f 100644 --- a/src/haz3lcore/projectors/ProjectorInit.re +++ b/src/haz3lcore/projectors/ProjectorInit.re @@ -26,6 +26,7 @@ let to_module = (kind: ProjectorCore.Kind.t): (module Cooked) => )) | Graph => (module Cook(GraphProj.M)) + | Patchwork => (module Cook(PatchworkProj.M)) | ObservablePlot => (module Cook(ObservablePlotProj.M)) }; diff --git a/src/haz3lcore/projectors/implementations/PatchworkProj.re b/src/haz3lcore/projectors/implementations/PatchworkProj.re new file mode 100644 index 0000000000..f411c13148 --- /dev/null +++ b/src/haz3lcore/projectors/implementations/PatchworkProj.re @@ -0,0 +1,193 @@ +open Util; +open Virtual_dom.Vdom; +open ProjectorBase; +open Language; + +type patchwork_config = { + doc_url: string, + tool_id: string, +}; + +module Decode = { + let warn = (warnings: ref(list(string)), message: string): unit => + warnings := [message, ...warnings^]; + + let rec strip_parens = (exp: Exp.t): Exp.t => + switch (exp.term) { + | Parens(inner) => strip_parens(inner) + | _ => exp + }; + + let string_literal = (exp: Exp.t): option(string) => + switch (exp.term) { + | Atom(String(text)) => Some(text) + | _ => None + }; + + let decode_tuple = + (exp: Exp.t, warnings: ref(list(string))): option(patchwork_config) => { + let normalized: Exp.t = strip_parens(exp); + switch (normalized.term) { + | Tuple([doc_exp, tool_exp]) => + let doc_opt: option(string) = string_literal(doc_exp); + let tool_opt: option(string) = string_literal(tool_exp); + switch (doc_opt, tool_opt) { + | (Some(doc_url), Some(tool_id)) => + Some({ + doc_url, + tool_id, + }) + | _ => + if (doc_opt == None) { + warn( + warnings, + "Patchwork projector doc-url argument must be a string literal.", + ); + }; + if (tool_opt == None) { + warn( + warnings, + "Patchwork projector tool-id argument must be a string literal.", + ); + }; + None; + }; + | Tuple(_) => + warn( + warnings, + "Patchwork projector expects exactly two arguments (doc-url, tool-id).", + ); + None; + | _ => + warn( + warnings, + "Patchwork projector arguments must be provided as a tuple literal.", + ); + None; + }; + }; + + let decode_any = + (term: Any.t, warnings: ref(list(string))): option(patchwork_config) => + switch (term) { + | Exp(exp_term) => decode_tuple(exp_term, warnings) + | _ => + warn( + warnings, + "Patchwork projector is only supported for expression syntax.", + ); + None; + }; + + let decode_info = (info: info): (option(patchwork_config), list(string)) => { + let warnings: ref(list(string)) = ref([]); + let config_opt: option(patchwork_config) = + switch (info.syntax |> info.utility.seg_to_term) { + | Some(term) => decode_any(term, warnings) + | None => + warn( + warnings, + "Patchwork projector could not read the underlying syntax.", + ); + None; + }; + (config_opt, List.rev(warnings^)); + }; + + let decode_for_init = (term: Any.t): option(patchwork_config) => { + let warnings: ref(list(string)) = ref([]); + decode_any(term, warnings); + }; +}; + +let warning_list = (warnings: list(string)): Node.t => + Node.div( + ~attrs=[Attr.classes(["patchwork-warning-list"])], + List.map( + (message: string) => + Node.div( + ~attrs=[Attr.classes(["patchwork-warning-item"])], + [Node.text(message)], + ), + warnings, + ), + ); + +let patchwork_element = (config: patchwork_config): Node.t => + Node.create( + "patchwork-view", + ~attrs=[ + Attr.create("doc-url", config.doc_url), + Attr.create("tool-id", config.tool_id), + ], + [], + ); + +let error_node = (warnings: list(string)): Node.t => { + let extra_children: list(Node.t) = + switch (warnings) { + | [] => [] + | _ => [warning_list(warnings)] + }; + Node.div( + ~attrs=[Attr.classes(["patchwork-error"])], + [Node.text("Unable to render Patchwork projector.")] @ extra_children, + ); +}; + +let content_with_warnings = (content: Node.t, warnings: list(string)): Node.t => + switch (warnings) { + | [] => content + | _ => + Node.div( + ~attrs=[Attr.classes(["patchwork-container"])], + [content, warning_list(warnings)], + ) + }; + +module M: Projector = { + [@deriving (show({with_path: false}), sexp, yojson)] + type model = unit; + [@deriving (show({with_path: false}), sexp, yojson)] + type action = unit; + + let default_model: model = (); + + let init = (term: Language.Any.t): option(model) => + switch (Decode.decode_for_init(term)) { + | Some(_) => Some(default_model) + | None => None + }; + + let focusable: Focusable.t = Focusable.non; + + let dynamics: bool = false; + + let placeholder_size: ProjectorCore.Shape.t = { + horizontal: 48, + vertical: Block(18), + }; + + let placeholder = (_model: model, _info: info): ProjectorCore.Shape.t => placeholder_size; + + let update = (model: model, _info: info, _action: action): model => model; + + let view = ({info, status, _}: View.args(model, action)): View.t => { + let indicated_class: list(string) = + switch (status.indication) { + | Some(_) => ["indicated"] + | None => [] + }; + let class_list: list(string) = + ["projector", "Patchwork"] @ indicated_class; + let (config_opt, warnings) = Decode.decode_info(info); + let body: Node.t = + switch (config_opt) { + | Some(config) => + let element: Node.t = patchwork_element(config); + content_with_warnings(element, warnings); + | None => error_node(warnings) + }; + View.mk(Node.div(~attrs=[Attr.classes(class_list)], [body])); + }; +}; diff --git a/src/language/ProjectorKind.re b/src/language/ProjectorKind.re index dbe60e84da..422b66ea7f 100644 --- a/src/language/ProjectorKind.re +++ b/src/language/ProjectorKind.re @@ -27,6 +27,7 @@ type t = | Csv | Graph | ObservablePlot + | Patchwork | Exo(exo); let livelit_projectors: list(t) = @@ -43,7 +44,8 @@ let livelit_projectors: list(t) = @ List.map(x => Exo(x), all_of_exo); /* Note: Probe intentionally excluded - probes use separate action path */ -let projectors: list(t) = livelit_projectors @ [Fold, Graph, ObservablePlot]; +let projectors: list(t) = + livelit_projectors @ [Fold, Graph, ObservablePlot, Patchwork]; /* Refractors are like probes - additive decorations, not syntax-replacing */ let refractors: list(t) = [Probe, Statics]; @@ -66,6 +68,7 @@ let name = (p: t): string => | Csv => "csv" | Graph => "graph" | ObservablePlot => "ObservablePlot" + | Patchwork => "Patchwork" | Exo(exo_kind) => show_exo(exo_kind) }; @@ -85,6 +88,7 @@ let of_name = (p: string): t => | "card" => Card | "csv" => Csv | "graph" => Graph + | "Patchwork" => Patchwork | "ObservablePlot" => ObservablePlot | _ => Exo(p |> Sexplib.Sexp.of_string |> exo_of_sexp) }; diff --git a/src/web/app/editors/code/ContextMenu.re b/src/web/app/editors/code/ContextMenu.re index db9da89096..eaa7b77da9 100644 --- a/src/web/app/editors/code/ContextMenu.re +++ b/src/web/app/editors/code/ContextMenu.re @@ -421,6 +421,7 @@ module Projectors = { | Livelit => "Livelit" | Probe => "Probe" /* shouldn't appear in menu */ | Graph => "Graph" + | Patchwork => "Patchwork" | ObservablePlot => "Plot" | Exo(exo_kind) => Exo.name(exo_kind) }; diff --git a/src/web/www/assets/automerge_wasm_bg-U6EuUum1.wasm b/src/web/www/assets/automerge_wasm_bg-U6EuUum1.wasm new file mode 100644 index 0000000000..89f69a74b2 Binary files /dev/null and b/src/web/www/assets/automerge_wasm_bg-U6EuUum1.wasm differ diff --git a/src/web/www/assets/todo b/src/web/www/assets/todo new file mode 100644 index 0000000000..e69de29bb2 diff --git a/src/web/www/automerge.wasm b/src/web/www/automerge.wasm new file mode 100644 index 0000000000..23adac197c Binary files /dev/null and b/src/web/www/automerge.wasm differ diff --git a/src/web/www/build-prebundle.mjs b/src/web/www/build-prebundle.mjs new file mode 100644 index 0000000000..d86e0f9247 --- /dev/null +++ b/src/web/www/build-prebundle.mjs @@ -0,0 +1,33 @@ +#!/usr/bin/env node + +import {build} from "esbuild" +import {wasmLoader} from "esbuild-plugin-wasm" +import {fileURLToPath} from "node:url" +import path from "node:path" +import externals from "@inkandswitch/patchwork-bootloader/externals" + +const __filename = fileURLToPath(import.meta.url) +const __dirname = path.dirname(__filename) + +const entryPoint = path.join(__dirname, "prebundle.js") +const outFile = path.join(__dirname, "bundled.js") + +async function run() { + await build({ + entryPoints: [entryPoint], + bundle: true, + outfile: outFile, + absWorkingDir: __dirname, + format: "esm", + platform: "browser", + target: "esnext", + logLevel: "info", + plugins: [wasmLoader()], + external: externals, + }) +} + +run().catch(error => { + console.error(error) + process.exit(1) +}) diff --git a/src/web/www/dune b/src/web/www/dune index 6a7c57a033..6d7fbf9760 100644 --- a/src/web/www/dune +++ b/src/web/www/dune @@ -6,10 +6,10 @@ (rule (targets bundled.js) - (deps prebundle.js) + (deps + prebundle.js + (source_tree %{workspace_root}/node_modules)) (action - (run - %{project_root}/node_modules/esbuild/bin/esbuild - prebundle.js - --bundle - --outfile=bundled.js))) + (chdir + %{workspace_root} + (run node %{dep:build-prebundle.mjs})))) diff --git a/src/web/www/index.html b/src/web/www/index.html index cc3b4e9516..7bfb982b67 100644 --- a/src/web/www/index.html +++ b/src/web/www/index.html @@ -1,38 +1,65 @@ - + - - - - - - hazel - - - - + + + + + + + hazel + + + + + + + - + +
+
+
+
+
+ +
+
+ loading +
+
+ + - + - -
-
-
-
-
- -
-
- loading -
-
- - - - diff --git a/src/web/www/prebundle.js b/src/web/www/prebundle.js index f1a68d04fb..f11d340b0f 100644 --- a/src/web/www/prebundle.js +++ b/src/web/www/prebundle.js @@ -5,39 +5,82 @@ import hotkeys from "hotkeys-js"; import Algebrite from "algebrite"; import * as Plot from "@observablehq/plot"; -window.Algebrite = Algebrite; -window.Plot = Plot; +import {registerPatchworkViewElement} from "@inkandswitch/patchwork-elements" +import { + ModuleWatcher, + createFilesystemHandoffHandler, +} from "@inkandswitch/patchwork-filesystem" +import setup from "@inkandswitch/patchwork-bootloader" +import {registerPlugins, getRegistry} from "@inkandswitch/patchwork-plugins" + +import { + IndexedDBStorageAdapter, + Repo, + WebSocketClientAdapter, +} from "@automerge/vanillajs/slim" + +const repo = new Repo({ + network: [new WebSocketClientAdapter("wss://sync3.automerge.org")], + storage: new IndexedDBStorageAdapter(), +}) + +window.repo = repo + +const handoff = createFilesystemHandoffHandler(repo) +setup(async (href, request) => handoff(href, request)) + +const moduleWatcher = new ModuleWatcher( + repo, + // rabbitcounter + ["automerge:4GHeCq7k1BEhPdpPDWyF2EQFXKrG"], + (name, mod) => { + console.log("Prebundled module loaded:", name, mod) + if (Array.isArray(mod.plugins)) { + // TODO: maybe get rid of this check? + registerPlugins(mod.plugins, name) + } + } +) + +// "automerge:2kbRgPyThsqsAtFsaEV83AuQtHsr" + +//moduleWatcher.loadModules(["automerge:4GHeCq7k1BEhPdpPDWyF2EQFXKrG"]) + +registerPatchworkViewElement({repo}) + +window.Algebrite = Algebrite +window.Plot = Plot // This is the default behavior for the hotkeys module but I'm overriding it for the clipboard-shim -hotkeys.filter = (event) => { - const target = event.target || event.srcElement; - const { tagName, id } = target; - - // Override happening here - if (id == "clipboard-shim") { - return true; - } - - let flag = true; - const isInput = - tagName === "INPUT" && - ![ - "checkbox", - "radio", - "range", - "button", - "file", - "reset", - "submit", - "color", - ].includes(target.type); - // ignore: isContentEditable === 'true', and