From 0b9d3a36d6e9cdb14b32cb2b44fa2ea791abc767 Mon Sep 17 00:00:00 2001 From: Jacob Bolda Date: Wed, 29 May 2024 23:01:09 -0500 Subject: [PATCH] wire up simulation store with non-optimal TS --- package-lock.json | 291 +++++++++++++++++++++++++--- packages/foundation/index.ts | 115 ++++++----- packages/foundation/package.json | 3 +- packages/foundation/server.ts | 51 +++-- packages/foundation/store/index.ts | 44 +++++ packages/foundation/store/schema.ts | 23 +++ packages/foundation/store/setup.ts | 42 ++++ packages/foundation/store/thunks.ts | 9 + 8 files changed, 495 insertions(+), 83 deletions(-) create mode 100644 packages/foundation/store/index.ts create mode 100644 packages/foundation/store/schema.ts create mode 100644 packages/foundation/store/setup.ts create mode 100644 packages/foundation/store/thunks.ts diff --git a/package-lock.json b/package-lock.json index f989f7df..2ca5e4fd 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1066,7 +1066,6 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", - "dev": true, "dependencies": { "regenerator-runtime": "^0.13.11" }, @@ -4437,6 +4436,15 @@ "version": "5.5.5", "integrity": "sha512-TNR5SjCg8sSfU4bdXsPJlpLXOH4YGBCVggvdZnttD2SMiONSxfJm231Nxn1VaQWWF2Twl4Wr2KC1hYaNd4M5Zw==" }, + "node_modules/@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "dependencies": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.3", "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", @@ -4537,6 +4545,11 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, + "node_modules/@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, "node_modules/@types/qs": { "version": "6.9.6", "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", @@ -4547,6 +4560,15 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "devOptional": true }, + "node_modules/@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "dependencies": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, "node_modules/@types/seedrandom": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.1.tgz", @@ -4567,6 +4589,11 @@ "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, + "node_modules/@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "node_modules/@types/uuid": { "version": "8.3.0", "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==", @@ -6395,6 +6422,11 @@ "node": ">=8.0.0" } }, + "node_modules/csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "node_modules/dataloader": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.1.0.tgz", @@ -8181,6 +8213,19 @@ "tslib": "^2.0.3" } }, + "node_modules/hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": { + "react-is": "^16.7.0" + } + }, + "node_modules/hoist-non-react-statics/node_modules/react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, "node_modules/homedir-polyfill": { "version": "1.0.3", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", @@ -8383,6 +8428,15 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "node_modules/immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==", + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/immer" + } + }, "node_modules/immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", @@ -9383,7 +9437,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "dependencies": { "js-tokens": "^3.0.0 || ^4.0.0" }, @@ -10783,7 +10836,6 @@ "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -10793,8 +10845,7 @@ "node_modules/prop-types/node_modules/react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/proxy-addr": { "version": "2.0.7", @@ -10903,7 +10954,6 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -10917,7 +10967,7 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dev": true, + "devOptional": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -10989,8 +11039,7 @@ "node_modules/regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "node_modules/regexpp": { "version": "3.2.0", @@ -11075,6 +11124,11 @@ "node": ">=0.10.5" } }, + "node_modules/reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "node_modules/resolve-dir": { "version": "0.1.1", "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", @@ -11188,7 +11242,7 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dev": true, + "devOptional": true, "dependencies": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -12470,6 +12524,14 @@ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" }, + "node_modules/use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "peerDependencies": { + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + } + }, "node_modules/utf-8-validate": { "version": "5.0.6", "integrity": "sha512-hoY0gOf9EkCw+nimK21FVKHUIG1BMqSiRwxB/q3A9yKZOrOI99PP77BxmarDqWz6rG3vVYiBWfhG8z2Tl+7fZA==", @@ -12989,7 +13051,88 @@ "dependencies": { "express": "^4.19.2", "openapi-backend": "^5.10.6", - "openapi-merge": "^1.3.2" + "openapi-merge": "^1.3.2", + "starfx": "^0.12.0" + } + }, + "packages/foundation/node_modules/effection": { + "version": "3.0.0-beta.3", + "resolved": "https://registry.npmjs.org/effection/-/effection-3.0.0-beta.3.tgz", + "integrity": "sha512-OamLXbd8EdW9z6gIjfJ4c1MJykE/J5Q++j1wC8m6CNXatiETJtdF3lIwgrIRklKjQOYfW47tMgTllmHpHzR3fA==", + "engines": { + "node": ">= 16" + } + }, + "packages/foundation/node_modules/react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "peer": true, + "dependencies": { + "loose-envify": "^1.1.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "packages/foundation/node_modules/react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "packages/foundation/node_modules/react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "dependencies": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + }, + "peerDependencies": { + "@types/react": "^16.8 || ^17.0 || ^18.0", + "@types/react-dom": "^16.8 || ^17.0 || ^18.0", + "react": "^16.8 || ^17.0 || ^18.0", + "react-dom": "^16.8 || ^17.0 || ^18.0", + "react-native": ">=0.59", + "redux": "^4 || ^5.0.0-beta.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + }, + "@types/react-dom": { + "optional": true + }, + "react-dom": { + "optional": true + }, + "react-native": { + "optional": true + }, + "redux": { + "optional": true + } + } + }, + "packages/foundation/node_modules/starfx": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/starfx/-/starfx-0.12.0.tgz", + "integrity": "sha512-3hgYrKTTT77nLHVNAWnEQnMWAs2BfSjH3CK/0RV3aoLmoiKB5nBpzbjvC4xNrISlkFOjClOMkGi9RTgMtMs97Q==", + "dependencies": { + "effection": "3.0.0-beta.3", + "immer": "^10.0.2", + "react-redux": "^8.0.5", + "reselect": "^4.1.8" + }, + "engines": { + "node": ">= 18" + }, + "peerDependencies": { + "react": "^18.2.0" } }, "packages/github-api": { @@ -13884,7 +14027,6 @@ "version": "7.20.6", "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.20.6.tgz", "integrity": "sha512-Q+8MqP7TiHMWzSfwiJwXCjyf4GYA4Dgw3emg/7xmwsdLJOZUp+nMqcOwOzzYheuM1rhDu8FSj2l0aoMygEuXuA==", - "dev": true, "requires": { "regenerator-runtime": "^0.13.11" } @@ -16395,7 +16537,53 @@ "requires": { "express": "^4.19.2", "openapi-backend": "^5.10.6", - "openapi-merge": "^1.3.2" + "openapi-merge": "^1.3.2", + "starfx": "^0.12.0" + }, + "dependencies": { + "effection": { + "version": "3.0.0-beta.3", + "resolved": "https://registry.npmjs.org/effection/-/effection-3.0.0-beta.3.tgz", + "integrity": "sha512-OamLXbd8EdW9z6gIjfJ4c1MJykE/J5Q++j1wC8m6CNXatiETJtdF3lIwgrIRklKjQOYfW47tMgTllmHpHzR3fA==" + }, + "react": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react/-/react-18.3.1.tgz", + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "peer": true, + "requires": { + "loose-envify": "^1.1.0" + } + }, + "react-is": { + "version": "18.3.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-18.3.1.tgz", + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "react-redux": { + "version": "8.1.3", + "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-8.1.3.tgz", + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "requires": { + "@babel/runtime": "^7.12.1", + "@types/hoist-non-react-statics": "^3.3.1", + "@types/use-sync-external-store": "^0.0.3", + "hoist-non-react-statics": "^3.3.2", + "react-is": "^18.0.0", + "use-sync-external-store": "^1.0.0" + } + }, + "starfx": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/starfx/-/starfx-0.12.0.tgz", + "integrity": "sha512-3hgYrKTTT77nLHVNAWnEQnMWAs2BfSjH3CK/0RV3aoLmoiKB5nBpzbjvC4xNrISlkFOjClOMkGi9RTgMtMs97Q==", + "requires": { + "effection": "3.0.0-beta.3", + "immer": "^10.0.2", + "react-redux": "^8.0.5", + "reselect": "^4.1.8" + } + } } }, "@simulacrum/github-api-simulator": { @@ -16644,6 +16832,15 @@ "version": "5.5.5", "integrity": "sha512-TNR5SjCg8sSfU4bdXsPJlpLXOH4YGBCVggvdZnttD2SMiONSxfJm231Nxn1VaQWWF2Twl4Wr2KC1hYaNd4M5Zw==" }, + "@types/hoist-non-react-statics": { + "version": "3.3.5", + "resolved": "https://registry.npmjs.org/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.5.tgz", + "integrity": "sha512-SbcrWzkKBw2cdwRTwQAswfpB9g9LJWfjtUeW/jvNwbhC8cpmmNYVePa+ncbUe0rGTQ7G3Ff6mYUN2VMfLVr+Sg==", + "requires": { + "@types/react": "*", + "hoist-non-react-statics": "^3.3.0" + } + }, "@types/istanbul-lib-coverage": { "version": "2.0.3", "integrity": "sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==", @@ -16744,6 +16941,11 @@ "resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.0.tgz", "integrity": "sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==" }, + "@types/prop-types": { + "version": "15.7.12", + "resolved": "https://registry.npmjs.org/@types/prop-types/-/prop-types-15.7.12.tgz", + "integrity": "sha512-5zvhXYtRNRluoE/jAp4GVsSduVUzNWKkOZrCDBWYtE7biZywwdC2AcEzg+cSMLFRfVgeAFqpfNabiPjxFddV1Q==" + }, "@types/qs": { "version": "6.9.6", "integrity": "sha512-0/HnwIfW4ki2D8L8c9GVcG5I72s9jP5GSLVF0VIXDW00kmIpA6O33G7a8n59Tmh7Nz0WUC3rSb7PTY/sdW2JzA==", @@ -16754,6 +16956,15 @@ "integrity": "sha512-ewFXqrQHlFsgc09MK5jP5iR7vumV/BYayNC6PgJO2LPe8vrnNFyjQjSppfEngITi0qvfKtzFvgKymGheFM9UOA==", "devOptional": true }, + "@types/react": { + "version": "18.3.3", + "resolved": "https://registry.npmjs.org/@types/react/-/react-18.3.3.tgz", + "integrity": "sha512-hti/R0pS0q1/xx+TsI73XIqk26eBsISZ2R0wUijXIngRK9R/e7Xw/cXVxQK7R5JjW+SV4zGcn5hXjudkN/pLIw==", + "requires": { + "@types/prop-types": "*", + "csstype": "^3.0.2" + } + }, "@types/seedrandom": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/@types/seedrandom/-/seedrandom-3.0.1.tgz", @@ -16774,6 +16985,11 @@ "integrity": "sha512-RJJrrySY7A8havqpGObOB4W92QXKJo63/jFLLgpvOtsGUqbQZ9Sbgl35KMm1DjC6j7AvmmU2bIno+3IyEaemaw==", "dev": true }, + "@types/use-sync-external-store": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz", + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, "@types/uuid": { "version": "8.3.0", "integrity": "sha512-eQ9qFW/fhfGJF8WKHGEHZEyVWfZxrT+6CLIJGBcZPfxUh/+BnEj+UCGYMlr9qZuX/2AltsvwrGqp0LhEW8D0zQ==", @@ -18126,6 +18342,11 @@ "css-tree": "^1.1.2" } }, + "csstype": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz", + "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==" + }, "dataloader": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/dataloader/-/dataloader-2.1.0.tgz", @@ -19453,6 +19674,21 @@ "tslib": "^2.0.3" } }, + "hoist-non-react-statics": { + "version": "3.3.2", + "resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz", + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "requires": { + "react-is": "^16.7.0" + }, + "dependencies": { + "react-is": { + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + } + } + }, "homedir-polyfill": { "version": "1.0.3", "integrity": "sha512-eSmmWE5bZTK2Nou4g0AI3zZ9rswp7GRKoKXS1BLUkvPviOqs4YTN1djQIqrXy9k5gEtdLPy86JjRwsNM9tnDcA==", @@ -19569,6 +19805,11 @@ "integrity": "sha512-Ius2VYcGNk7T90CppJqcIkS5ooHUZyIQK+ClZfMfMNFEF9VSE73Fq+906u/CWu92x4gzZMWOwfFYckPObzdEbA==", "dev": true }, + "immer": { + "version": "10.1.1", + "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz", + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==" + }, "immutable": { "version": "3.7.6", "resolved": "https://registry.npmjs.org/immutable/-/immutable-3.7.6.tgz", @@ -20284,7 +20525,6 @@ "version": "1.4.0", "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dev": true, "requires": { "js-tokens": "^3.0.0 || ^4.0.0" } @@ -21338,7 +21578,6 @@ "version": "15.7.2", "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dev": true, "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", @@ -21348,8 +21587,7 @@ "react-is": { "version": "16.13.1", "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", - "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==", - "dev": true + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" } } }, @@ -21428,7 +21666,6 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react/-/react-16.14.0.tgz", "integrity": "sha512-0X2CImDkJGApiAlcf0ODKIneSwBPhqJawOa5wCtKbu7ZECrmS26NvtSILynQ66cgkT/RJ4LidJOc3bUESwmU8g==", - "dev": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -21439,7 +21676,7 @@ "version": "16.14.0", "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.14.0.tgz", "integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==", - "dev": true, + "devOptional": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1", @@ -21501,8 +21738,7 @@ "regenerator-runtime": { "version": "0.13.11", "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz", - "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==", - "dev": true + "integrity": "sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==" }, "regexpp": { "version": "3.2.0", @@ -21566,6 +21802,11 @@ "integrity": "sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww==", "dev": true }, + "reselect": { + "version": "4.1.8", + "resolved": "https://registry.npmjs.org/reselect/-/reselect-4.1.8.tgz", + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, "resolve-dir": { "version": "0.1.1", "integrity": "sha1-shklmlYC+sXFxJatiUpujMQwJh4=", @@ -21642,7 +21883,7 @@ "version": "0.19.1", "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.19.1.tgz", "integrity": "sha512-n/zwRWRYSUj0/3g/otKDRPMh6qv2SYMWNq85IEa8iZyAv8od9zDYpGSnpBEjNgcMNq6Scbu5KfIPxNF72R/2EA==", - "dev": true, + "devOptional": true, "requires": { "loose-envify": "^1.1.0", "object-assign": "^4.1.1" @@ -22616,6 +22857,12 @@ "resolved": "https://registry.npmjs.org/urijs/-/urijs-1.19.11.tgz", "integrity": "sha512-HXgFDgDommxn5/bIv0cnQZsPhHDA90NPHD6+c/v21U5+Sx5hoP8+dP9IZXBU1gIfvdRfhG8cel9QNPeionfcCQ==" }, + "use-sync-external-store": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.2.2.tgz", + "integrity": "sha512-PElTlVMwpblvbNqQ82d2n6RjStvdSoNe9FG28kNfz3WiXilJm4DdNkEzRhCZuIDwY8U08WVihhGR5iRqAwfDiw==", + "requires": {} + }, "utf-8-validate": { "version": "5.0.6", "integrity": "sha512-hoY0gOf9EkCw+nimK21FVKHUIG1BMqSiRwxB/q3A9yKZOrOI99PP77BxmarDqWz6rG3vVYiBWfhG8z2Tl+7fZA==", diff --git a/packages/foundation/index.ts b/packages/foundation/index.ts index bb8f4ad6..24310d83 100644 --- a/packages/foundation/index.ts +++ b/packages/foundation/index.ts @@ -2,70 +2,87 @@ import express from "express"; import { merge } from "lodash"; import type { Handler, Request, Document } from "openapi-backend"; import OpenAPIBackend from "openapi-backend"; +import type { SimulationStore } from "./store"; +import { createSimulationStore } from "./store"; +import type { SimulationInputSchema } from "./store/schema"; + +type RecursivePartial = { + // eslint-disable-next-line @typescript-eslint/no-unused-vars + [P in keyof T]?: RecursivePartial; +}; export async function startServerStandalone({ - oas, - handlers, + openapi, port = 9000, - apiRoot, + extendStore = { actions: {}, schema: {} }, extend, }: { - oas: Document | [Document, Partial]; - handlers: Record>; + openapi?: { + document: Document | [Document, RecursivePartial]; + handlers: ({ + simulationStore, + }: { + simulationStore: SimulationStore; + }) => Record>; + apiRoot?: string; + }; port: number; - apiRoot?: string; - extend?(router: express.Router): void; + extendStore?: { actions: any; schema: SimulationInputSchema }; + extend?(router: express.Router, simulationStore: SimulationStore): void; }) { - // TODO init store - - let mergedOAS = Array.isArray(oas) ? merge(oas[0], oas[1]) : oas; + let app = express(); + app.use(express.json()); + let simulationStore = createSimulationStore(extendStore); + if (extend) { + extend(app, simulationStore); + } - let api = new OpenAPIBackend({ definition: mergedOAS, apiRoot }); + if (openapi) { + let { document, handlers, apiRoot } = openapi; + let mergedOAS = Array.isArray(document) + ? merge(document[0], document[1]) + : document; - // register your framework specific request handlers here - let handlerObjectRegistration = ( - handlerEntries: Record>, - prefix?: string - ) => { - for (let [key, handler] of Object.entries(handlerEntries)) { - if (typeof handler === "object") { - handlerObjectRegistration(handler, key); - } else { - api.register(`${prefix ? `${prefix}/` : ""}${key}`, handler); - } - } - }; - handlerObjectRegistration(handlers); // TODO pass store to handlers + let api = new OpenAPIBackend({ definition: mergedOAS, apiRoot }); - api.register({ - // getPets: (c, req, res) => res.status(200).json({ result: "ok" }), - validationFail: (c, req, res) => - res.status(400).json({ err: c.validation.errors }), - notFound: (c, req, res) => res.status(404).json({ err: "not found" }), - notImplemented: (c, req, res) => { - if (!c.operation.operationId) { - return res - .status(404) - .json({ status: 501, err: "No handler registered for operation" }); + // register your framework specific request handlers here + let handlerObjectRegistration = ( + handlerEntries: Record>, + prefix?: string + ) => { + for (let [key, handler] of Object.entries(handlerEntries)) { + if (typeof handler === "object") { + handlerObjectRegistration(handler, key); + } else { + api.register(`${prefix ? `${prefix}/` : ""}${key}`, handler); + } } - let { status, mock } = c.api.mockResponseForOperation( - c.operation.operationId - ); - return res.status(status).json(mock); - }, - }); + }; + handlerObjectRegistration(handlers({ simulationStore })); - // initalize the backend - api.init(); - - let app = express(); - app.use(express.json()); + api.register({ + validationFail: (c, req, res) => + res.status(400).json({ err: c.validation.errors }), + notFound: (c, req, res) => res.status(404).json({ error: "not found" }), + notImplemented: (c, req, res) => { + if (!c?.operation?.operationId) { + return res.status(404).json({ + status: 501, + error: "No handler registered for operation", + }); + } + let { status, mock } = c.api.mockResponseForOperation( + c.operation.operationId + ); + return res.status(status).json(mock); + }, + }); - if (extend) { - extend(app); // TODO implement and pass in store + // initalize the backend + api.init(); + app.use((req, res) => api.handleRequest(req as Request, req, res)); } - app.use((req, res) => api.handleRequest(req as Request, req, res)); let server = app.listen(port, () => console.info(`api listening at http://localhost:${port}`) ); diff --git a/packages/foundation/package.json b/packages/foundation/package.json index 9ac7f1ca..84abd38b 100644 --- a/packages/foundation/package.json +++ b/packages/foundation/package.json @@ -11,6 +11,7 @@ "dependencies": { "express": "^4.19.2", "openapi-backend": "^5.10.6", - "openapi-merge": "^1.3.2" + "openapi-merge": "^1.3.2", + "starfx": "^0.12.0" } } diff --git a/packages/foundation/server.ts b/packages/foundation/server.ts index c7ec8b56..a6dfeed3 100644 --- a/packages/foundation/server.ts +++ b/packages/foundation/server.ts @@ -1,4 +1,5 @@ import { startServerStandalone } from "./index"; +import type { SimulationSlice } from "./store/schema"; const oas1 = { openapi: "3.0.0", @@ -6,7 +7,19 @@ const oas1 = { title: "API", version: "1.0.0", }, - paths: {}, + paths: { + "/dogs": { + get: { + summary: "Get the dogs", + operationId: "getDogs", + responses: { + 200: { + description: "All of the dogs", + }, + }, + }, + }, + }, }; const oas2 = { @@ -15,21 +28,37 @@ const oas2 = { title: "API", version: "1.0.0", }, - "/dogs": { - get: { - summary: "Get the dogs", - responses: { - 200: { - description: "All of the dogs", - }, + paths: { + "/dogs": { + get: { + operationId: "getDogs", }, }, }, }; startServerStandalone({ - oas: [oas1, oas2], - handlers: {}, + openapi: { + document: [oas1, oas2], + // eslint-disable-next-line @typescript-eslint/no-unused-vars + handlers({ simulationStore }) { + return { + getDogs: (c, req, res) => { + res.sendStatus(200); + }, + }; + }, + apiRoot: "/api", + }, + extendStore: { + actions: () => ({}), + schema: ({ slice }: { slice: SimulationSlice }) => { + let slices = { + test: slice.table(), + booping: slice.str(), + }; + return slices; + }, + }, port: 9999, - apiRoot: "/api", }); diff --git a/packages/foundation/store/index.ts b/packages/foundation/store/index.ts new file mode 100644 index 00000000..5bab0826 --- /dev/null +++ b/packages/foundation/store/index.ts @@ -0,0 +1,44 @@ +import "./thunks"; +import { setupStore } from "./setup"; +import { thunks } from "./thunks"; +import type { StoreUpdater } from "starfx"; +import { updateStore } from "starfx"; +import type { SimulationInputSchema } from "./schema"; + +let updater = thunks.create[]>( + "update", + function* (ctx, next) { + yield* updateStore(ctx.payload); + yield* next(); + } +); + +type CreateSimulationStore = typeof createSimulationStore; +export type SimulationStore = ReturnType; +export function createSimulationStore( + { + actions: inputActions, + schema: inputSchema, + }: { actions: any; schema: SimulationInputSchema } = { + actions: () => ({}), + schema: () => ({}), + } +) { + let additionalTasks = [thunks.bootup]; + let { store, schema } = setupStore({ + logs: false, + additionalTasks, + inputSchema, + }); + + let actions = { + updater, + ...inputActions({ thunks, store, schema }), + }; + + return { + store, + schema, + actions, + }; +} diff --git a/packages/foundation/store/schema.ts b/packages/foundation/store/schema.ts new file mode 100644 index 00000000..f67ad745 --- /dev/null +++ b/packages/foundation/store/schema.ts @@ -0,0 +1,23 @@ +import { createSchema, slice as immerSlice } from "starfx"; + +export type SimulationSlice = typeof immerSlice; +export type SimulationInputSchema = Parameters< + typeof generateSchemaWithInputSlices +>[0]; +type SimulationSchemaSlices = Omit< + Parameters[0], + "loaders" | "cache" +>; + +export function generateSchemaWithInputSlices( + inputSchema: (args: { slice: SimulationSlice }) => SimulationSchemaSlices +) { + let slices = inputSchema({ slice: immerSlice }); + + return createSchema({ + cache: immerSlice.table({ empty: {} }), + loaders: immerSlice.loaders(), + boop: immerSlice.num(), + ...slices, + }); +} diff --git a/packages/foundation/store/setup.ts b/packages/foundation/store/setup.ts new file mode 100644 index 00000000..fa980a83 --- /dev/null +++ b/packages/foundation/store/setup.ts @@ -0,0 +1,42 @@ +import type { Callable } from "starfx"; +import { parallel, take, createStore } from "starfx"; +import type { SimulationInputSchema } from "./schema"; +import { generateSchemaWithInputSlices } from "./schema"; + +export function setupStore({ + logs = true, + additionalTasks = [], + initialState, + inputSchema, +}: { + logs: boolean; + initialState?: Record; + additionalTasks?: Callable[]; + inputSchema: SimulationInputSchema; +}) { + let [schema, schemaInitialState] = generateSchemaWithInputSlices(inputSchema); + let store = createStore({ + initialState: { + ...schemaInitialState, + ...initialState, + }, + }); + + let tsks: Callable[] = [...additionalTasks]; + if (logs) { + // log all actions dispatched + tsks.push(function* logActions() { + while (true) { + let action = yield* take("*"); + console.dir(action, { depth: 5 }); + } + }); + } + + store.run(function* () { + let group = yield* parallel(tsks); + yield* group; + }); + + return { store, schema }; +} diff --git a/packages/foundation/store/thunks.ts b/packages/foundation/store/thunks.ts new file mode 100644 index 00000000..a31b935f --- /dev/null +++ b/packages/foundation/store/thunks.ts @@ -0,0 +1,9 @@ +import { createThunks, mdw } from 'starfx'; + +const thunks = createThunks(); +// catch errors from task and logs them with extra info +thunks.use(mdw.err); +// where all the thunks get called in the middleware stack +thunks.use(thunks.routes()); + +export { thunks };