57 Commits

Author SHA1 Message Date
Julien Valverdé
3552c25b5c Mutation refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 19:07:11 +01:00
Julien Valverdé
516e0a465d Ref state fix
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-24 18:38:14 +01:00
Julien Valverdé
7cf5367409 Tests
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-24 17:34:50 +01:00
Julien Valverdé
3b237c0588 Query refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 17:30:41 +01:00
Julien Valverdé
d9aa42d23a Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 12:16:03 +01:00
Julien Valverdé
fd3213c53f Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-24 12:06:03 +01:00
Julien Valverdé
baa8c92221 Query refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-24 12:03:55 +01:00
Julien Valverdé
d55b432846 Refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-23 23:58:05 +01:00
Julien Valverdé
6266c7506e Example fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-23 07:32:11 +01:00
Julien Valverdé
043e966e45 ErrorHandler work
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-23 07:25:03 +01:00
Julien Valverdé
88fab2c7d7 ErrorHandler refactoring
Some checks failed
Lint / lint (push) Failing after 15s
2025-03-23 06:08:35 +01:00
Julien Valverdé
224ccd8e32 Fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 04:55:38 +01:00
Julien Valverdé
4cf70ada0b Fix
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-21 04:49:44 +01:00
Julien Valverdé
f9bd5d4d6b Query refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 04:37:32 +01:00
Julien Valverdé
1ec1db0658 Mutation progress
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 03:38:48 +01:00
Julien Valverdé
2d94e84941 Stream fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-21 03:24:55 +01:00
Julien Valverdé
aab83907ba Working mutation progress
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-21 02:14:36 +01:00
Julien Valverdé
8c0d6b4c8a Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-21 01:24:52 +01:00
Julien Valverdé
d82d1d1c29 Refactoring
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-21 01:23:47 +01:00
Julien Valverdé
0f09573948 Mutation services
Some checks failed
Lint / lint (push) Failing after 14s
2025-03-20 07:10:55 +01:00
Julien Valverdé
2b6b36713e MutationRunner work
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-20 04:31:38 +01:00
Julien Valverdé
5d0aecc9d5 QueryProgress
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-19 05:13:54 +01:00
Julien Valverdé
f21d8b2d8a QueryProgress
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-18 03:11:39 +01:00
Julien Valverdé
f85173fa68 Fix
All checks were successful
Lint / lint (push) Successful in 30s
2025-03-18 02:46:41 +01:00
Julien Valverdé
65a124de1f Mutation tests
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-17 05:52:13 +01:00
Julien Valverdé
16893761c6 Mutation refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-17 05:34:19 +01:00
Julien Valverdé
3fdc2e31eb Mutation example
All checks were successful
Lint / lint (push) Successful in 17s
2025-03-17 02:36:13 +01:00
Julien Valverdé
8636a28f2f Working mutations
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-17 02:15:27 +01:00
Julien Valverdé
d56578da8f useMutation
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 06:50:20 +01:00
Julien Valverdé
299109d421 Mutation fix
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-16 06:25:02 +01:00
Julien Valverdé
4995b2949f MutationRunner
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 05:20:55 +01:00
Julien Valverdé
6e6e675709 MutationRunner 2025-03-16 05:20:37 +01:00
Julien Valverdé
b04860aa25 Cleanup
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 04:32:51 +01:00
Julien Valverdé
e9e17ac211 Fix
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-16 04:11:25 +01:00
Julien Valverdé
1f0ff725ff Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 04:05:39 +01:00
Julien Valverdé
447d89982c Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 03:34:54 +01:00
Julien Valverdé
778ee27795 ErrorHandler refactoring
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-16 03:33:01 +01:00
Julien Valverdé
077816efb6 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 03:23:12 +01:00
Julien Valverdé
e4bacd1ca7 Working QueryClient refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 03:19:12 +01:00
Julien Valverdé
0e2c0db28f QueryClient refactoring
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-16 02:52:49 +01:00
Julien Valverdé
c943d81702 QueryClient.make
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-15 22:27:15 +01:00
Julien Valverdé
c2bc406a5f Fixed query error handler
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-15 06:43:47 +01:00
Julien Valverdé
4e778b6c95 VQueryErrorHandler
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-15 05:12:38 +01:00
Julien Valverdé
0437fa5dcc QueryErrorHandler work
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-15 02:30:37 +01:00
Julien Valverdé
5614b8df38 Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-15 00:52:00 +01:00
Julien Valverdé
70b6c4434e Tests
All checks were successful
Lint / lint (push) Successful in 16s
2025-03-14 22:07:53 +01:00
Julien Valverdé
2e8dfbc988 QueryClient
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-14 22:00:53 +01:00
Julien Valverdé
abc47c4647 Fix
Some checks failed
Lint / lint (push) Failing after 12s
2025-03-14 05:04:49 +01:00
Julien Valverdé
eedd2a7f2a makeTag
Some checks failed
Lint / lint (push) Failing after 12s
2025-03-14 04:57:07 +01:00
Julien Valverdé
f4ab575a8d QueryExtension work
Some checks failed
Lint / lint (push) Failing after 13s
2025-03-14 04:24:56 +01:00
Julien Valverdé
747e2c6056 Done QueryClient
All checks were successful
Lint / lint (push) Successful in 14s
2025-03-14 04:13:14 +01:00
Julien Valverdé
68c68417d8 QueryClient work
All checks were successful
Lint / lint (push) Successful in 12s
2025-03-14 03:56:54 +01:00
Julien Valverdé
ed384a62a8 QueryClient work
Some checks failed
Lint / lint (push) Failing after 15s
2025-03-14 03:26:28 +01:00
Julien Valverdé
3a1748bb39 QueryClient tests
All checks were successful
Lint / lint (push) Successful in 18s
2025-03-13 22:31:50 +01:00
Julien Valverdé
66b8fd2c2e Fix
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-12 06:37:39 +01:00
Julien Valverdé
bc81c443ab Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 21:19:57 +01:00
Julien Valverdé
ee5dbe3766 Query work
All checks were successful
Lint / lint (push) Successful in 13s
2025-03-11 20:39:56 +01:00
31 changed files with 769 additions and 665 deletions

221
bun.lock
View File

