set up mock shape server

main
Laurin Weger 3 weeks ago
parent 92a95ec6e7
commit 5f3b898b42
No known key found for this signature in database
GPG Key ID: 9B372BB0B792770F
  1. 427
      package-lock.json
  2. 12
      package.json
  3. 0
      src/frontends/react/SvelteWrapper.tsx
  4. 0
      src/frontends/react/VueWrapper.tsx
  5. 6
      src/ng-mock/js-land/connector/applyDiff.ts
  6. 4
      src/ng-mock/js-land/connector/connector.ts
  7. 33
      src/ng-mock/js-land/connector/ngSignals.ts
  8. 14
      src/ng-mock/js-land/types.ts
  9. 23
      src/ng-mock/tests/updatesWithWasm.test.ts
  10. 50
      src/ng-mock/wasm-land/handleShapeRequest.ts
  11. 20
      src/ng-mock/wasm-land/handleShapeUpdate.ts
  12. 10
      src/ng-mock/wasm-land/shapeManager.ts
  13. 17
      src/ng-mock/wasm-land/types.ts

427
package-lock.json generated

@ -11,7 +11,6 @@
"@astrojs/react": "4.3.0", "@astrojs/react": "4.3.0",
"@astrojs/svelte": "7.1.0", "@astrojs/svelte": "7.1.0",
"@astrojs/vue": "^5.1.0", "@astrojs/vue": "^5.1.0",
"@picocss/pico": "2.1.1",
"@types/react": "19.1.10", "@types/react": "19.1.10",
"@types/react-dom": "19.1.7", "@types/react-dom": "19.1.7",
"astro": "5.13.2", "astro": "5.13.2",
@ -24,7 +23,8 @@
"@types/node": "24.3.0", "@types/node": "24.3.0",
"@types/react": "19.1.10", "@types/react": "19.1.10",
"@types/react-dom": "19.1.7", "@types/react-dom": "19.1.7",
"vite": "7.1.3" "vite": "7.1.3",
"vitest": "^3.2.4"
} }
}, },
"node_modules/@ampproject/remapping": { "node_modules/@ampproject/remapping": {
@ -1359,12 +1359,6 @@
"integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==", "integrity": "sha512-70wQhgYmndg4GCPxPPxPGevRKqTIJ2Nh4OkiMWmDAVYsTQ+Ta7Sq+rPevXyXGdzr30/qZBnyOalCszoMxlyldQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/@picocss/pico": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/@picocss/pico/-/pico-2.1.1.tgz",
"integrity": "sha512-kIDugA7Ps4U+2BHxiNHmvgPIQDWPDU4IeU6TNRdvXQM1uZX+FibqDQT2xUOnnO2yq/LUHcwnGlu1hvf4KfXnMg==",
"license": "MIT"
},
"node_modules/@polka/url": { "node_modules/@polka/url": {
"version": "1.0.0-next.29", "version": "1.0.0-next.29",
"resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz", "resolved": "https://registry.npmjs.org/@polka/url/-/url-1.0.0-next.29.tgz",
@ -1563,6 +1557,16 @@
"@babel/types": "^7.28.2" "@babel/types": "^7.28.2"
} }
}, },
"node_modules/@types/chai": {
"version": "5.2.2",
"resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
"integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/deep-eql": "*"
}
},
"node_modules/@types/debug": { "node_modules/@types/debug": {
"version": "4.1.12", "version": "4.1.12",
"resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz", "resolved": "https://registry.npmjs.org/@types/debug/-/debug-4.1.12.tgz",
@ -1572,6 +1576,13 @@
"@types/ms": "*" "@types/ms": "*"
} }
}, },
"node_modules/@types/deep-eql": {
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
"integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
"dev": true,
"license": "MIT"
},
"node_modules/@types/estree": { "node_modules/@types/estree": {
"version": "1.0.8", "version": "1.0.8",
"license": "MIT" "license": "MIT"
@ -1671,6 +1682,131 @@
"vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0" "vite": "^4.2.0 || ^5.0.0 || ^6.0.0 || ^7.0.0"
} }
}, },
"node_modules/@vitest/expect": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.4.tgz",
"integrity": "sha512-Io0yyORnB6sikFlt8QW5K7slY4OjqNX9jmJQ02QDda8lyM6B5oNgVWoSoKPac8/kgnCUzuHQKrSLtu/uOqqrig==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/spy": "3.2.4",
"@vitest/utils": "3.2.4",
"chai": "^5.2.0",
"tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/mocker": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.4.tgz",
"integrity": "sha512-46ryTE9RZO/rfDd7pEqFl7etuyzekzEhUbTW3BvmeO/BcCMEgq59BKhek3dXDWgAj4oMK6OZi+vRr1wPW6qjEQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/spy": "3.2.4",
"estree-walker": "^3.0.3",
"magic-string": "^0.30.17"
},
"funding": {
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"msw": "^2.4.9",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
},
"peerDependenciesMeta": {
"msw": {
"optional": true
},
"vite": {
"optional": true
}
}
},
"node_modules/@vitest/mocker/node_modules/estree-walker": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
"integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/estree": "^1.0.0"
}
},
"node_modules/@vitest/pretty-format": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.4.tgz",
"integrity": "sha512-IVNZik8IVRJRTr9fxlitMKeJeXFFFN0JaB9PHPGQ8NKQbGpfjlTx9zO4RefN8gp7eqjNy8nyK3NZmBzOPeIxtA==",
"dev": true,
"license": "MIT",
"dependencies": {
"tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/runner": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.4.tgz",
"integrity": "sha512-oukfKT9Mk41LreEW09vt45f8wx7DordoWUZMYdY/cyAk7w5TWkTRCNZYF7sX7n2wB7jyGAl74OxgwhPgKaqDMQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/utils": "3.2.4",
"pathe": "^2.0.3",
"strip-literal": "^3.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/snapshot": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.4.tgz",
"integrity": "sha512-dEYtS7qQP2CjU27QBC5oUOxLE/v5eLkGqPE0ZKEIDGMs4vKWe7IjgLOeauHsR0D5YuuycGRO5oSRXnwnmA78fQ==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.2.4",
"magic-string": "^0.30.17",
"pathe": "^2.0.3"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/spy": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.4.tgz",
"integrity": "sha512-vAfasCOe6AIK70iP5UD11Ac4siNUNJ9i/9PZ3NKx07sG6sUxeag1LWdNrMWeKKYBLlzuK+Gn65Yd5nyL6ds+nw==",
"dev": true,
"license": "MIT",
"dependencies": {
"tinyspy": "^4.0.3"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vitest/utils": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.4.tgz",
"integrity": "sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==",
"dev": true,
"license": "MIT",
"dependencies": {
"@vitest/pretty-format": "3.2.4",
"loupe": "^3.1.4",
"tinyrainbow": "^2.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/@vue/babel-helper-vue-transform-on": { "node_modules/@vue/babel-helper-vue-transform-on": {
"version": "1.5.0", "version": "1.5.0",
"resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz", "resolved": "https://registry.npmjs.org/@vue/babel-helper-vue-transform-on/-/babel-helper-vue-transform-on-1.5.0.tgz",
@ -1994,6 +2130,16 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/assertion-error": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
"integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=12"
}
},
"node_modules/astro": { "node_modules/astro": {
"version": "5.13.2", "version": "5.13.2",
"resolved": "https://registry.npmjs.org/astro/-/astro-5.13.2.tgz", "resolved": "https://registry.npmjs.org/astro/-/astro-5.13.2.tgz",
@ -2324,6 +2470,16 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/cac": {
"version": "6.7.14",
"resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
"integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=8"
}
},
"node_modules/camelcase": { "node_modules/camelcase": {
"version": "8.0.0", "version": "8.0.0",
"resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz", "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-8.0.0.tgz",
@ -2366,6 +2522,23 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/chai": {
"version": "5.3.1",
"resolved": "https://registry.npmjs.org/chai/-/chai-5.3.1.tgz",
"integrity": "sha512-48af6xm9gQK8rhIcOxWwdGzIervm8BVTin+yRp9HEvU20BtVZ2lBywlIJBzwaDtvo0FvjeL7QdCADoUoqIbV3A==",
"dev": true,
"license": "MIT",
"dependencies": {
"assertion-error": "^2.0.1",
"check-error": "^2.1.1",
"deep-eql": "^5.0.1",
"loupe": "^3.1.0",
"pathval": "^2.0.0"
},
"engines": {
"node": ">=18"
}
},
"node_modules/chalk": { "node_modules/chalk": {
"version": "5.6.0", "version": "5.6.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz", "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.6.0.tgz",
@ -2408,6 +2581,16 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/check-error": {
"version": "2.1.1",
"resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
"integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 16"
}
},
"node_modules/chokidar": { "node_modules/chokidar": {
"version": "4.0.3", "version": "4.0.3",
"resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz", "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-4.0.3.tgz",
@ -2660,6 +2843,16 @@
"integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==", "integrity": "sha512-OUepMozQULMLUmhxS95Vudo0jb0UchLimi3+pQ2plj61Fcy8axbP9hbiD4Sz6DPqn6XG3kfmziVfQ1rSys5AJQ==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/deep-eql": {
"version": "5.0.2",
"resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
"integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=6"
}
},
"node_modules/deepmerge": { "node_modules/deepmerge": {
"version": "4.3.1", "version": "4.3.1",
"resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz", "resolved": "https://registry.npmjs.org/deepmerge/-/deepmerge-4.3.1.tgz",
@ -2945,6 +3138,16 @@
"url": "https://github.com/sindresorhus/execa?sponsor=1" "url": "https://github.com/sindresorhus/execa?sponsor=1"
} }
}, },
"node_modules/expect-type": {
"version": "1.2.2",
"resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.2.tgz",
"integrity": "sha512-JhFGDVJ7tmDJItKhYgJCGLOWjuK9vPxiXoUFLwLDc99NlmklilbiQJwoctZtt13+xMw91MCk/REan6MWHqDjyA==",
"dev": true,
"license": "Apache-2.0",
"engines": {
"node": ">=12.0.0"
}
},
"node_modules/extend": { "node_modules/extend": {
"version": "3.0.2", "version": "3.0.2",
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
@ -3568,6 +3771,13 @@
"url": "https://github.com/sponsors/wooorm" "url": "https://github.com/sponsors/wooorm"
} }
}, },
"node_modules/loupe": {
"version": "3.2.0",
"resolved": "https://registry.npmjs.org/loupe/-/loupe-3.2.0.tgz",
"integrity": "sha512-2NCfZcT5VGVNX9mSZIxLRkEAegDGBpuQZBy13desuHeVORmBDyAET4TkJr4SjqQy3A8JDofMN6LpkK8Xcm/dlw==",
"dev": true,
"license": "MIT"
},
"node_modules/lower-case": { "node_modules/lower-case": {
"version": "2.0.2", "version": "2.0.2",
"resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz",
@ -4738,6 +4948,16 @@
"integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==", "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/pathval": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.1.tgz",
"integrity": "sha512-//nshmD55c46FuFw26xV/xFAaB5HF9Xdap7HJBBnrKdAd6/GxDBaNA1870O79+9ueg61cZLSVc+OaFlfmObYVQ==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">= 14.16"
}
},
"node_modules/perfect-debounce": { "node_modules/perfect-debounce": {
"version": "1.0.0", "version": "1.0.0",
"resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz", "resolved": "https://registry.npmjs.org/perfect-debounce/-/perfect-debounce-1.0.0.tgz",
@ -5276,6 +5496,13 @@
"@types/hast": "^3.0.4" "@types/hast": "^3.0.4"
} }
}, },
"node_modules/siginfo": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
"integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
"dev": true,
"license": "ISC"
},
"node_modules/signal-exit": { "node_modules/signal-exit": {
"version": "4.1.0", "version": "4.1.0",
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
@ -5356,6 +5583,20 @@
"node": ">=0.10.0" "node": ">=0.10.0"
} }
}, },
"node_modules/stackback": {
"version": "0.0.2",
"resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
"integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
"dev": true,
"license": "MIT"
},
"node_modules/std-env": {
"version": "3.9.0",
"resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
"integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
"dev": true,
"license": "MIT"
},
"node_modules/string-width": { "node_modules/string-width": {
"version": "7.2.0", "version": "7.2.0",
"resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz", "resolved": "https://registry.npmjs.org/string-width/-/string-width-7.2.0.tgz",
@ -5414,6 +5655,26 @@
"url": "https://github.com/sponsors/sindresorhus" "url": "https://github.com/sponsors/sindresorhus"
} }
}, },
"node_modules/strip-literal": {
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/strip-literal/-/strip-literal-3.0.0.tgz",
"integrity": "sha512-TcccoMhJOM3OebGhSBEmp3UZ2SfDMZUEBdRA/9ynfLi8yYajyWX3JiXArcJt4Umh4vISpspkQIY8ZZoCqjbviA==",
"dev": true,
"license": "MIT",
"dependencies": {
"js-tokens": "^9.0.1"
},
"funding": {
"url": "https://github.com/sponsors/antfu"
}
},
"node_modules/strip-literal/node_modules/js-tokens": {
"version": "9.0.1",
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-9.0.1.tgz",
"integrity": "sha512-mxa9E9ITFOt0ban3j6L5MpjwegGz6lBQmM1IJkWeBZGcMxto50+eWdjC/52xDbS2vy0k7vIMK0Fe2wfL9OQSpQ==",
"dev": true,
"license": "MIT"
},
"node_modules/superjson": { "node_modules/superjson": {
"version": "2.2.2", "version": "2.2.2",
"resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz", "resolved": "https://registry.npmjs.org/superjson/-/superjson-2.2.2.tgz",
@ -5469,6 +5730,13 @@
"integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==", "integrity": "sha512-pkY1fj1cKHb2seWDy0B16HeWyczlJA9/WW3u3c4z/NiWDsO3DOU5D7nhTLE9CF0yXv/QZFY7sEJmj24dK+Rrqw==",
"license": "MIT" "license": "MIT"
}, },
"node_modules/tinybench": {
"version": "2.9.0",
"resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
"integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
"dev": true,
"license": "MIT"
},
"node_modules/tinyexec": { "node_modules/tinyexec": {
"version": "0.3.2", "version": "0.3.2",
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz", "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
@ -5489,6 +5757,36 @@
"url": "https://github.com/sponsors/SuperchupuDev" "url": "https://github.com/sponsors/SuperchupuDev"
} }
}, },
"node_modules/tinypool": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.1.tgz",
"integrity": "sha512-Zba82s87IFq9A9XmjiX5uZA/ARWDrB03OHlq+Vw1fSdt0I+4/Kutwy8BP4Y/y/aORMo61FQ0vIb5j44vSo5Pkg==",
"dev": true,
"license": "MIT",
"engines": {
"node": "^18.0.0 || >=20.0.0"
}
},
"node_modules/tinyrainbow": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
"integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/tinyspy": {
"version": "4.0.3",
"resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz",
"integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==",
"dev": true,
"license": "MIT",
"engines": {
"node": ">=14.0.0"
}
},
"node_modules/totalist": { "node_modules/totalist": {
"version": "3.0.1", "version": "3.0.1",
"resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz", "resolved": "https://registry.npmjs.org/totalist/-/totalist-3.0.1.tgz",
@ -6046,6 +6344,29 @@
"vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0" "vite": "^2.6.0 || ^3.0.0 || ^4.0.0 || ^5.0.0-0 || ^6.0.0-0 || ^7.0.0-0"
} }
}, },
"node_modules/vite-node": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.4.tgz",
"integrity": "sha512-EbKSKh+bh1E1IFxeO0pg1n4dvoOTt0UDiXMd/qn++r98+jPO1xtJilvXldeuQ8giIB5IkpjCgMleHMNEsGH6pg==",
"dev": true,
"license": "MIT",
"dependencies": {
"cac": "^6.7.14",
"debug": "^4.4.1",
"es-module-lexer": "^1.7.0",
"pathe": "^2.0.3",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
},
"bin": {
"vite-node": "vite-node.mjs"
},
"engines": {
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
}
},
"node_modules/vite-plugin-vue-devtools": { "node_modules/vite-plugin-vue-devtools": {
"version": "7.7.7", "version": "7.7.7",
"resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.7.tgz", "resolved": "https://registry.npmjs.org/vite-plugin-vue-devtools/-/vite-plugin-vue-devtools-7.7.7.tgz",
@ -6137,6 +6458,79 @@
} }
} }
}, },
"node_modules/vitest": {
"version": "3.2.4",
"resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.4.tgz",
"integrity": "sha512-LUCP5ev3GURDysTWiP47wRRUpLKMOfPh+yKTx3kVIEiu5KOMeqzpnYNsKyOoVrULivR8tLcks4+lga33Whn90A==",
"dev": true,
"license": "MIT",
"dependencies": {
"@types/chai": "^5.2.2",
"@vitest/expect": "3.2.4",
"@vitest/mocker": "3.2.4",
"@vitest/pretty-format": "^3.2.4",
"@vitest/runner": "3.2.4",
"@vitest/snapshot": "3.2.4",
"@vitest/spy": "3.2.4",
"@vitest/utils": "3.2.4",
"chai": "^5.2.0",
"debug": "^4.4.1",
"expect-type": "^1.2.1",
"magic-string": "^0.30.17",
"pathe": "^2.0.3",
"picomatch": "^4.0.2",
"std-env": "^3.9.0",
"tinybench": "^2.9.0",
"tinyexec": "^0.3.2",
"tinyglobby": "^0.2.14",
"tinypool": "^1.1.1",
"tinyrainbow": "^2.0.0",
"vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
"vite-node": "3.2.4",
"why-is-node-running": "^2.3.0"
},
"bin": {
"vitest": "vitest.mjs"
},
"engines": {
"node": "^18.0.0 || ^20.0.0 || >=22.0.0"
},
"funding": {
"url": "https://opencollective.com/vitest"
},
"peerDependencies": {
"@edge-runtime/vm": "*",
"@types/debug": "^4.1.12",
"@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
"@vitest/browser": "3.2.4",
"@vitest/ui": "3.2.4",
"happy-dom": "*",
"jsdom": "*"
},
"peerDependenciesMeta": {
"@edge-runtime/vm": {
"optional": true
},
"@types/debug": {
"optional": true
},
"@types/node": {
"optional": true
},
"@vitest/browser": {
"optional": true
},
"@vitest/ui": {
"optional": true
},
"happy-dom": {
"optional": true
},
"jsdom": {
"optional": true
}
}
},
"node_modules/vue": { "node_modules/vue": {
"version": "3.5.19", "version": "3.5.19",
"license": "MIT", "license": "MIT",
@ -6206,6 +6600,23 @@
"node": ">=4" "node": ">=4"
} }
}, },
"node_modules/why-is-node-running": {
"version": "2.3.0",
"resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
"integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
"dev": true,
"license": "MIT",
"dependencies": {
"siginfo": "^2.0.0",
"stackback": "0.0.2"
},
"bin": {
"why-is-node-running": "cli.js"
},
"engines": {
"node": ">=8"
}
},
"node_modules/widest-line": { "node_modules/widest-line": {
"version": "5.0.0", "version": "5.0.0",
"resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz", "resolved": "https://registry.npmjs.org/widest-line/-/widest-line-5.0.0.tgz",

@ -8,15 +8,16 @@
"start": "astro dev", "start": "astro dev",
"build": "astro build", "build": "astro build",
"preview": "astro preview", "preview": "astro preview",
"astro": "astro" "astro": "astro",
"test": "vitest"
}, },
"dependencies": { "dependencies": {
"@types/react": "19.1.10",
"@types/react-dom": "19.1.7",
"astro": "5.13.2",
"@astrojs/react": "4.3.0", "@astrojs/react": "4.3.0",
"@astrojs/svelte": "7.1.0", "@astrojs/svelte": "7.1.0",
"@astrojs/vue": "^5.1.0", "@astrojs/vue": "^5.1.0",
"@types/react": "19.1.10",
"@types/react-dom": "19.1.7",
"astro": "5.13.2",
"react": "19.1.1", "react": "19.1.1",
"react-dom": "19.1.1", "react-dom": "19.1.1",
"svelte": "5.38.2", "svelte": "5.38.2",
@ -26,6 +27,7 @@
"@types/node": "24.3.0", "@types/node": "24.3.0",
"@types/react": "19.1.10", "@types/react": "19.1.10",
"@types/react-dom": "19.1.7", "@types/react-dom": "19.1.7",
"vite": "7.1.3" "vite": "7.1.3",
"vitest": "^3.2.4"
} }
} }

@ -0,0 +1,6 @@
import type { Diff } from "../types";
/** Mock function to apply diffs. Just uses a copy of the diff as the new object. */
export function applyDiff(currentState: object, diff: Diff): object {
return JSON.parse(JSON.stringify(diff));
}

@ -1,4 +0,0 @@
// Requires functions
// - initializeConnection
// - sendUpdateToDb
// - onDbUpdate

@ -1,2 +1,31 @@
// Requires functions import handleShapeUpdate from "src/ng-mock/wasm-land/handleShapeUpdate";
// - createSignalForShape() import type { Connection, Diff, Scope, Shape } from "../types";
import handleShapeRequest from "src/ng-mock/wasm-land/handleShapeRequest";
import { applyDiff } from "./applyDiff";
export async function createSignalObjectForShape(shape: Shape, scope?: Scope) {
const ret: {
state?: any;
connectionId?: Connection["id"];
update: (diff: Diff) => Promise<void>;
} = {
async update(diff) {
if (!ret.connectionId)
throw new Error("Connection not established yet for shape" + shape);
await handleShapeUpdate(ret.connectionId, diff);
},
};
const onDbUpdate = (diff: Diff) => {
ret.state = applyDiff(ret.state || {}, diff);
};
await handleShapeRequest(shape, onDbUpdate).then(
({ connectionId, shapeObject }) => {
ret.state = shapeObject;
ret.connectionId = connectionId;
}
);
return ret;
}