@@ -4,7 +4,6 @@
"": {
"name": "@reffuse/monorepo",
"devDependencies": {
"code-narrator": "^1.0.17",
"npm-check-updates": "^17.1.14",
"npm-sort": "^0.0.4",
"turbo": "^2.4.4",
@@ -79,7 +78,7 @@
},
"packages/reffuse": {
"name": "reffuse",
"version": "0.1.3",
"version": "0.1.2",
"peerDependencies": {
"@types/react": "^19.0.0",
"effect": "^3.13.0",
@@ -208,10 +207,6 @@
"@floating-ui/utils": ["@floating-ui/utils@0.2.9", "", {}, "sha512-MDWhGtE+eHw5JW7lq4qhc5yRLS11ERl1c7Z6Xd0a58DozHES6EnNNwUWbMiG4J9Cgj053Bhk8zvlhFYKVhULwg=="],
"@gulp-sourcemaps/identity-map": ["@gulp-sourcemaps/identity-map@2.0.1", "", { "dependencies": { "acorn": "^6.4.1", "normalize-path": "^3.0.0", "postcss": "^7.0.16", "source-map": "^0.6.0", "through2": "^3.0.1" } }, "sha512-Tb+nSISZku+eQ4X1lAkevcQa+jknn/OVUgZ3XCxEKIsLsqYuPoJwJOPQeaOk75X3WPftb29GWY1eqE7GLsXb1Q=="],
"@gulp-sourcemaps/map-sources": ["@gulp-sourcemaps/map-sources@1.0.0", "", { "dependencies": { "normalize-path": "^2.0.1", "through2": "^2.0.3" } }, "sha512-o/EatdaGt8+x2qpb0vFLC/2Gug/xYPRXb6a+ET1wGYKozKN3krDWC/zZFZAtrzxJHuDL12mwdfEFKcKMNvc55A=="],
"@humanfs/core": ["@humanfs/core@0.19.1", "", {}, "sha512-5DyQ4+1JEUzejeK1JGICcideyfUbGixgS9jNgex5nqkW+cY7WZhxBigmieN5Qnw9ZosSNVC9KQKyb+GUaGyKUA=="],
"@humanfs/node": ["@humanfs/node@0.16.6", "", { "dependencies": { "@humanfs/core": "^0.19.1", "@humanwhocodes/retry": "^0.3.0" } }, "sha512-YuI2ZHQL78Q5HbhDiBA1X4LmYdXCKCMQIfw0pw7piHJwyREFebJUvrQN4cMssyES6x+vfUbx1CIpaQUKYdQZOw=="],
@@ -438,12 +433,6 @@
"@types/json-schema": ["@types/json-schema@7.0.15", "", {}, "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA=="],
"@types/jsonpath": ["@types/jsonpath@0.2.4", "", {}, "sha512-K3hxB8Blw0qgW6ExKgMbXQv2UPZBoE2GqLpVY+yr7nMD2Pq86lsuIzyAaiQ7eMqFL5B6di6pxSkogLJEyEHoGA=="],
"@types/minimatch": ["@types/minimatch@3.0.5", "", {}, "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ=="],
"@types/multimatch": ["@types/multimatch@4.0.0", "", { "dependencies": { "multimatch": "*" } }, "sha512-xS26gtqY5QASmfU/6jb5vj7F0D0SctgRGtwXsKSNng1knk/OewjISlkMwGonkMCbZCqSoW3s6nL0sAtTlzbL/g=="],
"@types/react": ["@types/react@19.0.10", "", { "dependencies": { "csstype": "^3.0.2" } }, "sha512-JuRQ9KXLEjaUNjTWpzuR231Z2WpIwczOkBEIvbHNCzQefFIT0L8IqE6NV6ULLyC1SI/i234JnDoMkfg+RjQj2g=="],
"@types/react-dom": ["@types/react-dom@19.0.4", "", { "peerDependencies": { "@types/react": "^19.0.0" } }, "sha512-4fSQ8vWFkg+TGhePfUzVmat3eC14TXYSsiiDSLI0dVLsrm9gZFABjPy/Qu6TKgl1tq1Bu1yDsuQgY3A3DOjCcg=="],
@@ -466,14 +455,12 @@
"@vitejs/plugin-react": ["@vitejs/plugin-react@4.3.4", "", { "dependencies": { "@babel/core": "^7.26.0", "@babel/plugin-transform-react-jsx-self": "^7.25.9", "@babel/plugin-transform-react-jsx-source": "^7.25.9", "@types/babel__core": "^7.20.5", "react-refresh": "^0.14.2" }, "peerDependencies": { "vite": "^4.2.0 || ^5.0.0 || ^6.0.0" } }, "sha512-SCCPBJtYLdE8PX/7ZQAs1QAZ8Jqwih+0VBLum1EGqmCCQal+MIUqLCzj3ZUy8ufbC0cAM4LRlSTm7IQJwWT4ug=="],
"acorn": ["acorn@6.4.2", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-XtGIhXwF8YM8bJhGxG5kXgjkEuNGLTkoYqVE+KMR+aspr4KGYmKYg7yUe3KghyQ9yheNwLnjmzh/7+gfDBmHCQ=="],
"acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
"acorn-jsx": ["acorn-jsx@5.3.2", "", { "peerDependencies": { "acorn": "^6.0.0 || ^7.0.0 || ^8.0.0" } }, "sha512-rq9s+JNhf0IChjtDXxllJ7g41oZk5SlXtp0LHwyA5cejwn7vKmKp4pPri6YEePv2PU65sAsegbXtIinmDFDXgQ=="],
"ajv": ["ajv@6.12.6", "", { "dependencies": { "fast-deep-equal": "^3.1.1", "fast-json-stable-stringify": "^2.0.0", "json-schema-traverse": "^0.4.1", "uri-js": "^4.2.2" } }, "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g=="],
"ansi-regex": ["ansi-regex@5.0.1", "", {}, "sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ=="],
"ansi-styles": ["ansi-styles@4.3.0", "", { "dependencies": { "color-convert": "^2.0.1" } }, "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg=="],
"ansis": ["ansis@3.17.0", "", {}, "sha512-0qWUglt9JEqLFr3w1I1pbrChn1grhaiAR2ocX1PP/flRmxgtwTzPFFFnfIlD6aMOLQZgSuCRlidD70lvx8yhzg=="],
@@ -484,16 +471,6 @@
"aria-hidden": ["aria-hidden@1.2.4", "", { "dependencies": { "tslib": "^2.0.0" } }, "sha512-y+CcFFwelSXpLZk/7fMB2mUbGtX9lKycf1MWJ7CaTIERyitVlyQx6C+sxcROU2BAJ24OiZyK+8wj2i8AlBoS3A=="],
"array-differ": ["array-differ@4.0.0", "", {}, "sha512-Q6VPTLMsmXZ47ENG3V+wQyZS1ZxXMxFyYzA+Z/GMrJ6yIutAIEf9wTyroTzmGjNfox9/h3GdGBCVh43GVFx4Uw=="],
"array-union": ["array-union@3.0.1", "", {}, "sha512-1OvF9IbWwaeiM9VhzYXVQacMibxpXOMYVNIvMtKRyX9SImBXpKcFr8XvFDeEslCyuH/t6KRt7HEO94AlP8Iatw=="],
"asynckit": ["asynckit@0.4.0", "", {}, "sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q=="],
"atob": ["atob@2.1.2", "", { "bin": { "atob": "bin/atob.js" } }, "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg=="],
"axios": ["axios@0.26.1", "", { "dependencies": { "follow-redirects": "^1.14.8" } }, "sha512-fPwcX4EvnSHuInCMItEhAGnaSEXRBjtzh9fOtsE6E1G6p7vl7edEeZe11QHf18+6+9gR5PbKV/sGKNaD8YaMeA=="],
"babel-dead-code-elimination": ["babel-dead-code-elimination@1.0.9", "", { "dependencies": { "@babel/core": "^7.23.7", "@babel/parser": "^7.23.6", "@babel/traverse": "^7.23.7", "@babel/types": "^7.23.6" } }, "sha512-JLIhax/xullfInZjtu13UJjaLHDeTzt3vOeomaSUdO/nAMEL/pWC/laKrSvWylXMnVWyL5bpmG9njqBZlUQOdg=="],
"balanced-match": ["balanced-match@1.0.2", "", {}, "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="],
@@ -506,8 +483,6 @@
"browserslist": ["browserslist@4.24.4", "", { "dependencies": { "caniuse-lite": "^1.0.30001688", "electron-to-chromium": "^1.5.73", "node-releases": "^2.0.19", "update-browserslist-db": "^1.1.1" }, "bin": { "browserslist": "cli.js" } }, "sha512-KDi1Ny1gSePi1vm0q4oxSF8b4DR44GF4BbmS2YdhPLOEqd8pDviZOGH/GsmRwoWJ2+5Lr085X7naowMwKHDG1A=="],
"call-bind-apply-helpers": ["call-bind-apply-helpers@1.0.2", "", { "dependencies": { "es-errors": "^1.3.0", "function-bind": "^1.1.2" } }, "sha512-Sp1ablJ0ivDkSzjcaJdxEunN5/XvksFJ2sMBFfq6x0ryhQV/2b/KwFe21cMpmHtPOSij8K99/wSfoEuTObmuMQ=="],
"callsites": ["callsites@3.1.0", "", {}, "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ=="],
"caniuse-lite": ["caniuse-lite@1.0.30001701", "", {}, "sha512-faRs/AW3jA9nTwmJBSO1PQ6L/EOgsB5HMQQq4iCu5zhPgVVgO/pZRHlmatwijZKetFw8/Pr4q6dEN8sJuq8qTw=="],
@@ -518,84 +493,38 @@
"classnames": ["classnames@2.5.1", "", {}, "sha512-saHYOzhIQs6wy2sVxTM6bUDsQO4F50V9RQ22qBpEdCW+I+/Wmke2HOl6lS6dTpdxVhb88/I6+Hs+438c3lfUow=="],
"cliui": ["cliui@8.0.1", "", { "dependencies": { "string-width": "^4.2.0", "strip-ansi": "^6.0.1", "wrap-ansi": "^7.0.0" } }, "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ=="],
"clsx": ["clsx@2.1.1", "", {}, "sha512-eYm0QWBtUrBWZWG0d386OGAw16Z995PiOVo2B7bjWSbHedGl5e0ZWaq65kOGgUSNesEIDkB9ISbTg/JK9dhCZA=="],
"code-narrator": ["code-narrator@1.0.17", "", { "dependencies": { "@types/jsonpath": "^0.2.0", "@types/multimatch": "^4.0.0", "asynckit": "^0.4.0", "axios": "^0.26.1", "combined-stream": "^1.0.8", "delayed-stream": "^1.0.0", "dotenv": "^16.0.3", "extract-json-from-string": "^1.0.1", "fast-glob": "^3.2.12", "follow-redirects": "^1.15.2", "form-data": "^4.0.0", "fs-extra": "^11.1.1", "gulp-sourcemaps": "^3.0.0", "ignore": "^5.2.4", "jsonpath": "^1.1.1", "liquidjs": "^10.7.0", "mime-db": "^1.52.0", "mime-types": "^2.1.35", "multimatch": "^6.0.0", "openai": "^3.1.0", "yargs": "^17.7.1" }, "bin": { "code-narrator-cli": "dist/src/cli.js" } }, "sha512-i9xn/GhAz9zE3mX5/OIk0DvcDrftlHo7cClXVTisJ8Vbt85JdZIr0jooEytrenUlxX9EzH3DO7WSI3lmMaPPQg=="],
"color-convert": ["color-convert@2.0.1", "", { "dependencies": { "color-name": "~1.1.4" } }, "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ=="],
"color-name": ["color-name@1.1.4", "", {}, "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA=="],
"combined-stream": ["combined-stream@1.0.8", "", { "dependencies": { "delayed-stream": "~1.0.0" } }, "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg=="],
"commander": ["commander@10.0.1", "", {}, "sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug=="],
"concat-map": ["concat-map@0.0.1", "", {}, "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="],
"convert-source-map": ["convert-source-map@1.9.0", "", {}, "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A=="],
"core-util-is": ["core-util-is@1.0.3", "", {}, "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ=="],
"convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
"cross-spawn": ["cross-spawn@7.0.6", "", { "dependencies": { "path-key": "^3.1.0", "shebang-command": "^2.0.0", "which": "^2.0.1" } }, "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA=="],
"css": ["css@3.0.0", "", { "dependencies": { "inherits": "^2.0.4", "source-map": "^0.6.1", "source-map-resolve": "^0.6.0" } }, "sha512-DG9pFfwOrzc+hawpmqX/dHYHJG+Bsdb0klhyi1sDneOgGOXy9wQIC8hzyVp1e4NRYDBdxcylvywPkkXCHAzTyQ=="],
"csstype": ["csstype@3.1.3", "", {}, "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw=="],
"d": ["d@1.0.2", "", { "dependencies": { "es5-ext": "^0.10.64", "type": "^2.7.2" } }, "sha512-MOqHvMWF9/9MX6nza0KgvFH4HpMU0EF5uUDXqX/BtxtU8NfB0QzRtJ8Oe/6SuS4kbhyzVJwjd97EA4PKrzJ8bw=="],
"debug": ["debug@4.4.0", "", { "dependencies": { "ms": "^2.1.3" } }, "sha512-6WTZ/IxCY/T6BALoZHaE4ctp9xm+Z5kY/pzYaCHRFeyVhojxlrm+46y68HA6hr0TcwEssoxNiDEUJQjfPZ/RYA=="],
"debug-fabulous": ["debug-fabulous@1.1.0", "", { "dependencies": { "debug": "3.X", "memoizee": "0.4.X", "object-assign": "4.X" } }, "sha512-GZqvGIgKNlUnHUPQhepnUZFIMoi3dgZKQBzKDeL2g7oJF9SNAji/AAu36dusFUas0O+pae74lNeoIPHqXWDkLg=="],
"decode-uri-component": ["decode-uri-component@0.2.2", "", {}, "sha512-FqUYQ+8o158GyGTrMFJms9qh3CqTKvAqgqsTnkLI8sKu0028orqBhxNMFkFen0zGyg6epACD32pjVk58ngIErQ=="],
"deep-is": ["deep-is@0.1.4", "", {}, "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ=="],
"delayed-stream": ["delayed-stream@1.0.0", "", {}, "sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ=="],
"detect-newline": ["detect-newline@2.1.0", "", {}, "sha512-CwffZFvlJffUg9zZA0uqrjQayUTC8ob94pnr5sFwaVv3IOmkfUHcWH+jXaQK3askE51Cqe8/9Ql/0uXNwqZ8Zg=="],
"detect-node-es": ["detect-node-es@1.1.0", "", {}, "sha512-ypdmJU/TbBby2Dxibuv7ZLW3Bs1QEmM7nHjEANfohJLvE0XVujisn1qPJcZxg+qDucsr+bP6fLD1rPS3AhJ7EQ=="],
"diff": ["diff@7.0.0", "", {}, "sha512-PJWHUb1RFevKCwaFA9RlG5tCd+FO5iRh9A8HEtkmBH2Li03iJriB6m6JIN4rGz3K3JLawI7/veA1xzRKP6ISBw=="],
"dotenv": ["dotenv@16.4.7", "", {}, "sha512-47qPchRCykZC03FhkYAhrvwU4xDBFIj1QPqaarj6mdM/hgUzfPHcpkHJOn3mJAufFeeAxAzeGsr5X0M4k6fLZQ=="],
"dunder-proto": ["dunder-proto@1.0.1", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.1", "es-errors": "^1.3.0", "gopd": "^1.2.0" } }, "sha512-KIN/nDJBQRcXw0MLVhZE9iQHmG68qAVIBg9CqmUYjmQIhgij9U5MFvrqkUL5FbtyyzZuOeOt0zdeRe4UY7ct+A=="],
"effect": ["effect@3.13.6", "", { "dependencies": { "@standard-schema/spec": "^1.0.0", "fast-check": "^3.23.1" } }, "sha512-NKmzyIuOb2UuHFPRz9EYScbhMBxXkzjPRuu+4axE+hMk1f0U7TZxzi2CP3TVVxA2kzvh00aBQEbyH7Opq4PnWg=="],
"electron-to-chromium": ["electron-to-chromium@1.5.111", "", {}, "sha512-vJyJlO95wQRAw6K2ZGF/8nol7AcbCOnp8S6H91mwOOBbXoS9seDBYxCTPYAFsvXLxl3lc0jLXXe9GLxC4nXVog=="],
"emoji-regex": ["emoji-regex@8.0.0", "", {}, "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A=="],
"es-define-property": ["es-define-property@1.0.1", "", {}, "sha512-e3nRfgfUZ4rNGL232gUgX06QNyyez04KdjFrF+LTRoOXmrOgFKDg4BCdsjW8EnT69eqdYGmRpJwiPVYNrCaW3g=="],
"es-errors": ["es-errors@1.3.0", "", {}, "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw=="],
"es-object-atoms": ["es-object-atoms@1.1.1", "", { "dependencies": { "es-errors": "^1.3.0" } }, "sha512-FGgH2h8zKNim9ljj7dankFPcICIK9Cp5bm+c2gQSYePhpaG5+esrLODihIorn+Pe6FGJzWhXQotPv73jTaldXA=="],
"es-set-tostringtag": ["es-set-tostringtag@2.1.0", "", { "dependencies": { "es-errors": "^1.3.0", "get-intrinsic": "^1.2.6", "has-tostringtag": "^1.0.2", "hasown": "^2.0.2" } }, "sha512-j6vWzfrGVfyXxge+O0x5sh6cvxAog0a/4Rdd2K36zCMV5eJ+/+tOAngRO8cODMNWbVRdVlmGZQL2YS3yR8bIUA=="],
"es5-ext": ["es5-ext@0.10.64", "", { "dependencies": { "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.3", "esniff": "^2.0.1", "next-tick": "^1.1.0" } }, "sha512-p2snDhiLaXe6dahss1LddxqEm+SkuDvV8dnIQG0MWjyHpcMNfXKPE+/Cc0y+PhxJX3A4xGNeFCj5oc0BUh6deg=="],
"es6-iterator": ["es6-iterator@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.35", "es6-symbol": "^3.1.1" } }, "sha512-zw4SRzoUkd+cl+ZoE15A9o1oQd920Bb0iOJMQkQhl3jNc03YqVjAhG7scf9C5KWRU/R13Orf588uCC6525o02g=="],
"es6-symbol": ["es6-symbol@3.1.4", "", { "dependencies": { "d": "^1.0.2", "ext": "^1.7.0" } }, "sha512-U9bFFjX8tFiATgtkJ1zg25+KviIXpgRvRHS8sau3GfhVzThRQrOeksPeT0BWW2MNZs1OEWJ1DPXOQMn0KKRkvg=="],
"es6-weak-map": ["es6-weak-map@2.0.3", "", { "dependencies": { "d": "1", "es5-ext": "^0.10.46", "es6-iterator": "^2.0.3", "es6-symbol": "^3.1.1" } }, "sha512-p5um32HOTO1kP+w7PRnB+5lQ43Z6muuMuIMffvDN8ZB4GcnjLBV6zGStpbASIMk4DCAvEaamhe2zhyCb/QXXsA=="],
"esbuild": ["esbuild@0.25.0", "", { "optionalDependencies": { "@esbuild/aix-ppc64": "0.25.0", "@esbuild/android-arm": "0.25.0", "@esbuild/android-arm64": "0.25.0", "@esbuild/android-x64": "0.25.0", "@esbuild/darwin-arm64": "0.25.0", "@esbuild/darwin-x64": "0.25.0", "@esbuild/freebsd-arm64": "0.25.0", "@esbuild/freebsd-x64": "0.25.0", "@esbuild/linux-arm": "0.25.0", "@esbuild/linux-arm64": "0.25.0", "@esbuild/linux-ia32": "0.25.0", "@esbuild/linux-loong64": "0.25.0", "@esbuild/linux-mips64el": "0.25.0", "@esbuild/linux-ppc64": "0.25.0", "@esbuild/linux-riscv64": "0.25.0", "@esbuild/linux-s390x": "0.25.0", "@esbuild/linux-x64": "0.25.0", "@esbuild/netbsd-arm64": "0.25.0", "@esbuild/netbsd-x64": "0.25.0", "@esbuild/openbsd-arm64": "0.25.0", "@esbuild/openbsd-x64": "0.25.0", "@esbuild/sunos-x64": "0.25.0", "@esbuild/win32-arm64": "0.25.0", "@esbuild/win32-ia32": "0.25.0", "@esbuild/win32-x64": "0.25.0" }, "bin": { "esbuild": "bin/esbuild" } }, "sha512-BXq5mqc8ltbaN34cDqWuYKyNhX8D/Z0J1xdtdQ8UcIIIyJyz+ZMKUt58tF3SrZ85jcfN/PZYhjR5uDQAYNVbuw=="],
"escalade": ["escalade@3.2.0", "", {}, "sha512-WUj2qlxaQtO4g6Pq5c29GTcWGDyd8itL8zTlipgECz3JesAiiOKotd8JU6otB3PACgG6xkJUyVhboMS+bje/jA=="],
"escape-string-regexp": ["escape-string-regexp@4.0.0", "", {}, "sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA=="],
"escodegen": ["escodegen@1.14.3", "", { "dependencies": { "esprima": "^4.0.1", "estraverse": "^4.2.0", "esutils": "^2.0.2", "optionator": "^0.8.1" }, "optionalDependencies": { "source-map": "~0.6.1" }, "bin": { "esgenerate": "bin/esgenerate.js", "escodegen": "bin/escodegen.js" } }, "sha512-qFcX0XJkdg+PB3xjZZG/wKSuT1PnQWx57+TVSjIMmILd2yC/6ByYElPwJnslDsuWuSAp4AwJGumarAAmJch5Kw=="],
"eslint": ["eslint@9.21.0", "", { "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", "@eslint-community/regexpp": "^4.12.1", "@eslint/config-array": "^0.19.2", "@eslint/core": "^0.12.0", "@eslint/eslintrc": "^3.3.0", "@eslint/js": "9.21.0", "@eslint/plugin-kit": "^0.2.7", "@humanfs/node": "^0.16.6", "@humanwhocodes/module-importer": "^1.0.1", "@humanwhocodes/retry": "^0.4.2", "@types/estree": "^1.0.6", "@types/json-schema": "^7.0.15", "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.6", "debug": "^4.3.2", "escape-string-regexp": "^4.0.0", "eslint-scope": "^8.2.0", "eslint-visitor-keys": "^4.2.0", "espree": "^10.3.0", "esquery": "^1.5.0", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", "file-entry-cache": "^8.0.0", "find-up": "^5.0.0", "glob-parent": "^6.0.2", "ignore": "^5.2.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "json-stable-stringify-without-jsonify": "^1.0.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", "optionator": "^0.9.3" }, "peerDependencies": { "jiti": "*" }, "optionalPeers": ["jiti"], "bin": { "eslint": "bin/eslint.js" } }, "sha512-KjeihdFqTPhOMXTt7StsDxriV4n66ueuF/jfPNC3j/lduHwr/ijDwJMsF+wyMJethgiKi5wniIE243vi07d3pg=="],
"eslint-plugin-react-hooks": ["eslint-plugin-react-hooks@5.2.0", "", { "peerDependencies": { "eslint": "^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 || ^9.0.0" } }, "sha512-+f15FfK64YQwZdJNELETdn5ibXEUQmW1DZL6KXhNnc2heoy/sg9VJJeT7n8TlMWouzWqSWavFkIhHyIbIAEapg=="],
@@ -606,12 +535,8 @@
"eslint-visitor-keys": ["eslint-visitor-keys@4.2.0", "", {}, "sha512-UyLnSehNt62FFhSwjZlHmeokpRK59rcz29j+F1/aDgbkbRTk7wIc9XzdoasMUbRNKDM0qQt/+BJ4BrpFeABemw=="],
"esniff": ["esniff@2.0.1", "", { "dependencies": { "d": "^1.0.1", "es5-ext": "^0.10.62", "event-emitter": "^0.3.5", "type": "^2.7.2" } }, "sha512-kTUIGKQ/mDPFoJ0oVfcmyJn4iBDRptjNVIzwIFR7tqWXdVI9xfA2RMwY/gbSpJG3lkdWNEjLap/NqVHZiJsdfg=="],
"espree": ["espree@10.3.0", "", { "dependencies": { "acorn": "^8.14.0", "acorn-jsx": "^5.3.2", "eslint-visitor-keys": "^4.2.0" } }, "sha512-0QYC8b24HWY8zjRnDTL6RiHfDbAWn63qb4LMj1Z4b076A4une81+z03Kg7l7mn/48PUTqoLptSXez8oknU8Clg=="],
"esprima": ["esprima@1.2.2", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-+JpPZam9w5DuJ3Q67SqsMGtiHKENSMRVoxvArfJZK01/BfLEObtZ6orJa/MtoGNR/rfMgp5837T41PAmTwAv/A=="],
"esquery": ["esquery@1.6.0", "", { "dependencies": { "estraverse": "^5.1.0" } }, "sha512-ca9pw9fomFcKPvFLXhBKUK90ZvGibiGOvRJNbjljY7s7uq/5YO4BOzcYtJqExdx99rF6aAcnRxHmcUHcz6sQsg=="],
"esrecurse": ["esrecurse@4.3.0", "", { "dependencies": { "estraverse": "^5.2.0" } }, "sha512-KmfKL3b6G+RXvP8N1vr3Tq1kL/oCFgn2NYXEtqP8/L3pKapUA4G8cFVaoF3SU323CD4XypR/ffioHmkti6/Tag=="],
@@ -620,12 +545,6 @@
"esutils": ["esutils@2.0.3", "", {}, "sha512-kVscqXk4OCp68SZ0dkgEKVi6/8ij300KBWTJq32P/dYeWTSwK41WyTxalN1eRmA5Z9UU/LX9D7FWSmV9SAYx6g=="],
"event-emitter": ["event-emitter@0.3.5", "", { "dependencies": { "d": "1", "es5-ext": "~0.10.14" } }, "sha512-D9rRn9y7kLPnJ+hMq7S/nhvoKwwvVJahBi2BPmx3bvbsEdK3W9ii8cBSGjP+72/LnM4n6fo3+dkCX5FeTQruXA=="],
"ext": ["ext@1.7.0", "", { "dependencies": { "type": "^2.7.2" } }, "sha512-6hxeJYaL110a9b5TEJSj0gojyHQAmA2ch5Os+ySCiA1QGdS697XWY1pzsrSjqA9LDEEgdB/KypIlR59RcLuHYw=="],
"extract-json-from-string": ["extract-json-from-string@1.0.1", "", {}, "sha512-xfQOSFYbELVs9QVkKsV9FZAjlAmXQ2SLR6FpfFX1kpn4QAvaGBJlrnVOblMLwrLPYc26H+q9qxo6JTd4E7AwgQ=="],
"fast-check": ["fast-check@3.23.2", "", { "dependencies": { "pure-rand": "^6.1.0" } }, "sha512-h5+1OzzfCC3Ef7VbtKdcv7zsstUQwUDlYpUTvjeUsJAssPgLn7QzbboPtL5ro04Mq0rPOsMzl7q5hIbRs2wD1A=="],
"fast-deep-equal": ["fast-deep-equal@3.1.3", "", {}, "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q=="],
@@ -650,26 +569,12 @@
"flatted": ["flatted@3.3.3", "", {}, "sha512-GX+ysw4PBCz0PzosHDepZGANEuFCMLrnRTiEy9McGjmkCQYwRq4A/X786G/fjM/+OjsWSU1ZrY5qyARZmO/uwg=="],
"follow-redirects": ["follow-redirects@1.15.9", "", {}, "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ=="],
"form-data": ["form-data@4.0.2", "", { "dependencies": { "asynckit": "^0.4.0", "combined-stream": "^1.0.8", "es-set-tostringtag": "^2.1.0", "mime-types": "^2.1.12" } }, "sha512-hGfm/slu0ZabnNt4oaRZ6uREyfCj6P4fT/n6A1rGV+Z0VdGXjfOhVUpkn6qVQONHGIFwmveGXyDs75+nr6FM8w=="],
"fs-extra": ["fs-extra@11.3.0", "", { "dependencies": { "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" } }, "sha512-Z4XaCL6dUDHfP/jT25jJKMmtxvuwbkrD1vNSMFlo9lNLY2c5FHYSQgHPRZUjAB26TpDEoW9HCOgplrdbaPV/ew=="],
"fsevents": ["fsevents@2.3.3", "", { "os": "darwin" }, "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw=="],
"function-bind": ["function-bind@1.1.2", "", {}, "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA=="],
"gensync": ["gensync@1.0.0-beta.2", "", {}, "sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg=="],
"get-caller-file": ["get-caller-file@2.0.5", "", {}, "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg=="],
"get-intrinsic": ["get-intrinsic@1.3.0", "", { "dependencies": { "call-bind-apply-helpers": "^1.0.2", "es-define-property": "^1.0.1", "es-errors": "^1.3.0", "es-object-atoms": "^1.1.1", "function-bind": "^1.1.2", "get-proto": "^1.0.1", "gopd": "^1.2.0", "has-symbols": "^1.1.0", "hasown": "^2.0.2", "math-intrinsics": "^1.1.0" } }, "sha512-9fSjSaos/fRIVIp+xSJlE6lfwhES7LNtKaCBIamHsjr2na1BiABJPo0mOjjz8GJDURarmCPGqaiVg5mfjb98CQ=="],
"get-nonce": ["get-nonce@1.0.1", "", {}, "sha512-FJhYRoDaiatfEkUK8HKlicmu/3SGFD51q3itKDGoSTysQJBnfOcxU5GxnhE1E6soB76MbT0MBtnKJuXyAx+96Q=="],
"get-proto": ["get-proto@1.0.1", "", { "dependencies": { "dunder-proto": "^1.0.1", "es-object-atoms": "^1.0.0" } }, "sha512-sTSfBjoXBp89JvIKIefqw7U2CCebsc74kiY6awiGogKtoSGbgjYE/G/+l9sF3MWFPNc9IcoOC4ODfKHfxFmp0g=="],
"get-tsconfig": ["get-tsconfig@4.10.0", "", { "dependencies": { "resolve-pkg-maps": "^1.0.0" } }, "sha512-kGzZ3LWWQcGIAmg6iWvXn0ei6WDtV26wzHRMwDSzmAbcXrTEXxHy6IehI6/4eT6VRKyMP1eF1VqwrVUmE/LR7A=="],
"glob-parent": ["glob-parent@6.0.2", "", { "dependencies": { "is-glob": "^4.0.3" } }, "sha512-XxwI8EOhVQgWp6iDL+3b0r86f4d6AX6zSU55HfB4ydCEuXLXc5FcYeOu+nnGftS4TEju/11rt4KJPTMgbfmv4A=="],
@@ -678,44 +583,24 @@
"goober": ["goober@2.1.16", "", { "peerDependencies": { "csstype": "^3.0.10" } }, "sha512-erjk19y1U33+XAMe1VTvIONHYoSqE4iS7BYUZfHaqeohLmnC0FdxEh7rQU+6MZ4OajItzjZFSRtVANrQwNq6/g=="],
"gopd": ["gopd@1.2.0", "", {}, "sha512-ZUKRh6/kUFoAiTAtTYPZJ3hw9wNxx+BIBOijnlG9PnrJsCcSjs1wyyD6vJpaYtgnzDrKYRSqf3OO6Rfa93xsRg=="],
"graceful-fs": ["graceful-fs@4.2.11", "", {}, "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ=="],
"graphemer": ["graphemer@1.4.0", "", {}, "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag=="],
"gulp-sourcemaps": ["gulp-sourcemaps@3.0.0", "", { "dependencies": { "@gulp-sourcemaps/identity-map": "^2.0.1", "@gulp-sourcemaps/map-sources": "^1.0.0", "acorn": "^6.4.1", "convert-source-map": "^1.0.0", "css": "^3.0.0", "debug-fabulous": "^1.0.0", "detect-newline": "^2.0.0", "graceful-fs": "^4.0.0", "source-map": "^0.6.0", "strip-bom-string": "^1.0.0", "through2": "^2.0.0" } }, "sha512-RqvUckJkuYqy4VaIH60RMal4ZtG0IbQ6PXMNkNsshEGJ9cldUPRb/YCgboYae+CLAs1HQNb4ADTKCx65HInquQ=="],
"has-flag": ["has-flag@4.0.0", "", {}, "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ=="],
"has-symbols": ["has-symbols@1.1.0", "", {}, "sha512-1cDNdwJ2Jaohmb3sg4OmKaMBwuC48sYni5HUw2DvsC8LjGTLK9h+eb1X6RyuOHe4hT0ULCW68iomhjUoKUqlPQ=="],
"has-tostringtag": ["has-tostringtag@1.0.2", "", { "dependencies": { "has-symbols": "^1.0.3" } }, "sha512-NqADB8VjPFLM2V0VvHUewwwsw0ZWBaIdgo+ieHtK3hasLz4qeCRjYcqfB6AQrBggRKppKF8L52/VqdVsO47Dlw=="],
"hasown": ["hasown@2.0.2", "", { "dependencies": { "function-bind": "^1.1.2" } }, "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ=="],
"ignore": ["ignore@5.3.2", "", {}, "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g=="],
"import-fresh": ["import-fresh@3.3.1", "", { "dependencies": { "parent-module": "^1.0.0", "resolve-from": "^4.0.0" } }, "sha512-TR3KfrTZTYLPB6jUjfx6MF9WcWrHL9su5TObK4ZkYgBdWKPOFoSoQIdEuTuR82pmtxH2spWG9h6etwfr1pLBqQ=="],
"imurmurhash": ["imurmurhash@0.1.4", "", {}, "sha512-JmXMZ6wuvDmLiHEml9ykzqO6lwFbof0GG4IkcGaENdCRDDmMVnny7s5HsIgHCbaq0w2MyPhDqkhTUgS2LU2PHA=="],
"inherits": ["inherits@2.0.4", "", {}, "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ=="],
"is-binary-path": ["is-binary-path@2.1.0", "", { "dependencies": { "binary-extensions": "^2.0.0" } }, "sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw=="],
"is-extglob": ["is-extglob@2.1.1", "", {}, "sha512-SbKbANkN603Vi4jEZv49LeVJMn4yGwsbzZworEoyEiutsN3nJYdbO36zfhGJ6QEDpOZIFkDtnq5JRxmvl3jsoQ=="],
"is-fullwidth-code-point": ["is-fullwidth-code-point@3.0.0", "", {}, "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg=="],
"is-glob": ["is-glob@4.0.3", "", { "dependencies": { "is-extglob": "^2.1.1" } }, "sha512-xelSayHH36ZgE7ZWhli7pW34hNbNl8Ojv5KVmkJD4hBdD3th8Tfk9vYasLM+mXWOZhFkgZfxhLSnrwRr4elSSg=="],
"is-number": ["is-number@7.0.0", "", {}, "sha512-41Cifkg6e8TylSpdtTpeLVMqvSBEVzTttHvERD741+pnZ8ANv0004MRL43QKPDlK9cGvNp6NZWZUBlbGXYxxng=="],
"is-promise": ["is-promise@2.2.2", "", {}, "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ=="],
"isarray": ["isarray@1.0.0", "", {}, "sha512-VLghIWNM6ELQzo7zwmcg0NmTVyWKYjvIeM83yjp0wRDTmUnrM678fQbcKBo6n2CJEF0szoG//ytg+TKla89ALQ=="],
"isexe": ["isexe@2.0.0", "", {}, "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="],
"js-tokens": ["js-tokens@4.0.0", "", {}, "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="],
@@ -732,54 +617,34 @@
"json5": ["json5@2.2.3", "", { "bin": { "json5": "lib/cli.js" } }, "sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg=="],
"jsonfile": ["jsonfile@6.1.0", "", { "dependencies": { "universalify": "^2.0.0" }, "optionalDependencies": { "graceful-fs": "^4.1.6" } }, "sha512-5dgndWOriYSm5cnYaJNhalLNDKOqFwyDB/rr1E9ZsGciGvKPs8R2xYGCacuf3z6K1YKDz182fd+fY3cn3pMqXQ=="],
"jsonpath": ["jsonpath@1.1.1", "", { "dependencies": { "esprima": "1.2.2", "static-eval": "2.0.2", "underscore": "1.12.1" } }, "sha512-l6Cg7jRpixfbgoWgkrl77dgEj8RPvND0wMH6TwQmi9Qs4TFfS9u5cUFnbeKTwj5ga5Y3BTGGNI28k117LJ009w=="],
"keyv": ["keyv@4.5.4", "", { "dependencies": { "json-buffer": "3.0.1" } }, "sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw=="],
"levn": ["levn@0.4.1", "", { "dependencies": { "prelude-ls": "^1.2.1", "type-check": "~0.4.0" } }, "sha512-+bT2uH4E5LGE7h/n3evcS/sQlJXCpIp6ym8OWJ5eV6+67Dsql/LaaT7qJBAt2rzfoa/5QBGBhxDix1dMt2kQKQ=="],
"liquidjs": ["liquidjs@10.21.0", "", { "dependencies": { "commander": "^10.0.0" }, "bin": { "liquidjs": "bin/liquid.js", "liquid": "bin/liquid.js" } }, "sha512-DouqxNU2jfoZzb1LinVjOc/f6ssitGIxiDJT+kEKyYqPSSSd+WmGOAhtWbVm1/n75svu4aQ+FyQ3ctd3wh1bbw=="],
"locate-path": ["locate-path@6.0.0", "", { "dependencies": { "p-locate": "^5.0.0" } }, "sha512-iPZK6eYjbxRu3uB4/WZ3EsEIMJFMqAoopl3R+zuq0UjcAm/MO6KCweDgPfP3elTztoKP3KtnVHxTn2NHBSDVUw=="],
"lodash.merge": ["lodash.merge@4.6.2", "", {}, "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ=="],
"lru-cache": ["lru-cache@5.1.1", "", { "dependencies": { "yallist": "^3.0.2" } }, "sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w=="],
"lru-queue": ["lru-queue@0.1.0", "", { "dependencies": { "es5-ext": "~0.10.2" } }, "sha512-BpdYkt9EvGl8OfWHDQPISVpcl5xZthb+XPsbELj5AQXxIC8IriDZIQYjBJPEm5rS420sjZ0TLEzRcq5KdBhYrQ=="],
"lucide-react": ["lucide-react@0.477.0", "", { "peerDependencies": { "react": "^16.5.1 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-yCf7aYxerFZAbd8jHJxjwe1j7jEMPptjnaOqdYeirFnEy85cNR3/L+o0I875CYFYya+eEVzZSbNuRk8BZPDpVw=="],
"math-intrinsics": ["math-intrinsics@1.1.0", "", {}, "sha512-/IXtbwEk5HTPyEwyKX6hGkYXxM9nbj64B+ilVJnC/R6B0pH5G4V3b0pVbL7DBj4tkhBAppbQUlf6F6Xl9LHu1g=="],
"memoizee": ["memoizee@0.4.17", "", { "dependencies": { "d": "^1.0.2", "es5-ext": "^0.10.64", "es6-weak-map": "^2.0.3", "event-emitter": "^0.3.5", "is-promise": "^2.2.2", "lru-queue": "^0.1.0", "next-tick": "^1.1.0", "timers-ext": "^0.1.7" } }, "sha512-DGqD7Hjpi/1or4F/aYAspXKNm5Yili0QDAFAY4QYvpqpgiY6+1jOfqpmByzjxbWd/T9mChbCArXAbDAsTm5oXA=="],
"merge2": ["merge2@1.4.1", "", {}, "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg=="],
"micromatch": ["micromatch@4.0.8", "", { "dependencies": { "braces": "^3.0.3", "picomatch": "^2.3.1" } }, "sha512-PXwfBhYu0hBCPw8Dn0E+WDYb7af3dSLVWKi3HGv84IdF4TyFoC0ysxFd0Goxw7nSv4T/PzEJQxsYsEiFCKo2BA=="],
"mime-db": ["mime-db@1.53.0", "", {}, "sha512-oHlN/w+3MQ3rba9rqFr6V/ypF10LSkdwUysQL7GkXoTgIWeV+tcXGA852TBxH+gsh8UWoyhR1hKcoMJTuWflpg=="],
"mime-types": ["mime-types@2.1.35", "", { "dependencies": { "mime-db": "1.52.0" } }, "sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw=="],
"minimatch": ["minimatch@3.1.2", "", { "dependencies": { "brace-expansion": "^1.1.7" } }, "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw=="],
"mobx": ["mobx@6.13.6", "", {}, "sha512-r19KNV0uBN4b+ER8Z0gA4y+MzDYIQ2SvOmn3fUrqPnWXdQfakd9yfbPBDBF/p5I+bd3N5Rk1fHONIvMay+bJGA=="],
"ms": ["ms@2.1.3", "", {}, "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA=="],
"multimatch": ["multimatch@6.0.0", "", { "dependencies": { "@types/minimatch": "^3.0.5", "array-differ": "^4.0.0", "array-union": "^3.0.1", "minimatch": "^3.0.4" } }, "sha512-I7tSVxHGPlmPN/enE3mS1aOSo6bWBfls+3HmuEeCUBCE7gWnm3cBXCBkpurzFjVRwC6Kld8lLaZ1Iv5vOcjvcQ=="],
"multipasta": ["multipasta@0.2.5", "", {}, "sha512-c8eMDb1WwZcE02WVjHoOmUVk7fnKU/RmUcosHACglrWAuPQsEJv+E8430sXj6jNc1jHw0zrS16aCjQh4BcEb4A=="],
"nanoid": ["nanoid@3.3.8", "", { "bin": { "nanoid": "bin/nanoid.cjs" } }, "sha512-WNLf5Sd8oZxOm+TzppcYk8gVOgP+l58xNy58D0nbUnOxOWRWvlcCV4kUF7ltmI6PsrLl/BgKEyS4mqsGChFN0w=="],
"natural-compare": ["natural-compare@1.4.0", "", {}, "sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw=="],
"next-tick": ["next-tick@1.1.0", "", {}, "sha512-CXdUiJembsNjuToQvxayPZF9Vqht7hewsvy2sOWafLvi2awflj9mOC6bHIg50orX8IJvWKY9wYQ/zB2kogPslQ=="],
"node-releases": ["node-releases@2.0.19", "", {}, "sha512-xxOWJsBKtzAq7DY0J+DTzuz58K8e7sJbdgwkbMWQe8UYB6ekmsQ45q0M/tJDsGaZmbC+l7n57UV8Hl5tHxO9uw=="],
"normalize-path": ["normalize-path@3.0.0", "", {}, "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA=="],
@@ -788,10 +653,6 @@
"npm-sort": ["npm-sort@0.0.4", "", { "bin": { "npm-sort": "./index.js" } }, "sha512-S5Id/3Jvr7Cf/QnWjRteprngERCBhhEFOM+wMhUrAYP060/HUBC1aL5GoXS3xITlgacJCWaSmP4HQaAt91nNYQ=="],
"object-assign": ["object-assign@4.1.1", "", {}, "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg=="],
"openai": ["openai@3.3.0", "", { "dependencies": { "axios": "^0.26.0", "form-data": "^4.0.0" } }, "sha512-uqxI/Au+aPRnsaQRe8CojU0eCR7I0mBiKjD3sNMzY6DaC1ZVrc85u98mtJW6voDug8fgGN+DIZmTDxTthxb7dQ=="],
"optionator": ["optionator@0.9.4", "", { "dependencies": { "deep-is": "^0.1.3", "fast-levenshtein": "^2.0.6", "levn": "^0.4.1", "prelude-ls": "^1.2.1", "type-check": "^0.4.0", "word-wrap": "^1.2.5" } }, "sha512-6IpQ7mKUxRcZNLIObR0hz7lxsapSSIYNZJwXPGeF0mTVqGKFIXj1DQcMoT22S3ROcLyY/rz0PWaWZ9ayWmad9g=="],
"p-limit": ["p-limit@3.1.0", "", { "dependencies": { "yocto-queue": "^0.1.0" } }, "sha512-TYOanM3wGwNGsZN2cVTYPArw454xnXj5qmWF1bEoAc4+cU/ol7GVh7odevjp1FNHduHc3KZMcFduxU5Xc6uJRQ=="],
@@ -814,8 +675,6 @@
"prettier": ["prettier@3.5.3", "", { "bin": { "prettier": "bin/prettier.cjs" } }, "sha512-QQtaxnoDJeAkDvDKWCLiwIXkTgRhwYDEQCghU9Z6q03iyek/rxRh/2lC3HB7P8sWT2xC/y5JDctPLBIGzHKbhw=="],
"process-nextick-args": ["process-nextick-args@2.0.1", "", {}, "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag=="],
"punycode": ["punycode@2.3.1", "", {}, "sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg=="],
"pure-rand": ["pure-rand@6.1.0", "", {}, "sha512-bVWawvoZoBYpp6yIoQtQXHZjmz35RSVHnUOTefl8Vcjr8snTPY1wnpSPMWekcFwbxI6gtmT7rSYPFvz71ldiOA=="],
@@ -836,18 +695,12 @@
"react-style-singleton": ["react-style-singleton@2.2.3", "", { "dependencies": { "get-nonce": "^1.0.0", "tslib": "^2.0.0" }, "peerDependencies": { "@types/react": "*", "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0 || ^19.0.0-rc" }, "optionalPeers": ["@types/react"] }, "sha512-b6jSvxvVnyptAiLjbkWLE/lOnR4lfTtDAl+eUC7RZy+QQWc6wRzIV2CE6xBuMmDxc2qIihtDCZD5NPOFl7fRBQ=="],
"readable-stream": ["readable-stream@2.3.8", "", { "dependencies": { "core-util-is": "~1.0.0", "inherits": "~2.0.3", "isarray": "~1.0.0", "process-nextick-args": "~2.0.0", "safe-buffer": "~5.1.1", "string_decoder": "~1.1.1", "util-deprecate": "~1.0.1" } }, "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA=="],
"readdirp": ["readdirp@3.6.0", "", { "dependencies": { "picomatch": "^2.2.1" } }, "sha512-hOS089on8RduqdbhvQ5Z37A0ESjsqz6qnRcffsMU3495FuTdqSm+7bhJ29JvIOsBDEEnan5DPu9t3To9VRlMzA=="],
"reffuse": ["reffuse@workspace:packages/reffuse"],
"remeda": ["remeda@2.21.0", "", { "dependencies": { "type-fest": "^4.35.0" } }, "sha512-ANFqOts3BsvW1MrKOv9SVHG3ly0MzzLa0HIu5qLkiRuEPGPuH9ny3sgd7VdHvC2VOUSN/7RkmabPlAda6JtGgg=="],
"remove-trailing-separator": ["remove-trailing-separator@1.1.0", "", {}, "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw=="],
"require-directory": ["require-directory@2.1.1", "", {}, "sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q=="],
"resolve-from": ["resolve-from@4.0.0", "", {}, "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g=="],
"resolve-pkg-maps": ["resolve-pkg-maps@1.0.0", "", {}, "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw=="],
@@ -858,8 +711,6 @@
"run-parallel": ["run-parallel@1.2.0", "", { "dependencies": { "queue-microtask": "^1.2.2" } }, "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA=="],
"safe-buffer": ["safe-buffer@5.1.2", "", {}, "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="],
"scheduler": ["scheduler@0.25.0", "", {}, "sha512-xFVuu11jh+xcO7JOAGJNOXld8/TcEHK/4CituBUeUb5hqxJLj9YuemAEuvm9gQ/+pgXYfbQuqAkiYu+u7YEsNA=="],
"semver": ["semver@6.3.1", "", { "bin": { "semver": "bin/semver.js" } }, "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA=="],
@@ -868,30 +719,12 @@
"shebang-regex": ["shebang-regex@3.0.0", "", {}, "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A=="],
"source-map": ["source-map@0.6.1", "", {}, "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g=="],
"source-map-js": ["source-map-js@1.2.1", "", {}, "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA=="],
"source-map-resolve": ["source-map-resolve@0.6.0", "", { "dependencies": { "atob": "^2.1.2", "decode-uri-component": "^0.2.0" } }, "sha512-KXBr9d/fO/bWo97NXsPIAW1bFSBOuCnjbNTBMO7N59hsv5i9yzRDfcYwwt0l04+VqnKC+EwzvJZIP/qkuMgR/w=="],
"static-eval": ["static-eval@2.0.2", "", { "dependencies": { "escodegen": "^1.8.1" } }, "sha512-N/D219Hcr2bPjLxPiV+TQE++Tsmrady7TqAJugLy7Xk1EumfDWS/f5dtBbkRCGE7wKKXuYockQoj8Rm2/pVKyg=="],
"string-width": ["string-width@4.2.3", "", { "dependencies": { "emoji-regex": "^8.0.0", "is-fullwidth-code-point": "^3.0.0", "strip-ansi": "^6.0.1" } }, "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g=="],
"string_decoder": ["string_decoder@1.1.1", "", { "dependencies": { "safe-buffer": "~5.1.0" } }, "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg=="],
"strip-ansi": ["strip-ansi@6.0.1", "", { "dependencies": { "ansi-regex": "^5.0.1" } }, "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A=="],
"strip-bom-string": ["strip-bom-string@1.0.0", "", {}, "sha512-uCC2VHvQRYu+lMh4My/sFNmF2klFymLX1wHJeXnbEJERpV/ZsVuonzerjfrGpIGF7LBVa1O7i9kjiWvJiFck8g=="],
"strip-json-comments": ["strip-json-comments@3.1.1", "", {}, "sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig=="],
"supports-color": ["supports-color@7.2.0", "", { "dependencies": { "has-flag": "^4.0.0" } }, "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw=="],
"through2": ["through2@2.0.5", "", { "dependencies": { "readable-stream": "~2.3.6", "xtend": "~4.0.1" } }, "sha512-/mrRod8xqpA+IHSLyGCQ2s8SPHiCDEeQJSep1jqLYeEUClOFG2Qsh+4FU6G9VeqpZnGW/Su8LQGc4YKni5rYSQ=="],
"timers-ext": ["timers-ext@0.1.8", "", { "dependencies": { "es5-ext": "^0.10.64", "next-tick": "^1.1.0" } }, "sha512-wFH7+SEAcKfJpfLPkrgMPvvwnEtj8W4IurvEyrKsDleXnKLCDw71w8jltvfLa8Rm4qQxxT4jmDBYbJG/z7qoww=="],
"tiny-invariant": ["tiny-invariant@1.3.3", "", {}, "sha512-+FbBPE1o9QAYvviau/qC5SE3caw21q3xkvWKBtja5vgqOWIHHJ3ioaq1VPfn/Szqctz2bU/oYeKd9/z5BL+PVg=="],
"tiny-warning": ["tiny-warning@1.0.3", "", {}, "sha512-lBN9zLN/oAf68o3zNXYrdCt1kP8WsiGW8Oo2ka41b2IM5JL/S1CTyX1rW0mb/zSuJun0ZUrDxx4sqvYS2FWzPA=="],
@@ -918,8 +751,6 @@
"turbo-windows-arm64": ["turbo-windows-arm64@2.4.4", "", { "os": "win32", "cpu": "arm64" }, "sha512-403sqp9t5sx6YGEC32IfZTVWkRAixOQomGYB8kEc6ZD+//LirSxzeCHCnM8EmSXw7l57U1G+Fb0kxgTcKPU/Lg=="],
"type": ["type@2.7.3", "", {}, "sha512-8j+1QmAbPvLZow5Qpi6NCaN8FB60p/6x8/vfNqOk/hC+HuvFZhL4+WfekuhQLiqFZXOgQdrs3B+XxEmCc6b3FQ=="],
"type-check": ["type-check@0.4.0", "", { "dependencies": { "prelude-ls": "^1.2.1" } }, "sha512-XleUoc9uwGXqjWwXaUTZAmzMcFZ5858QA2vvx1Ur5xIcixXIP+8LnFDgRplU30us6teqdlskFfu+ae4K79Ooew=="],
"type-fest": ["type-fest@4.36.0", "", {}, "sha512-3T/PUdKTCnkUmhQU6FFJEHsLwadsRegktX3TNHk+2JJB9HlA8gp1/VXblXVDI93kSnXF2rdPx0GMbHtJIV2LPg=="],
@@ -928,10 +759,6 @@
"typescript-eslint": ["typescript-eslint@8.26.0", "", { "dependencies": { "@typescript-eslint/eslint-plugin": "8.26.0", "@typescript-eslint/parser": "8.26.0", "@typescript-eslint/utils": "8.26.0" }, "peerDependencies": { "eslint": "^8.57.0 || ^9.0.0", "typescript": ">=4.8.4 <5.9.0" } }, "sha512-PtVz9nAnuNJuAVeUFvwztjuUgSnJInODAUx47VDwWPXzd5vismPOtPtt83tzNXyOjVQbPRp786D6WFW/M2koIA=="],
"underscore": ["underscore@1.12.1", "", {}, "sha512-hEQt0+ZLDVUMhebKxL4x1BTtDY7bavVofhZ9KZ4aI26X9SRaE+Y3m83XUL1UP2jn8ynjndwCCpEHdUG+9pP1Tw=="],
"universalify": ["universalify@2.0.1", "", {}, "sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw=="],
"unplugin": ["unplugin@2.2.0", "", { "dependencies": { "acorn": "^8.14.0", "webpack-virtual-modules": "^0.6.2" } }, "sha512-m1ekpSwuOT5hxkJeZGRxO7gXbXT3gF26NjQ7GdVHoLoF8/nopLcd/QfPigpCy7i51oFHiRJg/CyHhj4vs2+KGw=="],
"update-browserslist-db": ["update-browserslist-db@1.1.3", "", { "dependencies": { "escalade": "^3.2.0", "picocolors": "^1.1.1" }, "peerDependencies": { "browserslist": ">= 4.21.0" }, "bin": { "update-browserslist-db": "cli.js" } }, "sha512-UxhIZQ+QInVdunkDAaiazvvT/+fXL5Osr0JZlJulepYu6Jd7qJtDZjlur0emRlT71EN3ScPoE7gvsuIKKNavKw=="],
@@ -944,8 +771,6 @@
"use-sync-external-store": ["use-sync-external-store@1.4.0", "", { "peerDependencies": { "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0" } }, "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw=="],
"util-deprecate": ["util-deprecate@1.0.2", "", {}, "sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw=="],
"vite": ["vite@6.2.0", "", { "dependencies": { "esbuild": "^0.25.0", "postcss": "^8.5.3", "rollup": "^4.30.1" }, "optionalDependencies": { "fsevents": "~2.3.3" }, "peerDependencies": { "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0", "jiti": ">=1.21.0", "less": "*", "lightningcss": "^1.21.0", "sass": "*", "sass-embedded": "*", "stylus": "*", "sugarss": "*", "terser": "^5.16.0", "tsx": "^4.8.1", "yaml": "^2.4.2" }, "optionalPeers": ["@types/node", "jiti", "less", "lightningcss", "sass", "sass-embedded", "stylus", "sugarss", "terser", "tsx", "yaml"], "bin": { "vite": "bin/vite.js" } }, "sha512-7dPxoo+WsT/64rDcwoOjk76XHj+TqNTIvHKcuMQ1k4/SeHDaQt5GFAeLYzrimZrMpn/O6DtdI03WUjdxuPM0oQ=="],
"webpack-virtual-modules": ["webpack-virtual-modules@0.6.2", "", {}, "sha512-66/V2i5hQanC51vBQKPH4aI8NMAcBW59FVBs+rC7eGHupMyfn34q7rZIE+ETlJ+XTevqfUhVVBgSUNSW2flEUQ=="],
@@ -954,36 +779,18 @@
"word-wrap": ["word-wrap@1.2.5", "", {}, "sha512-BN22B5eaMMI9UMtjrGd5g5eCYPpCPDUy0FJXbYsaT5zYxjFOckS53SQDE3pWkVoWpHXVb3BrYcEN4Twa55B5cA=="],
"wrap-ansi": ["wrap-ansi@7.0.0", "", { "dependencies": { "ansi-styles": "^4.0.0", "string-width": "^4.1.0", "strip-ansi": "^6.0.0" } }, "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q=="],
"xtend": ["xtend@4.0.2", "", {}, "sha512-LKYU1iAXJXUgAXn9URjiu+MWhyUXHsvfp7mcuYm9dSUKK0/CjtrUwFAxD82/mCWbtLsGjFIad0wIsod4zrTAEQ=="],
"y18n": ["y18n@5.0.8", "", {}, "sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA=="],
"yallist": ["yallist@3.1.1", "", {}, "sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g=="],
"yargs": ["yargs@17.7.2", "", { "dependencies": { "cliui": "^8.0.1", "escalade": "^3.1.1", "get-caller-file": "^2.0.5", "require-directory": "^2.1.1", "string-width": "^4.2.3", "y18n": "^5.0.5", "yargs-parser": "^21.1.1" } }, "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w=="],
"yargs-parser": ["yargs-parser@21.1.1", "", {}, "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw=="],
"yocto-queue": ["yocto-queue@0.1.0", "", {}, "sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q=="],
"zod": ["zod@3.24.2", "", {}, "sha512-lY7CDW43ECgW9u1TcT3IoXHflywfVqDYze4waEz812jR/bZ8FHDsl7pFQoSZTz5N+2NqRXs8GBwnAwo3ZNxqhQ=="],
"@babel/core/convert-source-map": ["convert-source-map@2.0.0", "", {}, "sha512-Kvp459HrV2FEJ1CAsi1Ku+MY3kasH19TFykTz2xWmMeq6bk2NU3XXvfJ+Q61m0xktWwt+1HSYf3JZsTms3aRJg=="],
"@babel/traverse/globals": ["globals@11.12.0", "", {}, "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA=="],
"@eslint-community/eslint-utils/eslint-visitor-keys": ["eslint-visitor-keys@3.4.3", "", {}, "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag=="],
"@eslint/eslintrc/globals": ["globals@14.0.0", "", {}, "sha512-oahGvuMGQlPw/ivIYBjVSrWAfWLBeku5tpPE2fOPLi+WHffIWbuh2tCjhyQhTBPMf5E9jDEH4FOmTYgYwbKwtQ=="],
"@gulp-sourcemaps/identity-map/postcss": ["postcss@7.0.39", "", { "dependencies": { "picocolors": "^0.2.1", "source-map": "^0.6.1" } }, "sha512-yioayjNbHn6z1/Bywyb2Y4s3yvDAeXGOyxqD+LnVOinq6Mdmd++SW2wUNVzavyyHxd6+DxzWGIuosg6P1Rj8uA=="],
"@gulp-sourcemaps/identity-map/through2": ["through2@3.0.2", "", { "dependencies": { "inherits": "^2.0.4", "readable-stream": "2 || 3" } }, "sha512-enaDQ4MUyP2W6ZyT6EsMzqBPZaM/avg8iuo+l2d3QCs0J+6RaqkHV/2/lOwDTueBHeJ/2LG9lrLW3d5rWPucuQ=="],
"@gulp-sourcemaps/map-sources/normalize-path": ["normalize-path@2.1.1", "", { "dependencies": { "remove-trailing-separator": "^1.0.1" } }, "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w=="],
"@humanfs/node/@humanwhocodes/retry": ["@humanwhocodes/retry@0.3.1", "", {}, "sha512-JBxkERygn7Bv/GbN5Rv8Ul6LVknS+5Bp6RgDC/O8gEBU/yeH5Ui5C/OlWrTb6qct7LjjfT6Re2NxB0ln0yYybA=="],
"@typescript-eslint/typescript-estree/minimatch": ["minimatch@9.0.5", "", { "dependencies": { "brace-expansion": "^2.0.1" } }, "sha512-G6T0ZX48xgozx7587koeX9Ys2NYy6Gmv//P89sEte9V9whIapMNF4idKxnW2QtCcLiTWlb/wfCabAtAFWhhBow=="],
@@ -992,30 +799,8 @@
"chokidar/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"debug-fabulous/debug": ["debug@3.2.7", "", { "dependencies": { "ms": "^2.1.1" } }, "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ=="],
"escodegen/esprima": ["esprima@4.0.1", "", { "bin": { "esparse": "./bin/esparse.js", "esvalidate": "./bin/esvalidate.js" } }, "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A=="],
"escodegen/estraverse": ["estraverse@4.3.0", "", {}, "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw=="],
"escodegen/optionator": ["optionator@0.8.3", "", { "dependencies": { "deep-is": "~0.1.3", "fast-levenshtein": "~2.0.6", "levn": "~0.3.0", "prelude-ls": "~1.1.2", "type-check": "~0.3.2", "word-wrap": "~1.2.3" } }, "sha512-+IW9pACdk3XWmmTXG8m3upGUJst5XRGzxMRjXzAuJ1XnIFNvfhjjIuYkDvysnPQ7qzqVzLt78BCruntqRhWQbA=="],
"espree/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
"fast-glob/glob-parent": ["glob-parent@5.1.2", "", { "dependencies": { "is-glob": "^4.0.1" } }, "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow=="],
"mime-types/mime-db": ["mime-db@1.52.0", "", {}, "sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg=="],
"unplugin/acorn": ["acorn@8.14.0", "", { "bin": { "acorn": "bin/acorn" } }, "sha512-cl669nCJTZBsL97OF4kUQm5g5hC2uihk0NxY3WENAC0TYdILVkAyHymAntgxGkl7K+t0cXIrH5siy5S4XkFycA=="],
"@gulp-sourcemaps/identity-map/postcss/picocolors": ["picocolors@0.2.1", "", {}, "sha512-cMlDqaLEqfSaW8Z7N5Jw+lyIW869EzT73/F5lhtY9cLGoVxSXznfgfXMO0Z5K0o0Q2TkTXq+0KFsdnSe3jDViA=="],
"@typescript-eslint/typescript-estree/minimatch/brace-expansion": ["brace-expansion@2.0.1", "", { "dependencies": { "balanced-match": "^1.0.0" } }, "sha512-XnAIvQ8eM+kC6aULx6wuQiwVsnzsi9d3WxzV3FpWTGA19F621kwdbsAcFKXgKUHZWsy+mY6iL1sHTxWEFCytDA=="],
"escodegen/optionator/levn": ["levn@0.3.0", "", { "dependencies": { "prelude-ls": "~1.1.2", "type-check": "~0.3.2" } }, "sha512-0OO4y2iOHix2W6ujICbKIaEQXvFQHue65vUG3pb5EUomzPI90z9hsA1VsO/dbIIpC53J8gxM9Q4Oho0jrCM/yA=="],
"escodegen/optionator/prelude-ls": ["prelude-ls@1.1.2", "", {}, "sha512-ESF23V4SKG6lVSGZgYNpbsiaAkdab6ZgOxe52p7+Kid3W3u3bxR4Vfd/o21dmN7jSt0IwgZ4v5MUd26FEtXE9w=="],
"escodegen/optionator/type-check": ["type-check@0.3.2", "", { "dependencies": { "prelude-ls": "~1.1.2" } }, "sha512-ZCmOJdvOWDBYJlzAoFkC+Q0+bUyEOS1ltgp1MGU03fqHG+dbi9tBFU2Rd9QKiDZFAYrhPh2JUf7rZRIuHRKtOg=="],
}
}

View File

@@ -15,7 +15,6 @@
"clean:node": "rm -rf node_modules"
},
"devDependencies": {
"code-narrator": "^1.0.17",
"npm-check-updates": "^17.1.14",
"npm-sort": "^0.0.4",
"turbo": "^2.4.4",

View File

@@ -0,0 +1,57 @@
import { AlertDialog, Button, Flex, Text } from "@radix-ui/themes"
import { ErrorHandler } from "@reffuse/extension-query"
import { Cause, Console, Context, Effect, Either, flow, Match, Option, Stream } from "effect"
import { useState } from "react"
import { AppQueryErrorHandler } from "./query"
import { R } from "./reffuse"
export function VQueryErrorHandler() {
const [failure, setFailure] = useState(Option.none<Cause.Cause<
ErrorHandler.Error<Context.Tag.Service<AppQueryErrorHandler>>
>>())
R.useFork(() => AppQueryErrorHandler.pipe(Effect.flatMap(handler =>
Stream.runForEach(handler.errors, v => Console.error(v).pipe(
Effect.andThen(Effect.sync(() => { setFailure(Option.some(v)) }))
))
)), [])
return Option.match(failure, {
onSome: v => (
<AlertDialog.Root open>
<AlertDialog.Content maxWidth="450px">
<AlertDialog.Title>Error</AlertDialog.Title>
<AlertDialog.Description size="2">
{Either.match(Cause.failureOrCause(v), {
onLeft: flow(
Match.value,
Match.tag("RequestError", () => <Text>HTTP request error</Text>),
Match.tag("ResponseError", () => <Text>HTTP response error</Text>),
Match.exhaustive,
),
onRight: flow(
Cause.dieOption,
Option.match({
onSome: () => <Text>Unrecoverable defect</Text>,
onNone: () => <Text>Unknown error</Text>,
}),
),
})}
</AlertDialog.Description>
<Flex gap="3" mt="4" justify="end">
<AlertDialog.Action>
<Button variant="solid" color="red" onClick={() => setFailure(Option.none())}>
Ok
</Button>
</AlertDialog.Action>
</Flex>
</AlertDialog.Content>
</AlertDialog.Root>
),
onNone: () => <></>,
})
}

View File

@@ -5,6 +5,7 @@ import { Layer } from "effect"
import { StrictMode } from "react"
import { createRoot } from "react-dom/client"
import { ReffuseRuntime } from "reffuse"
import { AppQueryClient, AppQueryErrorHandler } from "./query"
import { GlobalContext } from "./reffuse"
import { routeTree } from "./routeTree.gen"
@@ -14,6 +15,8 @@ const layer = Layer.empty.pipe(
Layer.provideMerge(Geolocation.layer),
Layer.provideMerge(Permissions.layer),
Layer.provideMerge(FetchHttpClient.layer),
Layer.provideMerge(AppQueryClient.Live),
Layer.provideMerge(AppQueryErrorHandler.Live),
)
const router = createRouter({ routeTree })

View File

@@ -0,0 +1,21 @@
import { HttpClientError } from "@effect/platform"
import { ErrorHandler, QueryClient } from "@reffuse/extension-query"
import { Effect } from "effect"
export class AppQueryErrorHandler extends ErrorHandler.Service<AppQueryErrorHandler,
HttpClientError.HttpClientError
>()(
"AppQueryErrorHandler",
(self, failure, defect) => self.pipe(
Effect.catchTags({
RequestError: failure,
ResponseError: failure,
}),
Effect.catchAllDefect(defect),
),
) {}
export class AppQueryClient extends QueryClient.Service<AppQueryClient>()({ ErrorHandler: AppQueryErrorHandler }) {}

View File

@@ -1,4 +1,3 @@
import { HttpClientError } from "@effect/platform"
import { QueryService } from "@reffuse/extension-query"
import { ParseResult, Schema } from "effect"
@@ -8,5 +7,5 @@ export const Result = Schema.Array(Schema.String)
export class Uuid4Query extends QueryService.Tag("Uuid4Query")<Uuid4Query,
readonly ["uuid4", number],
typeof Result.Type,
HttpClientError.HttpClientError | ParseResult.ParseError
ParseResult.ParseError
>() {}

View File

@@ -5,7 +5,7 @@ import { Uuid4Query } from "../services"
export function Uuid4QueryService() {
const runSync = R.useRunSync()
const runFork = R.useRunFork()
const query = R.useMemo(() => Uuid4Query.Uuid4Query, [])
const [state] = R.useRefState(query.state)
@@ -25,7 +25,7 @@ export function Uuid4QueryService() {
})}
</Text>
<Button onClick={() => runSync(query.refresh)}>Refresh</Button>
<Button onClick={() => runFork(query.forkRefresh)}>Refresh</Button>
</Flex>
</Container>
)

View File

@@ -3,6 +3,7 @@ import { Clipboard, Geolocation, Permissions } from "@effect/platform-browser"
import { LazyRefExtension } from "@reffuse/extension-lazyref"
import { QueryExtension } from "@reffuse/extension-query"
import { Reffuse, ReffuseContext } from "reffuse"
import { AppQueryClient, AppQueryErrorHandler } from "./query"
export const GlobalContext = ReffuseContext.make<
@@ -10,6 +11,8 @@ export const GlobalContext = ReffuseContext.make<
| Geolocation.Geolocation
| Permissions.Permissions
| HttpClient.HttpClient
| AppQueryClient
| AppQueryErrorHandler
>()
export class GlobalReffuse extends Reffuse.Reffuse.pipe(

View File

@@ -19,6 +19,7 @@ import { Route as CountImport } from './routes/count'
import { Route as BlankImport } from './routes/blank'
import { Route as IndexImport } from './routes/index'
import { Route as QueryUsequeryImport } from './routes/query/usequery'
import { Route as QueryUsemutationImport } from './routes/query/usemutation'
import { Route as QueryServiceImport } from './routes/query/service'
// Create/Update Routes
@@ -71,6 +72,12 @@ const QueryUsequeryRoute = QueryUsequeryImport.update({
getParentRoute: () => rootRoute,
} as any)
const QueryUsemutationRoute = QueryUsemutationImport.update({
id: '/query/usemutation',
path: '/query/usemutation',
getParentRoute: () => rootRoute,
} as any)
const QueryServiceRoute = QueryServiceImport.update({
id: '/query/service',
path: '/query/service',
@@ -137,6 +144,13 @@ declare module '@tanstack/react-router' {
preLoaderRoute: typeof QueryServiceImport
parentRoute: typeof rootRoute
}
'/query/usemutation': {
id: '/query/usemutation'
path: '/query/usemutation'
fullPath: '/query/usemutation'
preLoaderRoute: typeof QueryUsemutationImport
parentRoute: typeof rootRoute
}
'/query/usequery': {
id: '/query/usequery'
path: '/query/usequery'
@@ -158,6 +172,7 @@ export interface FileRoutesByFullPath {
'/tests': typeof TestsRoute
'/time': typeof TimeRoute
'/query/service': typeof QueryServiceRoute
'/query/usemutation': typeof QueryUsemutationRoute
'/query/usequery': typeof QueryUsequeryRoute
}
@@ -170,6 +185,7 @@ export interface FileRoutesByTo {
'/tests': typeof TestsRoute
'/time': typeof TimeRoute
'/query/service': typeof QueryServiceRoute
'/query/usemutation': typeof QueryUsemutationRoute
'/query/usequery': typeof QueryUsequeryRoute
}
@@ -183,6 +199,7 @@ export interface FileRoutesById {
'/tests': typeof TestsRoute
'/time': typeof TimeRoute
'/query/service': typeof QueryServiceRoute
'/query/usemutation': typeof QueryUsemutationRoute
'/query/usequery': typeof QueryUsequeryRoute
}
@@ -197,6 +214,7 @@ export interface FileRouteTypes {
| '/tests'
| '/time'
| '/query/service'
| '/query/usemutation'
| '/query/usequery'
fileRoutesByTo: FileRoutesByTo
to:
@@ -208,6 +226,7 @@ export interface FileRouteTypes {
| '/tests'
| '/time'
| '/query/service'
| '/query/usemutation'
| '/query/usequery'
id:
| '__root__'
@@ -219,6 +238,7 @@ export interface FileRouteTypes {
| '/tests'
| '/time'
| '/query/service'
| '/query/usemutation'
| '/query/usequery'
fileRoutesById: FileRoutesById
}
@@ -232,6 +252,7 @@ export interface RootRouteChildren {
TestsRoute: typeof TestsRoute
TimeRoute: typeof TimeRoute
QueryServiceRoute: typeof QueryServiceRoute
QueryUsemutationRoute: typeof QueryUsemutationRoute
QueryUsequeryRoute: typeof QueryUsequeryRoute
}
@@ -244,6 +265,7 @@ const rootRouteChildren: RootRouteChildren = {
TestsRoute: TestsRoute,
TimeRoute: TimeRoute,
QueryServiceRoute: QueryServiceRoute,
QueryUsemutationRoute: QueryUsemutationRoute,
QueryUsequeryRoute: QueryUsequeryRoute,
}
@@ -265,6 +287,7 @@ export const routeTree = rootRoute
"/tests",
"/time",
"/query/service",
"/query/usemutation",
"/query/usequery"
]
},
@@ -292,6 +315,9 @@ export const routeTree = rootRoute
"/query/service": {
"filePath": "query/service.tsx"
},
"/query/usemutation": {
"filePath": "query/usemutation.tsx"
},
"/query/usequery": {
"filePath": "query/usequery.tsx"
}

View File

@@ -1,3 +1,4 @@
import { VQueryErrorHandler } from "@/QueryErrorHandler"
import { Container, Flex, Theme } from "@radix-ui/themes"
import { createRootRoute, Link, Outlet } from "@tanstack/react-router"
import { TanStackRouterDevtools } from "@tanstack/router-devtools"
@@ -26,6 +27,8 @@ function Root() {
</Container>
<Outlet />
<VQueryErrorHandler />
<TanStackRouterDevtools />
</Theme>
)

View File

@@ -0,0 +1,81 @@
import { R } from "@/reffuse"
import { HttpClient } from "@effect/platform"
import { Button, Container, Flex, Slider, Text } from "@radix-ui/themes"
import { QueryProgress } from "@reffuse/extension-query"
import { createFileRoute } from "@tanstack/react-router"
import * as AsyncData from "@typed/async-data"
import { Array, Console, Effect, flow, Option, Schema, Stream } from "effect"
import { useState } from "react"
export const Route = createFileRoute("/query/usemutation")({
component: RouteComponent
})
const Result = Schema.Array(Schema.String)
function RouteComponent() {
const runFork = R.useRunFork()
const [count, setCount] = useState(1)
const mutation = R.useMutation({
mutation: ([count]: readonly [count: number]) => Console.log(`Querying ${ count } IDs...`).pipe(
Effect.andThen(QueryProgress.QueryProgress.update(() =>
AsyncData.Progress.make({ loaded: 0, total: Option.some(100) })
)),
Effect.andThen(Effect.sleep("500 millis")),
Effect.tap(() => QueryProgress.QueryProgress.update(() =>
AsyncData.Progress.make({ loaded: 50, total: Option.some(100) })
)),
Effect.andThen(HttpClient.get(`https://www.uuidtools.com/api/generate/v4/count/${ count }`)),
HttpClient.withTracerPropagation(false),
Effect.flatMap(res => res.json),
Effect.flatMap(Schema.decodeUnknown(Result)),
Effect.scoped,
)
})
const [state] = R.useRefState(mutation.state)
return (
<Container>
<Flex direction="column" align="center" gap="2">
<Slider
min={1}
max={100}
value={[count]}
onValueChange={flow(
Array.head,
Option.getOrThrow,
setCount,
)}
/>
<Text>
{AsyncData.match(state, {
NoData: () => "No data yet",
Loading: progress =>
`Loading...
${ Option.match(progress, {
onSome: ({ loaded, total }) => ` (${ loaded }/${ Option.getOrElse(total, () => "unknown") })`,
onNone: () => "",
}) }`,
Success: value => `Value: ${ value }`,
Failure: cause => `Error: ${ cause }`,
})}
</Text>
<Button onClick={() => mutation.forkMutate(count).pipe(
Effect.flatMap(([, state]) => Stream.runForEach(state, Console.log)),
Effect.andThen(Console.log("Mutation done.")),
runFork,
)}>
Get
</Button>
</Flex>
</Container>
)
}

View File

@@ -3,7 +3,7 @@ import { HttpClient } from "@effect/platform"
import { Button, Container, Flex, Slider, Text } from "@radix-ui/themes"
import { createFileRoute } from "@tanstack/react-router"
import * as AsyncData from "@typed/async-data"
import { Array, Console, Effect, flow, Option, Schema } from "effect"
import { Array, Console, Effect, flow, Option, Schema, Stream } from "effect"
import { useState } from "react"
@@ -15,7 +15,7 @@ export const Route = createFileRoute("/query/usequery")({
const Result = Schema.Array(Schema.String)
function RouteComponent() {
const runSync = R.useRunSync()
const runFork = R.useRunFork()
const [count, setCount] = useState(1)
@@ -59,7 +59,15 @@ function RouteComponent() {
})}
</Text>
<Button onClick={() => runSync(query.refresh)}>Refresh</Button>
<Button
onClick={() => query.forkRefresh.pipe(
Effect.flatMap(([, state]) => Stream.runForEach(state, Console.log)),
Effect.andThen(Console.log("Refresh finished or stopped")),
runFork,
)}
>
Refresh
</Button>
</Flex>
</Container>
)

View File

@@ -12,9 +12,10 @@ export const LazyRefExtension = ReffuseExtension.make(() => ({
const initialState = this.useMemo(() => ref, [], { doNotReExecuteOnRuntimeOrContextChange: true })
const [reactStateValue, setReactStateValue] = React.useState(initialState)
this.useFork(() => Stream.runForEach(ref.changes, v => Effect.sync(() =>
setReactStateValue(v)
)), [ref])
this.useFork(() => Stream.runForEach(
Stream.changesWith(ref.changes, (x, y) => x === y),
v => Effect.sync(() => setReactStateValue(v)),
), [ref])
const setValue = this.useCallbackSync((setStateAction: React.SetStateAction<A>) =>
LazyRef.update(ref, prevState =>

View File

@@ -0,0 +1,54 @@
import { Cause, Context, Effect, identity, Layer, Queue, Stream } from "effect"
import type { Mutable } from "effect/Types"
export interface ErrorHandler<E> {
readonly errors: Stream.Stream<Cause.Cause<E>>
readonly handle: <A, SelfE, R>(self: Effect.Effect<A, SelfE, R>) => Effect.Effect<A, Exclude<SelfE, E>, R>
}
export type Error<T> = T extends ErrorHandler<infer E> ? E : never
export interface ServiceResult<Self, Id extends string, E> extends Context.TagClass<Self, Id, ErrorHandler<E>> {
readonly Live: Layer.Layer<Self>
}
export const Service = <Self, E = never>() => (
<const Id extends string>(
id: Id,
f: <A, R>(
self: Effect.Effect<A, E, R>,
failure: (failure: E) => Effect.Effect<never>,
defect: (defect: unknown) => Effect.Effect<never>,
) => Effect.Effect<A, never, R>,
): ServiceResult<Self, Id, E> => {
const TagClass = Context.Tag(id)() as ServiceResult<Self, Id, E>
(TagClass as Mutable<typeof TagClass>).Live = Layer.effect(TagClass, Effect.gen(function*() {
const queue = yield* Queue.unbounded<Cause.Cause<E>>()
const errors = Stream.fromQueue(queue)
const handle = <A, SelfE, R>(
self: Effect.Effect<A, SelfE, R>
): Effect.Effect<A, Exclude<SelfE, E>, R> => f(self as unknown as Effect.Effect<A, E, R>,
(failure: E) => Queue.offer(queue, Cause.fail(failure)).pipe(
Effect.andThen(Effect.failCause(Cause.empty))
),
(defect: unknown) => Queue.offer(queue, Cause.die(defect)).pipe(
Effect.andThen(Effect.failCause(Cause.empty))
),
)
return { errors, handle }
}))
return TagClass
}
)
export class DefaultErrorHandler extends Service<DefaultErrorHandler>()(
"@reffuse/extension-query/DefaultErrorHandler",
identity,
) {}

View File

@@ -1,134 +0,0 @@
// import { BrowserStream } from "@effect/platform-browser"
// import * as AsyncData from "@typed/async-data"
// import { type Cause, Effect, Fiber, identity, Option, Ref, type Scope, Stream, SubscriptionRef } from "effect"
// export interface MutationRunner<K extends readonly unknown[], A, E, R> {
// readonly mutation: (...args: K) => Effect.Effect<A, E, R>
// readonly stateRef: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
// readonly forkMutate: Effect.Effect<Fiber.RuntimeFiber<void>>
// }
// export interface MakeProps<K extends readonly unknown[], A, E, R> {
// readonly mutation: (...args: K) => Effect.Effect<A, E, R>
// }
// export const make = <K extends readonly unknown[], A, E, R>(
// { key, query }: MakeProps<K, A, E, R>
// ): Effect.Effect<MutationRunner<K, A, E, R>, never, R> => Effect.gen(function*() {
// const context = yield* Effect.context<R>()
// const stateRef = yield* SubscriptionRef.make(AsyncData.noData<A, E>())
// const interrupt = fiberRef.pipe(
// Effect.flatMap(Option.match({
// onSome: fiber => Ref.set(fiberRef, Option.none()).pipe(
// Effect.andThen(Fiber.interrupt(fiber))
// ),
// onNone: () => Effect.void,
// }))
// )
// const forkInterrupt = fiberRef.pipe(
// Effect.flatMap(Option.match({
// onSome: fiber => Ref.set(fiberRef, Option.none()).pipe(
// Effect.andThen(Fiber.interrupt(fiber).pipe(
// Effect.asVoid,
// Effect.forkDaemon,
// ))
// ),
// onNone: () => Effect.forkDaemon(Effect.void),
// }))
// )
// const forkFetch = interrupt.pipe(
// Effect.andThen(
// Ref.set(stateRef, AsyncData.loading()).pipe(
// Effect.andThen(latestKeyRef),
// Effect.flatMap(identity),
// Effect.flatMap(key => query(key).pipe(
// Effect.matchCauseEffect({
// onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
// onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
// })
// )),
// Effect.provide(context),
// Effect.fork,
// )
// ),
// Effect.flatMap(fiber =>
// Ref.set(fiberRef, Option.some(fiber)).pipe(
// Effect.andThen(Fiber.join(fiber)),
// Effect.andThen(Ref.set(fiberRef, Option.none())),
// )
// ),
// Effect.forkDaemon,
// )
// const forkRefresh = interrupt.pipe(
// Effect.andThen(
// Ref.update(stateRef, previous => {
// if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous))
// return AsyncData.refreshing(previous)
// if (AsyncData.isRefreshing(previous))
// return AsyncData.refreshing(previous.previous)
// return AsyncData.loading()
// }).pipe(
// Effect.andThen(latestKeyRef),
// Effect.flatMap(identity),
// Effect.flatMap(key => query(key).pipe(
// Effect.matchCauseEffect({
// onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
// onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
// })
// )),
// Effect.provide(context),
// Effect.fork,
// )
// ),
// Effect.flatMap(fiber =>
// Ref.set(fiberRef, Option.some(fiber)).pipe(
// Effect.andThen(Fiber.join(fiber)),
// Effect.andThen(Ref.set(fiberRef, Option.none())),
// )
// ),
// Effect.forkDaemon,
// )
// const fetchOnKeyChange = Effect.addFinalizer(() => interrupt).pipe(
// Effect.andThen(Stream.runForEach(key, latestKey =>
// Ref.set(latestKeyRef, Option.some(latestKey)).pipe(
// Effect.andThen(forkFetch)
// )
// ))
// )
// const refreshOnWindowFocus = Stream.runForEach(
// BrowserStream.fromEventListenerWindow("focus"),
// () => forkRefresh,
// )
// return {
// query,
// latestKeyRef,
// stateRef,
// fiberRef,
// forkInterrupt,
// forkFetch,
// forkRefresh,
// fetchOnKeyChange,
// refreshOnWindowFocus,
// }
// })

View File

@@ -0,0 +1,16 @@
import type * as AsyncData from "@typed/async-data"
import { Effect, type Fiber, type Stream, type SubscriptionRef } from "effect"
export interface MutationService<K extends readonly unknown[], A, E> {
readonly state: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly mutate: (...key: K) => Effect.Effect<AsyncData.Success<A> | AsyncData.Failure<E>>
readonly forkMutate: (...key: K) => Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
}
export const Tag = <const Id extends string>(id: Id) => <
Self, K extends readonly unknown[], A, E = never,
>() => Effect.Tag(id)<Self, MutationService<K, A, E>>()

View File

@@ -0,0 +1,39 @@
import { Context, Layer } from "effect"
import type { Mutable } from "effect/Types"
import * as ErrorHandler from "./ErrorHandler.js"
export interface QueryClient<EH, HandledE> {
readonly ErrorHandler: Context.Tag<EH, ErrorHandler.ErrorHandler<HandledE>>
}
const id = "@reffuse/extension-query/QueryClient"
export type TagClassShape<EH, HandledE> = Context.TagClassShape<typeof id, QueryClient<EH, HandledE>>
export type GenericTagClass<EH, HandledE> = Context.TagClass<TagClassShape<EH, HandledE>, typeof id, QueryClient<EH, HandledE>>
export const makeGenericTagClass = <EH = never, HandledE = never>(): GenericTagClass<EH, HandledE> => Context.Tag(id)()
export interface ServiceProps<EH, HandledE> {
readonly ErrorHandler?: Context.Tag<EH, ErrorHandler.ErrorHandler<HandledE>>
}
export interface ServiceResult<Self, EH, HandledE> extends Context.TagClass<Self, typeof id, QueryClient<EH, HandledE>> {
readonly Live: Layer.Layer<Self>
}
export const Service = <Self>() => (
<
EH = ErrorHandler.DefaultErrorHandler,
HandledE = ErrorHandler.Error<Context.Tag.Service<ErrorHandler.DefaultErrorHandler>>,
>(
props?: ServiceProps<EH, HandledE>
): ServiceResult<Self, EH, HandledE> => {
const TagClass = Context.Tag(id)() as ServiceResult<Self, EH, HandledE>
(TagClass as Mutable<typeof TagClass>).Live = Layer.succeed(TagClass, {
ErrorHandler: (props?.ErrorHandler ?? ErrorHandler.DefaultErrorHandler) as Context.Tag<EH, ErrorHandler.ErrorHandler<HandledE>>
})
return TagClass
}
)

View File

@@ -2,20 +2,27 @@ import type * as AsyncData from "@typed/async-data"
import { type Cause, type Context, Effect, type Fiber, Layer, type Option, type Stream, type SubscriptionRef } from "effect"
import * as React from "react"
import { ReffuseExtension, type ReffuseHelpers } from "reffuse"
import * as QueryRunner from "./QueryRunner.js"
import type * as MutationService from "./MutationService.js"
import * as QueryClient from "./QueryClient.js"
import type * as QueryProgress from "./QueryProgress.js"
import type * as QueryService from "./QueryService.js"
import { MutationRunner, QueryRunner } from "./internal/index.js"
export interface UseQueryProps<K extends readonly unknown[], A, E, R> {
readonly key: Stream.Stream<K>
readonly query: (key: K) => Effect.Effect<A, E, R>
readonly query: (key: K) => Effect.Effect<A, E, R | QueryProgress.QueryProgress>
readonly refreshOnWindowFocus?: boolean
}
export interface UseQueryResult<K extends readonly unknown[], A, E> {
readonly latestKey: SubscriptionRef.SubscriptionRef<Option.Option<K>>
readonly state: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly refresh: Effect.Effect<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>
readonly forkRefresh: Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>, Cause.NoSuchElementException>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
readonly layer: <Self, Id extends string>(
tag: Context.TagClass<Self, Id, QueryService.QueryService<K, A, E>>
@@ -23,12 +30,40 @@ export interface UseQueryResult<K extends readonly unknown[], A, E> {
}
export interface UseMutationProps<K extends readonly unknown[], A, E, R> {
readonly mutation: (key: K) => Effect.Effect<A, E, R | QueryProgress.QueryProgress>
}
export interface UseMutationResult<K extends readonly unknown[], A, E> {
readonly state: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly mutate: (...key: K) => Effect.Effect<AsyncData.Success<A> | AsyncData.Failure<E>>
readonly forkMutate: (...key: K) => Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
readonly layer: <Self, Id extends string>(
tag: Context.TagClass<Self, Id, MutationService.MutationService<K, A, E>>
) => Layer.Layer<Self>
}
export const QueryExtension = ReffuseExtension.make(() => ({
useQuery<K extends readonly unknown[], A, E, R>(
this: ReffuseHelpers.ReffuseHelpers<R>,
props: UseQueryProps<K, A, E, R>,
): UseQueryResult<K, A, E> {
useQuery<
EH,
QK extends readonly unknown[],
QA,
QE,
HandledE,
QR extends R,
R,
>(
this: ReffuseHelpers.ReffuseHelpers<R | QueryClient.TagClassShape<EH, HandledE> | EH>,
props: UseQueryProps<QK, QA, QE, QR>,
): UseQueryResult<QK, QA, Exclude<QE, HandledE>> {
const runner = this.useMemo(() => QueryRunner.make({
QueryClient: QueryClient.makeGenericTagClass<EH, HandledE>(),
key: props.key,
query: props.query,
}), [props.key])
@@ -43,13 +78,45 @@ export const QueryExtension = ReffuseExtension.make(() => ({
return React.useMemo(() => ({
latestKey: runner.latestKeyRef,
state: runner.stateRef,
refresh: runner.forkRefresh,
forkRefresh: runner.forkRefresh,
layer: tag => Layer.succeed(tag, {
latestKey: runner.latestKeyRef,
state: runner.stateRef,
refresh: runner.forkRefresh,
forkRefresh: runner.forkRefresh,
}),
}), [runner])
}
},
useMutation<
EH,
QK extends readonly unknown[],
QA,
QE,
HandledE,
QR extends R,
R,
>(
this: ReffuseHelpers.ReffuseHelpers<R | QueryClient.TagClassShape<EH, HandledE> | EH>,
props: UseMutationProps<QK, QA, QE, QR>,
): UseMutationResult<QK, QA, Exclude<QE, HandledE>> {
const runner = this.useMemo(() => MutationRunner.make({
QueryClient: QueryClient.makeGenericTagClass<EH, HandledE>(),
mutation: props.mutation,
}), [])
return React.useMemo(() => ({
state: runner.stateRef,
mutate: runner.mutate,
forkMutate: runner.forkMutate,
layer: tag => Layer.succeed(tag, {
state: runner.stateRef,
mutate: runner.mutate,
forkMutate: runner.forkMutate,
}),
}), [runner])
},
}))

View File

@@ -0,0 +1,37 @@
import * as AsyncData from "@typed/async-data"
import { Effect, flow, Layer, Match, Option } from "effect"
import { QueryState } from "./internal/index.js"
export class QueryProgress extends Effect.Tag("@reffuse/extension-query/QueryProgress")<QueryProgress, {
readonly get: Effect.Effect<Option.Option<AsyncData.Progress>>
readonly update: (
f: (previous: Option.Option<AsyncData.Progress>) => AsyncData.Progress
) => Effect.Effect<void>
}>() {
static readonly Live: Layer.Layer<
QueryProgress,
never,
QueryState.QueryState<any, any>
> = Layer.effect(this, Effect.gen(function*() {
const state = yield* QueryState.makeTag()
const get = state.get.pipe(
Effect.map(flow(Match.value,
Match.tag("Loading", v => v.progress),
Match.tag("Refreshing", v => v.progress),
Match.orElse(() => Option.none()),
))
)
const update = (f: (previous: Option.Option<AsyncData.Progress>) => AsyncData.Progress) => get.pipe(
Effect.map(f),
Effect.flatMap(progress => state.update(previous =>
AsyncData.updateProgress(previous, progress)
)),
)
return { get, update }
}))
}

View File

@@ -1,144 +0,0 @@
import { BrowserStream } from "@effect/platform-browser"
import * as AsyncData from "@typed/async-data"
import { type Cause, Effect, Fiber, identity, Option, Ref, type Scope, Stream, SubscriptionRef } from "effect"
export interface QueryRunner<K extends readonly unknown[], A, E, R> {
readonly query: (key: K) => Effect.Effect<A, E, R>
readonly latestKeyRef: SubscriptionRef.SubscriptionRef<Option.Option<K>>
readonly stateRef: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly fiberRef: SubscriptionRef.SubscriptionRef<Option.Option<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>>
readonly forkInterrupt: Effect.Effect<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>
readonly forkFetch: Effect.Effect<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>
readonly forkRefresh: Effect.Effect<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>
readonly fetchOnKeyChange: Effect.Effect<void, Cause.NoSuchElementException, Scope.Scope>
readonly refreshOnWindowFocus: Effect.Effect<void>
}
export interface MakeProps<K extends readonly unknown[], A, E, R> {
readonly key: Stream.Stream<K>
readonly query: (key: K) => Effect.Effect<A, E, R>
}
export const make = <K extends readonly unknown[], A, E, R>(
{ key, query }: MakeProps<K, A, E, R>
): Effect.Effect<QueryRunner<K, A, E, R>, never, R> => Effect.gen(function*() {
const context = yield* Effect.context<R>()
const latestKeyRef = yield* SubscriptionRef.make(Option.none<K>())
const stateRef = yield* SubscriptionRef.make(AsyncData.noData<A, E>())
const fiberRef = yield* SubscriptionRef.make(Option.none<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>())
const interrupt = fiberRef.pipe(
Effect.flatMap(Option.match({
onSome: fiber => Ref.set(fiberRef, Option.none()).pipe(
Effect.andThen(Fiber.interrupt(fiber))
),
onNone: () => Effect.void,
}))
)
const forkInterrupt = fiberRef.pipe(
Effect.flatMap(Option.match({
onSome: fiber => Ref.set(fiberRef, Option.none()).pipe(
Effect.andThen(Fiber.interrupt(fiber).pipe(
Effect.asVoid,
Effect.forkDaemon,
))
),
onNone: () => Effect.forkDaemon(Effect.void),
}))
)
const forkFetch = interrupt.pipe(
Effect.andThen(
Ref.set(stateRef, AsyncData.loading()).pipe(
Effect.andThen(latestKeyRef),
Effect.flatMap(identity),
Effect.flatMap(key => query(key).pipe(
Effect.matchCauseEffect({
onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
})
)),
Effect.provide(context),
Effect.fork,
)
),
Effect.flatMap(fiber =>
Ref.set(fiberRef, Option.some(fiber)).pipe(
Effect.andThen(Fiber.join(fiber)),
Effect.andThen(Ref.set(fiberRef, Option.none())),
)
),
Effect.forkDaemon,
)
const forkRefresh = interrupt.pipe(
Effect.andThen(
Ref.update(stateRef, previous => {
if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous))
return AsyncData.refreshing(previous)
if (AsyncData.isRefreshing(previous))
return AsyncData.refreshing(previous.previous)
return AsyncData.loading()
}).pipe(
Effect.andThen(latestKeyRef),
Effect.flatMap(identity),
Effect.flatMap(key => query(key).pipe(
Effect.matchCauseEffect({
onSuccess: v => Ref.set(stateRef, AsyncData.success(v)),
onFailure: c => Ref.set(stateRef, AsyncData.failure(c)),
})
)),
Effect.provide(context),
Effect.fork,
)
),
Effect.flatMap(fiber =>
Ref.set(fiberRef, Option.some(fiber)).pipe(
Effect.andThen(Fiber.join(fiber)),
Effect.andThen(Ref.set(fiberRef, Option.none())),
)
),
Effect.forkDaemon,
)
const fetchOnKeyChange = Effect.addFinalizer(() => interrupt).pipe(
Effect.andThen(Stream.runForEach(key, latestKey =>
Ref.set(latestKeyRef, Option.some(latestKey)).pipe(
Effect.andThen(forkFetch)
)
))
)
const refreshOnWindowFocus = Stream.runForEach(
BrowserStream.fromEventListenerWindow("focus"),
() => forkRefresh,
)
return {
query,
latestKeyRef,
stateRef,
fiberRef,
forkInterrupt,
forkFetch,
forkRefresh,
fetchOnKeyChange,
refreshOnWindowFocus,
}
})

View File

@@ -1,32 +1,16 @@
import type * as AsyncData from "@typed/async-data"
import { type Cause, Effect, type Fiber, type Option, type SubscriptionRef } from "effect"
import { type Cause, Effect, type Fiber, type Option, type Stream, type SubscriptionRef } from "effect"
export interface QueryService<K extends readonly unknown[], A, E> {
readonly latestKey: SubscriptionRef.SubscriptionRef<Option.Option<K>>
readonly state: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly refresh: Effect.Effect<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>
readonly forkRefresh: Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>, Cause.NoSuchElementException>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
}
export const Tag = <const Id extends string>(id: Id) => <
Self, K extends readonly unknown[], A, E = never,
>() => Effect.Tag(id)<Self, QueryService<K, A, E>>()
// export interface LayerProps<A, E, R> {
// readonly query: Effect.Effect<A, E, R>
// }
// export const layer = <Self, Id extends string, A, E, R>(
// tag: Context.TagClass<Self, Id, QueryService<A, E>>,
// props: LayerProps<A, E, R>,
// ): Layer.Layer<Self, never, R> => Layer.effect(tag, Effect.gen(function*() {
// const runner = yield* QueryRunner.make({
// query: props.query
// })
// return {
// state: runner.stateRef,
// refresh: runner.forkRefresh,
// }
// }))

View File

@@ -1,3 +1,6 @@
export * as ErrorHandler from "./ErrorHandler.js"
export * as MutationService from "./MutationService.js"
export * as QueryClient from "./QueryClient.js"
export * from "./QueryExtension.js"
export * as QueryRunner from "./QueryRunner.js"
export * as QueryProgress from "./QueryProgress.js"
export * as QueryService from "./QueryService.js"

View File

@@ -0,0 +1,98 @@
import * as AsyncData from "@typed/async-data"
import { type Context, Effect, type Fiber, Queue, Ref, Stream, SubscriptionRef } from "effect"
import type * as QueryClient from "../QueryClient.js"
import * as QueryProgress from "../QueryProgress.js"
import * as QueryState from "./QueryState.js"
export interface MutationRunner<K extends readonly unknown[], A, E, R> {
readonly context: Context.Context<R>
readonly stateRef: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly mutate: (...key: K) => Effect.Effect<AsyncData.Success<A> | AsyncData.Failure<E>>
readonly forkMutate: (...key: K) => Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
}
export interface MakeProps<EH, K extends readonly unknown[], A, E, HandledE, R> {
readonly QueryClient: QueryClient.GenericTagClass<EH, HandledE>
readonly mutation: (key: K) => Effect.Effect<A, E, R | QueryProgress.QueryProgress>
}
export const make = <EH, K extends readonly unknown[], A, E, HandledE, R>(
{
QueryClient,
mutation,
}: MakeProps<EH, K, A, E, HandledE, R>
): Effect.Effect<
MutationRunner<K, A, Exclude<E, HandledE>, R>,
never,
R | QueryClient.TagClassShape<EH, HandledE> | EH
> => Effect.gen(function*() {
const context = yield* Effect.context<R | QueryClient.TagClassShape<EH, HandledE> | EH>()
const globalStateRef = yield* SubscriptionRef.make(AsyncData.noData<A, Exclude<E, HandledE>>())
const queryStateTag = QueryState.makeTag<A, Exclude<E, HandledE>>()
const run = (key: K) => Effect.all([
queryStateTag,
QueryClient.pipe(Effect.flatMap(client => client.ErrorHandler)),
]).pipe(
Effect.flatMap(([state, errorHandler]) => state.set(AsyncData.loading()).pipe(
Effect.andThen(mutation(key)),
errorHandler.handle,
Effect.matchCauseEffect({
onSuccess: v => Effect.succeed(AsyncData.success(v)).pipe(
Effect.tap(state.set)
),
onFailure: c => Effect.succeed(AsyncData.failure(c)).pipe(
Effect.tap(state.set)
),
}),
)),
Effect.provide(context),
Effect.provide(QueryProgress.QueryProgress.Live),
)
const mutate = (...key: K) => Effect.provide(run(key), QueryState.layer(
queryStateTag,
globalStateRef,
value => Ref.set(globalStateRef, value),
))
const forkMutate = (...key: K) => Effect.all([
Ref.make(AsyncData.noData<A, Exclude<E, HandledE>>()),
Queue.unbounded<AsyncData.AsyncData<A, Exclude<E, HandledE>>>(),
]).pipe(
Effect.flatMap(([stateRef, stateQueue]) =>
Effect.addFinalizer(() => Queue.shutdown(stateQueue)).pipe(
Effect.andThen(run(key)),
Effect.scoped,
Effect.forkDaemon,
Effect.map(fiber => [fiber, Stream.fromQueue(stateQueue)] as const),
Effect.provide(QueryState.layer(
queryStateTag,
stateRef,
value => Queue.offer(stateQueue, value).pipe(
Effect.andThen(Ref.set(stateRef, value)),
Effect.andThen(Ref.set(globalStateRef, value)),
),
)),
)
)
)
return {
context,
stateRef: globalStateRef,
mutate,
forkMutate,
}
})

View File

@@ -0,0 +1,193 @@
import { BrowserStream } from "@effect/platform-browser"
import * as AsyncData from "@typed/async-data"
import { type Cause, type Context, Effect, Fiber, identity, Option, Queue, Ref, type Scope, Stream, SubscriptionRef } from "effect"
import type * as QueryClient from "../QueryClient.js"
import * as QueryProgress from "../QueryProgress.js"
import * as QueryState from "./QueryState.js"
export interface QueryRunner<K extends readonly unknown[], A, E, R> {
readonly context: Context.Context<R>
readonly latestKeyRef: SubscriptionRef.SubscriptionRef<Option.Option<K>>
readonly stateRef: SubscriptionRef.SubscriptionRef<AsyncData.AsyncData<A, E>>
readonly fiberRef: SubscriptionRef.SubscriptionRef<Option.Option<Fiber.RuntimeFiber<
AsyncData.Success<A> | AsyncData.Failure<E>,
Cause.NoSuchElementException
>>>
readonly forkInterrupt: Effect.Effect<Fiber.RuntimeFiber<void, Cause.NoSuchElementException>>
readonly forkFetch: Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>, Cause.NoSuchElementException>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
readonly forkRefresh: Effect.Effect<readonly [
fiber: Fiber.RuntimeFiber<AsyncData.Success<A> | AsyncData.Failure<E>, Cause.NoSuchElementException>,
state: Stream.Stream<AsyncData.AsyncData<A, E>>,
]>
readonly fetchOnKeyChange: Effect.Effect<void, Cause.NoSuchElementException, Scope.Scope>
readonly refreshOnWindowFocus: Effect.Effect<void>
}
export interface MakeProps<EH, K extends readonly unknown[], A, E, HandledE, R> {
readonly QueryClient: QueryClient.GenericTagClass<EH, HandledE>
readonly key: Stream.Stream<K>
readonly query: (key: K) => Effect.Effect<A, E, R | QueryProgress.QueryProgress>
}
export const make = <EH, K extends readonly unknown[], A, E, HandledE, R>(
{
QueryClient,
key,
query,
}: MakeProps<EH, K, A, E, HandledE, R>
): Effect.Effect<
QueryRunner<K, A, Exclude<E, HandledE>, R>,
never,
R | QueryClient.TagClassShape<EH, HandledE> | EH
> => Effect.gen(function*() {
const context = yield* Effect.context<R | QueryClient.TagClassShape<EH, HandledE> | EH>()
const latestKeyRef = yield* SubscriptionRef.make(Option.none<K>())
const stateRef = yield* SubscriptionRef.make(AsyncData.noData<A, Exclude<E, HandledE>>())
const fiberRef = yield* SubscriptionRef.make(Option.none<Fiber.RuntimeFiber<
AsyncData.Success<A> | AsyncData.Failure<Exclude<E, HandledE>>,
Cause.NoSuchElementException
>>())
const queryStateTag = QueryState.makeTag<A, Exclude<E, HandledE>>()
const interrupt = fiberRef.pipe(
Effect.flatMap(Option.match({
onSome: fiber => Ref.set(fiberRef, Option.none()).pipe(
Effect.andThen(Fiber.interrupt(fiber))
),
onNone: () => Effect.void,
}))
)
const forkInterrupt = fiberRef.pipe(
Effect.flatMap(Option.match({
onSome: fiber => Ref.set(fiberRef, Option.none()).pipe(
Effect.andThen(Fiber.interrupt(fiber).pipe(
Effect.asVoid,
Effect.forkDaemon,
))
),
onNone: () => Effect.forkDaemon(Effect.void),
}))
)
const run = Effect.all([
queryStateTag,
QueryClient.pipe(Effect.flatMap(client => client.ErrorHandler)),
]).pipe(
Effect.flatMap(([state, errorHandler]) => latestKeyRef.pipe(
Effect.flatMap(identity),
Effect.flatMap(key => query(key).pipe(
errorHandler.handle,
Effect.matchCauseEffect({
onSuccess: v => Effect.succeed(AsyncData.success(v)).pipe(
Effect.tap(state.set)
),
onFailure: c => Effect.succeed(AsyncData.failure(c)).pipe(
Effect.tap(state.set)
),
}),
)),
)),
Effect.provide(context),
Effect.provide(QueryProgress.QueryProgress.Live),
)
const forkFetch = Queue.unbounded<AsyncData.AsyncData<A, Exclude<E, HandledE>>>().pipe(
Effect.flatMap(stateQueue => queryStateTag.pipe(
Effect.flatMap(state => interrupt.pipe(
Effect.andThen(Effect.addFinalizer(() => Ref.set(fiberRef, Option.none()).pipe(
Effect.andThen(Queue.shutdown(stateQueue))
)).pipe(
Effect.andThen(state.set(AsyncData.loading())),
Effect.andThen(run),
Effect.scoped,
Effect.forkDaemon,
)),
Effect.tap(fiber => Ref.set(fiberRef, Option.some(fiber))),
Effect.map(fiber => [fiber, Stream.fromQueue(stateQueue)] as const),
)),
Effect.provide(QueryState.layer(
queryStateTag,
stateRef,
value => Queue.offer(stateQueue, value).pipe(
Effect.andThen(Ref.set(stateRef, value))
),
)),
))
)
const setInitialRefreshState = queryStateTag.pipe(
Effect.flatMap(state => state.update(previous => {
if (AsyncData.isSuccess(previous) || AsyncData.isFailure(previous))
return AsyncData.refreshing(previous)
if (AsyncData.isRefreshing(previous))
return AsyncData.refreshing(previous.previous)
return AsyncData.loading()
}))
)
const forkRefresh = Queue.unbounded<AsyncData.AsyncData<A, Exclude<E, HandledE>>>().pipe(
Effect.flatMap(stateQueue => interrupt.pipe(
Effect.andThen(Effect.addFinalizer(() => Ref.set(fiberRef, Option.none()).pipe(
Effect.andThen(Queue.shutdown(stateQueue))
)).pipe(
Effect.andThen(setInitialRefreshState),
Effect.andThen(run),
Effect.scoped,
Effect.forkDaemon,
)),
Effect.tap(fiber => Ref.set(fiberRef, Option.some(fiber))),
Effect.map(fiber => [fiber, Stream.fromQueue(stateQueue)] as const),
Effect.provide(QueryState.layer(
queryStateTag,
stateRef,
value => Queue.offer(stateQueue, value).pipe(
Effect.andThen(Ref.set(stateRef, value))
),
)),
))
)
const fetchOnKeyChange = Effect.addFinalizer(() => interrupt).pipe(
Effect.andThen(Stream.runForEach(Stream.changes(key), latestKey =>
Ref.set(latestKeyRef, Option.some(latestKey)).pipe(
Effect.andThen(forkFetch)
)
))
)
const refreshOnWindowFocus = Stream.runForEach(
BrowserStream.fromEventListenerWindow("focus"),
() => forkRefresh,
)
return {
context,
latestKeyRef,
stateRef,
fiberRef,
forkInterrupt,
forkFetch,
forkRefresh,
fetchOnKeyChange,
refreshOnWindowFocus,
}
})

View File

@@ -0,0 +1,24 @@
import type * as AsyncData from "@typed/async-data"
import { Context, Effect, Layer } from "effect"
export interface QueryState<A, E> {
readonly get: Effect.Effect<AsyncData.AsyncData<A, E>>
readonly set: (value: AsyncData.AsyncData<A, E>) => Effect.Effect<void>
readonly update: (f: (previous: AsyncData.AsyncData<A, E>) => AsyncData.AsyncData<A, E>) => Effect.Effect<void>
}
export const makeTag = <A, E>(): Context.Tag<QueryState<A, E>, QueryState<A, E>> => Context.GenericTag("@reffuse/query-extension/QueryState")
export const layer = <A, E>(
tag: Context.Tag<QueryState<A, E>, QueryState<A, E>>,
get: Effect.Effect<AsyncData.AsyncData<A, E>>,
set: (value: AsyncData.AsyncData<A, E>) => Effect.Effect<void>,
): Layer.Layer<QueryState<A, E>> => Layer.succeed(tag, {
get,
set,
update: f => get.pipe(
Effect.map(f),
Effect.flatMap(set),
),
})

View File

@@ -0,0 +1,3 @@
export * as MutationRunner from "./MutationRunner.js"
export * as QueryRunner from "./QueryRunner.js"
export * as QueryState from "./QueryState.js"

View File

@@ -1,14 +0,0 @@
Create a "ReadMe" guide for the project, named "{{ projectName }}".
Include the following:
Title, Description,
Getting Started by installing npm package, how to run it with npx
Configuration is optional and will be generated on first run
Reporting bugs, repository and homepage
Versioning
Authors
License
This is the entry file:
###
{{ entryFileContent }}
###

View File

@@ -1,4 +0,0 @@
Show how developer would add HowTo in config file,
args property is used to inject properties into liquid template, any property set in args can be access in liquid template with {{ keyName }}
file property appends extracted content of a file to liquid template, using JSONPath or the extract property that uses LLM to extract content from file
Developers MUST create a liquid template in .code-narrator/gpt_questions, this template file is used to ask GPT question

View File

@@ -1,4 +0,0 @@
Give title and short description that this is an overview file for files located in directory
Give short description of each file that is provided
Add link to each file, link should be the filename

View File

@@ -1,101 +0,0 @@
const ConfigurationBuilder = require("code-narrator/dist/src/documentation/plugins/builders/Configuration/ConfigurationBuilder");
const FilesBuilder = require("code-narrator/dist/src/documentation/plugins/builders/Files/FilesBuilder");
const FoldersBuilder = require("code-narrator/dist/src/documentation/plugins/builders/Folders/FoldersBuilder");
const UserDefinedBuilder = require("code-narrator/dist/src/documentation/plugins/builders/UserDefined/UserDefinedBuilder");
/**
* You can find the documentation about code-narrator.config.js at
* https://github.com/ingig/code-narrator/blob/master/docs/Configuration/code-narrator.config.js.md
*
* @type {ICodeNarratorConfig}
*/
const config = {
// App specific configuration files. This could be something like project_name.json
config_files: [
],
project_file: "package.json",
entry_file: "./dist/index.js",
cli_file: "",
project_path: "./",
source_path: "src",
documentation_path: "./docs",
test_path: "test",
exclude: [
"/node_modules",
".env",
"/.idea",
"/.git",
".gitignore",
"/.code-narrator",
"/dist",
"/build",
"package-lock.json",
],
// Indicates if the documentation should create a README file in root of project
readmeRoot: true,
// Url to the repository, code-narrator tries to extract this from project file
repository_url: "git+https://github.com/Thiladev/reffuse.git",
// These are the plugins used when building documentation. You can create your own plugin. Checkout the code-narrator docs HowTo create a builder plugin
builderPlugins: [
ConfigurationBuilder,
FilesBuilder,
FoldersBuilder,
UserDefinedBuilder,
],
// These are system commends send to GPT with every query
gptSystemCommands: [
"Act as a documentation expert for software",
"If there is :::note, :::info, :::caution, :::tip, :::danger in the text, extract that from its location and format it correctly",
"Return your answer in {DocumentationType} format",
"If you notice any secret information, replace it with ***** in your response",
],
documentation_type: "md",
document_file_extension: ".md",
folderRootFileName: "README",
cache_file: ".code-narrator/cache.json",
gptModel: "gpt-4",
aiService: undefined,
project_name: "reffuse",
include: [
"src/**/*",
],
// Array of user defined documentations. See code-narrator How to create a user defined builder
builders: [
{
name: "README",
type: "README",
template: "README",
sidebarPosition: 1,
args: {
entryFileContent: "content(package.json)",
aiService: undefined,
},
aiService: undefined,
},
{
name: "HowTo Overview",
type: "README",
template: "overview_readme",
path: "howto",
files: [
{
path: "howto/*.md",
aiService: undefined,
},
],
pages: [
{
name: "HowTo Example",
type: "howto",
template: "howto_create_howto",
aiService: undefined,
},
],
aiService: undefined,
},
],
}
module.exports = config;

View File

@@ -395,9 +395,10 @@ export abstract class ReffuseHelpers<R> {
const initialState = this.useMemo(() => ref, [], { doNotReExecuteOnRuntimeOrContextChange: true })
const [reactStateValue, setReactStateValue] = React.useState(initialState)
this.useFork(() => Stream.runForEach(ref.changes, v => Effect.sync(() =>
setReactStateValue(v)
)), [ref])
this.useFork(() => Stream.runForEach(
Stream.changesWith(ref.changes, (x, y) => x === y),
v => Effect.sync(() => setReactStateValue(v)),
), [ref])
const setValue = this.useCallbackSync((setStateAction: React.SetStateAction<A>) =>
Ref.update(ref, prevState =>