@ -0,0 +1,14 @@
/** The shape of an object requested. */
export type Shape = "Shape1" | "Shape2";
/** The Scope of a shape request */
export type Scope = string | string[];
/** The diff format used to communicate updates between wasm-land and js-land. */
export type Diff = object;
/** A connection established between wasm-land and js-land for subscription of a shape. */
export type Connection = {
id: string;
onUpdateFromWasm: (diff: Diff) => void;
};

@ -0,0 +1,23 @@
import { expect, test } from "vitest";
import { createSignalObjectForShape } from "../js-land/connector/ngSignals";
test("shape object notification comes back to others", async () => {
const object1 = await createSignalObjectForShape("Shape1");
const object2 = await createSignalObjectForShape("Shape1");
const object3 = await createSignalObjectForShape("Shape2");
const object4 = await createSignalObjectForShape("Shape2");
// Update object 1 and expect object 2 to update as well.
await object1.update({ name: "Updated name from object1" });
expect(object2.state?.name).toBe("Updated name from object1");
// Expect object of different shape not to have changed.
expect(object3.state?.name).toBe("Niko's cat");
// Update object 4 and expect object 3 with same shape to have updated.
await object4.update({ name: "Updated name from object4" });
expect(object3.state?.name).toBe("Updated name from object4");
});

@ -0,0 +1,50 @@
import { randomUUID } from "crypto";
import * as shapeManager from "./shapeManager";
import type { WasmConnection, Diff } from "./types";
import type { Shape } from "../js-land/types";
const mockShapeObject1 = {
type: "Person",
name: "Bob",
address: {
street: "First street",
houseNumber: "15",
},
hasChildren: true,
numberOfHouses: 0,
};
const mockShapeObject2 = {
type: "Cat",
name: "Niko's cat",
age: 12,
numberOfHomes: 3,
address: {
street: "Niko's street",
compartment: 2,
},
};
export default async function handleShapeRequest(
shape: Shape,
callback: (diff: Diff, connectionId: WasmConnection["id"]) => void
): Promise<{
connectionId: string;
shapeObject: object;
}> {
const connection: WasmConnection = {
id: randomUUID(),
shape,
// Create a deep copy to prevent accidental by-reference changes.
state: JSON.parse(
JSON.stringify(shape === "Shape1" ? mockShapeObject1 : mockShapeObject2)
),
callback,
};
shapeManager.connections.set(connection.id, connection);
return {
connectionId: connection.id,
shapeObject: connection.state,
};
}

@ -0,0 +1,20 @@
import * as shapeManager from "./shapeManager";
import type { WasmConnection, Diff } from "./types";
export default async function handleShapeUpdate(
connectionId: WasmConnection["id"],
diff: Diff
) {
const connection = shapeManager.connections.get(connectionId);
if (!connection) throw new Error("No Connection found.");
const newState = shapeManager.applyDiff(connection.state, diff);
connection.state = newState;
shapeManager.connections.forEach((con) => {
if (con.shape == connection.shape) {
con.state = newState;
con.callback(diff, con.id);
}
});
}

@ -0,0 +1,10 @@
import type { Diff, ObjectState, WasmConnection } from "./types";
const connections: Map<WasmConnection["id"], WasmConnection> = new Map();
/** Mock function to apply diffs. Just uses a copy of the diff as the new object. */
export function applyDiff(currentState: ObjectState, diff: Diff): ObjectState {
return JSON.parse(JSON.stringify(diff));
}
export { connections };

@ -0,0 +1,17 @@
import type { Shape } from "../js-land/types";
/** The Scope of a shape request */
export type Scope = string | string[];
/** The diff format used to communicate updates between wasm-land and js-land. */
export type Diff = object;
export type ObjectState = object;
/** A connection established between wasm-land and js-land for subscription of a shape. */
export type WasmConnection = {
id: string;
shape: Shape;
state: ObjectState;
callback: (diff: Diff, connectionId: WasmConnection["id"]) => void;
};
Loading…
Cancel
Save