- commit
- 43bddc0
- parent
- f18f8d6
- author
- Eric Bower
- date
- 2025-06-06 08:00:07 -0400 EDT
deno to node (#60) This changes the language runtime from deno to node. The reason for this change is because the target of this library is the browser and node has the best compatibility with it. Further we were running into a bunch of issues with the deno tooling for creating npm packages (e.g. dnt). deno is also pretty good at loading npm packages into its runtime so starting in deno doesn't help us that much. Ultimately there's just a few too many layers in between us and the npm release and at this point deno is not really serving us. --------- Co-authored-by: Vlad <vladmarginean@softwiz.ro>
+38,
-0
1@@ -0,0 +1,38 @@
2+name: build and test
3+
4+on:
5+ push:
6+ branches: main
7+ pull_request:
8+ branches: main
9+
10+permissions:
11+ contents: read
12+
13+jobs:
14+ bnt:
15+ name: ${{ matrix.example }}
16+ runs-on: ubuntu-latest
17+ strategy:
18+ fail-fast: false
19+ matrix:
20+ example:
21+ - ./examples/vite-react
22+ - ./examples/parcel-react
23+ - ./examples/tests-rtl
24+
25+ steps:
26+ - name: checkout
27+ uses: actions/checkout@v4
28+
29+ - name: npm install
30+ working-directory: ${{ matrix.example }}
31+ run: npm install
32+
33+ - name: test
34+ working-directory: ${{ matrix.example }}
35+ run: npm run test --if-present
36+
37+ - name: build
38+ working-directory: ${{ matrix.example }}
39+ run: npm run build --if-present
+4,
-10
1@@ -11,8 +11,6 @@ jobs:
2 steps:
3 - name: checkout
4 uses: actions/checkout@v4
5- - name: setup deno
6- uses: denoland/setup-deno@v2
7 - name: get version
8 id: vars
9 run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^v//')
10@@ -21,16 +19,12 @@ jobs:
11 with:
12 node-version: 18.x
13 registry-url: https://registry.npmjs.com
14+ - name: install
15+ run: npm install
16 - name: build
17- run: deno task npm $NPM_VERSION
18+ run: npm run build
19 env:
20 NPM_VERSION: ${{steps.vars.outputs.version}}
21
22- - name: checkout neurosnap/starfx-examples
23- uses: actions/checkout@v4
24- with:
25- repository: neurosnap/starfx-examples
26- path: examples
27-
28 - name: Publish Preview Versions
29- run: npx pkg-pr-new publish './npm' --template './examples/*'
30+ run: npx pkg-pr-new publish '.' --template './examples/*'
+0,
-75
1@@ -1,75 +0,0 @@
2-name: test-ecosystem
3-
4-on:
5- push:
6- branches: main
7- pull_request:
8- branches: main
9-
10-permissions:
11- contents: read
12-
13-jobs:
14- test-ecosystem:
15- name: ${{ matrix.example.repo }}/${{ matrix.example.folder }}
16- runs-on: ubuntu-latest
17- strategy:
18- fail-fast: false
19- matrix:
20- example:
21- - owner: neurosnap
22- repo: starfx-examples
23- folder: vite-react
24- - owner: neurosnap
25- repo: starfx-examples
26- folder: parcel-react
27- - owner: neurosnap
28- repo: starfx-examples
29- folder: tests-rtl
30- steps:
31- - name: checkout main repo
32- uses: actions/checkout@v4
33- with:
34- repository: "neurosnap/starfx"
35- path: "starfx"
36-
37- - name: setup deno
38- uses: denoland/setup-deno@v2
39-
40- # determines branch and sets it as output available through the `id`
41- - name: dynamically determine ${{ matrix.example.owner }}/${{ matrix.example.repo }} branch
42- id: conditionalBranch
43- shell: bash
44- run: deno run -A ./starfx/scripts/branch-exists.ts "$GITHUB_HEAD_REF" neurosnap/starfx-examples
45-
46- - name: checkout ${{ matrix.example.owner }}/${{ matrix.example.repo }} on ${{ steps.conditionalBranch.outputs.branch }}
47- uses: actions/checkout@v4
48- with:
49- repository: ${{ matrix.example.owner }}/${{ matrix.example.repo }}
50- path: ${{ matrix.example.repo }}
51- ref: ${{ steps.conditionalBranch.outputs.branch }}
52-
53- - name: bundle for npm
54- shell: bash
55- run: deno task npm 0.0.0
56- working-directory: starfx
57-
58- # install in example repos
59- - name: install ${{ matrix.example.owner }}/${{ matrix.example.repo }}
60- shell: bash
61- working-directory: ${{ matrix.example.repo }}/${{ matrix.example.folder }}
62- run: npm install
63-
64- # symlink example repos
65- - name: symlink built assets
66- shell: bash
67- run: deno task sync-build-to install ${{ matrix.example.repo }}/${{ matrix.example.folder }}
68- working-directory: starfx
69-
70- # run build and test in example repos
71- - name: build ${{ matrix.example.owner }}/${{ matrix.example.repo }}
72- working-directory: ${{ matrix.example.repo }}/${{ matrix.example.folder }}
73- run: npm run build --if-present
74- - name: test ${{ matrix.example.owner }}/${{ matrix.example.repo }}
75- working-directory: ${{ matrix.example.repo }}/${{ matrix.example.folder }}
76- run: npm run test --if-present
+8,
-8
1@@ -16,17 +16,17 @@ jobs:
2 - name: checkout
3 uses: actions/checkout@v4
4
5- - name: setup deno
6- uses: denoland/setup-deno@v2
7+ - name: setup node
8+ uses: actions/setup-node@v4
9
10- - name: format
11- run: deno fmt --check
12+ - name: install
13+ run: npm install
14
15 - name: lint
16- run: deno lint
17+ run: npm run ci
18
19 - name: test
20- run: deno task test
21+ run: npm test
22
23- - name: npm
24- run: deno task npm 0.0.0
25+ - name: test build
26+ run: npm run build
+2,
-0
1@@ -7,3 +7,5 @@ npm/
2 .vscode
3 docs/public/*
4 !docs/public/.gitkeep
5+dist/
6+src/package.json
M
Makefile
+1,
-9
1@@ -1,11 +1,3 @@
2 fmt:
3- deno fmt
4+ npm run fmt
5 .PHONY:
6-
7-lint:
8- deno lint
9-.PHONY: lint
10-
11-test:
12- deno task test
13-.PHONY: test
R api-type-template.ts =>
api-type-template.mts
+12,
-12
1@@ -1,3 +1,9 @@
2+import { writeFileSync } from "node:fs";
3+
4+console.log("writing api template file");
5+createTemplateFile(createQueryApi());
6+console.log("DONE!");
7+
8 function createQueryApi() {
9 const methods = [
10 "get",
11@@ -163,7 +169,7 @@ ${method}<P, ApiSuccess, ApiError = unknown>(
12 fn: MiddlewareApiCo<
13 Omit<Ctx, 'payload' | 'json'> &
14 Payload<P> &
15- FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>,
16+ FetchJson<ApiSuccess, ApiError extends unknown ? Ctx["_error"] : ApiError>
17 >,
18 ): CreateActionWithPayload<
19 Omit<Ctx, 'payload' | 'json'> &
20@@ -222,7 +228,7 @@ ${method}<P, ApiSuccess, ApiError = unknown>(
21 * This is an auto-generated file, do not edit directly!
22 * Run "yarn template" to generate this file.
23 */
24-import type { ThunksApi } from "./thunk.ts";
25+import type { ThunksApi } from "./thunk.js";
26 import type {
27 ApiCtx,
28 CreateAction,
29@@ -230,8 +236,8 @@ import type {
30 FetchJson,
31 MiddlewareApiCo,
32 Supervisor,
33-} from "./types.ts";
34-import type { Next, Payload } from "../types.ts";
35+} from "./types.js";
36+import type { Next, Payload } from "../types.js";
37 import type { Operation } from "effection";
38
39 export type ApiName = string | string[];
40@@ -252,12 +258,6 @@ ${regMethods}
41 return tmpl;
42 }
43
44-async function createTemplateFile(tmpl: string) {
45- try {
46- await Deno.writeTextFile("./query/api-types.ts", tmpl);
47- } catch (err) {
48- console.error(err);
49- }
50+function createTemplateFile(tmpl: string) {
51+ writeFileSync("./src/query/api-types.ts", tmpl);
52 }
53-
54-createTemplateFile(createQueryApi()).then(console.log).catch(console.error);
+30,
-0
1@@ -0,0 +1,30 @@
2+{
3+ "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
4+ "vcs": {
5+ "enabled": false,
6+ "clientKind": "git",
7+ "useIgnoreFile": false
8+ },
9+ "files": { "ignoreUnknown": false, "ignore": ["dist", "examples"] },
10+ "formatter": { "enabled": true, "indentStyle": "space" },
11+ "organizeImports": { "enabled": true },
12+ "linter": {
13+ "enabled": true,
14+ "rules": {
15+ "recommended": true,
16+ "suspicious": {
17+ "noExplicitAny": "off",
18+ "noImplicitAnyLet": "off",
19+ "noConfusingVoidType": "off"
20+ },
21+ "correctness": {
22+ "useYield": "off",
23+ "noChildrenProp": "off"
24+ },
25+ "complexity": {
26+ "noForEach": "off"
27+ }
28+ }
29+ },
30+ "javascript": { "formatter": { "quoteStyle": "double" } }
31+}
+37,
-0
1@@ -0,0 +1,37 @@
2+// https://github.com/colinhacks/zod/blob/c58bd9b0125881caee03a408eae88ec1dc5eb18b/packages/zod/build.mts
3+import * as fs from "node:fs";
4+import * as path from "node:path";
5+import { execaSync } from "execa";
6+
7+const $ = execaSync({ stdio: "inherit" });
8+
9+$`rm -rf ./dist`;
10+
11+function writePackageJson(dir: string, fields: Record<string, any>) {
12+ const packageJsonPath = path.join(path.resolve(dir), "package.json");
13+ fs.mkdirSync(dir, {
14+ recursive: true,
15+ });
16+ console.log(`writing package.json to ${packageJsonPath}...`);
17+ fs.writeFileSync(packageJsonPath, JSON.stringify(fields, null, 2));
18+ return packageJsonPath;
19+}
20+
21+console.log("building ESM...");
22+const esmPkg = writePackageJson("./src", { type: "module" });
23+$`npx tsc -p tsconfig.esm.json`;
24+fs.rmSync(esmPkg, { force: true });
25+
26+writePackageJson("./dist/esm", { type: "module" });
27+
28+console.log("building CJS...");
29+const cjsPkg = writePackageJson("./src", { type: "commonjs" });
30+$`npx tsc -p tsconfig.cjs.json`;
31+fs.rmSync(cjsPkg, { force: true });
32+writePackageJson("./dist/cjs", { type: "commonjs" });
33+
34+console.log("building types...");
35+$`npx tsc -p tsconfig.types.json`;
36+writePackageJson("./dist/types", { type: "commonjs" });
37+
38+console.log("DONE.");
+0,
-33
1@@ -1,33 +0,0 @@
2-{
3- "tasks": {
4- "types": "deno run --allow-write ./api-type-template.ts",
5- "npm": "deno run -A ./scripts/npm.ts",
6- "test": "deno test --allow-env --allow-read --allow-import",
7- "sync-build-to": "deno run -A ./scripts/sync.ts"
8- },
9- "lint": {
10- "exclude": ["npm/", "examples/"],
11- "rules": {
12- "tags": ["recommended"],
13- "exclude": ["no-explicit-any", "require-yield"]
14- }
15- },
16- "fmt": {
17- "exclude": ["npm/", "examples/"]
18- },
19- "compilerOptions": {
20- "strict": true,
21- "lib": ["deno.window", "dom"],
22- "jsx": "react",
23- "jsxFactory": "React.createElement",
24- "jsxFragmentFactory": "React.Fragment"
25- },
26- "imports": {
27- "react": "npm:react@^18.2.0",
28- "react-dom": "npm:react-dom@^18.2.0",
29- "react-redux": "npm:react-redux@^8.0.5",
30- "reselect": "npm:reselect@^4.1.8",
31- "immer": "npm:immer@^10.0.2",
32- "effection": "https://deno.land/x/effection@3.0.0-beta.3/mod.ts"
33- }
34-}
+0,
-347
1@@ -1,347 +0,0 @@
2-{
3- "version": "4",
4- "specifiers": {
5- "jsr:@david/code-block-writer@^13.0.2": "13.0.3",
6- "jsr:@deno/cache-dir@~0.10.3": "0.10.3",
7- "jsr:@deno/dnt@0.41.3": "0.41.3",
8- "jsr:@std/assert@*": "1.0.10",
9- "jsr:@std/assert@0.223": "0.223.0",
10- "jsr:@std/assert@0.226": "0.226.0",
11- "jsr:@std/assert@^1.0.10": "1.0.10",
12- "jsr:@std/bytes@0.223": "0.223.0",
13- "jsr:@std/expect@*": "1.0.10",
14- "jsr:@std/fmt@0.223": "0.223.0",
15- "jsr:@std/fmt@1": "1.0.3",
16- "jsr:@std/fs@0.223": "0.223.0",
17- "jsr:@std/fs@1": "1.0.8",
18- "jsr:@std/fs@~0.229.3": "0.229.3",
19- "jsr:@std/internal@^1.0.5": "1.0.5",
20- "jsr:@std/io@0.223": "0.223.0",
21- "jsr:@std/path@0.223": "0.223.0",
22- "jsr:@std/path@1": "1.0.8",
23- "jsr:@std/path@1.0.0-rc.1": "1.0.0-rc.1",
24- "jsr:@std/path@^1.0.8": "1.0.8",
25- "jsr:@std/path@~0.225.2": "0.225.2",
26- "jsr:@std/testing@*": "1.0.8",
27- "jsr:@ts-morph/bootstrap@0.24": "0.24.0",
28- "jsr:@ts-morph/common@0.24": "0.24.0",
29- "npm:effection@*": "3.0.3",
30- "npm:immer@^10.0.2": "10.1.1",
31- "npm:react-dom@^18.2.0": "18.2.0_react@18.3.1",
32- "npm:react-redux@^8.0.5": "8.1.3_react@18.3.1_react-dom@18.2.0__react@18.3.1",
33- "npm:react@^18.2.0": "18.3.1",
34- "npm:reselect@^4.1.8": "4.1.8"
35- },
36- "jsr": {
37- "@david/code-block-writer@13.0.3": {
38- "integrity": "f98c77d320f5957899a61bfb7a9bead7c6d83ad1515daee92dbacc861e13bb7f"
39- },
40- "@deno/cache-dir@0.10.3": {
41- "integrity": "eb022f84ecc49c91d9d98131c6e6b118ff63a29e343624d058646b9d50404776",
42- "dependencies": [
43- "jsr:@std/fmt@0.223",
44- "jsr:@std/fs@0.223",
45- "jsr:@std/io",
46- "jsr:@std/path@0.223"
47- ]
48- },
49- "@deno/dnt@0.41.3": {
50- "integrity": "b2ef2c8a5111eef86cb5bfcae103d6a2938e8e649e2461634a7befb7fc59d6d2",
51- "dependencies": [
52- "jsr:@david/code-block-writer",
53- "jsr:@deno/cache-dir",
54- "jsr:@std/fmt@1",
55- "jsr:@std/fs@1",
56- "jsr:@std/path@1",
57- "jsr:@ts-morph/bootstrap"
58- ]
59- },
60- "@std/assert@0.223.0": {
61- "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24"
62- },
63- "@std/assert@0.226.0": {
64- "integrity": "0dfb5f7c7723c18cec118e080fec76ce15b4c31154b15ad2bd74822603ef75b3"
65- },
66- "@std/assert@1.0.10": {
67- "integrity": "59b5cbac5bd55459a19045d95cc7c2ff787b4f8527c0dd195078ff6f9481fbb3",
68- "dependencies": [
69- "jsr:@std/internal"
70- ]
71- },
72- "@std/bytes@0.223.0": {
73- "integrity": "84b75052cd8680942c397c2631318772b295019098f40aac5c36cead4cba51a8"
74- },
75- "@std/expect@1.0.10": {
76- "integrity": "7659b640447887cd1735f866962e10e434f12443b13595b149970c806e6f08db",
77- "dependencies": [
78- "jsr:@std/assert@^1.0.10",
79- "jsr:@std/internal"
80- ]
81- },
82- "@std/fmt@0.223.0": {
83- "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208"
84- },
85- "@std/fmt@1.0.3": {
86- "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f"
87- },
88- "@std/fs@0.223.0": {
89- "integrity": "3b4b0550b2c524cbaaa5a9170c90e96cbb7354e837ad1bdaf15fc9df1ae9c31c"
90- },
91- "@std/fs@0.229.3": {
92- "integrity": "783bca21f24da92e04c3893c9e79653227ab016c48e96b3078377ebd5222e6eb",
93- "dependencies": [
94- "jsr:@std/path@1.0.0-rc.1"
95- ]
96- },
97- "@std/fs@1.0.8": {
98- "integrity": "161c721b6f9400b8100a851b6f4061431c538b204bb76c501d02c508995cffe0",
99- "dependencies": [
100- "jsr:@std/path@^1.0.8"
101- ]
102- },
103- "@std/internal@1.0.5": {
104- "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba"
105- },
106- "@std/io@0.223.0": {
107- "integrity": "2d8c3c2ab3a515619b90da2c6ff5ea7b75a94383259ef4d02116b228393f84f1",
108- "dependencies": [
109- "jsr:@std/assert@0.223",
110- "jsr:@std/bytes"
111- ]
112- },
113- "@std/path@0.223.0": {
114- "integrity": "593963402d7e6597f5a6e620931661053572c982fc014000459edc1f93cc3989",
115- "dependencies": [
116- "jsr:@std/assert@0.223"
117- ]
118- },
119- "@std/path@0.225.2": {
120- "integrity": "0f2db41d36b50ef048dcb0399aac720a5348638dd3cb5bf80685bf2a745aa506",
121- "dependencies": [
122- "jsr:@std/assert@0.226"
123- ]
124- },
125- "@std/path@1.0.0-rc.1": {
126- "integrity": "b8c00ae2f19106a6bb7cbf1ab9be52aa70de1605daeb2dbdc4f87a7cbaf10ff6"
127- },
128- "@std/path@1.0.8": {
129- "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
130- },
131- "@std/testing@1.0.8": {
132- "integrity": "ceef535808fb7568e91b0f8263599bd29b1c5603ffb0377227f00a8ca9fe42a2",
133- "dependencies": [
134- "jsr:@std/assert@^1.0.10",
135- "jsr:@std/internal"
136- ]
137- },
138- "@ts-morph/bootstrap@0.24.0": {
139- "integrity": "a826a2ef7fa8a7c3f1042df2c034d20744d94da2ee32bf29275bcd4dffd3c060",
140- "dependencies": [
141- "jsr:@ts-morph/common"
142- ]
143- },
144- "@ts-morph/common@0.24.0": {
145- "integrity": "12b625b8e562446ba658cdbe9ad77774b4bd96b992ae8bd34c60dbf24d06c1f3",
146- "dependencies": [
147- "jsr:@std/fs@~0.229.3",
148- "jsr:@std/path@~0.225.2"
149- ]
150- }
151- },
152- "npm": {
153- "@babel/runtime@7.26.0": {
154- "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
155- "dependencies": [
156- "regenerator-runtime"
157- ]
158- },
159- "@types/hoist-non-react-statics@3.3.6": {
160- "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
161- "dependencies": [
162- "@types/react",
163- "hoist-non-react-statics"
164- ]
165- },
166- "@types/prop-types@15.7.5": {
167- "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
168- },
169- "@types/react@18.0.32": {
170- "integrity": "sha512-gYGXdtPQ9Cj0w2Fwqg5/ak6BcK3Z15YgjSqtyDizWUfx7mQ8drs0NBUzRRsAdoFVTO8kJ8L2TL8Skm7OFPnLUw==",
171- "dependencies": [
172- "@types/prop-types",
173- "@types/scheduler",
174- "csstype"
175- ]
176- },
177- "@types/scheduler@0.16.3": {
178- "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
179- },
180- "@types/use-sync-external-store@0.0.3": {
181- "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
182- },
183- "csstype@3.1.2": {
184- "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
185- },
186- "effection@3.0.3": {
187- "integrity": "sha512-9ASCaJ44flDoEKUUJtn9drfIomn2z30sZUw7//crbq+eltMu09AyILcouXwpMkcHR8TsD5hDvTTsOLHswWRxXQ=="
188- },
189- "hoist-non-react-statics@3.3.2": {
190- "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
191- "dependencies": [
192- "react-is@16.13.1"
193- ]
194- },
195- "immer@10.1.1": {
196- "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw=="
197- },
198- "js-tokens@4.0.0": {
199- "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
200- },
201- "loose-envify@1.4.0": {
202- "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
203- "dependencies": [
204- "js-tokens"
205- ]
206- },
207- "react-dom@18.2.0_react@18.3.1": {
208- "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
209- "dependencies": [
210- "loose-envify",
211- "react",
212- "scheduler"
213- ]
214- },
215- "react-is@16.13.1": {
216- "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
217- },
218- "react-is@18.3.1": {
219- "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
220- },
221- "react-redux@8.1.3_react@18.3.1_react-dom@18.2.0__react@18.3.1": {
222- "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
223- "dependencies": [
224- "@babel/runtime",
225- "@types/hoist-non-react-statics",
226- "@types/use-sync-external-store",
227- "hoist-non-react-statics",
228- "react",
229- "react-dom",
230- "react-is@18.3.1",
231- "use-sync-external-store"
232- ]
233- },
234- "react@18.3.1": {
235- "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
236- "dependencies": [
237- "loose-envify"
238- ]
239- },
240- "regenerator-runtime@0.14.1": {
241- "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
242- },
243- "reselect@4.1.8": {
244- "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
245- },
246- "scheduler@0.23.0": {
247- "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
248- "dependencies": [
249- "loose-envify"
250- ]
251- },
252- "use-sync-external-store@1.4.0_react@18.3.1": {
253- "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
254- "dependencies": [
255- "react"
256- ]
257- }
258- },
259- "redirects": {
260- "https://crux.land/api/get/2KNRVU": "https://crux.land/api/get/2KNRVU.ts",
261- "https://crux.land/api/get/router@0.0.5": "https://crux.land/api/get/2KNRVU",
262- "https://crux.land/router@0.0.5": "https://crux.land/api/get/router@0.0.5"
263- },
264- "remote": {
265- "https://crux.land/api/get/2KNRVU.ts": "6a77d55844aba78d01520c5ff0b2f0af7f24cc1716a0de8b3bb6bd918c47b5ba",
266- "https://deno.land/std@0.158.0/fmt/colors.ts": "ff7dc9c9f33a72bd48bc24b21bbc1b4545d8494a431f17894dbc5fe92a938fc4",
267- "https://deno.land/std@0.158.0/testing/_diff.ts": "a23e7fc2b4d8daa3e158fa06856bedf5334ce2a2831e8bf9e509717f455adb2c",
268- "https://deno.land/std@0.158.0/testing/_format.ts": "cd11136e1797791045e639e9f0f4640d5b4166148796cad37e6ef75f7d7f3832",
269- "https://deno.land/std@0.158.0/testing/asserts.ts": "8696c488bc98d8d175e74dc652a0ffbc7fca93858da01edc57ed33c1148345da",
270- "https://deno.land/x/continuation@0.1.5/mod.ts": "690def2735046367b3e1b4bc6e51b5912f2ed09c41c7df7a55c060f23720ad33",
271- "https://deno.land/x/effection@3.0.0-beta.3/lib/abort-signal.ts": "8be1b331b2bc417d70fe4c07e0b806e89972b8eab519ce58beed7ec632ae9048",
272- "https://deno.land/x/effection@3.0.0-beta.3/lib/all.ts": "acadab8258228e290192f587c8c532428f9093337a9b7688ae55cbc2cacd5caf",
273- "https://deno.land/x/effection@3.0.0-beta.3/lib/async.ts": "086b27b253be944c47c633d105f1657e243cd8c0d35b9a0dc5383528d7235dde",
274- "https://deno.land/x/effection@3.0.0-beta.3/lib/call.ts": "2fe2d0ac5f4bda345ef8627b9047d19336f2926c25cf661bc982b84754aa57fa",
275- "https://deno.land/x/effection@3.0.0-beta.3/lib/channel.ts": "f86b36666463f8f86fc1ac1726a94f0f08dc05559ba710b8eb93581b2b8588e6",
276- "https://deno.land/x/effection@3.0.0-beta.3/lib/context.ts": "108989ac839d6756e30f6c0afc458bfa3975dd0f970d5173b6b8f8473ce4c335",
277- "https://deno.land/x/effection@3.0.0-beta.3/lib/deps.ts": "91062b4b97089a8cf36550d4f9605d325a0fd19bebc72d15524481a3b56ea669",
278- "https://deno.land/x/effection@3.0.0-beta.3/lib/each.ts": "9689346d1db3fedcd87d48c70be5515ad3e18fa4b894755fa53910fb8ad356f3",
279- "https://deno.land/x/effection@3.0.0-beta.3/lib/ensure.ts": "c3640cc12c1bc747a8a4086af476840db026d04ea22f45a697d53617b2b1cc66",
280- "https://deno.land/x/effection@3.0.0-beta.3/lib/events.ts": "d962e7403d62948642f5a3161f611f4375932aa8702050575f0d538aab7c3467",
281- "https://deno.land/x/effection@3.0.0-beta.3/lib/filter.ts": "39f349ee921ba718cf3259e05003255eeeafbb5ca6e437d2d269b1805da2236e",
282- "https://deno.land/x/effection@3.0.0-beta.3/lib/first.ts": "5bc321069d2e2b87b6623f626a929d5d5ba32bca32ee03b37bdc1a64722eebb9",
283- "https://deno.land/x/effection@3.0.0-beta.3/lib/instructions.ts": "5fd8638e385068adc6c1a896bba02b736d7c2c26e5124d3d063fdbcaf140abec",
284- "https://deno.land/x/effection@3.0.0-beta.3/lib/lazy.ts": "92ea526c5ad7d88290f2a87168e038d482f97421379508d85cf2e049ee60639b",
285- "https://deno.land/x/effection@3.0.0-beta.3/lib/lift.ts": "0c622bf0359f92235547b57efa66139b265a7b259428e6883469de0b3af32f5d",
286- "https://deno.land/x/effection@3.0.0-beta.3/lib/main.ts": "a0deaf1d1d958ef7a5821d8ac3dfbd190a47608d603798a5fc3b0c2309a724da",
287- "https://deno.land/x/effection@3.0.0-beta.3/lib/map.ts": "1a0c369dad53affc4b798a04142de637a75f981385acafcafd26bdc569675bc2",
288- "https://deno.land/x/effection@3.0.0-beta.3/lib/mod.ts": "f7189b02d008baba1166d33779379b12f7104e0b6d373194270ac126a73ba82d",
289- "https://deno.land/x/effection@3.0.0-beta.3/lib/pause.ts": "a690b0d67cf970c34f528df8c61d69eb43deda9817362776f6359f506dc0da45",
290- "https://deno.land/x/effection@3.0.0-beta.3/lib/pipe.ts": "4a28fa93a1ba53661bafb84265f3fcb5614920bbecc0db1c261e1093da3b2cdf",
291- "https://deno.land/x/effection@3.0.0-beta.3/lib/queue.ts": "80c6234cb6eaba9fd1abdae077e73f51897b099ea54f852b9a744e8eba51302f",
292- "https://deno.land/x/effection@3.0.0-beta.3/lib/race.ts": "0c43f24ce5006768f5cbac8d6f5dc07848bafa625cc0bc6c24fb6a2f2a8808f2",
293- "https://deno.land/x/effection@3.0.0-beta.3/lib/result.ts": "44e4bdadad155beb9bbfe41948819bbcb9e27a772283e52e89981bd6636a8687",
294- "https://deno.land/x/effection@3.0.0-beta.3/lib/run.ts": "b85043bc8b30c0eb0d04654cdd07004b21145f2e3f59f52e39df76558e324ca4",
295- "https://deno.land/x/effection@3.0.0-beta.3/lib/run/create.ts": "be9139af2fbe15908256d2d159dec8dca079f94cf02d488074c94fa26fc651fa",
296- "https://deno.land/x/effection@3.0.0-beta.3/lib/run/frame.ts": "132fdace9c00e6ad0e249d7faab1c33680336c5fa8e4a893f092ecec4e2df786",
297- "https://deno.land/x/effection@3.0.0-beta.3/lib/run/scope.ts": "e1c195fd4f954e4b525db25fb1db79447e745b2c0bb7c74a8a31ca58b1f4e64e",
298- "https://deno.land/x/effection@3.0.0-beta.3/lib/run/task.ts": "7084b9cabdc338c776dc522ec8b677fb3ac41aa0c94e454d467731494cb68737",
299- "https://deno.land/x/effection@3.0.0-beta.3/lib/run/types.ts": "010bea700f68fef99dd87ca5ca3cbbc90e026ac467889d8429d39cba0ee55fda",
300- "https://deno.land/x/effection@3.0.0-beta.3/lib/run/value.ts": "d57428b45dfeecc9df1e68dadf8697dbc33cd412e6ffcab9d0ba4368e8c1fbd6",
301- "https://deno.land/x/effection@3.0.0-beta.3/lib/shift-sync.ts": "74ecefa9cb2e145a3c52f363319f8d6296b804600852044b7d14bd53bc10b512",
302- "https://deno.land/x/effection@3.0.0-beta.3/lib/signal.ts": "da723b43b6bd61ea86dab991e9a6c6249a61d3b1c3c98ef473b160c9383e7d07",
303- "https://deno.land/x/effection@3.0.0-beta.3/lib/sleep.ts": "44e3a80248dad7a47066a99a7daec9b318e87d5d211adf27776145544d455689",
304- "https://deno.land/x/effection@3.0.0-beta.3/lib/types.ts": "9738143fe6bfd5709a6ff10b6dd065582cfaca1167bf57902cb7bcca89b53dc4",
305- "https://deno.land/x/effection@3.0.0-beta.3/mod.ts": "ffae461c16d4a1bf24c2179582ab8d5c81ad0df61e4ae2fba51ef5e5bdf90345",
306- "https://deno.land/x/effection@3.0.3/lib/abort-signal.ts": "b404e2c4250edb6df67f757cf190c87915fd4edbd3200c47b11db762a4cc10cc",
307- "https://deno.land/x/effection@3.0.3/lib/all.ts": "e45b9701998212b8a97949b1a6f0defb71ce90e56eb57d5afb365e3bba2e3791",
308- "https://deno.land/x/effection@3.0.3/lib/async.ts": "ac4bed095e849584a6170ac9a47c9217c2e1e99543275cbc9407d92851120ada",
309- "https://deno.land/x/effection@3.0.3/lib/call.ts": "096705dfd01fa19b6ae01fe3e362c919308a011e6d4647029cdb31dac80eadb2",
310- "https://deno.land/x/effection@3.0.3/lib/channel.ts": "445b29c5cfc0b6bc48b1a7ea81e09d14c452ee4646c49c7753c8e5b34962ad50",
311- "https://deno.land/x/effection@3.0.3/lib/context.ts": "108989ac839d6756e30f6c0afc458bfa3975dd0f970d5173b6b8f8473ce4c335",
312- "https://deno.land/x/effection@3.0.3/lib/deps.ts": "91062b4b97089a8cf36550d4f9605d325a0fd19bebc72d15524481a3b56ea669",
313- "https://deno.land/x/effection@3.0.3/lib/each.ts": "0a32eaa8b54966a913c843714e669c1f1e8933a3570d54797cc20ee2c4b5de41",
314- "https://deno.land/x/effection@3.0.3/lib/ensure.ts": "8043d8e6e67ad27382cba05b3c8b886cf46436871831171b8a8eea66609a6313",
315- "https://deno.land/x/effection@3.0.3/lib/events.ts": "bdaf6c87c368aebff1e4287a9917ae0b6ba880c4008ecf0abf6b5af922233c62",
316- "https://deno.land/x/effection@3.0.3/lib/instructions.ts": "3e5316bb7f32a70f93b853673dd1192cdfa11a04037e630d07ddf8fd5eba5d08",
317- "https://deno.land/x/effection@3.0.3/lib/lazy.ts": "92ea526c5ad7d88290f2a87168e038d482f97421379508d85cf2e049ee60639b",
318- "https://deno.land/x/effection@3.0.3/lib/lift.ts": "06fafd92f3a8e87c34e9bb9d9dacbb0333b5213c9c65c7245b2cab2cf3cf99e9",
319- "https://deno.land/x/effection@3.0.3/lib/main.ts": "5f4793fe6d82dcbf991d3306334b784c2b2617f618295e8c368f3fe714e66c01",
320- "https://deno.land/x/effection@3.0.3/lib/mod.ts": "bbbffe1265d9848812feefa7b20307c448bd4ce1d4c6232d2312f3722dca0fa7",
321- "https://deno.land/x/effection@3.0.3/lib/pause.ts": "a690b0d67cf970c34f528df8c61d69eb43deda9817362776f6359f506dc0da45",
322- "https://deno.land/x/effection@3.0.3/lib/queue.ts": "80c6234cb6eaba9fd1abdae077e73f51897b099ea54f852b9a744e8eba51302f",
323- "https://deno.land/x/effection@3.0.3/lib/race.ts": "ab652679ee00fd3f4ca5156628bf3af7aea55b2e20bb6387693075f7ea27d5ca",
324- "https://deno.land/x/effection@3.0.3/lib/result.ts": "44e4bdadad155beb9bbfe41948819bbcb9e27a772283e52e89981bd6636a8687",
325- "https://deno.land/x/effection@3.0.3/lib/run.ts": "55070ed92c5881e86b9724f519986058286ef54b6c12adf82847023631ebcfd3",
326- "https://deno.land/x/effection@3.0.3/lib/run/create.ts": "be9139af2fbe15908256d2d159dec8dca079f94cf02d488074c94fa26fc651fa",
327- "https://deno.land/x/effection@3.0.3/lib/run/frame.ts": "132fdace9c00e6ad0e249d7faab1c33680336c5fa8e4a893f092ecec4e2df786",
328- "https://deno.land/x/effection@3.0.3/lib/run/scope.ts": "a968455e313ba9aa097ee5c18b4db0d8e2397b90c78e413fa08396baead7b74a",
329- "https://deno.land/x/effection@3.0.3/lib/run/task.ts": "7084b9cabdc338c776dc522ec8b677fb3ac41aa0c94e454d467731494cb68737",
330- "https://deno.land/x/effection@3.0.3/lib/run/types.ts": "010bea700f68fef99dd87ca5ca3cbbc90e026ac467889d8429d39cba0ee55fda",
331- "https://deno.land/x/effection@3.0.3/lib/run/value.ts": "d57428b45dfeecc9df1e68dadf8697dbc33cd412e6ffcab9d0ba4368e8c1fbd6",
332- "https://deno.land/x/effection@3.0.3/lib/shift-sync.ts": "74ecefa9cb2e145a3c52f363319f8d6296b804600852044b7d14bd53bc10b512",
333- "https://deno.land/x/effection@3.0.3/lib/signal.ts": "6aba1f372419e1540bd29a9ff992ffd2500e035b2e455d2c11d856a052f698d1",
334- "https://deno.land/x/effection@3.0.3/lib/sleep.ts": "ff8ba6a0266f2e8837a9ae5f63402f8db51a39ce573abf1335109bef772d6b4a",
335- "https://deno.land/x/effection@3.0.3/lib/types.ts": "06b435b6152b17ef7959a37e1901109b3c716e14ee5e0ae942314439f63bb630",
336- "https://deno.land/x/effection@3.0.3/mod.ts": "ffae461c16d4a1bf24c2179582ab8d5c81ad0df61e4ae2fba51ef5e5bdf90345",
337- "https://deno.land/x/mock_fetch@0.3.0/mod.ts": "7e7806c65ab17b2b684c334c4e565812bdaf504a3e9c938d2bb52bb67428bc89"
338- },
339- "workspace": {
340- "dependencies": [
341- "npm:immer@^10.0.2",
342- "npm:react-dom@^18.2.0",
343- "npm:react-redux@^8.0.5",
344- "npm:react@^18.2.0",
345- "npm:reselect@^4.1.8"
346- ]
347- }
348-}
D
deps.ts
+0,
-61
1@@ -1,61 +0,0 @@
2-export type {
3- Callable,
4- Channel,
5- Instruction,
6- Operation,
7- Predicate,
8- Queue,
9- Reject,
10- Resolve,
11- Result,
12- Scope,
13- Signal,
14- Stream,
15- Subscription,
16- Task,
17-} from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts";
18-export {
19- action,
20- call,
21- createChannel,
22- createContext,
23- createQueue,
24- createScope,
25- createSignal,
26- each,
27- ensure,
28- Err,
29- Ok,
30- race,
31- resource,
32- run,
33- SignalQueueFactory,
34- sleep,
35- spawn,
36- suspend,
37- useAbortSignal,
38- useScope,
39-} from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts";
40-
41-import React from "https://esm.sh/react@18.2.0?pin=v135";
42-
43-export type { JSX } from "https://esm.sh/react@18.2.0?pin=v135";
44-
45-export { React };
46-export {
47- Provider,
48- useDispatch,
49- useSelector,
50- useStore,
51-} from "https://esm.sh/react-redux@8.0.5?pin=v135";
52-export type {
53- TypedUseSelectorHook,
54-} from "https://esm.sh/react-redux@8.0.5?pin=v135";
55-export { createSelector } from "https://esm.sh/reselect@4.1.8?pin=v135";
56-
57-export {
58- enablePatches,
59- produce,
60- produceWithPatches,
61-} from "https://esm.sh/immer@10.0.2?pin=v135";
62-export type { Patch } from "https://esm.sh/immer@10.0.2?pin=v135";
+8,
-0
1@@ -0,0 +1,8 @@
2+node_modules/
3+*.swp
4+*.log
5+.DS_Store
6+.yarn/**
7+yarn.lock
8+package-lock.json
9+dist/
+5,
-0
1@@ -0,0 +1,5 @@
2+# starfx examples
3+
4+This repo is showcases what `starfx` can do.
5+
6+[starfx](https://github.com/neurosnap/starfx)
+14,
-0
1@@ -0,0 +1,14 @@
2+module.exports = {
3+ env: { browser: true, es2020: true },
4+ extends: [
5+ "eslint:recommended",
6+ "plugin:@typescript-eslint/recommended",
7+ "plugin:react-hooks/recommended",
8+ ],
9+ parser: "@typescript-eslint/parser",
10+ parserOptions: { ecmaVersion: "latest", sourceType: "module" },
11+ plugins: ["react-refresh"],
12+ rules: {
13+ "react-refresh/only-export-components": "warn",
14+ },
15+};
+25,
-0
1@@ -0,0 +1,25 @@
2+# Logs
3+logs
4+*.log
5+npm-debug.log*
6+yarn-debug.log*
7+yarn-error.log*
8+pnpm-debug.log*
9+lerna-debug.log*
10+
11+node_modules
12+dist
13+dist-ssr
14+*.local
15+
16+# Editor directories and files
17+.vscode/*
18+!.vscode/extensions.json
19+.idea
20+.DS_Store
21+*.suo
22+*.ntvs*
23+*.njsproj
24+*.sln
25+*.sw?
26+.yarn/**
+12,
-0
1@@ -0,0 +1,12 @@
2+<!DOCTYPE html>
3+<html lang="en">
4+ <head>
5+ <meta charset="UTF-8" />
6+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+ <title>vite + react + starfx</title>
8+ </head>
9+ <body>
10+ <div id="root"></div>
11+ <script type="module" src="/src/main.tsx"></script>
12+ </body>
13+</html>
+29,
-0
1@@ -0,0 +1,29 @@
2+{
3+ "name": "vite-react",
4+ "private": true,
5+ "version": "0.0.0",
6+ "type": "module",
7+ "scripts": {
8+ "start": "vite --host 0.0.0.0",
9+ "build": "tsc && vite build",
10+ "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
11+ "preview": "vite preview"
12+ },
13+ "dependencies": {
14+ "react": "^18.2.0",
15+ "react-dom": "^18.2.0",
16+ "starfx": "^0.13.0"
17+ },
18+ "devDependencies": {
19+ "@types/react": "^18.0.28",
20+ "@types/react-dom": "^18.0.11",
21+ "@typescript-eslint/eslint-plugin": "^5.57.1",
22+ "@typescript-eslint/parser": "^5.57.1",
23+ "@vitejs/plugin-react": "^4.0.0",
24+ "eslint": "^8.38.0",
25+ "eslint-plugin-react-hooks": "^4.6.0",
26+ "eslint-plugin-react-refresh": "^0.3.4",
27+ "typescript": "^5.3.2",
28+ "vite": "^4.3.2"
29+ }
30+}
+53,
-0
1@@ -0,0 +1,53 @@
2+import ReactDOM from "react-dom/client";
3+import { createApi, createSchema, createStore, mdw, timer } from "starfx";
4+import { Provider, useCache } from "starfx/react";
5+
6+const [schema, initialState] = createSchema();
7+const store = createStore({ initialState });
8+
9+const api = createApi();
10+// mdw = middleware
11+api.use(mdw.api({ schema }));
12+api.use(api.routes());
13+api.use(mdw.fetch({ baseUrl: "https://api.github.com" }));
14+
15+const fetchRepo = api.get(
16+ "/repos/neurosnap/starfx",
17+ { supervisor: timer() },
18+ api.cache(),
19+);
20+
21+store.run(api.register);
22+
23+function App() {
24+ return (
25+ <Provider schema={schema} store={store}>
26+ <Example />
27+ </Provider>
28+ );
29+}
30+
31+function Example() {
32+ const { isLoading, isError, message, data } = useCache(fetchRepo());
33+
34+ if (isLoading || !data) return "Loading ...";
35+
36+ if (isError) return `An error has occurred: ${message}`;
37+
38+ return (
39+ <div>
40+ <h1>{data.name}</h1>
41+ <p>{data.description}</p>
42+ <strong>👀 {data.subscribers_count}</strong>{" "}
43+ <strong>✨ {data.stargazers_count}</strong>{" "}
44+ <strong>🍴 {data.forks_count}</strong>
45+ </div>
46+ );
47+}
48+
49+const root = document.getElementById("root") as HTMLElement;
50+ReactDOM.createRoot(root).render(
51+ <Provider schema={schema} store={store}>
52+ <App />
53+ </Provider>,
54+);
+1,
-0
1@@ -0,0 +1 @@
2+/// <reference types="vite/client" />
+24,
-0
1@@ -0,0 +1,24 @@
2+{
3+ "compilerOptions": {
4+ "target": "ESNext",
5+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
6+ "module": "ESNext",
7+ "skipLibCheck": true,
8+
9+ /* Bundler mode */
10+ "moduleResolution": "bundler",
11+ "allowImportingTsExtensions": true,
12+ "resolveJsonModule": true,
13+ "isolatedModules": true,
14+ "noEmit": true,
15+ "jsx": "react-jsx",
16+
17+ /* Linting */
18+ "strict": true,
19+ "noUnusedLocals": true,
20+ "noUnusedParameters": true,
21+ "noFallthroughCasesInSwitch": true
22+ },
23+ "include": ["src"],
24+ "references": [{ "path": "./tsconfig.node.json" }]
25+}
+10,
-0
1@@ -0,0 +1,10 @@
2+{
3+ "compilerOptions": {
4+ "composite": true,
5+ "skipLibCheck": true,
6+ "module": "ESNext",
7+ "moduleResolution": "bundler",
8+ "allowSyntheticDefaultImports": true
9+ },
10+ "include": ["vite.config.ts"]
11+}
+7,
-0
1@@ -0,0 +1,7 @@
2+import { defineConfig } from "vite";
3+import react from "@vitejs/plugin-react";
4+
5+// https://vitejs.dev/config/
6+export default defineConfig({
7+ plugins: [react()],
8+});
+2,
-0
1@@ -0,0 +1,2 @@
2+.parcel-cache
3+dist
+20,
-0
1@@ -0,0 +1,20 @@
2+{
3+ "name": "starfx-parcel",
4+ "source": "src/index.html",
5+ "scripts": {
6+ "start": "parcel --host 0.0.0.0",
7+ "build": "parcel build"
8+ },
9+ "@parcel/resolver-default": {
10+ "packageExports": true
11+ },
12+ "devDependencies": {
13+ "parcel": "^2.11.0",
14+ "process": "^0.11.10"
15+ },
16+ "dependencies": {
17+ "react": "^18.2.0",
18+ "react-dom": "^18.2.0",
19+ "starfx": "^0.13.0"
20+ }
21+}
+35,
-0
1@@ -0,0 +1,35 @@
2+import { createApi, createSchema, mdw, slice } from "starfx";
3+
4+const emptyUser = { id: "", name: "" };
5+export const [schema, initialState] = createSchema({
6+ users: slice.table({ empty: emptyUser }),
7+ cache: slice.table(),
8+ loaders: slice.loaders(),
9+});
10+
11+export const api = createApi();
12+api.use(function* (ctx, next) {
13+ yield* next();
14+ console.log(`ctx [${ctx.name}]`, ctx);
15+});
16+api.use(mdw.api({ schema }));
17+api.use(api.routes());
18+api.use(mdw.fetch({ baseUrl: "https://jsonplaceholder.typicode.com" }));
19+
20+export const fetchUsers = api.get(
21+ "/users",
22+ function* (ctx, next) {
23+ yield* next();
24+
25+ if (!ctx.json.ok) {
26+ return;
27+ }
28+
29+ const users = ctx.json.value.reduce((acc, user) => {
30+ acc[user.id] = user;
31+ return acc;
32+ }, {});
33+
34+ yield* schema.update(schema.users.add(users));
35+ },
36+);
+17,
-0
1@@ -0,0 +1,17 @@
2+import { useDispatch, useSelector } from "starfx/react";
3+import { fetchUsers, schema } from "./api.js";
4+
5+export function App({ id }) {
6+ const dispatch = useDispatch();
7+ const user = useSelector((s) => schema.users.selectById(s, { id }));
8+ const userList = useSelector(schema.users.selectTableAsList);
9+ return (
10+ <div>
11+ <div>hi there, {user.name}</div>
12+ <button onClick={() => dispatch(fetchUsers())}>Fetch users</button>
13+ {userList.map((u) => {
14+ return <div key={u.id}>({u.id}) {u.name}</div>;
15+ })}
16+ </div>
17+ );
18+}
+11,
-0
1@@ -0,0 +1,11 @@
2+<!doctype html>
3+<html lang="en">
4+ <head>
5+ <meta charset="utf-8"/>
6+ <title>parcel + react + starfx</title>
7+ <script type="module" src="index.jsx"></script>
8+ </head>
9+ <body>
10+ <div id="root"></div>
11+ </body>
12+</html>
+31,
-0
1@@ -0,0 +1,31 @@
2+import React from "react";
3+import ReactDOM from "react-dom/client";
4+import { createStore, take } from "starfx";
5+import { Provider } from "starfx/react";
6+import { api, initialState, schema } from "./api.js";
7+import { App } from "./app.jsx";
8+
9+init();
10+
11+function init() {
12+ const store = createStore({ initialState });
13+ window.fx = store;
14+
15+ store.run([
16+ function* logger() {
17+ while (true) {
18+ const action = yield* take("*");
19+ console.log("action", action);
20+ }
21+ },
22+ api.register,
23+ ]);
24+
25+ ReactDOM.createRoot(document.getElementById("root")).render(
26+ <React.StrictMode>
27+ <Provider schema={schema} store={store}>
28+ <App id="1" />
29+ </Provider>
30+ </React.StrictMode>,
31+ );
32+}
+2,
-0
1@@ -0,0 +1,2 @@
2+.parcel-cache
3+dist
+6,
-0
1@@ -0,0 +1,6 @@
2+module.exports = {
3+ presets: [
4+ "@babel/preset-env",
5+ ["@babel/preset-react", { runtime: "automatic" }],
6+ ],
7+};
+7,
-0
1@@ -0,0 +1,7 @@
2+module.exports = {
3+ testEnvironment: "jsdom",
4+ transform: {
5+ "^.+\\.(t|j)sx?$": "babel-jest",
6+ },
7+ setupFilesAfterEnv: ["<rootDir>/tests/setup.ts"],
8+};
+22,
-0
1@@ -0,0 +1,22 @@
2+{
3+ "name": "tests-rtl",
4+ "scripts": {
5+ "test": "jest"
6+ },
7+ "dependencies": {
8+ "react": "^18.2.0",
9+ "react-dom": "^18.2.0",
10+ "starfx": "^0.13.3"
11+ },
12+ "devDependencies": {
13+ "@babel/preset-env": "^7.23.9",
14+ "@babel/preset-react": "^7.23.3",
15+ "@testing-library/jest-dom": "^6.3.0",
16+ "@testing-library/react": "^14.1.2",
17+ "@testing-library/user-event": "^14.5.2",
18+ "babel-jest": "^29.7.0",
19+ "jest": "^29.7.0",
20+ "jest-environment-jsdom": "^29.7.0",
21+ "whatwg-fetch": "^3.6.20"
22+ }
23+}
+31,
-0
1@@ -0,0 +1,31 @@
2+import { createApi, createSchema, mdw, slice } from "starfx";
3+
4+const emptyUser = { id: "", name: "" };
5+export const [schema, initialState] = createSchema({
6+ users: slice.table({ empty: emptyUser }),
7+ cache: slice.table(),
8+ loaders: slice.loaders(),
9+});
10+
11+export const api = createApi();
12+api.use(mdw.api({ schema }));
13+api.use(api.routes());
14+api.use(mdw.fetch({ baseUrl: "https://jsonplaceholder.typicode.com" }));
15+
16+export const fetchUsers = api.get(
17+ "/users",
18+ function* (ctx, next) {
19+ yield* next();
20+
21+ if (!ctx.json.ok) {
22+ return;
23+ }
24+
25+ const users = ctx.json.value.reduce((acc, user) => {
26+ acc[user.id] = user;
27+ return acc;
28+ }, {});
29+
30+ yield* schema.update(schema.users.add(users));
31+ },
32+);
+21,
-0
1@@ -0,0 +1,21 @@
2+import { useDispatch, useSelector } from "starfx/react";
3+import { fetchUsers, schema } from "./api";
4+
5+export function App({ id }) {
6+ const dispatch = useDispatch();
7+ const user = useSelector((s) => schema.users.selectById(s, { id }));
8+ const userList = useSelector(schema.users.selectTableAsList);
9+ return (
10+ <div>
11+ <h1>hi there, {user.name}</h1>
12+ <button onClick={() => dispatch(fetchUsers())}>Fetch users</button>
13+ {userList.map((u) => {
14+ return (
15+ <div key={u.id}>
16+ ({u.id}) {u.name}
17+ </div>
18+ );
19+ })}
20+ </div>
21+ );
22+}
+15,
-0
1@@ -0,0 +1,15 @@
2+import { api, initialState as schemaInitialState } from "./api";
3+import { createStore } from "starfx";
4+
5+export function setupStore({ initialState = {} }) {
6+ const store = createStore({
7+ initialState: {
8+ ...schemaInitialState,
9+ ...initialState,
10+ },
11+ });
12+
13+ store.run(api.register);
14+
15+ return store;
16+}
+41,
-0
1@@ -0,0 +1,41 @@
2+import { expect, test } from "@jest/globals";
3+import { fireEvent, render, screen, waitFor } from "./utils";
4+import { fetchUsers } from "../src/api";
5+import { App } from "../src/app";
6+
7+test("loads homepage", async () => {
8+ render(<App id="1" />);
9+ expect(screen.getByRole("heading")).toHaveTextContent("hi there");
10+});
11+
12+test("fetches users", async () => {
13+ fetchUsers.use(function* (ctx, next) {
14+ ctx.response = new Response(
15+ JSON.stringify([
16+ {
17+ id: 1,
18+ name: "Leanne Graham",
19+ },
20+ {
21+ id: 2,
22+ name: "Ervin Howell",
23+ },
24+ ]),
25+ );
26+ yield* next();
27+ });
28+
29+ render(<App id="1" />);
30+
31+ expect(screen.getByRole("heading")).toHaveTextContent("hi there");
32+
33+ const btn = await screen.findByRole("button", { name: /Fetch users/ });
34+ fireEvent.click(btn);
35+
36+ await waitFor(() => {
37+ expect(screen.getByText("(1) Leanne Graham")).toBeInTheDocument();
38+ });
39+ await waitFor(() => {
40+ expect(screen.getByText("(2) Ervin Howell")).toBeInTheDocument();
41+ });
42+});
+5,
-0
1@@ -0,0 +1,5 @@
2+import "@testing-library/jest-dom";
3+// jsdom doesn't have the fetch API which we need for Response()
4+// so polyfilling it here for every file
5+// see https://github.com/jsdom/jsdom/issues/1724
6+import "whatwg-fetch";
+23,
-0
1@@ -0,0 +1,23 @@
2+import React from "react";
3+import { render } from "@testing-library/react";
4+import { Provider } from "starfx/react";
5+import { schema } from "../src/api";
6+import { setupStore } from "../src/store";
7+
8+const AllTheProviders = ({ children }) => {
9+ const store = setupStore({});
10+ return (
11+ <Provider schema={schema} store={store}>
12+ {children}
13+ </Provider>
14+ );
15+};
16+
17+const customRender = (ui, options) =>
18+ render(ui, { wrapper: AllTheProviders, ...options });
19+
20+// re-export everything
21+export * from "@testing-library/react";
22+
23+// override render method
24+export { customRender as render };
+23,
-0
1@@ -0,0 +1,23 @@
2+{
3+ "$schema": "https://json.schemastore.org/tsconfig",
4+ "compilerOptions": {
5+ "baseUrl": ".",
6+ "types": ["vitest/globals"],
7+ "lib": ["dom", "dom.iterable", "esnext"],
8+ "allowJs": true,
9+ "skipLibCheck": true,
10+ "esModuleInterop": true,
11+ "allowSyntheticDefaultImports": true,
12+ "strict": true,
13+ "forceConsistentCasingInFileNames": true,
14+ "target": "esnext",
15+ "module": "esnext",
16+ "moduleResolution": "bundler",
17+ "resolveJsonModule": true,
18+ "isolatedModules": true,
19+ "noEmit": true,
20+ "noUnusedLocals": true,
21+ "jsx": "react-jsx"
22+ },
23+ "include": ["./src"]
24+}
+14,
-0
1@@ -0,0 +1,14 @@
2+module.exports = {
3+ env: { browser: true, es2020: true },
4+ extends: [
5+ "eslint:recommended",
6+ "plugin:@typescript-eslint/recommended",
7+ "plugin:react-hooks/recommended",
8+ ],
9+ parser: "@typescript-eslint/parser",
10+ parserOptions: { ecmaVersion: "latest", sourceType: "module" },
11+ plugins: ["react-refresh"],
12+ rules: {
13+ "react-refresh/only-export-components": "warn",
14+ },
15+};
+25,
-0
1@@ -0,0 +1,25 @@
2+# Logs
3+logs
4+*.log
5+npm-debug.log*
6+yarn-debug.log*
7+yarn-error.log*
8+pnpm-debug.log*
9+lerna-debug.log*
10+
11+node_modules
12+dist
13+dist-ssr
14+*.local
15+
16+# Editor directories and files
17+.vscode/*
18+!.vscode/extensions.json
19+.idea
20+.DS_Store
21+*.suo
22+*.ntvs*
23+*.njsproj
24+*.sln
25+*.sw?
26+.yarn/**
+12,
-0
1@@ -0,0 +1,12 @@
2+<!DOCTYPE html>
3+<html lang="en">
4+ <head>
5+ <meta charset="UTF-8" />
6+ <meta name="viewport" content="width=device-width, initial-scale=1.0" />
7+ <title>vite + react + starfx</title>
8+ </head>
9+ <body>
10+ <div id="root"></div>
11+ <script type="module" src="/src/main.tsx"></script>
12+ </body>
13+</html>
+29,
-0
1@@ -0,0 +1,29 @@
2+{
3+ "name": "vite-react",
4+ "private": true,
5+ "version": "0.0.0",
6+ "type": "module",
7+ "scripts": {
8+ "start": "vite --host 0.0.0.0",
9+ "build": "tsc && vite build",
10+ "lint": "eslint src --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
11+ "preview": "vite preview"
12+ },
13+ "dependencies": {
14+ "react": "^18.2.0",
15+ "react-dom": "^18.2.0",
16+ "starfx": "^0.13.0"
17+ },
18+ "devDependencies": {
19+ "@types/react": "^18.0.28",
20+ "@types/react-dom": "^18.0.11",
21+ "@typescript-eslint/eslint-plugin": "^5.57.1",
22+ "@typescript-eslint/parser": "^5.57.1",
23+ "@vitejs/plugin-react": "^4.0.0",
24+ "eslint": "^8.38.0",
25+ "eslint-plugin-react-hooks": "^4.6.0",
26+ "eslint-plugin-react-refresh": "^0.3.4",
27+ "typescript": "^5.3.2",
28+ "vite": "^4.3.2"
29+ }
30+}
+42,
-0
1@@ -0,0 +1,42 @@
2+#root {
3+ max-width: 1280px;
4+ margin: 0 auto;
5+ padding: 2rem;
6+ text-align: center;
7+}
8+
9+.logo {
10+ height: 6em;
11+ padding: 1.5em;
12+ will-change: filter;
13+ transition: filter 300ms;
14+}
15+.logo:hover {
16+ filter: drop-shadow(0 0 2em #646cffaa);
17+}
18+.logo.react:hover {
19+ filter: drop-shadow(0 0 2em #61dafbaa);
20+}
21+
22+@keyframes logo-spin {
23+ from {
24+ transform: rotate(0deg);
25+ }
26+ to {
27+ transform: rotate(360deg);
28+ }
29+}
30+
31+@media (prefers-reduced-motion: no-preference) {
32+ a:nth-of-type(2) .logo {
33+ animation: logo-spin infinite 20s linear;
34+ }
35+}
36+
37+.card {
38+ padding: 2em;
39+}
40+
41+.read-the-docs {
42+ color: #888;
43+}
+26,
-0
1@@ -0,0 +1,26 @@
2+import {
3+ TypedUseSelectorHook,
4+ useDispatch,
5+ useSelector as useSel,
6+} from "starfx/react";
7+import "./App.css";
8+import { AppState, fetchUsers, schema } from "./api.ts";
9+
10+const useSelector: TypedUseSelectorHook<AppState> = useSel;
11+
12+function App({ id }: { id: string }) {
13+ const dispatch = useDispatch();
14+ const user = useSelector((s) => schema.users.selectById(s, { id }));
15+ const userList = useSelector(schema.users.selectTableAsList);
16+ return (
17+ <div>
18+ <div>hi there, {user.name}</div>
19+ <button onClick={() => dispatch(fetchUsers())}>Fetch users</button>
20+ {userList.map((u) => {
21+ return <div key={u.id}>({u.id}) {u.name}</div>;
22+ })}
23+ </div>
24+ );
25+}
26+
27+export default App;
+37,
-0
1@@ -0,0 +1,37 @@
2+import { createApi, createSchema, mdw, slice } from "starfx";
3+
4+interface User {
5+ id: string;
6+ name: string;
7+}
8+
9+const emptyUser: User = { id: "", name: "" };
10+export const [schema, initialState] = createSchema({
11+ users: slice.table({ empty: emptyUser }),
12+ cache: slice.table(),
13+ loaders: slice.loaders(),
14+});
15+export type AppState = typeof initialState;
16+
17+export const api = createApi();
18+api.use(mdw.api({ schema }));
19+api.use(api.routes());
20+api.use(mdw.fetch({ baseUrl: "https://jsonplaceholder.typicode.com" }));
21+
22+export const fetchUsers = api.get<never, User[]>(
23+ "/users",
24+ function* (ctx, next) {
25+ yield* next();
26+
27+ if (!ctx.json.ok) {
28+ return;
29+ }
30+
31+ const users = ctx.json.value.reduce<Record<string, User>>((acc, user) => {
32+ acc[user.id] = user;
33+ return acc;
34+ }, {});
35+
36+ yield* schema.update(schema.users.add(users));
37+ },
38+);
+69,
-0
1@@ -0,0 +1,69 @@
2+:root {
3+ font-family: Inter, system-ui, Avenir, Helvetica, Arial, sans-serif;
4+ line-height: 1.5;
5+ font-weight: 400;
6+
7+ color-scheme: light dark;
8+ color: rgba(255, 255, 255, 0.87);
9+ background-color: #242424;
10+
11+ font-synthesis: none;
12+ text-rendering: optimizeLegibility;
13+ -webkit-font-smoothing: antialiased;
14+ -moz-osx-font-smoothing: grayscale;
15+ -webkit-text-size-adjust: 100%;
16+}
17+
18+a {
19+ font-weight: 500;
20+ color: #646cff;
21+ text-decoration: inherit;
22+}
23+a:hover {
24+ color: #535bf2;
25+}
26+
27+body {
28+ margin: 0;
29+ display: flex;
30+ place-items: center;
31+ min-width: 320px;
32+ min-height: 100vh;
33+}
34+
35+h1 {
36+ font-size: 3.2em;
37+ line-height: 1.1;
38+}
39+
40+button {
41+ border-radius: 8px;
42+ border: 1px solid transparent;
43+ padding: 0.6em 1.2em;
44+ font-size: 1em;
45+ font-weight: 500;
46+ font-family: inherit;
47+ background-color: #1a1a1a;
48+ cursor: pointer;
49+ transition: border-color 0.25s;
50+}
51+button:hover {
52+ border-color: #646cff;
53+}
54+button:focus,
55+button:focus-visible {
56+ outline: 4px auto -webkit-focus-ring-color;
57+}
58+
59+@media (prefers-color-scheme: light) {
60+ :root {
61+ color: #213547;
62+ background-color: #ffffff;
63+ }
64+ a:hover {
65+ color: #747bff;
66+ }
67+ button {
68+ background-color: #f9f9f9;
69+ }
70+}
+33,
-0
1@@ -0,0 +1,33 @@
2+import React from "react";
3+import ReactDOM from "react-dom/client";
4+import { createStore, take } from "starfx";
5+import { Provider } from "starfx/react";
6+import { api, initialState, schema } from "./api.ts";
7+import App from "./App.tsx";
8+import "./index.css";
9+
10+init();
11+
12+function init() {
13+ const store = createStore({ initialState });
14+ // makes `fx` available in devtools
15+ (window as any).fx = store;
16+
17+ store.run([
18+ function* logger() {
19+ while (true) {
20+ const action = yield* take("*");
21+ console.log("action", action);
22+ }
23+ },
24+ api.register,
25+ ]);
26+
27+ ReactDOM.createRoot(document.getElementById("root") as HTMLElement).render(
28+ <React.StrictMode>
29+ <Provider schema={schema} store={store}>
30+ <App id="1" />
31+ </Provider>
32+ </React.StrictMode>,
33+ );
34+}
1@@ -0,0 +1 @@
2+/// <reference types="vite/client" />
+24,
-0
1@@ -0,0 +1,24 @@
2+{
3+ "compilerOptions": {
4+ "target": "ESNext",
5+ "lib": ["DOM", "DOM.Iterable", "ESNext"],
6+ "module": "ESNext",
7+ "skipLibCheck": true,
8+
9+ /* Bundler mode */
10+ "moduleResolution": "bundler",
11+ "allowImportingTsExtensions": true,
12+ "resolveJsonModule": true,
13+ "isolatedModules": true,
14+ "noEmit": true,
15+ "jsx": "react-jsx",
16+
17+ /* Linting */
18+ "strict": true,
19+ "noUnusedLocals": true,
20+ "noUnusedParameters": true,
21+ "noFallthroughCasesInSwitch": true
22+ },
23+ "include": ["src"],
24+ "references": [{ "path": "./tsconfig.node.json" }]
25+}
+10,
-0
1@@ -0,0 +1,10 @@
2+{
3+ "compilerOptions": {
4+ "composite": true,
5+ "skipLibCheck": true,
6+ "module": "ESNext",
7+ "moduleResolution": "bundler",
8+ "allowSyntheticDefaultImports": true
9+ },
10+ "include": ["vite.config.ts"]
11+}
+7,
-0
1@@ -0,0 +1,7 @@
2+import { defineConfig } from "vite";
3+import react from "@vitejs/plugin-react";
4+
5+// https://vitejs.dev/config/
6+export default defineConfig({
7+ plugins: [react()],
8+});
+0,
-5
1@@ -1,5 +0,0 @@
2-export * from "./parallel.ts";
3-export * from "./safe.ts";
4-export * from "./race.ts";
5-export * from "./request.ts";
6-export * from "./supervisor.ts";
+0,
-4
1@@ -1,4 +0,0 @@
2-import * as queryMdw from "./query.ts";
3-import * as storeMdw from "./store.ts";
4-
5-export const mdw = { ...queryMdw, ...storeMdw };
+2252,
-0
1@@ -0,0 +1,2252 @@
2+{
3+ "name": "starfx",
4+ "version": "0.14.0",
5+ "lockfileVersion": 3,
6+ "requires": true,
7+ "packages": {
8+ "": {
9+ "name": "starfx",
10+ "version": "0.14.0",
11+ "license": "MIT",
12+ "dependencies": {
13+ "effection": "^3.5.0",
14+ "immer": "^10.1.1",
15+ "react-redux": "^9.2.0",
16+ "reselect": "^5.1.1"
17+ },
18+ "devDependencies": {
19+ "@biomejs/biome": "^1.9.4",
20+ "@types/node": "^22.15.29",
21+ "@types/react": "^19.1.6",
22+ "@types/react-dom": "^19.1.5",
23+ "execa": "^9.6.0",
24+ "nock": "^14.0.5",
25+ "react": "^19.1.0",
26+ "react-dom": "^19.1.0",
27+ "tsx": "^4.19.4",
28+ "typescript": "^5.8.3",
29+ "vitest": "^3.2.0"
30+ },
31+ "peerDependencies": {
32+ "react": ">=18",
33+ "react-dom": ">=18"
34+ }
35+ },
36+ "node_modules/@biomejs/biome": {
37+ "version": "1.9.4",
38+ "resolved": "https://registry.npmjs.org/@biomejs/biome/-/biome-1.9.4.tgz",
39+ "integrity": "sha512-1rkd7G70+o9KkTn5KLmDYXihGoTaIGO9PIIN2ZB7UJxFrWw04CZHPYiMRjYsaDvVV7hP1dYNRLxSANLaBFGpog==",
40+ "dev": true,
41+ "hasInstallScript": true,
42+ "license": "MIT OR Apache-2.0",
43+ "bin": {
44+ "biome": "bin/biome"
45+ },
46+ "engines": {
47+ "node": ">=14.21.3"
48+ },
49+ "funding": {
50+ "type": "opencollective",
51+ "url": "https://opencollective.com/biome"
52+ },
53+ "optionalDependencies": {
54+ "@biomejs/cli-darwin-arm64": "1.9.4",
55+ "@biomejs/cli-darwin-x64": "1.9.4",
56+ "@biomejs/cli-linux-arm64": "1.9.4",
57+ "@biomejs/cli-linux-arm64-musl": "1.9.4",
58+ "@biomejs/cli-linux-x64": "1.9.4",
59+ "@biomejs/cli-linux-x64-musl": "1.9.4",
60+ "@biomejs/cli-win32-arm64": "1.9.4",
61+ "@biomejs/cli-win32-x64": "1.9.4"
62+ }
63+ },
64+ "node_modules/@biomejs/cli-darwin-arm64": {
65+ "version": "1.9.4",
66+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-arm64/-/cli-darwin-arm64-1.9.4.tgz",
67+ "integrity": "sha512-bFBsPWrNvkdKrNCYeAp+xo2HecOGPAy9WyNyB/jKnnedgzl4W4Hb9ZMzYNbf8dMCGmUdSavlYHiR01QaYR58cw==",
68+ "cpu": [
69+ "arm64"
70+ ],
71+ "dev": true,
72+ "license": "MIT OR Apache-2.0",
73+ "optional": true,
74+ "os": [
75+ "darwin"
76+ ],
77+ "engines": {
78+ "node": ">=14.21.3"
79+ }
80+ },
81+ "node_modules/@biomejs/cli-darwin-x64": {
82+ "version": "1.9.4",
83+ "resolved": "https://registry.npmjs.org/@biomejs/cli-darwin-x64/-/cli-darwin-x64-1.9.4.tgz",
84+ "integrity": "sha512-ngYBh/+bEedqkSevPVhLP4QfVPCpb+4BBe2p7Xs32dBgs7rh9nY2AIYUL6BgLw1JVXV8GlpKmb/hNiuIxfPfZg==",
85+ "cpu": [
86+ "x64"
87+ ],
88+ "dev": true,
89+ "license": "MIT OR Apache-2.0",
90+ "optional": true,
91+ "os": [
92+ "darwin"
93+ ],
94+ "engines": {
95+ "node": ">=14.21.3"
96+ }
97+ },
98+ "node_modules/@biomejs/cli-linux-arm64": {
99+ "version": "1.9.4",
100+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64/-/cli-linux-arm64-1.9.4.tgz",
101+ "integrity": "sha512-fJIW0+LYujdjUgJJuwesP4EjIBl/N/TcOX3IvIHJQNsAqvV2CHIogsmA94BPG6jZATS4Hi+xv4SkBBQSt1N4/g==",
102+ "cpu": [
103+ "arm64"
104+ ],
105+ "dev": true,
106+ "license": "MIT OR Apache-2.0",
107+ "optional": true,
108+ "os": [
109+ "linux"
110+ ],
111+ "engines": {
112+ "node": ">=14.21.3"
113+ }
114+ },
115+ "node_modules/@biomejs/cli-linux-arm64-musl": {
116+ "version": "1.9.4",
117+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-arm64-musl/-/cli-linux-arm64-musl-1.9.4.tgz",
118+ "integrity": "sha512-v665Ct9WCRjGa8+kTr0CzApU0+XXtRgwmzIf1SeKSGAv+2scAlW6JR5PMFo6FzqqZ64Po79cKODKf3/AAmECqA==",
119+ "cpu": [
120+ "arm64"
121+ ],
122+ "dev": true,
123+ "license": "MIT OR Apache-2.0",
124+ "optional": true,
125+ "os": [
126+ "linux"
127+ ],
128+ "engines": {
129+ "node": ">=14.21.3"
130+ }
131+ },
132+ "node_modules/@biomejs/cli-linux-x64": {
133+ "version": "1.9.4",
134+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64/-/cli-linux-x64-1.9.4.tgz",
135+ "integrity": "sha512-lRCJv/Vi3Vlwmbd6K+oQ0KhLHMAysN8lXoCI7XeHlxaajk06u7G+UsFSO01NAs5iYuWKmVZjmiOzJ0OJmGsMwg==",
136+ "cpu": [
137+ "x64"
138+ ],
139+ "dev": true,
140+ "license": "MIT OR Apache-2.0",
141+ "optional": true,
142+ "os": [
143+ "linux"
144+ ],
145+ "engines": {
146+ "node": ">=14.21.3"
147+ }
148+ },
149+ "node_modules/@biomejs/cli-linux-x64-musl": {
150+ "version": "1.9.4",
151+ "resolved": "https://registry.npmjs.org/@biomejs/cli-linux-x64-musl/-/cli-linux-x64-musl-1.9.4.tgz",
152+ "integrity": "sha512-gEhi/jSBhZ2m6wjV530Yy8+fNqG8PAinM3oV7CyO+6c3CEh16Eizm21uHVsyVBEB6RIM8JHIl6AGYCv6Q6Q9Tg==",
153+ "cpu": [
154+ "x64"
155+ ],
156+ "dev": true,
157+ "license": "MIT OR Apache-2.0",
158+ "optional": true,
159+ "os": [
160+ "linux"
161+ ],
162+ "engines": {
163+ "node": ">=14.21.3"
164+ }
165+ },
166+ "node_modules/@biomejs/cli-win32-arm64": {
167+ "version": "1.9.4",
168+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-arm64/-/cli-win32-arm64-1.9.4.tgz",
169+ "integrity": "sha512-tlbhLk+WXZmgwoIKwHIHEBZUwxml7bRJgk0X2sPyNR3S93cdRq6XulAZRQJ17FYGGzWne0fgrXBKpl7l4M87Hg==",
170+ "cpu": [
171+ "arm64"
172+ ],
173+ "dev": true,
174+ "license": "MIT OR Apache-2.0",
175+ "optional": true,
176+ "os": [
177+ "win32"
178+ ],
179+ "engines": {
180+ "node": ">=14.21.3"
181+ }
182+ },
183+ "node_modules/@biomejs/cli-win32-x64": {
184+ "version": "1.9.4",
185+ "resolved": "https://registry.npmjs.org/@biomejs/cli-win32-x64/-/cli-win32-x64-1.9.4.tgz",
186+ "integrity": "sha512-8Y5wMhVIPaWe6jw2H+KlEm4wP/f7EW3810ZLmDlrEEy5KvBsb9ECEfu/kMWD484ijfQ8+nIi0giMgu9g1UAuuA==",
187+ "cpu": [
188+ "x64"
189+ ],
190+ "dev": true,
191+ "license": "MIT OR Apache-2.0",
192+ "optional": true,
193+ "os": [
194+ "win32"
195+ ],
196+ "engines": {
197+ "node": ">=14.21.3"
198+ }
199+ },
200+ "node_modules/@esbuild/aix-ppc64": {
201+ "version": "0.25.5",
202+ "resolved": "https://registry.npmjs.org/@esbuild/aix-ppc64/-/aix-ppc64-0.25.5.tgz",
203+ "integrity": "sha512-9o3TMmpmftaCMepOdA5k/yDw8SfInyzWWTjYTFCX3kPSDJMROQTb8jg+h9Cnwnmm1vOzvxN7gIfB5V2ewpjtGA==",
204+ "cpu": [
205+ "ppc64"
206+ ],
207+ "dev": true,
208+ "license": "MIT",
209+ "optional": true,
210+ "os": [
211+ "aix"
212+ ],
213+ "engines": {
214+ "node": ">=18"
215+ }
216+ },
217+ "node_modules/@esbuild/android-arm": {
218+ "version": "0.25.5",
219+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm/-/android-arm-0.25.5.tgz",
220+ "integrity": "sha512-AdJKSPeEHgi7/ZhuIPtcQKr5RQdo6OO2IL87JkianiMYMPbCtot9fxPbrMiBADOWWm3T2si9stAiVsGbTQFkbA==",
221+ "cpu": [
222+ "arm"
223+ ],
224+ "dev": true,
225+ "license": "MIT",
226+ "optional": true,
227+ "os": [
228+ "android"
229+ ],
230+ "engines": {
231+ "node": ">=18"
232+ }
233+ },
234+ "node_modules/@esbuild/android-arm64": {
235+ "version": "0.25.5",
236+ "resolved": "https://registry.npmjs.org/@esbuild/android-arm64/-/android-arm64-0.25.5.tgz",
237+ "integrity": "sha512-VGzGhj4lJO+TVGV1v8ntCZWJktV7SGCs3Pn1GRWI1SBFtRALoomm8k5E9Pmwg3HOAal2VDc2F9+PM/rEY6oIDg==",
238+ "cpu": [
239+ "arm64"
240+ ],
241+ "dev": true,
242+ "license": "MIT",
243+ "optional": true,
244+ "os": [
245+ "android"
246+ ],
247+ "engines": {
248+ "node": ">=18"
249+ }
250+ },
251+ "node_modules/@esbuild/android-x64": {
252+ "version": "0.25.5",
253+ "resolved": "https://registry.npmjs.org/@esbuild/android-x64/-/android-x64-0.25.5.tgz",
254+ "integrity": "sha512-D2GyJT1kjvO//drbRT3Hib9XPwQeWd9vZoBJn+bu/lVsOZ13cqNdDeqIF/xQ5/VmWvMduP6AmXvylO/PIc2isw==",
255+ "cpu": [
256+ "x64"
257+ ],
258+ "dev": true,
259+ "license": "MIT",
260+ "optional": true,
261+ "os": [
262+ "android"
263+ ],
264+ "engines": {
265+ "node": ">=18"
266+ }
267+ },
268+ "node_modules/@esbuild/darwin-arm64": {
269+ "version": "0.25.5",
270+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-arm64/-/darwin-arm64-0.25.5.tgz",
271+ "integrity": "sha512-GtaBgammVvdF7aPIgH2jxMDdivezgFu6iKpmT+48+F8Hhg5J/sfnDieg0aeG/jfSvkYQU2/pceFPDKlqZzwnfQ==",
272+ "cpu": [
273+ "arm64"
274+ ],
275+ "dev": true,
276+ "license": "MIT",
277+ "optional": true,
278+ "os": [
279+ "darwin"
280+ ],
281+ "engines": {
282+ "node": ">=18"
283+ }
284+ },
285+ "node_modules/@esbuild/darwin-x64": {
286+ "version": "0.25.5",
287+ "resolved": "https://registry.npmjs.org/@esbuild/darwin-x64/-/darwin-x64-0.25.5.tgz",
288+ "integrity": "sha512-1iT4FVL0dJ76/q1wd7XDsXrSW+oLoquptvh4CLR4kITDtqi2e/xwXwdCVH8hVHU43wgJdsq7Gxuzcs6Iq/7bxQ==",
289+ "cpu": [
290+ "x64"
291+ ],
292+ "dev": true,
293+ "license": "MIT",
294+ "optional": true,
295+ "os": [
296+ "darwin"
297+ ],
298+ "engines": {
299+ "node": ">=18"
300+ }
301+ },
302+ "node_modules/@esbuild/freebsd-arm64": {
303+ "version": "0.25.5",
304+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-arm64/-/freebsd-arm64-0.25.5.tgz",
305+ "integrity": "sha512-nk4tGP3JThz4La38Uy/gzyXtpkPW8zSAmoUhK9xKKXdBCzKODMc2adkB2+8om9BDYugz+uGV7sLmpTYzvmz6Sw==",
306+ "cpu": [
307+ "arm64"
308+ ],
309+ "dev": true,
310+ "license": "MIT",
311+ "optional": true,
312+ "os": [
313+ "freebsd"
314+ ],
315+ "engines": {
316+ "node": ">=18"
317+ }
318+ },
319+ "node_modules/@esbuild/freebsd-x64": {
320+ "version": "0.25.5",
321+ "resolved": "https://registry.npmjs.org/@esbuild/freebsd-x64/-/freebsd-x64-0.25.5.tgz",
322+ "integrity": "sha512-PrikaNjiXdR2laW6OIjlbeuCPrPaAl0IwPIaRv+SMV8CiM8i2LqVUHFC1+8eORgWyY7yhQY+2U2fA55mBzReaw==",
323+ "cpu": [
324+ "x64"
325+ ],
326+ "dev": true,
327+ "license": "MIT",
328+ "optional": true,
329+ "os": [
330+ "freebsd"
331+ ],
332+ "engines": {
333+ "node": ">=18"
334+ }
335+ },
336+ "node_modules/@esbuild/linux-arm": {
337+ "version": "0.25.5",
338+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm/-/linux-arm-0.25.5.tgz",
339+ "integrity": "sha512-cPzojwW2okgh7ZlRpcBEtsX7WBuqbLrNXqLU89GxWbNt6uIg78ET82qifUy3W6OVww6ZWobWub5oqZOVtwolfw==",
340+ "cpu": [
341+ "arm"
342+ ],
343+ "dev": true,
344+ "license": "MIT",
345+ "optional": true,
346+ "os": [
347+ "linux"
348+ ],
349+ "engines": {
350+ "node": ">=18"
351+ }
352+ },
353+ "node_modules/@esbuild/linux-arm64": {
354+ "version": "0.25.5",
355+ "resolved": "https://registry.npmjs.org/@esbuild/linux-arm64/-/linux-arm64-0.25.5.tgz",
356+ "integrity": "sha512-Z9kfb1v6ZlGbWj8EJk9T6czVEjjq2ntSYLY2cw6pAZl4oKtfgQuS4HOq41M/BcoLPzrUbNd+R4BXFyH//nHxVg==",
357+ "cpu": [
358+ "arm64"
359+ ],
360+ "dev": true,
361+ "license": "MIT",
362+ "optional": true,
363+ "os": [
364+ "linux"
365+ ],
366+ "engines": {
367+ "node": ">=18"
368+ }
369+ },
370+ "node_modules/@esbuild/linux-ia32": {
371+ "version": "0.25.5",
372+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ia32/-/linux-ia32-0.25.5.tgz",
373+ "integrity": "sha512-sQ7l00M8bSv36GLV95BVAdhJ2QsIbCuCjh/uYrWiMQSUuV+LpXwIqhgJDcvMTj+VsQmqAHL2yYaasENvJ7CDKA==",
374+ "cpu": [
375+ "ia32"
376+ ],
377+ "dev": true,
378+ "license": "MIT",
379+ "optional": true,
380+ "os": [
381+ "linux"
382+ ],
383+ "engines": {
384+ "node": ">=18"
385+ }
386+ },
387+ "node_modules/@esbuild/linux-loong64": {
388+ "version": "0.25.5",
389+ "resolved": "https://registry.npmjs.org/@esbuild/linux-loong64/-/linux-loong64-0.25.5.tgz",
390+ "integrity": "sha512-0ur7ae16hDUC4OL5iEnDb0tZHDxYmuQyhKhsPBV8f99f6Z9KQM02g33f93rNH5A30agMS46u2HP6qTdEt6Q1kg==",
391+ "cpu": [
392+ "loong64"
393+ ],
394+ "dev": true,
395+ "license": "MIT",
396+ "optional": true,
397+ "os": [
398+ "linux"
399+ ],
400+ "engines": {
401+ "node": ">=18"
402+ }
403+ },
404+ "node_modules/@esbuild/linux-mips64el": {
405+ "version": "0.25.5",
406+ "resolved": "https://registry.npmjs.org/@esbuild/linux-mips64el/-/linux-mips64el-0.25.5.tgz",
407+ "integrity": "sha512-kB/66P1OsHO5zLz0i6X0RxlQ+3cu0mkxS3TKFvkb5lin6uwZ/ttOkP3Z8lfR9mJOBk14ZwZ9182SIIWFGNmqmg==",
408+ "cpu": [
409+ "mips64el"
410+ ],
411+ "dev": true,
412+ "license": "MIT",
413+ "optional": true,
414+ "os": [
415+ "linux"
416+ ],
417+ "engines": {
418+ "node": ">=18"
419+ }
420+ },
421+ "node_modules/@esbuild/linux-ppc64": {
422+ "version": "0.25.5",
423+ "resolved": "https://registry.npmjs.org/@esbuild/linux-ppc64/-/linux-ppc64-0.25.5.tgz",
424+ "integrity": "sha512-UZCmJ7r9X2fe2D6jBmkLBMQetXPXIsZjQJCjgwpVDz+YMcS6oFR27alkgGv3Oqkv07bxdvw7fyB71/olceJhkQ==",
425+ "cpu": [
426+ "ppc64"
427+ ],
428+ "dev": true,
429+ "license": "MIT",
430+ "optional": true,
431+ "os": [
432+ "linux"
433+ ],
434+ "engines": {
435+ "node": ">=18"
436+ }
437+ },
438+ "node_modules/@esbuild/linux-riscv64": {
439+ "version": "0.25.5",
440+ "resolved": "https://registry.npmjs.org/@esbuild/linux-riscv64/-/linux-riscv64-0.25.5.tgz",
441+ "integrity": "sha512-kTxwu4mLyeOlsVIFPfQo+fQJAV9mh24xL+y+Bm6ej067sYANjyEw1dNHmvoqxJUCMnkBdKpvOn0Ahql6+4VyeA==",
442+ "cpu": [
443+ "riscv64"
444+ ],
445+ "dev": true,
446+ "license": "MIT",
447+ "optional": true,
448+ "os": [
449+ "linux"
450+ ],
451+ "engines": {
452+ "node": ">=18"
453+ }
454+ },
455+ "node_modules/@esbuild/linux-s390x": {
456+ "version": "0.25.5",
457+ "resolved": "https://registry.npmjs.org/@esbuild/linux-s390x/-/linux-s390x-0.25.5.tgz",
458+ "integrity": "sha512-K2dSKTKfmdh78uJ3NcWFiqyRrimfdinS5ErLSn3vluHNeHVnBAFWC8a4X5N+7FgVE1EjXS1QDZbpqZBjfrqMTQ==",
459+ "cpu": [
460+ "s390x"
461+ ],
462+ "dev": true,
463+ "license": "MIT",
464+ "optional": true,
465+ "os": [
466+ "linux"
467+ ],
468+ "engines": {
469+ "node": ">=18"
470+ }
471+ },
472+ "node_modules/@esbuild/linux-x64": {
473+ "version": "0.25.5",
474+ "resolved": "https://registry.npmjs.org/@esbuild/linux-x64/-/linux-x64-0.25.5.tgz",
475+ "integrity": "sha512-uhj8N2obKTE6pSZ+aMUbqq+1nXxNjZIIjCjGLfsWvVpy7gKCOL6rsY1MhRh9zLtUtAI7vpgLMK6DxjO8Qm9lJw==",
476+ "cpu": [
477+ "x64"
478+ ],
479+ "dev": true,
480+ "license": "MIT",
481+ "optional": true,
482+ "os": [
483+ "linux"
484+ ],
485+ "engines": {
486+ "node": ">=18"
487+ }
488+ },
489+ "node_modules/@esbuild/netbsd-arm64": {
490+ "version": "0.25.5",
491+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-arm64/-/netbsd-arm64-0.25.5.tgz",
492+ "integrity": "sha512-pwHtMP9viAy1oHPvgxtOv+OkduK5ugofNTVDilIzBLpoWAM16r7b/mxBvfpuQDpRQFMfuVr5aLcn4yveGvBZvw==",
493+ "cpu": [
494+ "arm64"
495+ ],
496+ "dev": true,
497+ "license": "MIT",
498+ "optional": true,
499+ "os": [
500+ "netbsd"
501+ ],
502+ "engines": {
503+ "node": ">=18"
504+ }
505+ },
506+ "node_modules/@esbuild/netbsd-x64": {
507+ "version": "0.25.5",
508+ "resolved": "https://registry.npmjs.org/@esbuild/netbsd-x64/-/netbsd-x64-0.25.5.tgz",
509+ "integrity": "sha512-WOb5fKrvVTRMfWFNCroYWWklbnXH0Q5rZppjq0vQIdlsQKuw6mdSihwSo4RV/YdQ5UCKKvBy7/0ZZYLBZKIbwQ==",
510+ "cpu": [
511+ "x64"
512+ ],
513+ "dev": true,
514+ "license": "MIT",
515+ "optional": true,
516+ "os": [
517+ "netbsd"
518+ ],
519+ "engines": {
520+ "node": ">=18"
521+ }
522+ },
523+ "node_modules/@esbuild/openbsd-arm64": {
524+ "version": "0.25.5",
525+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-arm64/-/openbsd-arm64-0.25.5.tgz",
526+ "integrity": "sha512-7A208+uQKgTxHd0G0uqZO8UjK2R0DDb4fDmERtARjSHWxqMTye4Erz4zZafx7Di9Cv+lNHYuncAkiGFySoD+Mw==",
527+ "cpu": [
528+ "arm64"
529+ ],
530+ "dev": true,
531+ "license": "MIT",
532+ "optional": true,
533+ "os": [
534+ "openbsd"
535+ ],
536+ "engines": {
537+ "node": ">=18"
538+ }
539+ },
540+ "node_modules/@esbuild/openbsd-x64": {
541+ "version": "0.25.5",
542+ "resolved": "https://registry.npmjs.org/@esbuild/openbsd-x64/-/openbsd-x64-0.25.5.tgz",
543+ "integrity": "sha512-G4hE405ErTWraiZ8UiSoesH8DaCsMm0Cay4fsFWOOUcz8b8rC6uCvnagr+gnioEjWn0wC+o1/TAHt+It+MpIMg==",
544+ "cpu": [
545+ "x64"
546+ ],
547+ "dev": true,
548+ "license": "MIT",
549+ "optional": true,
550+ "os": [
551+ "openbsd"
552+ ],
553+ "engines": {
554+ "node": ">=18"
555+ }
556+ },
557+ "node_modules/@esbuild/sunos-x64": {
558+ "version": "0.25.5",
559+ "resolved": "https://registry.npmjs.org/@esbuild/sunos-x64/-/sunos-x64-0.25.5.tgz",
560+ "integrity": "sha512-l+azKShMy7FxzY0Rj4RCt5VD/q8mG/e+mDivgspo+yL8zW7qEwctQ6YqKX34DTEleFAvCIUviCFX1SDZRSyMQA==",
561+ "cpu": [
562+ "x64"
563+ ],
564+ "dev": true,
565+ "license": "MIT",
566+ "optional": true,
567+ "os": [
568+ "sunos"
569+ ],
570+ "engines": {
571+ "node": ">=18"
572+ }
573+ },
574+ "node_modules/@esbuild/win32-arm64": {
575+ "version": "0.25.5",
576+ "resolved": "https://registry.npmjs.org/@esbuild/win32-arm64/-/win32-arm64-0.25.5.tgz",
577+ "integrity": "sha512-O2S7SNZzdcFG7eFKgvwUEZ2VG9D/sn/eIiz8XRZ1Q/DO5a3s76Xv0mdBzVM5j5R639lXQmPmSo0iRpHqUUrsxw==",
578+ "cpu": [
579+ "arm64"
580+ ],
581+ "dev": true,
582+ "license": "MIT",
583+ "optional": true,
584+ "os": [
585+ "win32"
586+ ],
587+ "engines": {
588+ "node": ">=18"
589+ }
590+ },
591+ "node_modules/@esbuild/win32-ia32": {
592+ "version": "0.25.5",
593+ "resolved": "https://registry.npmjs.org/@esbuild/win32-ia32/-/win32-ia32-0.25.5.tgz",
594+ "integrity": "sha512-onOJ02pqs9h1iMJ1PQphR+VZv8qBMQ77Klcsqv9CNW2w6yLqoURLcgERAIurY6QE63bbLuqgP9ATqajFLK5AMQ==",
595+ "cpu": [
596+ "ia32"
597+ ],
598+ "dev": true,
599+ "license": "MIT",
600+ "optional": true,
601+ "os": [
602+ "win32"
603+ ],
604+ "engines": {
605+ "node": ">=18"
606+ }
607+ },
608+ "node_modules/@esbuild/win32-x64": {
609+ "version": "0.25.5",
610+ "resolved": "https://registry.npmjs.org/@esbuild/win32-x64/-/win32-x64-0.25.5.tgz",
611+ "integrity": "sha512-TXv6YnJ8ZMVdX+SXWVBo/0p8LTcrUYngpWjvm91TMjjBQii7Oz11Lw5lbDV5Y0TzuhSJHwiH4hEtC1I42mMS0g==",
612+ "cpu": [
613+ "x64"
614+ ],
615+ "dev": true,
616+ "license": "MIT",
617+ "optional": true,
618+ "os": [
619+ "win32"
620+ ],
621+ "engines": {
622+ "node": ">=18"
623+ }
624+ },
625+ "node_modules/@jridgewell/sourcemap-codec": {
626+ "version": "1.5.0",
627+ "resolved": "https://registry.npmjs.org/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.5.0.tgz",
628+ "integrity": "sha512-gv3ZRaISU3fjPAgNsriBRqGWQL6quFx04YMPW/zD8XMLsU32mhCCbfbO6KZFLjvYpCZ8zyDEgqsgf+PwPaM7GQ==",
629+ "dev": true,
630+ "license": "MIT"
631+ },
632+ "node_modules/@mswjs/interceptors": {
633+ "version": "0.38.7",
634+ "resolved": "https://registry.npmjs.org/@mswjs/interceptors/-/interceptors-0.38.7.tgz",
635+ "integrity": "sha512-Jkb27iSn7JPdkqlTqKfhncFfnEZsIJVYxsFbUSWEkxdIPdsyngrhoDBk0/BGD2FQcRH99vlRrkHpNTyKqI+0/w==",
636+ "dev": true,
637+ "license": "MIT",
638+ "dependencies": {
639+ "@open-draft/deferred-promise": "^2.2.0",
640+ "@open-draft/logger": "^0.3.0",
641+ "@open-draft/until": "^2.0.0",
642+ "is-node-process": "^1.2.0",
643+ "outvariant": "^1.4.3",
644+ "strict-event-emitter": "^0.5.1"
645+ },
646+ "engines": {
647+ "node": ">=18"
648+ }
649+ },
650+ "node_modules/@open-draft/deferred-promise": {
651+ "version": "2.2.0",
652+ "resolved": "https://registry.npmjs.org/@open-draft/deferred-promise/-/deferred-promise-2.2.0.tgz",
653+ "integrity": "sha512-CecwLWx3rhxVQF6V4bAgPS5t+So2sTbPgAzafKkVizyi7tlwpcFpdFqq+wqF2OwNBmqFuu6tOyouTuxgpMfzmA==",
654+ "dev": true,
655+ "license": "MIT"
656+ },
657+ "node_modules/@open-draft/logger": {
658+ "version": "0.3.0",
659+ "resolved": "https://registry.npmjs.org/@open-draft/logger/-/logger-0.3.0.tgz",
660+ "integrity": "sha512-X2g45fzhxH238HKO4xbSr7+wBS8Fvw6ixhTDuvLd5mqh6bJJCFAPwU9mPDxbcrRtfxv4u5IHCEH77BmxvXmmxQ==",
661+ "dev": true,
662+ "license": "MIT",
663+ "dependencies": {
664+ "is-node-process": "^1.2.0",
665+ "outvariant": "^1.4.0"
666+ }
667+ },
668+ "node_modules/@open-draft/until": {
669+ "version": "2.1.0",
670+ "resolved": "https://registry.npmjs.org/@open-draft/until/-/until-2.1.0.tgz",
671+ "integrity": "sha512-U69T3ItWHvLwGg5eJ0n3I62nWuE6ilHlmz7zM0npLBRvPRd7e6NYmg54vvRtP5mZG7kZqZCFVdsTWo7BPtBujg==",
672+ "dev": true,
673+ "license": "MIT"
674+ },
675+ "node_modules/@rollup/rollup-android-arm-eabi": {
676+ "version": "4.41.1",
677+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.41.1.tgz",
678+ "integrity": "sha512-NELNvyEWZ6R9QMkiytB4/L4zSEaBC03KIXEghptLGLZWJ6VPrL63ooZQCOnlx36aQPGhzuOMwDerC1Eb2VmrLw==",
679+ "cpu": [
680+ "arm"
681+ ],
682+ "dev": true,
683+ "license": "MIT",
684+ "optional": true,
685+ "os": [
686+ "android"
687+ ]
688+ },
689+ "node_modules/@rollup/rollup-android-arm64": {
690+ "version": "4.41.1",
691+ "resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm64/-/rollup-android-arm64-4.41.1.tgz",
692+ "integrity": "sha512-DXdQe1BJ6TK47ukAoZLehRHhfKnKg9BjnQYUu9gzhI8Mwa1d2fzxA1aw2JixHVl403bwp1+/o/NhhHtxWJBgEA==",
693+ "cpu": [
694+ "arm64"
695+ ],
696+ "dev": true,
697+ "license": "MIT",
698+ "optional": true,
699+ "os": [
700+ "android"
701+ ]
702+ },
703+ "node_modules/@rollup/rollup-darwin-arm64": {
704+ "version": "4.41.1",
705+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-arm64/-/rollup-darwin-arm64-4.41.1.tgz",
706+ "integrity": "sha512-5afxvwszzdulsU2w8JKWwY8/sJOLPzf0e1bFuvcW5h9zsEg+RQAojdW0ux2zyYAz7R8HvvzKCjLNJhVq965U7w==",
707+ "cpu": [
708+ "arm64"
709+ ],
710+ "dev": true,
711+ "license": "MIT",
712+ "optional": true,
713+ "os": [
714+ "darwin"
715+ ]
716+ },
717+ "node_modules/@rollup/rollup-darwin-x64": {
718+ "version": "4.41.1",
719+ "resolved": "https://registry.npmjs.org/@rollup/rollup-darwin-x64/-/rollup-darwin-x64-4.41.1.tgz",
720+ "integrity": "sha512-egpJACny8QOdHNNMZKf8xY0Is6gIMz+tuqXlusxquWu3F833DcMwmGM7WlvCO9sB3OsPjdC4U0wHw5FabzCGZg==",
721+ "cpu": [
722+ "x64"
723+ ],
724+ "dev": true,
725+ "license": "MIT",
726+ "optional": true,
727+ "os": [
728+ "darwin"
729+ ]
730+ },
731+ "node_modules/@rollup/rollup-freebsd-arm64": {
732+ "version": "4.41.1",
733+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-arm64/-/rollup-freebsd-arm64-4.41.1.tgz",
734+ "integrity": "sha512-DBVMZH5vbjgRk3r0OzgjS38z+atlupJ7xfKIDJdZZL6sM6wjfDNo64aowcLPKIx7LMQi8vybB56uh1Ftck/Atg==",
735+ "cpu": [
736+ "arm64"
737+ ],
738+ "dev": true,
739+ "license": "MIT",
740+ "optional": true,
741+ "os": [
742+ "freebsd"
743+ ]
744+ },
745+ "node_modules/@rollup/rollup-freebsd-x64": {
746+ "version": "4.41.1",
747+ "resolved": "https://registry.npmjs.org/@rollup/rollup-freebsd-x64/-/rollup-freebsd-x64-4.41.1.tgz",
748+ "integrity": "sha512-3FkydeohozEskBxNWEIbPfOE0aqQgB6ttTkJ159uWOFn42VLyfAiyD9UK5mhu+ItWzft60DycIN1Xdgiy8o/SA==",
749+ "cpu": [
750+ "x64"
751+ ],
752+ "dev": true,
753+ "license": "MIT",
754+ "optional": true,
755+ "os": [
756+ "freebsd"
757+ ]
758+ },
759+ "node_modules/@rollup/rollup-linux-arm-gnueabihf": {
760+ "version": "4.41.1",
761+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-gnueabihf/-/rollup-linux-arm-gnueabihf-4.41.1.tgz",
762+ "integrity": "sha512-wC53ZNDgt0pqx5xCAgNunkTzFE8GTgdZ9EwYGVcg+jEjJdZGtq9xPjDnFgfFozQI/Xm1mh+D9YlYtl+ueswNEg==",
763+ "cpu": [
764+ "arm"
765+ ],
766+ "dev": true,
767+ "license": "MIT",
768+ "optional": true,
769+ "os": [
770+ "linux"
771+ ]
772+ },
773+ "node_modules/@rollup/rollup-linux-arm-musleabihf": {
774+ "version": "4.41.1",
775+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm-musleabihf/-/rollup-linux-arm-musleabihf-4.41.1.tgz",
776+ "integrity": "sha512-jwKCca1gbZkZLhLRtsrka5N8sFAaxrGz/7wRJ8Wwvq3jug7toO21vWlViihG85ei7uJTpzbXZRcORotE+xyrLA==",
777+ "cpu": [
778+ "arm"
779+ ],
780+ "dev": true,
781+ "license": "MIT",
782+ "optional": true,
783+ "os": [
784+ "linux"
785+ ]
786+ },
787+ "node_modules/@rollup/rollup-linux-arm64-gnu": {
788+ "version": "4.41.1",
789+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-gnu/-/rollup-linux-arm64-gnu-4.41.1.tgz",
790+ "integrity": "sha512-g0UBcNknsmmNQ8V2d/zD2P7WWfJKU0F1nu0k5pW4rvdb+BIqMm8ToluW/eeRmxCared5dD76lS04uL4UaNgpNA==",
791+ "cpu": [
792+ "arm64"
793+ ],
794+ "dev": true,
795+ "license": "MIT",
796+ "optional": true,
797+ "os": [
798+ "linux"
799+ ]
800+ },
801+ "node_modules/@rollup/rollup-linux-arm64-musl": {
802+ "version": "4.41.1",
803+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-arm64-musl/-/rollup-linux-arm64-musl-4.41.1.tgz",
804+ "integrity": "sha512-XZpeGB5TKEZWzIrj7sXr+BEaSgo/ma/kCgrZgL0oo5qdB1JlTzIYQKel/RmhT6vMAvOdM2teYlAaOGJpJ9lahg==",
805+ "cpu": [
806+ "arm64"
807+ ],
808+ "dev": true,
809+ "license": "MIT",
810+ "optional": true,
811+ "os": [
812+ "linux"
813+ ]
814+ },
815+ "node_modules/@rollup/rollup-linux-loongarch64-gnu": {
816+ "version": "4.41.1",
817+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-loongarch64-gnu/-/rollup-linux-loongarch64-gnu-4.41.1.tgz",
818+ "integrity": "sha512-bkCfDJ4qzWfFRCNt5RVV4DOw6KEgFTUZi2r2RuYhGWC8WhCA8lCAJhDeAmrM/fdiAH54m0mA0Vk2FGRPyzI+tw==",
819+ "cpu": [
820+ "loong64"
821+ ],
822+ "dev": true,
823+ "license": "MIT",
824+ "optional": true,
825+ "os": [
826+ "linux"
827+ ]
828+ },
829+ "node_modules/@rollup/rollup-linux-powerpc64le-gnu": {
830+ "version": "4.41.1",
831+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-powerpc64le-gnu/-/rollup-linux-powerpc64le-gnu-4.41.1.tgz",
832+ "integrity": "sha512-3mr3Xm+gvMX+/8EKogIZSIEF0WUu0HL9di+YWlJpO8CQBnoLAEL/roTCxuLncEdgcfJcvA4UMOf+2dnjl4Ut1A==",
833+ "cpu": [
834+ "ppc64"
835+ ],
836+ "dev": true,
837+ "license": "MIT",
838+ "optional": true,
839+ "os": [
840+ "linux"
841+ ]
842+ },
843+ "node_modules/@rollup/rollup-linux-riscv64-gnu": {
844+ "version": "4.41.1",
845+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-gnu/-/rollup-linux-riscv64-gnu-4.41.1.tgz",
846+ "integrity": "sha512-3rwCIh6MQ1LGrvKJitQjZFuQnT2wxfU+ivhNBzmxXTXPllewOF7JR1s2vMX/tWtUYFgphygxjqMl76q4aMotGw==",
847+ "cpu": [
848+ "riscv64"
849+ ],
850+ "dev": true,
851+ "license": "MIT",
852+ "optional": true,
853+ "os": [
854+ "linux"
855+ ]
856+ },
857+ "node_modules/@rollup/rollup-linux-riscv64-musl": {
858+ "version": "4.41.1",
859+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-riscv64-musl/-/rollup-linux-riscv64-musl-4.41.1.tgz",
860+ "integrity": "sha512-LdIUOb3gvfmpkgFZuccNa2uYiqtgZAz3PTzjuM5bH3nvuy9ty6RGc/Q0+HDFrHrizJGVpjnTZ1yS5TNNjFlklw==",
861+ "cpu": [
862+ "riscv64"
863+ ],
864+ "dev": true,
865+ "license": "MIT",
866+ "optional": true,
867+ "os": [
868+ "linux"
869+ ]
870+ },
871+ "node_modules/@rollup/rollup-linux-s390x-gnu": {
872+ "version": "4.41.1",
873+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-s390x-gnu/-/rollup-linux-s390x-gnu-4.41.1.tgz",
874+ "integrity": "sha512-oIE6M8WC9ma6xYqjvPhzZYk6NbobIURvP/lEbh7FWplcMO6gn7MM2yHKA1eC/GvYwzNKK/1LYgqzdkZ8YFxR8g==",
875+ "cpu": [
876+ "s390x"
877+ ],
878+ "dev": true,
879+ "license": "MIT",
880+ "optional": true,
881+ "os": [
882+ "linux"
883+ ]
884+ },
885+ "node_modules/@rollup/rollup-linux-x64-gnu": {
886+ "version": "4.41.1",
887+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-gnu/-/rollup-linux-x64-gnu-4.41.1.tgz",
888+ "integrity": "sha512-cWBOvayNvA+SyeQMp79BHPK8ws6sHSsYnK5zDcsC3Hsxr1dgTABKjMnMslPq1DvZIp6uO7kIWhiGwaTdR4Og9A==",
889+ "cpu": [
890+ "x64"
891+ ],
892+ "dev": true,
893+ "license": "MIT",
894+ "optional": true,
895+ "os": [
896+ "linux"
897+ ]
898+ },
899+ "node_modules/@rollup/rollup-linux-x64-musl": {
900+ "version": "4.41.1",
901+ "resolved": "https://registry.npmjs.org/@rollup/rollup-linux-x64-musl/-/rollup-linux-x64-musl-4.41.1.tgz",
902+ "integrity": "sha512-y5CbN44M+pUCdGDlZFzGGBSKCA4A/J2ZH4edTYSSxFg7ce1Xt3GtydbVKWLlzL+INfFIZAEg1ZV6hh9+QQf9YQ==",
903+ "cpu": [
904+ "x64"
905+ ],
906+ "dev": true,
907+ "license": "MIT",
908+ "optional": true,
909+ "os": [
910+ "linux"
911+ ]
912+ },
913+ "node_modules/@rollup/rollup-win32-arm64-msvc": {
914+ "version": "4.41.1",
915+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-arm64-msvc/-/rollup-win32-arm64-msvc-4.41.1.tgz",
916+ "integrity": "sha512-lZkCxIrjlJlMt1dLO/FbpZbzt6J/A8p4DnqzSa4PWqPEUUUnzXLeki/iyPLfV0BmHItlYgHUqJe+3KiyydmiNQ==",
917+ "cpu": [
918+ "arm64"
919+ ],
920+ "dev": true,
921+ "license": "MIT",
922+ "optional": true,
923+ "os": [
924+ "win32"
925+ ]
926+ },
927+ "node_modules/@rollup/rollup-win32-ia32-msvc": {
928+ "version": "4.41.1",
929+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-ia32-msvc/-/rollup-win32-ia32-msvc-4.41.1.tgz",
930+ "integrity": "sha512-+psFT9+pIh2iuGsxFYYa/LhS5MFKmuivRsx9iPJWNSGbh2XVEjk90fmpUEjCnILPEPJnikAU6SFDiEUyOv90Pg==",
931+ "cpu": [
932+ "ia32"
933+ ],
934+ "dev": true,
935+ "license": "MIT",
936+ "optional": true,
937+ "os": [
938+ "win32"
939+ ]
940+ },
941+ "node_modules/@rollup/rollup-win32-x64-msvc": {
942+ "version": "4.41.1",
943+ "resolved": "https://registry.npmjs.org/@rollup/rollup-win32-x64-msvc/-/rollup-win32-x64-msvc-4.41.1.tgz",
944+ "integrity": "sha512-Wq2zpapRYLfi4aKxf2Xff0tN+7slj2d4R87WEzqw7ZLsVvO5zwYCIuEGSZYiK41+GlwUo1HiR+GdkLEJnCKTCw==",
945+ "cpu": [
946+ "x64"
947+ ],
948+ "dev": true,
949+ "license": "MIT",
950+ "optional": true,
951+ "os": [
952+ "win32"
953+ ]
954+ },
955+ "node_modules/@sec-ant/readable-stream": {
956+ "version": "0.4.1",
957+ "resolved": "https://registry.npmjs.org/@sec-ant/readable-stream/-/readable-stream-0.4.1.tgz",
958+ "integrity": "sha512-831qok9r2t8AlxLko40y2ebgSDhenenCatLVeW/uBtnHPyhHOvG0C7TvfgecV+wHzIm5KUICgzmVpWS+IMEAeg==",
959+ "dev": true,
960+ "license": "MIT"
961+ },
962+ "node_modules/@sindresorhus/merge-streams": {
963+ "version": "4.0.0",
964+ "resolved": "https://registry.npmjs.org/@sindresorhus/merge-streams/-/merge-streams-4.0.0.tgz",
965+ "integrity": "sha512-tlqY9xq5ukxTUZBmoOp+m61cqwQD5pHJtFY3Mn8CA8ps6yghLH/Hw8UPdqg4OLmFW3IFlcXnQNmo/dh8HzXYIQ==",
966+ "dev": true,
967+ "license": "MIT",
968+ "engines": {
969+ "node": ">=18"
970+ },
971+ "funding": {
972+ "url": "https://github.com/sponsors/sindresorhus"
973+ }
974+ },
975+ "node_modules/@types/chai": {
976+ "version": "5.2.2",
977+ "resolved": "https://registry.npmjs.org/@types/chai/-/chai-5.2.2.tgz",
978+ "integrity": "sha512-8kB30R7Hwqf40JPiKhVzodJs2Qc1ZJ5zuT3uzw5Hq/dhNCl3G3l83jfpdI1e20BP348+fV7VIL/+FxaXkqBmWg==",
979+ "dev": true,
980+ "license": "MIT",
981+ "dependencies": {
982+ "@types/deep-eql": "*"
983+ }
984+ },
985+ "node_modules/@types/deep-eql": {
986+ "version": "4.0.2",
987+ "resolved": "https://registry.npmjs.org/@types/deep-eql/-/deep-eql-4.0.2.tgz",
988+ "integrity": "sha512-c9h9dVVMigMPc4bwTvC5dxqtqJZwQPePsWjPlpSOnojbor6pGqdk541lfA7AqFQr5pB1BRdq0juY9db81BwyFw==",
989+ "dev": true,
990+ "license": "MIT"
991+ },
992+ "node_modules/@types/estree": {
993+ "version": "1.0.7",
994+ "resolved": "https://registry.npmjs.org/@types/estree/-/estree-1.0.7.tgz",
995+ "integrity": "sha512-w28IoSUCJpidD/TGviZwwMJckNESJZXFu7NBZ5YJ4mEUnNraUn9Pm8HSZm/jDF1pDWYKspWE7oVphigUPRakIQ==",
996+ "dev": true,
997+ "license": "MIT"
998+ },
999+ "node_modules/@types/node": {
1000+ "version": "22.15.29",
1001+ "resolved": "https://registry.npmjs.org/@types/node/-/node-22.15.29.tgz",
1002+ "integrity": "sha512-LNdjOkUDlU1RZb8e1kOIUpN1qQUlzGkEtbVNo53vbrwDg5om6oduhm4SiUaPW5ASTXhAiP0jInWG8Qx9fVlOeQ==",
1003+ "dev": true,
1004+ "license": "MIT",
1005+ "dependencies": {
1006+ "undici-types": "~6.21.0"
1007+ }
1008+ },
1009+ "node_modules/@types/react": {
1010+ "version": "19.1.6",
1011+ "resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.6.tgz",
1012+ "integrity": "sha512-JeG0rEWak0N6Itr6QUx+X60uQmN+5t3j9r/OVDtWzFXKaj6kD1BwJzOksD0FF6iWxZlbE1kB0q9vtnU2ekqa1Q==",
1013+ "devOptional": true,
1014+ "license": "MIT",
1015+ "dependencies": {
1016+ "csstype": "^3.0.2"
1017+ }
1018+ },
1019+ "node_modules/@types/react-dom": {
1020+ "version": "19.1.5",
1021+ "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-19.1.5.tgz",
1022+ "integrity": "sha512-CMCjrWucUBZvohgZxkjd6S9h0nZxXjzus6yDfUb+xLxYM7VvjKNH1tQrE9GWLql1XoOP4/Ds3bwFqShHUYraGg==",
1023+ "dev": true,
1024+ "license": "MIT",
1025+ "peerDependencies": {
1026+ "@types/react": "^19.0.0"
1027+ }
1028+ },
1029+ "node_modules/@types/use-sync-external-store": {
1030+ "version": "0.0.6",
1031+ "resolved": "https://registry.npmjs.org/@types/use-sync-external-store/-/use-sync-external-store-0.0.6.tgz",
1032+ "integrity": "sha512-zFDAD+tlpf2r4asuHEj0XH6pY6i0g5NeAHPn+15wk3BV6JA69eERFXC1gyGThDkVa1zCyKr5jox1+2LbV/AMLg==",
1033+ "license": "MIT"
1034+ },
1035+ "node_modules/@vitest/expect": {
1036+ "version": "3.2.0",
1037+ "resolved": "https://registry.npmjs.org/@vitest/expect/-/expect-3.2.0.tgz",
1038+ "integrity": "sha512-0v4YVbhDKX3SKoy0PHWXpKhj44w+3zZkIoVES9Ex2pq+u6+Bijijbi2ua5kE+h3qT6LBWFTNZSCOEU37H8Y5sA==",
1039+ "dev": true,
1040+ "license": "MIT",
1041+ "dependencies": {
1042+ "@types/chai": "^5.2.2",
1043+ "@vitest/spy": "3.2.0",
1044+ "@vitest/utils": "3.2.0",
1045+ "chai": "^5.2.0",
1046+ "tinyrainbow": "^2.0.0"
1047+ },
1048+ "funding": {
1049+ "url": "https://opencollective.com/vitest"
1050+ }
1051+ },
1052+ "node_modules/@vitest/mocker": {
1053+ "version": "3.2.0",
1054+ "resolved": "https://registry.npmjs.org/@vitest/mocker/-/mocker-3.2.0.tgz",
1055+ "integrity": "sha512-HFcW0lAMx3eN9vQqis63H0Pscv0QcVMo1Kv8BNysZbxcmHu3ZUYv59DS6BGYiGQ8F5lUkmsfMMlPm4DJFJdf/A==",
1056+ "dev": true,
1057+ "license": "MIT",
1058+ "dependencies": {
1059+ "@vitest/spy": "3.2.0",
1060+ "estree-walker": "^3.0.3",
1061+ "magic-string": "^0.30.17"
1062+ },
1063+ "funding": {
1064+ "url": "https://opencollective.com/vitest"
1065+ },
1066+ "peerDependencies": {
1067+ "msw": "^2.4.9",
1068+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
1069+ },
1070+ "peerDependenciesMeta": {
1071+ "msw": {
1072+ "optional": true
1073+ },
1074+ "vite": {
1075+ "optional": true
1076+ }
1077+ }
1078+ },
1079+ "node_modules/@vitest/pretty-format": {
1080+ "version": "3.2.0",
1081+ "resolved": "https://registry.npmjs.org/@vitest/pretty-format/-/pretty-format-3.2.0.tgz",
1082+ "integrity": "sha512-gUUhaUmPBHFkrqnOokmfMGRBMHhgpICud9nrz/xpNV3/4OXCn35oG+Pl8rYYsKaTNd/FAIrqRHnwpDpmYxCYZw==",
1083+ "dev": true,
1084+ "license": "MIT",
1085+ "dependencies": {
1086+ "tinyrainbow": "^2.0.0"
1087+ },
1088+ "funding": {
1089+ "url": "https://opencollective.com/vitest"
1090+ }
1091+ },
1092+ "node_modules/@vitest/runner": {
1093+ "version": "3.2.0",
1094+ "resolved": "https://registry.npmjs.org/@vitest/runner/-/runner-3.2.0.tgz",
1095+ "integrity": "sha512-bXdmnHxuB7fXJdh+8vvnlwi/m1zvu+I06i1dICVcDQFhyV4iKw2RExC/acavtDn93m/dRuawUObKsrNE1gJacA==",
1096+ "dev": true,
1097+ "license": "MIT",
1098+ "dependencies": {
1099+ "@vitest/utils": "3.2.0",
1100+ "pathe": "^2.0.3"
1101+ },
1102+ "funding": {
1103+ "url": "https://opencollective.com/vitest"
1104+ }
1105+ },
1106+ "node_modules/@vitest/snapshot": {
1107+ "version": "3.2.0",
1108+ "resolved": "https://registry.npmjs.org/@vitest/snapshot/-/snapshot-3.2.0.tgz",
1109+ "integrity": "sha512-z7P/EneBRMe7hdvWhcHoXjhA6at0Q4ipcoZo6SqgxLyQQ8KSMMCmvw1cSt7FHib3ozt0wnRHc37ivuUMbxzG/A==",
1110+ "dev": true,
1111+ "license": "MIT",
1112+ "dependencies": {
1113+ "@vitest/pretty-format": "3.2.0",
1114+ "magic-string": "^0.30.17",
1115+ "pathe": "^2.0.3"
1116+ },
1117+ "funding": {
1118+ "url": "https://opencollective.com/vitest"
1119+ }
1120+ },
1121+ "node_modules/@vitest/spy": {
1122+ "version": "3.2.0",
1123+ "resolved": "https://registry.npmjs.org/@vitest/spy/-/spy-3.2.0.tgz",
1124+ "integrity": "sha512-s3+TkCNUIEOX99S0JwNDfsHRaZDDZZR/n8F0mop0PmsEbQGKZikCGpTGZ6JRiHuONKew3Fb5//EPwCP+pUX9cw==",
1125+ "dev": true,
1126+ "license": "MIT",
1127+ "dependencies": {
1128+ "tinyspy": "^4.0.3"
1129+ },
1130+ "funding": {
1131+ "url": "https://opencollective.com/vitest"
1132+ }
1133+ },
1134+ "node_modules/@vitest/utils": {
1135+ "version": "3.2.0",
1136+ "resolved": "https://registry.npmjs.org/@vitest/utils/-/utils-3.2.0.tgz",
1137+ "integrity": "sha512-gXXOe7Fj6toCsZKVQouTRLJftJwmvbhH5lKOBR6rlP950zUq9AitTUjnFoXS/CqjBC2aoejAztLPzzuva++XBw==",
1138+ "dev": true,
1139+ "license": "MIT",
1140+ "dependencies": {
1141+ "@vitest/pretty-format": "3.2.0",
1142+ "loupe": "^3.1.3",
1143+ "tinyrainbow": "^2.0.0"
1144+ },
1145+ "funding": {
1146+ "url": "https://opencollective.com/vitest"
1147+ }
1148+ },
1149+ "node_modules/assertion-error": {
1150+ "version": "2.0.1",
1151+ "resolved": "https://registry.npmjs.org/assertion-error/-/assertion-error-2.0.1.tgz",
1152+ "integrity": "sha512-Izi8RQcffqCeNVgFigKli1ssklIbpHnCYc6AknXGYoB6grJqyeby7jv12JUQgmTAnIDnbck1uxksT4dzN3PWBA==",
1153+ "dev": true,
1154+ "license": "MIT",
1155+ "engines": {
1156+ "node": ">=12"
1157+ }
1158+ },
1159+ "node_modules/cac": {
1160+ "version": "6.7.14",
1161+ "resolved": "https://registry.npmjs.org/cac/-/cac-6.7.14.tgz",
1162+ "integrity": "sha512-b6Ilus+c3RrdDk+JhLKUAQfzzgLEPy6wcXqS7f/xe1EETvsDP6GORG7SFuOs6cID5YkqchW/LXZbX5bc8j7ZcQ==",
1163+ "dev": true,
1164+ "license": "MIT",
1165+ "engines": {
1166+ "node": ">=8"
1167+ }
1168+ },
1169+ "node_modules/chai": {
1170+ "version": "5.2.0",
1171+ "resolved": "https://registry.npmjs.org/chai/-/chai-5.2.0.tgz",
1172+ "integrity": "sha512-mCuXncKXk5iCLhfhwTc0izo0gtEmpz5CtG2y8GiOINBlMVS6v8TMRc5TaLWKS6692m9+dVVfzgeVxR5UxWHTYw==",
1173+ "dev": true,
1174+ "license": "MIT",
1175+ "dependencies": {
1176+ "assertion-error": "^2.0.1",
1177+ "check-error": "^2.1.1",
1178+ "deep-eql": "^5.0.1",
1179+ "loupe": "^3.1.0",
1180+ "pathval": "^2.0.0"
1181+ },
1182+ "engines": {
1183+ "node": ">=12"
1184+ }
1185+ },
1186+ "node_modules/check-error": {
1187+ "version": "2.1.1",
1188+ "resolved": "https://registry.npmjs.org/check-error/-/check-error-2.1.1.tgz",
1189+ "integrity": "sha512-OAlb+T7V4Op9OwdkjmguYRqncdlx5JiofwOAUkmTF+jNdHwzTaTs4sRAGpzLF3oOz5xAyDGrPgeIDFQmDOTiJw==",
1190+ "dev": true,
1191+ "license": "MIT",
1192+ "engines": {
1193+ "node": ">= 16"
1194+ }
1195+ },
1196+ "node_modules/cross-spawn": {
1197+ "version": "7.0.6",
1198+ "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
1199+ "integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
1200+ "dev": true,
1201+ "license": "MIT",
1202+ "dependencies": {
1203+ "path-key": "^3.1.0",
1204+ "shebang-command": "^2.0.0",
1205+ "which": "^2.0.1"
1206+ },
1207+ "engines": {
1208+ "node": ">= 8"
1209+ }
1210+ },
1211+ "node_modules/csstype": {
1212+ "version": "3.1.3",
1213+ "resolved": "https://registry.npmjs.org/csstype/-/csstype-3.1.3.tgz",
1214+ "integrity": "sha512-M1uQkMl8rQK/szD0LNhtqxIPLpimGm8sOBwU7lLnCpSbTyY3yeU1Vc7l4KT5zT4s/yOxHH5O7tIuuLOCnLADRw==",
1215+ "devOptional": true,
1216+ "license": "MIT"
1217+ },
1218+ "node_modules/debug": {
1219+ "version": "4.4.1",
1220+ "resolved": "https://registry.npmjs.org/debug/-/debug-4.4.1.tgz",
1221+ "integrity": "sha512-KcKCqiftBJcZr++7ykoDIEwSa3XWowTfNPo92BYxjXiyYEVrUQh2aLyhxBCwww+heortUFxEJYcRzosstTEBYQ==",
1222+ "dev": true,
1223+ "license": "MIT",
1224+ "dependencies": {
1225+ "ms": "^2.1.3"
1226+ },
1227+ "engines": {
1228+ "node": ">=6.0"
1229+ },
1230+ "peerDependenciesMeta": {
1231+ "supports-color": {
1232+ "optional": true
1233+ }
1234+ }
1235+ },
1236+ "node_modules/deep-eql": {
1237+ "version": "5.0.2",
1238+ "resolved": "https://registry.npmjs.org/deep-eql/-/deep-eql-5.0.2.tgz",
1239+ "integrity": "sha512-h5k/5U50IJJFpzfL6nO9jaaumfjO/f2NjK/oYB2Djzm4p9L+3T9qWpZqZ2hAbLPuuYq9wrU08WQyBTL5GbPk5Q==",
1240+ "dev": true,
1241+ "license": "MIT",
1242+ "engines": {
1243+ "node": ">=6"
1244+ }
1245+ },
1246+ "node_modules/effection": {
1247+ "version": "3.5.0",
1248+ "resolved": "https://registry.npmjs.org/effection/-/effection-3.5.0.tgz",
1249+ "integrity": "sha512-PcKRGoP68CM3c/DODTc38xp0rIjfREH7/fBGu4tiHU/aPb/PvSxv3tvWaJt6JxpxqT0jIXvcOyn+yjk46KcNXw==",
1250+ "license": "ISC",
1251+ "engines": {
1252+ "node": ">= 16"
1253+ }
1254+ },
1255+ "node_modules/es-module-lexer": {
1256+ "version": "1.7.0",
1257+ "resolved": "https://registry.npmjs.org/es-module-lexer/-/es-module-lexer-1.7.0.tgz",
1258+ "integrity": "sha512-jEQoCwk8hyb2AZziIOLhDqpm5+2ww5uIE6lkO/6jcOCusfk6LhMHpXXfBLXTZ7Ydyt0j4VoUQv6uGNYbdW+kBA==",
1259+ "dev": true,
1260+ "license": "MIT"
1261+ },
1262+ "node_modules/esbuild": {
1263+ "version": "0.25.5",
1264+ "resolved": "https://registry.npmjs.org/esbuild/-/esbuild-0.25.5.tgz",
1265+ "integrity": "sha512-P8OtKZRv/5J5hhz0cUAdu/cLuPIKXpQl1R9pZtvmHWQvrAUVd0UNIPT4IB4W3rNOqVO0rlqHmCIbSwxh/c9yUQ==",
1266+ "dev": true,
1267+ "hasInstallScript": true,
1268+ "license": "MIT",
1269+ "bin": {
1270+ "esbuild": "bin/esbuild"
1271+ },
1272+ "engines": {
1273+ "node": ">=18"
1274+ },
1275+ "optionalDependencies": {
1276+ "@esbuild/aix-ppc64": "0.25.5",
1277+ "@esbuild/android-arm": "0.25.5",
1278+ "@esbuild/android-arm64": "0.25.5",
1279+ "@esbuild/android-x64": "0.25.5",
1280+ "@esbuild/darwin-arm64": "0.25.5",
1281+ "@esbuild/darwin-x64": "0.25.5",
1282+ "@esbuild/freebsd-arm64": "0.25.5",
1283+ "@esbuild/freebsd-x64": "0.25.5",
1284+ "@esbuild/linux-arm": "0.25.5",
1285+ "@esbuild/linux-arm64": "0.25.5",
1286+ "@esbuild/linux-ia32": "0.25.5",
1287+ "@esbuild/linux-loong64": "0.25.5",
1288+ "@esbuild/linux-mips64el": "0.25.5",
1289+ "@esbuild/linux-ppc64": "0.25.5",
1290+ "@esbuild/linux-riscv64": "0.25.5",
1291+ "@esbuild/linux-s390x": "0.25.5",
1292+ "@esbuild/linux-x64": "0.25.5",
1293+ "@esbuild/netbsd-arm64": "0.25.5",
1294+ "@esbuild/netbsd-x64": "0.25.5",
1295+ "@esbuild/openbsd-arm64": "0.25.5",
1296+ "@esbuild/openbsd-x64": "0.25.5",
1297+ "@esbuild/sunos-x64": "0.25.5",
1298+ "@esbuild/win32-arm64": "0.25.5",
1299+ "@esbuild/win32-ia32": "0.25.5",
1300+ "@esbuild/win32-x64": "0.25.5"
1301+ }
1302+ },
1303+ "node_modules/estree-walker": {
1304+ "version": "3.0.3",
1305+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-3.0.3.tgz",
1306+ "integrity": "sha512-7RUKfXgSMMkzt6ZuXmqapOurLGPPfgj6l9uRZ7lRGolvk0y2yocc35LdcxKC5PQZdn2DMqioAQ2NoWcrTKmm6g==",
1307+ "dev": true,
1308+ "license": "MIT",
1309+ "dependencies": {
1310+ "@types/estree": "^1.0.0"
1311+ }
1312+ },
1313+ "node_modules/execa": {
1314+ "version": "9.6.0",
1315+ "resolved": "https://registry.npmjs.org/execa/-/execa-9.6.0.tgz",
1316+ "integrity": "sha512-jpWzZ1ZhwUmeWRhS7Qv3mhpOhLfwI+uAX4e5fOcXqwMR7EcJ0pj2kV1CVzHVMX/LphnKWD3LObjZCoJ71lKpHw==",
1317+ "dev": true,
1318+ "license": "MIT",
1319+ "dependencies": {
1320+ "@sindresorhus/merge-streams": "^4.0.0",
1321+ "cross-spawn": "^7.0.6",
1322+ "figures": "^6.1.0",
1323+ "get-stream": "^9.0.0",
1324+ "human-signals": "^8.0.1",
1325+ "is-plain-obj": "^4.1.0",
1326+ "is-stream": "^4.0.1",
1327+ "npm-run-path": "^6.0.0",
1328+ "pretty-ms": "^9.2.0",
1329+ "signal-exit": "^4.1.0",
1330+ "strip-final-newline": "^4.0.0",
1331+ "yoctocolors": "^2.1.1"
1332+ },
1333+ "engines": {
1334+ "node": "^18.19.0 || >=20.5.0"
1335+ },
1336+ "funding": {
1337+ "url": "https://github.com/sindresorhus/execa?sponsor=1"
1338+ }
1339+ },
1340+ "node_modules/expect-type": {
1341+ "version": "1.2.1",
1342+ "resolved": "https://registry.npmjs.org/expect-type/-/expect-type-1.2.1.tgz",
1343+ "integrity": "sha512-/kP8CAwxzLVEeFrMm4kMmy4CCDlpipyA7MYLVrdJIkV0fYF0UaigQHRsxHiuY/GEea+bh4KSv3TIlgr+2UL6bw==",
1344+ "dev": true,
1345+ "license": "Apache-2.0",
1346+ "engines": {
1347+ "node": ">=12.0.0"
1348+ }
1349+ },
1350+ "node_modules/fdir": {
1351+ "version": "6.4.5",
1352+ "resolved": "https://registry.npmjs.org/fdir/-/fdir-6.4.5.tgz",
1353+ "integrity": "sha512-4BG7puHpVsIYxZUbiUE3RqGloLaSSwzYie5jvasC4LWuBWzZawynvYouhjbQKw2JuIGYdm0DzIxl8iVidKlUEw==",
1354+ "dev": true,
1355+ "license": "MIT",
1356+ "peerDependencies": {
1357+ "picomatch": "^3 || ^4"
1358+ },
1359+ "peerDependenciesMeta": {
1360+ "picomatch": {
1361+ "optional": true
1362+ }
1363+ }
1364+ },
1365+ "node_modules/figures": {
1366+ "version": "6.1.0",
1367+ "resolved": "https://registry.npmjs.org/figures/-/figures-6.1.0.tgz",
1368+ "integrity": "sha512-d+l3qxjSesT4V7v2fh+QnmFnUWv9lSpjarhShNTgBOfA0ttejbQUAlHLitbjkoRiDulW0OPoQPYIGhIC8ohejg==",
1369+ "dev": true,
1370+ "license": "MIT",
1371+ "dependencies": {
1372+ "is-unicode-supported": "^2.0.0"
1373+ },
1374+ "engines": {
1375+ "node": ">=18"
1376+ },
1377+ "funding": {
1378+ "url": "https://github.com/sponsors/sindresorhus"
1379+ }
1380+ },
1381+ "node_modules/fsevents": {
1382+ "version": "2.3.3",
1383+ "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-2.3.3.tgz",
1384+ "integrity": "sha512-5xoDfX+fL7faATnagmWPpbFtwh/R77WmMMqqHGS65C3vvB0YHrgF+B1YmZ3441tMj5n63k0212XNoJwzlhffQw==",
1385+ "dev": true,
1386+ "hasInstallScript": true,
1387+ "license": "MIT",
1388+ "optional": true,
1389+ "os": [
1390+ "darwin"
1391+ ],
1392+ "engines": {
1393+ "node": "^8.16.0 || ^10.6.0 || >=11.0.0"
1394+ }
1395+ },
1396+ "node_modules/get-stream": {
1397+ "version": "9.0.1",
1398+ "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-9.0.1.tgz",
1399+ "integrity": "sha512-kVCxPF3vQM/N0B1PmoqVUqgHP+EeVjmZSQn+1oCRPxd2P21P2F19lIgbR3HBosbB1PUhOAoctJnfEn2GbN2eZA==",
1400+ "dev": true,
1401+ "license": "MIT",
1402+ "dependencies": {
1403+ "@sec-ant/readable-stream": "^0.4.1",
1404+ "is-stream": "^4.0.1"
1405+ },
1406+ "engines": {
1407+ "node": ">=18"
1408+ },
1409+ "funding": {
1410+ "url": "https://github.com/sponsors/sindresorhus"
1411+ }
1412+ },
1413+ "node_modules/get-tsconfig": {
1414+ "version": "4.10.1",
1415+ "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
1416+ "integrity": "sha512-auHyJ4AgMz7vgS8Hp3N6HXSmlMdUyhSUrfBF16w153rxtLIEOE+HGqaBppczZvnHLqQJfiHotCYpNhl0lUROFQ==",
1417+ "dev": true,
1418+ "license": "MIT",
1419+ "dependencies": {
1420+ "resolve-pkg-maps": "^1.0.0"
1421+ },
1422+ "funding": {
1423+ "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1"
1424+ }
1425+ },
1426+ "node_modules/human-signals": {
1427+ "version": "8.0.1",
1428+ "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-8.0.1.tgz",
1429+ "integrity": "sha512-eKCa6bwnJhvxj14kZk5NCPc6Hb6BdsU9DZcOnmQKSnO1VKrfV0zCvtttPZUsBvjmNDn8rpcJfpwSYnHBjc95MQ==",
1430+ "dev": true,
1431+ "license": "Apache-2.0",
1432+ "engines": {
1433+ "node": ">=18.18.0"
1434+ }
1435+ },
1436+ "node_modules/immer": {
1437+ "version": "10.1.1",
1438+ "resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
1439+ "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
1440+ "license": "MIT",
1441+ "funding": {
1442+ "type": "opencollective",
1443+ "url": "https://opencollective.com/immer"
1444+ }
1445+ },
1446+ "node_modules/is-node-process": {
1447+ "version": "1.2.0",
1448+ "resolved": "https://registry.npmjs.org/is-node-process/-/is-node-process-1.2.0.tgz",
1449+ "integrity": "sha512-Vg4o6/fqPxIjtxgUH5QLJhwZ7gW5diGCVlXpuUfELC62CuxM1iHcRe51f2W1FDy04Ai4KJkagKjx3XaqyfRKXw==",
1450+ "dev": true,
1451+ "license": "MIT"
1452+ },
1453+ "node_modules/is-plain-obj": {
1454+ "version": "4.1.0",
1455+ "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-4.1.0.tgz",
1456+ "integrity": "sha512-+Pgi+vMuUNkJyExiMBt5IlFoMyKnr5zhJ4Uspz58WOhBF5QoIZkFyNHIbBAtHwzVAgk5RtndVNsDRN61/mmDqg==",
1457+ "dev": true,
1458+ "license": "MIT",
1459+ "engines": {
1460+ "node": ">=12"
1461+ },
1462+ "funding": {
1463+ "url": "https://github.com/sponsors/sindresorhus"
1464+ }
1465+ },
1466+ "node_modules/is-stream": {
1467+ "version": "4.0.1",
1468+ "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-4.0.1.tgz",
1469+ "integrity": "sha512-Dnz92NInDqYckGEUJv689RbRiTSEHCQ7wOVeALbkOz999YpqT46yMRIGtSNl2iCL1waAZSx40+h59NV/EwzV/A==",
1470+ "dev": true,
1471+ "license": "MIT",
1472+ "engines": {
1473+ "node": ">=18"
1474+ },
1475+ "funding": {
1476+ "url": "https://github.com/sponsors/sindresorhus"
1477+ }
1478+ },
1479+ "node_modules/is-unicode-supported": {
1480+ "version": "2.1.0",
1481+ "resolved": "https://registry.npmjs.org/is-unicode-supported/-/is-unicode-supported-2.1.0.tgz",
1482+ "integrity": "sha512-mE00Gnza5EEB3Ds0HfMyllZzbBrmLOX3vfWoj9A9PEnTfratQ/BcaJOuMhnkhjXvb2+FkY3VuHqtAGpTPmglFQ==",
1483+ "dev": true,
1484+ "license": "MIT",
1485+ "engines": {
1486+ "node": ">=18"
1487+ },
1488+ "funding": {
1489+ "url": "https://github.com/sponsors/sindresorhus"
1490+ }
1491+ },
1492+ "node_modules/isexe": {
1493+ "version": "2.0.0",
1494+ "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
1495+ "integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
1496+ "dev": true,
1497+ "license": "ISC"
1498+ },
1499+ "node_modules/json-stringify-safe": {
1500+ "version": "5.0.1",
1501+ "resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
1502+ "integrity": "sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==",
1503+ "dev": true,
1504+ "license": "ISC"
1505+ },
1506+ "node_modules/loupe": {
1507+ "version": "3.1.3",
1508+ "resolved": "https://registry.npmjs.org/loupe/-/loupe-3.1.3.tgz",
1509+ "integrity": "sha512-kkIp7XSkP78ZxJEsSxW3712C6teJVoeHHwgo9zJ380de7IYyJ2ISlxojcH2pC5OFLewESmnRi/+XCDIEEVyoug==",
1510+ "dev": true,
1511+ "license": "MIT"
1512+ },
1513+ "node_modules/magic-string": {
1514+ "version": "0.30.17",
1515+ "resolved": "https://registry.npmjs.org/magic-string/-/magic-string-0.30.17.tgz",
1516+ "integrity": "sha512-sNPKHvyjVf7gyjwS4xGTaW/mCnF8wnjtifKBEhxfZ7E/S8tQ0rssrwGNn6q8JH/ohItJfSQp9mBtQYuTlH5QnA==",
1517+ "dev": true,
1518+ "license": "MIT",
1519+ "dependencies": {
1520+ "@jridgewell/sourcemap-codec": "^1.5.0"
1521+ }
1522+ },
1523+ "node_modules/ms": {
1524+ "version": "2.1.3",
1525+ "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz",
1526+ "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==",
1527+ "dev": true,
1528+ "license": "MIT"
1529+ },
1530+ "node_modules/nanoid": {
1531+ "version": "3.3.11",
1532+ "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.11.tgz",
1533+ "integrity": "sha512-N8SpfPUnUp1bK+PMYW8qSWdl9U+wwNWI4QKxOYDy9JAro3WMX7p2OeVRF9v+347pnakNevPmiHhNmZ2HbFA76w==",
1534+ "dev": true,
1535+ "funding": [
1536+ {
1537+ "type": "github",
1538+ "url": "https://github.com/sponsors/ai"
1539+ }
1540+ ],
1541+ "license": "MIT",
1542+ "bin": {
1543+ "nanoid": "bin/nanoid.cjs"
1544+ },
1545+ "engines": {
1546+ "node": "^10 || ^12 || ^13.7 || ^14 || >=15.0.1"
1547+ }
1548+ },
1549+ "node_modules/nock": {
1550+ "version": "14.0.5",
1551+ "resolved": "https://registry.npmjs.org/nock/-/nock-14.0.5.tgz",
1552+ "integrity": "sha512-R49fALR9caB6vxuSWUIaK2eBYeTloZQUFBZ4rHO+TbhMGQHtwnhdqKLYki+o+8qMgLvoBYWrp/2KzGPhxL4S6w==",
1553+ "dev": true,
1554+ "license": "MIT",
1555+ "dependencies": {
1556+ "@mswjs/interceptors": "^0.38.7",
1557+ "json-stringify-safe": "^5.0.1",
1558+ "propagate": "^2.0.0"
1559+ },
1560+ "engines": {
1561+ "node": ">=18.20.0 <20 || >=20.12.1"
1562+ }
1563+ },
1564+ "node_modules/npm-run-path": {
1565+ "version": "6.0.0",
1566+ "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-6.0.0.tgz",
1567+ "integrity": "sha512-9qny7Z9DsQU8Ou39ERsPU4OZQlSTP47ShQzuKZ6PRXpYLtIFgl/DEBYEXKlvcEa+9tHVcK8CF81Y2V72qaZhWA==",
1568+ "dev": true,
1569+ "license": "MIT",
1570+ "dependencies": {
1571+ "path-key": "^4.0.0",
1572+ "unicorn-magic": "^0.3.0"
1573+ },
1574+ "engines": {
1575+ "node": ">=18"
1576+ },
1577+ "funding": {
1578+ "url": "https://github.com/sponsors/sindresorhus"
1579+ }
1580+ },
1581+ "node_modules/npm-run-path/node_modules/path-key": {
1582+ "version": "4.0.0",
1583+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz",
1584+ "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==",
1585+ "dev": true,
1586+ "license": "MIT",
1587+ "engines": {
1588+ "node": ">=12"
1589+ },
1590+ "funding": {
1591+ "url": "https://github.com/sponsors/sindresorhus"
1592+ }
1593+ },
1594+ "node_modules/outvariant": {
1595+ "version": "1.4.3",
1596+ "resolved": "https://registry.npmjs.org/outvariant/-/outvariant-1.4.3.tgz",
1597+ "integrity": "sha512-+Sl2UErvtsoajRDKCE5/dBz4DIvHXQQnAxtQTF04OJxY0+DyZXSo5P5Bb7XYWOh81syohlYL24hbDwxedPUJCA==",
1598+ "dev": true,
1599+ "license": "MIT"
1600+ },
1601+ "node_modules/parse-ms": {
1602+ "version": "4.0.0",
1603+ "resolved": "https://registry.npmjs.org/parse-ms/-/parse-ms-4.0.0.tgz",
1604+ "integrity": "sha512-TXfryirbmq34y8QBwgqCVLi+8oA3oWx2eAnSn62ITyEhEYaWRlVZ2DvMM9eZbMs/RfxPu/PK/aBLyGj4IrqMHw==",
1605+ "dev": true,
1606+ "license": "MIT",
1607+ "engines": {
1608+ "node": ">=18"
1609+ },
1610+ "funding": {
1611+ "url": "https://github.com/sponsors/sindresorhus"
1612+ }
1613+ },
1614+ "node_modules/path-key": {
1615+ "version": "3.1.1",
1616+ "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
1617+ "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
1618+ "dev": true,
1619+ "license": "MIT",
1620+ "engines": {
1621+ "node": ">=8"
1622+ }
1623+ },
1624+ "node_modules/pathe": {
1625+ "version": "2.0.3",
1626+ "resolved": "https://registry.npmjs.org/pathe/-/pathe-2.0.3.tgz",
1627+ "integrity": "sha512-WUjGcAqP1gQacoQe+OBJsFA7Ld4DyXuUIjZ5cc75cLHvJ7dtNsTugphxIADwspS+AraAUePCKrSVtPLFj/F88w==",
1628+ "dev": true,
1629+ "license": "MIT"
1630+ },
1631+ "node_modules/pathval": {
1632+ "version": "2.0.0",
1633+ "resolved": "https://registry.npmjs.org/pathval/-/pathval-2.0.0.tgz",
1634+ "integrity": "sha512-vE7JKRyES09KiunauX7nd2Q9/L7lhok4smP9RZTDeD4MVs72Dp2qNFVz39Nz5a0FVEW0BJR6C0DYrq6unoziZA==",
1635+ "dev": true,
1636+ "license": "MIT",
1637+ "engines": {
1638+ "node": ">= 14.16"
1639+ }
1640+ },
1641+ "node_modules/picocolors": {
1642+ "version": "1.1.1",
1643+ "resolved": "https://registry.npmjs.org/picocolors/-/picocolors-1.1.1.tgz",
1644+ "integrity": "sha512-xceH2snhtb5M9liqDsmEw56le376mTZkEX/jEb/RxNFyegNul7eNslCXP9FDj/Lcu0X8KEyMceP2ntpaHrDEVA==",
1645+ "dev": true,
1646+ "license": "ISC"
1647+ },
1648+ "node_modules/picomatch": {
1649+ "version": "4.0.2",
1650+ "resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.2.tgz",
1651+ "integrity": "sha512-M7BAV6Rlcy5u+m6oPhAPFgJTzAioX/6B0DxyvDlo9l8+T3nLKbrczg2WLUyzd45L8RqfUMyGPzekbMvX2Ldkwg==",
1652+ "dev": true,
1653+ "license": "MIT",
1654+ "engines": {
1655+ "node": ">=12"
1656+ },
1657+ "funding": {
1658+ "url": "https://github.com/sponsors/jonschlinkert"
1659+ }
1660+ },
1661+ "node_modules/postcss": {
1662+ "version": "8.5.4",
1663+ "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.5.4.tgz",
1664+ "integrity": "sha512-QSa9EBe+uwlGTFmHsPKokv3B/oEMQZxfqW0QqNCyhpa6mB1afzulwn8hihglqAb2pOw+BJgNlmXQ8la2VeHB7w==",
1665+ "dev": true,
1666+ "funding": [
1667+ {
1668+ "type": "opencollective",
1669+ "url": "https://opencollective.com/postcss/"
1670+ },
1671+ {
1672+ "type": "tidelift",
1673+ "url": "https://tidelift.com/funding/github/npm/postcss"
1674+ },
1675+ {
1676+ "type": "github",
1677+ "url": "https://github.com/sponsors/ai"
1678+ }
1679+ ],
1680+ "license": "MIT",
1681+ "dependencies": {
1682+ "nanoid": "^3.3.11",
1683+ "picocolors": "^1.1.1",
1684+ "source-map-js": "^1.2.1"
1685+ },
1686+ "engines": {
1687+ "node": "^10 || ^12 || >=14"
1688+ }
1689+ },
1690+ "node_modules/pretty-ms": {
1691+ "version": "9.2.0",
1692+ "resolved": "https://registry.npmjs.org/pretty-ms/-/pretty-ms-9.2.0.tgz",
1693+ "integrity": "sha512-4yf0QO/sllf/1zbZWYnvWw3NxCQwLXKzIj0G849LSufP15BXKM0rbD2Z3wVnkMfjdn/CB0Dpp444gYAACdsplg==",
1694+ "dev": true,
1695+ "license": "MIT",
1696+ "dependencies": {
1697+ "parse-ms": "^4.0.0"
1698+ },
1699+ "engines": {
1700+ "node": ">=18"
1701+ },
1702+ "funding": {
1703+ "url": "https://github.com/sponsors/sindresorhus"
1704+ }
1705+ },
1706+ "node_modules/propagate": {
1707+ "version": "2.0.1",
1708+ "resolved": "https://registry.npmjs.org/propagate/-/propagate-2.0.1.tgz",
1709+ "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==",
1710+ "dev": true,
1711+ "license": "MIT",
1712+ "engines": {
1713+ "node": ">= 8"
1714+ }
1715+ },
1716+ "node_modules/react": {
1717+ "version": "19.1.0",
1718+ "resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
1719+ "integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
1720+ "license": "MIT",
1721+ "engines": {
1722+ "node": ">=0.10.0"
1723+ }
1724+ },
1725+ "node_modules/react-dom": {
1726+ "version": "19.1.0",
1727+ "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
1728+ "integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
1729+ "dev": true,
1730+ "license": "MIT",
1731+ "dependencies": {
1732+ "scheduler": "^0.26.0"
1733+ },
1734+ "peerDependencies": {
1735+ "react": "^19.1.0"
1736+ }
1737+ },
1738+ "node_modules/react-redux": {
1739+ "version": "9.2.0",
1740+ "resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
1741+ "integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
1742+ "license": "MIT",
1743+ "dependencies": {
1744+ "@types/use-sync-external-store": "^0.0.6",
1745+ "use-sync-external-store": "^1.4.0"
1746+ },
1747+ "peerDependencies": {
1748+ "@types/react": "^18.2.25 || ^19",
1749+ "react": "^18.0 || ^19",
1750+ "redux": "^5.0.0"
1751+ },
1752+ "peerDependenciesMeta": {
1753+ "@types/react": {
1754+ "optional": true
1755+ },
1756+ "redux": {
1757+ "optional": true
1758+ }
1759+ }
1760+ },
1761+ "node_modules/reselect": {
1762+ "version": "5.1.1",
1763+ "resolved": "https://registry.npmjs.org/reselect/-/reselect-5.1.1.tgz",
1764+ "integrity": "sha512-K/BG6eIky/SBpzfHZv/dd+9JBFiS4SWV7FIujVyJRux6e45+73RaUHXLmIR1f7WOMaQ0U1km6qwklRQxpJJY0w==",
1765+ "license": "MIT"
1766+ },
1767+ "node_modules/resolve-pkg-maps": {
1768+ "version": "1.0.0",
1769+ "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz",
1770+ "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==",
1771+ "dev": true,
1772+ "license": "MIT",
1773+ "funding": {
1774+ "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1"
1775+ }
1776+ },
1777+ "node_modules/rollup": {
1778+ "version": "4.41.1",
1779+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-4.41.1.tgz",
1780+ "integrity": "sha512-cPmwD3FnFv8rKMBc1MxWCwVQFxwf1JEmSX3iQXrRVVG15zerAIXRjMFVWnd5Q5QvgKF7Aj+5ykXFhUl+QGnyOw==",
1781+ "dev": true,
1782+ "license": "MIT",
1783+ "dependencies": {
1784+ "@types/estree": "1.0.7"
1785+ },
1786+ "bin": {
1787+ "rollup": "dist/bin/rollup"
1788+ },
1789+ "engines": {
1790+ "node": ">=18.0.0",
1791+ "npm": ">=8.0.0"
1792+ },
1793+ "optionalDependencies": {
1794+ "@rollup/rollup-android-arm-eabi": "4.41.1",
1795+ "@rollup/rollup-android-arm64": "4.41.1",
1796+ "@rollup/rollup-darwin-arm64": "4.41.1",
1797+ "@rollup/rollup-darwin-x64": "4.41.1",
1798+ "@rollup/rollup-freebsd-arm64": "4.41.1",
1799+ "@rollup/rollup-freebsd-x64": "4.41.1",
1800+ "@rollup/rollup-linux-arm-gnueabihf": "4.41.1",
1801+ "@rollup/rollup-linux-arm-musleabihf": "4.41.1",
1802+ "@rollup/rollup-linux-arm64-gnu": "4.41.1",
1803+ "@rollup/rollup-linux-arm64-musl": "4.41.1",
1804+ "@rollup/rollup-linux-loongarch64-gnu": "4.41.1",
1805+ "@rollup/rollup-linux-powerpc64le-gnu": "4.41.1",
1806+ "@rollup/rollup-linux-riscv64-gnu": "4.41.1",
1807+ "@rollup/rollup-linux-riscv64-musl": "4.41.1",
1808+ "@rollup/rollup-linux-s390x-gnu": "4.41.1",
1809+ "@rollup/rollup-linux-x64-gnu": "4.41.1",
1810+ "@rollup/rollup-linux-x64-musl": "4.41.1",
1811+ "@rollup/rollup-win32-arm64-msvc": "4.41.1",
1812+ "@rollup/rollup-win32-ia32-msvc": "4.41.1",
1813+ "@rollup/rollup-win32-x64-msvc": "4.41.1",
1814+ "fsevents": "~2.3.2"
1815+ }
1816+ },
1817+ "node_modules/scheduler": {
1818+ "version": "0.26.0",
1819+ "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.26.0.tgz",
1820+ "integrity": "sha512-NlHwttCI/l5gCPR3D1nNXtWABUmBwvZpEQiD4IXSbIDq8BzLIK/7Ir5gTFSGZDUu37K5cMNp0hFtzO38sC7gWA==",
1821+ "dev": true,
1822+ "license": "MIT"
1823+ },
1824+ "node_modules/shebang-command": {
1825+ "version": "2.0.0",
1826+ "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
1827+ "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
1828+ "dev": true,
1829+ "license": "MIT",
1830+ "dependencies": {
1831+ "shebang-regex": "^3.0.0"
1832+ },
1833+ "engines": {
1834+ "node": ">=8"
1835+ }
1836+ },
1837+ "node_modules/shebang-regex": {
1838+ "version": "3.0.0",
1839+ "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
1840+ "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
1841+ "dev": true,
1842+ "license": "MIT",
1843+ "engines": {
1844+ "node": ">=8"
1845+ }
1846+ },
1847+ "node_modules/siginfo": {
1848+ "version": "2.0.0",
1849+ "resolved": "https://registry.npmjs.org/siginfo/-/siginfo-2.0.0.tgz",
1850+ "integrity": "sha512-ybx0WO1/8bSBLEWXZvEd7gMW3Sn3JFlW3TvX1nREbDLRNQNaeNN8WK0meBwPdAaOI7TtRRRJn/Es1zhrrCHu7g==",
1851+ "dev": true,
1852+ "license": "ISC"
1853+ },
1854+ "node_modules/signal-exit": {
1855+ "version": "4.1.0",
1856+ "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz",
1857+ "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==",
1858+ "dev": true,
1859+ "license": "ISC",
1860+ "engines": {
1861+ "node": ">=14"
1862+ },
1863+ "funding": {
1864+ "url": "https://github.com/sponsors/isaacs"
1865+ }
1866+ },
1867+ "node_modules/source-map-js": {
1868+ "version": "1.2.1",
1869+ "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz",
1870+ "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==",
1871+ "dev": true,
1872+ "license": "BSD-3-Clause",
1873+ "engines": {
1874+ "node": ">=0.10.0"
1875+ }
1876+ },
1877+ "node_modules/stackback": {
1878+ "version": "0.0.2",
1879+ "resolved": "https://registry.npmjs.org/stackback/-/stackback-0.0.2.tgz",
1880+ "integrity": "sha512-1XMJE5fQo1jGH6Y/7ebnwPOBEkIEnT4QF32d5R1+VXdXveM0IBMJt8zfaxX1P3QhVwrYe+576+jkANtSS2mBbw==",
1881+ "dev": true,
1882+ "license": "MIT"
1883+ },
1884+ "node_modules/std-env": {
1885+ "version": "3.9.0",
1886+ "resolved": "https://registry.npmjs.org/std-env/-/std-env-3.9.0.tgz",
1887+ "integrity": "sha512-UGvjygr6F6tpH7o2qyqR6QYpwraIjKSdtzyBdyytFOHmPZY917kwdwLG0RbOjWOnKmnm3PeHjaoLLMie7kPLQw==",
1888+ "dev": true,
1889+ "license": "MIT"
1890+ },
1891+ "node_modules/strict-event-emitter": {
1892+ "version": "0.5.1",
1893+ "resolved": "https://registry.npmjs.org/strict-event-emitter/-/strict-event-emitter-0.5.1.tgz",
1894+ "integrity": "sha512-vMgjE/GGEPEFnhFub6pa4FmJBRBVOLpIII2hvCZ8Kzb7K0hlHo7mQv6xYrBvCL2LtAIBwFUK8wvuJgTVSQ5MFQ==",
1895+ "dev": true,
1896+ "license": "MIT"
1897+ },
1898+ "node_modules/strip-final-newline": {
1899+ "version": "4.0.0",
1900+ "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-4.0.0.tgz",
1901+ "integrity": "sha512-aulFJcD6YK8V1G7iRB5tigAP4TsHBZZrOV8pjV++zdUwmeV8uzbY7yn6h9MswN62adStNZFuCIx4haBnRuMDaw==",
1902+ "dev": true,
1903+ "license": "MIT",
1904+ "engines": {
1905+ "node": ">=18"
1906+ },
1907+ "funding": {
1908+ "url": "https://github.com/sponsors/sindresorhus"
1909+ }
1910+ },
1911+ "node_modules/tinybench": {
1912+ "version": "2.9.0",
1913+ "resolved": "https://registry.npmjs.org/tinybench/-/tinybench-2.9.0.tgz",
1914+ "integrity": "sha512-0+DUvqWMValLmha6lr4kD8iAMK1HzV0/aKnCtWb9v9641TnP/MFb7Pc2bxoxQjTXAErryXVgUOfv2YqNllqGeg==",
1915+ "dev": true,
1916+ "license": "MIT"
1917+ },
1918+ "node_modules/tinyexec": {
1919+ "version": "0.3.2",
1920+ "resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.2.tgz",
1921+ "integrity": "sha512-KQQR9yN7R5+OSwaK0XQoj22pwHoTlgYqmUscPYoknOoWCWfj/5/ABTMRi69FrKU5ffPVh5QcFikpWJI/P1ocHA==",
1922+ "dev": true,
1923+ "license": "MIT"
1924+ },
1925+ "node_modules/tinyglobby": {
1926+ "version": "0.2.14",
1927+ "resolved": "https://registry.npmjs.org/tinyglobby/-/tinyglobby-0.2.14.tgz",
1928+ "integrity": "sha512-tX5e7OM1HnYr2+a2C/4V0htOcSQcoSTH9KgJnVvNm5zm/cyEWKJ7j7YutsH9CxMdtOkkLFy2AHrMci9IM8IPZQ==",
1929+ "dev": true,
1930+ "license": "MIT",
1931+ "dependencies": {
1932+ "fdir": "^6.4.4",
1933+ "picomatch": "^4.0.2"
1934+ },
1935+ "engines": {
1936+ "node": ">=12.0.0"
1937+ },
1938+ "funding": {
1939+ "url": "https://github.com/sponsors/SuperchupuDev"
1940+ }
1941+ },
1942+ "node_modules/tinypool": {
1943+ "version": "1.1.0",
1944+ "resolved": "https://registry.npmjs.org/tinypool/-/tinypool-1.1.0.tgz",
1945+ "integrity": "sha512-7CotroY9a8DKsKprEy/a14aCCm8jYVmR7aFy4fpkZM8sdpNJbKkixuNjgM50yCmip2ezc8z4N7k3oe2+rfRJCQ==",
1946+ "dev": true,
1947+ "license": "MIT",
1948+ "engines": {
1949+ "node": "^18.0.0 || >=20.0.0"
1950+ }
1951+ },
1952+ "node_modules/tinyrainbow": {
1953+ "version": "2.0.0",
1954+ "resolved": "https://registry.npmjs.org/tinyrainbow/-/tinyrainbow-2.0.0.tgz",
1955+ "integrity": "sha512-op4nsTR47R6p0vMUUoYl/a+ljLFVtlfaXkLQmqfLR1qHma1h/ysYk4hEXZ880bf2CYgTskvTa/e196Vd5dDQXw==",
1956+ "dev": true,
1957+ "license": "MIT",
1958+ "engines": {
1959+ "node": ">=14.0.0"
1960+ }
1961+ },
1962+ "node_modules/tinyspy": {
1963+ "version": "4.0.3",
1964+ "resolved": "https://registry.npmjs.org/tinyspy/-/tinyspy-4.0.3.tgz",
1965+ "integrity": "sha512-t2T/WLB2WRgZ9EpE4jgPJ9w+i66UZfDc8wHh0xrwiRNN+UwH98GIJkTeZqX9rg0i0ptwzqW+uYeIF0T4F8LR7A==",
1966+ "dev": true,
1967+ "license": "MIT",
1968+ "engines": {
1969+ "node": ">=14.0.0"
1970+ }
1971+ },
1972+ "node_modules/tsx": {
1973+ "version": "4.19.4",
1974+ "resolved": "https://registry.npmjs.org/tsx/-/tsx-4.19.4.tgz",
1975+ "integrity": "sha512-gK5GVzDkJK1SI1zwHf32Mqxf2tSJkNx+eYcNly5+nHvWqXUJYUkWBQtKauoESz3ymezAI++ZwT855x5p5eop+Q==",
1976+ "dev": true,
1977+ "license": "MIT",
1978+ "dependencies": {
1979+ "esbuild": "~0.25.0",
1980+ "get-tsconfig": "^4.7.5"
1981+ },
1982+ "bin": {
1983+ "tsx": "dist/cli.mjs"
1984+ },
1985+ "engines": {
1986+ "node": ">=18.0.0"
1987+ },
1988+ "optionalDependencies": {
1989+ "fsevents": "~2.3.3"
1990+ }
1991+ },
1992+ "node_modules/typescript": {
1993+ "version": "5.8.3",
1994+ "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.8.3.tgz",
1995+ "integrity": "sha512-p1diW6TqL9L07nNxvRMM7hMMw4c5XOo/1ibL4aAIGmSAt9slTE1Xgw5KWuof2uTOvCg9BY7ZRi+GaF+7sfgPeQ==",
1996+ "dev": true,
1997+ "license": "Apache-2.0",
1998+ "bin": {
1999+ "tsc": "bin/tsc",
2000+ "tsserver": "bin/tsserver"
2001+ },
2002+ "engines": {
2003+ "node": ">=14.17"
2004+ }
2005+ },
2006+ "node_modules/undici-types": {
2007+ "version": "6.21.0",
2008+ "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-6.21.0.tgz",
2009+ "integrity": "sha512-iwDZqg0QAGrg9Rav5H4n0M64c3mkR59cJ6wQp+7C4nI0gsmExaedaYLNO44eT4AtBBwjbTiGPMlt2Md0T9H9JQ==",
2010+ "dev": true,
2011+ "license": "MIT"
2012+ },
2013+ "node_modules/unicorn-magic": {
2014+ "version": "0.3.0",
2015+ "resolved": "https://registry.npmjs.org/unicorn-magic/-/unicorn-magic-0.3.0.tgz",
2016+ "integrity": "sha512-+QBBXBCvifc56fsbuxZQ6Sic3wqqc3WWaqxs58gvJrcOuN83HGTCwz3oS5phzU9LthRNE9VrJCFCLUgHeeFnfA==",
2017+ "dev": true,
2018+ "license": "MIT",
2019+ "engines": {
2020+ "node": ">=18"
2021+ },
2022+ "funding": {
2023+ "url": "https://github.com/sponsors/sindresorhus"
2024+ }
2025+ },
2026+ "node_modules/use-sync-external-store": {
2027+ "version": "1.5.0",
2028+ "resolved": "https://registry.npmjs.org/use-sync-external-store/-/use-sync-external-store-1.5.0.tgz",
2029+ "integrity": "sha512-Rb46I4cGGVBmjamjphe8L/UnvJD+uPPtTkNvX5mZgqdbavhI4EbgIWJiIHXJ8bc/i9EQGPRh4DwEURJ552Do0A==",
2030+ "license": "MIT",
2031+ "peerDependencies": {
2032+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
2033+ }
2034+ },
2035+ "node_modules/vite": {
2036+ "version": "6.3.5",
2037+ "resolved": "https://registry.npmjs.org/vite/-/vite-6.3.5.tgz",
2038+ "integrity": "sha512-cZn6NDFE7wdTpINgs++ZJ4N49W2vRp8LCKrn3Ob1kYNtOo21vfDoaV5GzBfLU4MovSAB8uNRm4jgzVQZ+mBzPQ==",
2039+ "dev": true,
2040+ "license": "MIT",
2041+ "dependencies": {
2042+ "esbuild": "^0.25.0",
2043+ "fdir": "^6.4.4",
2044+ "picomatch": "^4.0.2",
2045+ "postcss": "^8.5.3",
2046+ "rollup": "^4.34.9",
2047+ "tinyglobby": "^0.2.13"
2048+ },
2049+ "bin": {
2050+ "vite": "bin/vite.js"
2051+ },
2052+ "engines": {
2053+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
2054+ },
2055+ "funding": {
2056+ "url": "https://github.com/vitejs/vite?sponsor=1"
2057+ },
2058+ "optionalDependencies": {
2059+ "fsevents": "~2.3.3"
2060+ },
2061+ "peerDependencies": {
2062+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
2063+ "jiti": ">=1.21.0",
2064+ "less": "*",
2065+ "lightningcss": "^1.21.0",
2066+ "sass": "*",
2067+ "sass-embedded": "*",
2068+ "stylus": "*",
2069+ "sugarss": "*",
2070+ "terser": "^5.16.0",
2071+ "tsx": "^4.8.1",
2072+ "yaml": "^2.4.2"
2073+ },
2074+ "peerDependenciesMeta": {
2075+ "@types/node": {
2076+ "optional": true
2077+ },
2078+ "jiti": {
2079+ "optional": true
2080+ },
2081+ "less": {
2082+ "optional": true
2083+ },
2084+ "lightningcss": {
2085+ "optional": true
2086+ },
2087+ "sass": {
2088+ "optional": true
2089+ },
2090+ "sass-embedded": {
2091+ "optional": true
2092+ },
2093+ "stylus": {
2094+ "optional": true
2095+ },
2096+ "sugarss": {
2097+ "optional": true
2098+ },
2099+ "terser": {
2100+ "optional": true
2101+ },
2102+ "tsx": {
2103+ "optional": true
2104+ },
2105+ "yaml": {
2106+ "optional": true
2107+ }
2108+ }
2109+ },
2110+ "node_modules/vite-node": {
2111+ "version": "3.2.0",
2112+ "resolved": "https://registry.npmjs.org/vite-node/-/vite-node-3.2.0.tgz",
2113+ "integrity": "sha512-8Fc5Ko5Y4URIJkmMF/iFP1C0/OJyY+VGVe9Nw6WAdZyw4bTO+eVg9mwxWkQp/y8NnAoQY3o9KAvE1ZdA2v+Vmg==",
2114+ "dev": true,
2115+ "license": "MIT",
2116+ "dependencies": {
2117+ "cac": "^6.7.14",
2118+ "debug": "^4.4.1",
2119+ "es-module-lexer": "^1.7.0",
2120+ "pathe": "^2.0.3",
2121+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0"
2122+ },
2123+ "bin": {
2124+ "vite-node": "vite-node.mjs"
2125+ },
2126+ "engines": {
2127+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
2128+ },
2129+ "funding": {
2130+ "url": "https://opencollective.com/vitest"
2131+ }
2132+ },
2133+ "node_modules/vitest": {
2134+ "version": "3.2.0",
2135+ "resolved": "https://registry.npmjs.org/vitest/-/vitest-3.2.0.tgz",
2136+ "integrity": "sha512-P7Nvwuli8WBNmeMHHek7PnGW4oAZl9za1fddfRVidZar8wDZRi7hpznLKQePQ8JPLwSBEYDK11g+++j7uFJV8Q==",
2137+ "dev": true,
2138+ "license": "MIT",
2139+ "dependencies": {
2140+ "@types/chai": "^5.2.2",
2141+ "@vitest/expect": "3.2.0",
2142+ "@vitest/mocker": "3.2.0",
2143+ "@vitest/pretty-format": "^3.2.0",
2144+ "@vitest/runner": "3.2.0",
2145+ "@vitest/snapshot": "3.2.0",
2146+ "@vitest/spy": "3.2.0",
2147+ "@vitest/utils": "3.2.0",
2148+ "chai": "^5.2.0",
2149+ "debug": "^4.4.1",
2150+ "expect-type": "^1.2.1",
2151+ "magic-string": "^0.30.17",
2152+ "pathe": "^2.0.3",
2153+ "picomatch": "^4.0.2",
2154+ "std-env": "^3.9.0",
2155+ "tinybench": "^2.9.0",
2156+ "tinyexec": "^0.3.2",
2157+ "tinyglobby": "^0.2.14",
2158+ "tinypool": "^1.1.0",
2159+ "tinyrainbow": "^2.0.0",
2160+ "vite": "^5.0.0 || ^6.0.0 || ^7.0.0-0",
2161+ "vite-node": "3.2.0",
2162+ "why-is-node-running": "^2.3.0"
2163+ },
2164+ "bin": {
2165+ "vitest": "vitest.mjs"
2166+ },
2167+ "engines": {
2168+ "node": "^18.0.0 || ^20.0.0 || >=22.0.0"
2169+ },
2170+ "funding": {
2171+ "url": "https://opencollective.com/vitest"
2172+ },
2173+ "peerDependencies": {
2174+ "@edge-runtime/vm": "*",
2175+ "@types/debug": "^4.1.12",
2176+ "@types/node": "^18.0.0 || ^20.0.0 || >=22.0.0",
2177+ "@vitest/browser": "3.2.0",
2178+ "@vitest/ui": "3.2.0",
2179+ "happy-dom": "*",
2180+ "jsdom": "*"
2181+ },
2182+ "peerDependenciesMeta": {
2183+ "@edge-runtime/vm": {
2184+ "optional": true
2185+ },
2186+ "@types/debug": {
2187+ "optional": true
2188+ },
2189+ "@types/node": {
2190+ "optional": true
2191+ },
2192+ "@vitest/browser": {
2193+ "optional": true
2194+ },
2195+ "@vitest/ui": {
2196+ "optional": true
2197+ },
2198+ "happy-dom": {
2199+ "optional": true
2200+ },
2201+ "jsdom": {
2202+ "optional": true
2203+ }
2204+ }
2205+ },
2206+ "node_modules/which": {
2207+ "version": "2.0.2",
2208+ "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
2209+ "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
2210+ "dev": true,
2211+ "license": "ISC",
2212+ "dependencies": {
2213+ "isexe": "^2.0.0"
2214+ },
2215+ "bin": {
2216+ "node-which": "bin/node-which"
2217+ },
2218+ "engines": {
2219+ "node": ">= 8"
2220+ }
2221+ },
2222+ "node_modules/why-is-node-running": {
2223+ "version": "2.3.0",
2224+ "resolved": "https://registry.npmjs.org/why-is-node-running/-/why-is-node-running-2.3.0.tgz",
2225+ "integrity": "sha512-hUrmaWBdVDcxvYqnyh09zunKzROWjbZTiNy8dBEjkS7ehEDQibXJ7XvlmtbwuTclUiIyN+CyXQD4Vmko8fNm8w==",
2226+ "dev": true,
2227+ "license": "MIT",
2228+ "dependencies": {
2229+ "siginfo": "^2.0.0",
2230+ "stackback": "0.0.2"
2231+ },
2232+ "bin": {
2233+ "why-is-node-running": "cli.js"
2234+ },
2235+ "engines": {
2236+ "node": ">=8"
2237+ }
2238+ },
2239+ "node_modules/yoctocolors": {
2240+ "version": "2.1.1",
2241+ "resolved": "https://registry.npmjs.org/yoctocolors/-/yoctocolors-2.1.1.tgz",
2242+ "integrity": "sha512-GQHQqAopRhwU8Kt1DDM8NjibDXHC8eoh1erhGAJPEyveY9qqVeXvVikNKrDz69sHowPMorbPUrH/mx8c50eiBQ==",
2243+ "dev": true,
2244+ "license": "MIT",
2245+ "engines": {
2246+ "node": ">=18"
2247+ },
2248+ "funding": {
2249+ "url": "https://github.com/sponsors/sindresorhus"
2250+ }
2251+ }
2252+ }
2253+}
+75,
-0
1@@ -0,0 +1,75 @@
2+{
3+ "name": "starfx",
4+ "version": "0.14.0",
5+ "description": "A micro-mvc framework for react apps",
6+ "type": "module",
7+ "files": ["/dist"],
8+ "sideEffects": false,
9+ "main": "./dist/cjs/index.js",
10+ "types": "./dist/types/index.d.ts",
11+ "module": "./dist/esm/index.js",
12+ "scripts": {
13+ "test": "vitest --exclude examples",
14+ "lint": "npx @biomejs/biome check --write",
15+ "fmt": "npx @biomejs/biome check --write --linter-enabled=false",
16+ "ci": "npx @biomejs/biome ci .",
17+ "template": "tsx ./api-type-template.mts",
18+ "build": "tsx ./build.mts"
19+ },
20+ "repository": {
21+ "type": "git",
22+ "url": "git+https://github.com/neurosnap/starfx.git"
23+ },
24+ "author": "Eric Bower",
25+ "license": "MIT",
26+ "bugs": {
27+ "url": "https://github.com/neurosnap/starfx/issues"
28+ },
29+ "homepage": "https://github.com/neurosnap/starfx#readme",
30+ "dependencies": {
31+ "effection": "^3.5.0",
32+ "immer": "^10.1.1",
33+ "react-redux": "^9.2.0",
34+ "reselect": "^5.1.1"
35+ },
36+ "devDependencies": {
37+ "@biomejs/biome": "^1.9.4",
38+ "@types/node": "^22.15.29",
39+ "@types/react": "^19.1.6",
40+ "@types/react-dom": "^19.1.5",
41+ "execa": "^9.6.0",
42+ "nock": "^14.0.5",
43+ "react": "^19.1.0",
44+ "react-dom": "^19.1.0",
45+ "tsx": "^4.19.4",
46+ "typescript": "^5.8.3",
47+ "vitest": "^3.2.0"
48+ },
49+ "peerDependencies": {
50+ "react": ">=18",
51+ "react-dom": ">=18"
52+ },
53+ "exports": {
54+ ".": {
55+ "import": {
56+ "types": "./dist/types/index.d.ts",
57+ "default": "./dist/esm/index.js"
58+ },
59+ "require": {
60+ "types": "./dist/types/index.d.ts",
61+ "default": "./dist/cjs/index.js"
62+ }
63+ },
64+ "./react": {
65+ "import": {
66+ "types": "./dist/types/index.d.ts",
67+ "default": "./dist/esm/react.js"
68+ },
69+ "require": {
70+ "types": "./dist/types/index.d.ts",
71+ "default": "./dist/cjs/react.js"
72+ }
73+ },
74+ "./package.json": "./package.json"
75+ }
76+}
+0,
-12
1@@ -1,12 +0,0 @@
2-import { createThunks, type ThunksApi } from "./thunk.ts";
3-
4-export * from "./api.ts";
5-export * from "./types.ts";
6-export * from "./create-key.ts";
7-
8-export { createThunks, ThunksApi };
9-
10-/**
11- * @deprecated Use {@link createThunks} instead;
12- */
13-export const createPipe = createThunks;
+0,
-52
1@@ -1,52 +0,0 @@
2-import { call, main, type Operation } from "effection";
3-
4-await main(function* (): Operation<void> {
5- // based on env created from ${{ secrets.GITHUB_TOKEN }} in CI
6- const token = Deno.env.get("GITHUB_TOKEN");
7- const [branch, ownerRepo] = Deno.args;
8- console.dir({ branch, ownerRepo });
9-
10- const response = yield* call(
11- fetch(`https://api.github.com/repos/${ownerRepo}/branches`, {
12- headers: {
13- Accept: "application/vnd.github+json",
14- "X-GitHub-Api-Version": "2022-11-28",
15- // the token isn't required but helps with rate limiting
16- ...(token ? { Authorization: `Bearer ${token}` } : {}),
17- },
18- }),
19- );
20-
21- if (response.ok) {
22- const branches = yield* call(response.json());
23- const branchList = branches.map((branch: { name: string }) => branch.name);
24- // for CI debug purposes
25- console.dir({ branchList });
26- // GitHub Actions maintains the step output through a file which you append keys into
27- // the path that file is available as an env var
28- if (Deno.env.get("CI")) {
29- const output = Deno.env.get("GITHUB_OUTPUT");
30- if (!output) throw new Error("$GITHUB_OUTPUT is not set");
31- const encoder = new TextEncoder();
32- if (branchList.includes(branch)) {
33- const data = encoder.encode(`branch=${branch}`);
34- yield* call(Deno.writeFile(output, data, { append: true }));
35- } else {
36- const data = encoder.encode("branch=main");
37- yield* call(Deno.writeFile(output, data, { append: true }));
38- }
39- }
40- // always log out the branch for both CI and local running
41- if (branchList.includes(branch)) {
42- console.log(`branch=${branch}`);
43- } else {
44- console.log(`branch=main`);
45- }
46- } else {
47- console.error(
48- `Error trying to fetch https://api.github.com/repos/${ownerRepo}/branches and check for ${branch}`,
49- );
50- const text = yield* call(response.text());
51- throw new Error(text);
52- }
53-});
+0,
-72
1@@ -1,72 +0,0 @@
2-import { build, emptyDir } from "jsr:@deno/dnt@0.41.3";
3-
4-const [version] = Deno.args;
5-if (!version) {
6- throw new Error("a version argument is required to build the npm package");
7-}
8-
9-init().then(console.log).catch(console.error);
10-
11-async function init() {
12- await emptyDir("./npm");
13- await build({
14- declaration: "inline",
15- scriptModule: "cjs",
16- entryPoints: [
17- {
18- name: ".",
19- path: "mod.ts",
20- },
21- {
22- name: "./react",
23- path: "react.ts",
24- },
25- ],
26- mappings: {
27- // use the deno module in this repo, but use the npm module when publishing
28- "https://deno.land/x/effection@3.0.0-beta.3/mod.ts": {
29- name: "effection",
30- version: "3.0.0-beta.3",
31- },
32- },
33- importMap: "deno.json",
34- outDir: "./npm",
35- shims: {
36- deno: false,
37- },
38- test: false,
39-
40- typeCheck: "both",
41- compilerOptions: {
42- target: "ES2020",
43- sourceMap: true,
44- lib: ["DOM", "DOM.Iterable", "ESNext"],
45- },
46- package: {
47- name: "starfx",
48- version,
49- description:
50- "Async flow control and state management system for deno, node, and browser",
51- license: "MIT",
52- author: {
53- name: "Eric Bower",
54- email: "me@erock.io",
55- },
56- repository: {
57- type: "git",
58- url: "git+https://github.com/neurosnap/starfx.git",
59- },
60- bugs: {
61- url: "https://github.com/neurosnap/starfx/issues",
62- },
63- engines: {
64- node: ">= 18",
65- },
66- sideEffects: false,
67- },
68- postBuild() {
69- Deno.copyFileSync("LICENSE.md", "npm/LICENSE.md");
70- Deno.copyFileSync("README.md", "npm/README.md");
71- },
72- });
73-}
+0,
-30
1@@ -1,30 +0,0 @@
2-import { call, main, type Operation } from "effection";
3-
4-await main(function* (): Operation<void> {
5- const [syncMethod, folderFromArgs] = Deno.args;
6- const folder = folderFromArgs ?? "starfx-examples/vite-react";
7- const dir = `../${folder}/node_modules/starfx`;
8- const npmAssets = yield* call(Deno.realPath("./npm"));
9-
10- if (syncMethod === "install") {
11- // parcel doesn't handle symlinks well, do a `file:` install instead
12- const command = new Deno.Command("npm", {
13- args: ["add", "starfx@file:../../starfx/npm", "--install-links"],
14- cwd: `../${folder}`,
15- stderr: "piped",
16- stdout: "piped",
17- });
18- yield* call(command.output());
19- } else if (syncMethod === "symlink") {
20- // this option is primarily for local usage
21- try {
22- yield* call(Deno.remove(dir, { recursive: true }));
23- } catch (_error) {
24- // assume that the folder does not exist
25- }
26-
27- // create a symlink to the `dir` which should allow
28- // this example to run with the build assets
29- yield* call(Deno.symlink(npmAssets, dir));
30- }
31-});
R action.ts =>
src/action.ts
+14,
-14
1@@ -1,19 +1,19 @@
2 import {
3+ type Callable,
4+ type Operation,
5+ type Signal,
6+ SignalQueueFactory,
7+ type Stream,
8 call,
9- Callable,
10 createContext,
11 createSignal,
12 each,
13- Operation,
14- Signal,
15- SignalQueueFactory,
16 spawn,
17- Stream,
18 } from "effection";
19-import { ActionPattern, matcher } from "./matcher.ts";
20-import type { Action, ActionWithPayload, AnyAction } from "./types.ts";
21-import { createFilterQueue } from "./queue.ts";
22-import { ActionFnWithPayload } from "./types.ts";
23+import { type ActionPattern, matcher } from "./matcher.js";
24+import { createFilterQueue } from "./queue.js";
25+import type { Action, ActionWithPayload, AnyAction } from "./types.js";
26+import type { ActionFnWithPayload } from "./types.js";
27
28 export const ActionContext = createContext(
29 "starfx:action",
30@@ -22,11 +22,11 @@ export const ActionContext = createContext(
31
32 export function useActions(pattern: ActionPattern): Stream<AnyAction, void> {
33 return {
34- *subscribe() {
35- const actions = yield* ActionContext;
36+ [Symbol.iterator]: function* () {
37+ const actions = yield* ActionContext.expect();
38 const match = matcher(pattern);
39 yield* SignalQueueFactory.set(() => createFilterQueue(match) as any);
40- return yield* actions.subscribe();
41+ return yield* actions;
42 },
43 };
44 }
45@@ -49,7 +49,7 @@ export function emit({
46 }
47
48 export function* put(action: AnyAction | AnyAction[]) {
49- const signal = yield* ActionContext;
50+ const signal = yield* ActionContext.expect();
51 return emit({
52 signal,
53 action,
54@@ -113,7 +113,7 @@ export function* waitFor(predicate: Callable<boolean>) {
55
56 while (true) {
57 yield* take("*");
58- const result = yield* call(() => predicate as any);
59+ const result = yield* call(predicate as any);
60 if (result) {
61 return;
62 }
R compose.ts =>
src/compose.ts
+2,
-2
1@@ -1,5 +1,5 @@
2-import { Instruction, Operation } from "effection";
3-import type { Next } from "./types.ts";
4+import type { Instruction, Operation } from "effection";
5+import type { Next } from "./types.js";
6
7 export interface BaseCtx {
8 // deno-lint-ignore no-explicit-any
+5,
-0
1@@ -0,0 +1,5 @@
2+export * from "./parallel.js";
3+export * from "./safe.js";
4+export * from "./race.js";
5+export * from "./request.js";
6+export * from "./supervisor.js";
R fx/parallel.ts =>
src/fx/parallel.ts
+2,
-2
1@@ -1,7 +1,7 @@
2 import type { Callable, Channel, Operation, Result } from "effection";
3 import { createChannel, resource, spawn } from "effection";
4-import type { Computation } from "../types.ts";
5-import { safe } from "./safe.ts";
6+import type { Computation } from "../types.js";
7+import { safe } from "./safe.js";
8
9 export interface ParallelRet<T> extends Computation<Result<T>[]> {
10 sequence: Channel<Result<T>, void>;
R fx/race.ts =>
src/fx/race.ts
+5,
-7
1@@ -5,13 +5,11 @@ interface OpMap<T = unknown> {
2 [key: string]: Callable<T>;
3 }
4
5-export function raceMap<T>(opMap: OpMap): Operation<
6- {
7- [K in keyof OpMap<T>]: OpMap[K] extends (...args: any[]) => any
8- ? ReturnType<OpMap[K]>
9- : OpMap[K];
10- }
11-> {
12+export function raceMap<T>(opMap: OpMap): Operation<{
13+ [K in keyof OpMap<T>]: OpMap[K] extends (...args: any[]) => any
14+ ? ReturnType<OpMap[K]>
15+ : OpMap[K];
16+}> {
17 return resource(function* Race(provide) {
18 const keys = Object.keys(opMap);
19 const taskMap: { [key: string]: Task<unknown> } = {};
R fx/request.ts =>
src/fx/request.ts
+0,
-0
R fx/safe.ts =>
src/fx/safe.ts
+1,
-1
1@@ -1,5 +1,5 @@
2 import type { Callable, Operation, Result } from "effection";
3-import { call, Err, Ok } from "effection";
4+import { Err, Ok, call } from "effection";
5
6 /**
7 * The goal of `safe` is to wrap Operations to prevent them from raising
R fx/supervisor.ts =>
src/fx/supervisor.ts
+4,
-5
1@@ -1,8 +1,8 @@
2 import { type Callable, type Operation, sleep } from "effection";
3-import { safe } from "./safe.ts";
4-import { parallel } from "./parallel.ts";
5-import { API_ACTION_PREFIX, put } from "../action.ts";
6 import type { Result } from "effection"; // Adjust the import path as needed
7+import { API_ACTION_PREFIX, put } from "../action.js";
8+import { parallel } from "./parallel.js";
9+import { safe } from "./safe.js";
10
11 export function superviseBackoff(attempt: number, max = 10): number {
12 if (attempt > max) return -1;
13@@ -34,8 +34,7 @@ export function supervise<T>(
14 yield* put({
15 type: `${API_ACTION_PREFIX}supervise`,
16 payload: res.error,
17- meta:
18- `Exception caught, waiting ${waitFor}ms before restarting operation`,
19+ meta: `Exception caught, waiting ${waitFor}ms before restarting operation`,
20 });
21 yield* sleep(waitFor);
22 }
R mod.ts =>
src/index.ts
+8,
-8
1@@ -1,12 +1,12 @@
2-export * from "./fx/mod.ts";
3-export * from "./query/mod.ts";
4-export * from "./store/mod.ts";
5-export * from "./mdw/mod.ts";
6+export * from "./fx/index.js";
7+export * from "./query/index.js";
8+export * from "./store/index.js";
9+export * from "./mdw/index.js";
10
11-export * from "./types.ts";
12-export * from "./compose.ts";
13-export * from "./action.ts";
14-export * from "./supervisor.ts";
15+export * from "./types.js";
16+export * from "./compose.js";
17+export * from "./action.js";
18+export * from "./supervisor.js";
19 export {
20 action,
21 call,
R matcher.ts =>
src/matcher.ts
+17,
-17
1@@ -1,4 +1,4 @@
2-import type { AnyAction } from "./types.ts";
3+import type { AnyAction } from "./types.js";
4
5 type ActionType = string;
6 type GuardPredicate<G extends T, T = unknown> = (arg: T) => arg is G;
7@@ -23,35 +23,35 @@ export type ActionPattern<Guard extends AnyAction = AnyAction> =
8 | ActionSubPattern<Guard>
9 | ActionSubPattern<Guard>[];
10
11+function isThunk(fn: any): boolean {
12+ return (
13+ typeof fn === "function" &&
14+ typeof fn.run === "function" &&
15+ typeof fn.name === "string" &&
16+ typeof fn.key === "string" &&
17+ typeof fn.toString === "function"
18+ );
19+}
20 export function matcher(pattern: ActionPattern): Predicate {
21 if (pattern === "*") {
22- return function (input) {
23- return !!input;
24- };
25+ return (input) => !!input;
26 }
27
28 if (typeof pattern === "string") {
29- return function (input) {
30- return pattern === input.type;
31- };
32+ return (input) => pattern === input.type;
33 }
34
35 if (Array.isArray(pattern)) {
36- return function (input) {
37- return pattern.some((p) => matcher(p)(input));
38- };
39+ return (input) => pattern.some((p) => matcher(p)(input));
40 }
41
42- if (typeof pattern === "function" && Object.hasOwn(pattern, "toString")) {
43- return function (input) {
44- return pattern.toString() === input.type;
45- };
46+ // detects thunk action creators
47+ if (isThunk(pattern)) {
48+ return (input) => pattern.toString() === input.type;
49 }
50
51 if (typeof pattern === "function") {
52- return function (input) {
53- return pattern(input) as boolean;
54- };
55+ return (input) => pattern(input) as boolean;
56 }
57
58 throw new Error("invalid pattern");
R mdw/fetch.ts =>
src/mdw/fetch.ts
+7,
-8
1@@ -1,8 +1,8 @@
2 import { sleep } from "effection";
3-import { safe } from "../fx/mod.ts";
4-import type { FetchCtx, FetchJsonCtx } from "../query/mod.ts";
5-import { isObject, noop } from "../query/util.ts";
6-import type { Next } from "../types.ts";
7+import { safe } from "../fx/index.js";
8+import type { FetchCtx, FetchJsonCtx } from "../query/index.js";
9+import { isObject, noop } from "../query/util.js";
10+import type { Next } from "../types.js";
11
12 /**
13 * This middleware converts the name provided to {@link createApi}
14@@ -36,7 +36,7 @@ export function* nameParser<Ctx extends FetchJsonCtx = FetchJsonCtx>(
15
16 let method = "";
17 httpMethods.forEach((curMethod) => {
18- const pattern = new RegExp(`\\s*\\[` + curMethod + `\\]\\s*\\w*`, "i");
19+ const pattern = new RegExp(`\\s*\\[${curMethod}\\]\\s*\\w*`, "i");
20 const tmpUrl = url.replace(pattern, "");
21 if (tmpUrl.length !== url.length) {
22 method = curMethod.toLocaleUpperCase();
23@@ -69,7 +69,7 @@ export function* headers<CurCtx extends FetchCtx = FetchCtx>(
24 }
25
26 const cur = ctx.req();
27- if (!Object.hasOwn(cur.headers, "Content-Type")) {
28+ if (!(cur as any).headers["Content-Type"]) {
29 ctx.request = ctx.req({
30 headers: { "Content-Type": "application/json" },
31 });
32@@ -182,8 +182,7 @@ export function* payload<CurCtx extends FetchJsonCtx = FetchJsonCtx>(
33
34 const val = payload[key];
35 if (!val) {
36- const data =
37- `found :${key} in endpoint name (${ctx.name}) but payload has falsy value (${val})`;
38+ const data = `found :${key} in endpoint name (${ctx.name}) but payload has falsy value (${val})`;
39 ctx.json = {
40 ok: false,
41 error: data,
+4,
-0
1@@ -0,0 +1,4 @@
2+import * as queryMdw from "./query.js";
3+import * as storeMdw from "./store.js";
4+
5+export const mdw = { ...queryMdw, ...storeMdw };
R mdw/query.ts =>
src/mdw/query.ts
+11,
-12
1@@ -1,7 +1,7 @@
2-import { call, type Callable } from "effection";
3-import { safe } from "../fx/mod.ts";
4-import { compose } from "../compose.ts";
5-import { put } from "../action.ts";
6+import { type Callable, call } from "effection";
7+import { put } from "../action.js";
8+import { compose } from "../compose.js";
9+import { safe } from "../fx/index.js";
10 import type {
11 ApiCtx,
12 ApiRequest,
13@@ -10,11 +10,11 @@ import type {
14 PerfCtx,
15 RequiredApiRequest,
16 ThunkCtx,
17-} from "../query/types.ts";
18-import type { AnyAction, Next } from "../types.ts";
19-import { mergeRequest } from "../query/util.ts";
20-import * as fetchMdw from "./fetch.ts";
21-export * from "./fetch.ts";
22+} from "../query/types.js";
23+import { mergeRequest } from "../query/util.js";
24+import type { AnyAction, Next } from "../types.js";
25+import * as fetchMdw from "./fetch.js";
26+export * from "./fetch.js";
27
28 /**
29 * This middleware will catch any errors in the pipeline
30@@ -30,8 +30,7 @@ export * from "./fetch.ts";
31 export function* err<Ctx extends ThunkCtx = ThunkCtx>(ctx: Ctx, next: Next) {
32 ctx.result = yield* safe(next);
33 if (!ctx.result.ok) {
34- const message =
35- `Error: ${ctx.result.error.message}. Check the endpoint [${ctx.name}]`;
36+ const message = `Error: ${ctx.result.error.message}. Check the endpoint [${ctx.name}]`;
37 console.error(message, ctx);
38 yield* put({
39 type: "error:query",
40@@ -68,7 +67,7 @@ export function* customKey<Ctx extends ThunkCtx = ThunkCtx>(
41 ctx?.action?.payload?.key &&
42 ctx.key !== ctx.action.payload.key
43 ) {
44- const newKey = ctx.name.split("|")[0] + "|" + ctx.key;
45+ const newKey = `${ctx.name.split("|")[0]}|${ctx.key}`;
46 ctx.key = newKey;
47 ctx.action.payload.key = newKey;
48 }
R mdw/store.ts =>
src/mdw/store.ts
+10,
-10
1@@ -1,14 +1,14 @@
2-import type { ApiCtx, ThunkCtxWLoader } from "../query/mod.ts";
3-import { compose } from "../compose.ts";
4-import type { AnyState, Next } from "../types.ts";
5+import { compose } from "../compose.js";
6+import type { ApiCtx, ThunkCtxWLoader } from "../query/index.js";
7 import {
8- LoaderOutput,
9+ type LoaderOutput,
10+ type TableOutput,
11 select,
12- TableOutput,
13 updateStore,
14-} from "../store/mod.ts";
15-import { actions, customKey, err, queryCtx } from "./query.ts";
16-import { nameParser } from "./fetch.ts";
17+} from "../store/index.js";
18+import type { AnyState, Next } from "../types.js";
19+import { nameParser } from "./fetch.js";
20+import { actions, customKey, err, queryCtx } from "./query.js";
21
22 export interface ApiMdwProps<
23 Ctx extends ApiCtx = ApiCtx,
24@@ -128,7 +128,7 @@ export function loader<M extends AnyState = AnyState>(schema: {
25 ]);
26 } finally {
27 const loaders = yield* select((s: any) =>
28- schema.loaders.selectByIds(s, { ids: [ctx.name, ctx.key] })
29+ schema.loaders.selectByIds(s, { ids: [ctx.name, ctx.key] }),
30 );
31 const ids = loaders
32 .filter((loader) => loader.status === "loading")
33@@ -209,7 +209,7 @@ export function loaderApi<
34 ]);
35 } finally {
36 const loaders = yield* select((s: any) =>
37- schema.loaders.selectByIds(s, { ids: [ctx.name, ctx.key] })
38+ schema.loaders.selectByIds(s, { ids: [ctx.name, ctx.key] }),
39 );
40 const ids = loaders
41 .filter((loader) => loader.status === "loading")
R query/api-types.ts =>
src/query/api-types.ts
+1021,
-1012
1@@ -1,9 +1,10 @@
2+import type { Operation } from "effection";
3+import type { Next, Payload } from "../types.js";
4 /**
5 * This is an auto-generated file, do not edit directly!
6 * Run "yarn template" to generate this file.
7 */
8-import type { Operation } from "effection";
9-import type { ThunksApi } from "./thunk.ts";
10+import type { ThunksApi } from "./thunk.js";
11 import type {
12 ApiCtx,
13 CreateAction,
14@@ -11,8 +12,7 @@ import type {
15 FetchJson,
16 MiddlewareApiCo,
17 Supervisor,
18-} from "./types.ts";
19-import type { Next, Payload } from "../types.ts";
20+} from "./types.js";
21
22 export type ApiName = string | string[];
23
24@@ -27,28 +27,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
25 * Options only
26 */
27 get(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
28- get<P>(req: {
29- supervisor?: Supervisor;
30- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
31+ get<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
32+ Omit<Ctx, "payload"> & Payload<P>,
33+ P
34+ >;
35 get<P extends never, ApiSuccess, ApiError = unknown>(req: {
36 supervisor?: Supervisor;
37 }): CreateAction<
38- & Omit<Ctx, "json">
39- & FetchJson<
40- ApiSuccess,
41- ApiError extends unknown ? Ctx["_error"] : ApiError
42- >,
43+ Omit<Ctx, "json"> &
44+ FetchJson<
45+ ApiSuccess,
46+ ApiError extends unknown ? Ctx["_error"] : ApiError
47+ >,
48 ApiSuccess
49 >;
50 get<P, ApiSuccess, ApiError = unknown>(req: {
51 supervisor?: Supervisor;
52 }): CreateActionWithPayload<
53- & Omit<Ctx, "payload" | "json">
54- & Payload<P>
55- & FetchJson<
56- ApiSuccess,
57- ApiError extends unknown ? Ctx["_error"] : ApiError
58- >,
59+ Omit<Ctx, "payload" | "json"> &
60+ Payload<P> &
61+ FetchJson<
62+ ApiSuccess,
63+ ApiError extends unknown ? Ctx["_error"] : ApiError
64+ >,
65 P,
66 ApiSuccess
67 >;
68@@ -66,29 +67,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
69 ): CreateActionWithPayload<Gtx, P>;
70 get<P extends never, ApiSuccess, ApiError = unknown>(
71 fn: MiddlewareApiCo<
72- & Omit<Ctx, "json">
73- & FetchJson<
74- ApiSuccess,
75- ApiError extends unknown ? Ctx["_error"] : ApiError
76- >
77+ Omit<Ctx, "json"> &
78+ FetchJson<
79+ ApiSuccess,
80+ ApiError extends unknown ? Ctx["_error"] : ApiError
81+ >
82 >,
83 ): CreateAction<
84- & Omit<Ctx, "json">
85- & FetchJson<
86- ApiSuccess,
87- ApiError extends unknown ? Ctx["_error"] : ApiError
88- >,
89+ Omit<Ctx, "json"> &
90+ FetchJson<
91+ ApiSuccess,
92+ ApiError extends unknown ? Ctx["_error"] : ApiError
93+ >,
94 ApiSuccess
95 >;
96 get<P, ApiSuccess, ApiError = unknown>(
97 fn: MiddlewareApiCo<Ctx>,
98 ): CreateActionWithPayload<
99- & Omit<Ctx, "payload" | "json">
100- & Payload<P>
101- & FetchJson<
102- ApiSuccess,
103- ApiError extends unknown ? Ctx["_error"] : ApiError
104- >,
105+ Omit<Ctx, "payload" | "json"> &
106+ Payload<P> &
107+ FetchJson<
108+ ApiSuccess,
109+ ApiError extends unknown ? Ctx["_error"] : ApiError
110+ >,
111 P,
112 ApiSuccess
113 >;
114@@ -115,30 +116,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
115 get<P extends never, ApiSuccess, ApiError = unknown>(
116 req: { supervisor?: Supervisor },
117 fn: MiddlewareApiCo<
118- & Omit<Ctx, "json">
119- & FetchJson<
120- ApiSuccess,
121- ApiError extends unknown ? Ctx["_error"] : ApiError
122- >
123+ Omit<Ctx, "json"> &
124+ FetchJson<
125+ ApiSuccess,
126+ ApiError extends unknown ? Ctx["_error"] : ApiError
127+ >
128 >,
129 ): CreateAction<
130- & Omit<Ctx, "json">
131- & FetchJson<
132- ApiSuccess,
133- ApiError extends unknown ? Ctx["_error"] : ApiError
134- >,
135+ Omit<Ctx, "json"> &
136+ FetchJson<
137+ ApiSuccess,
138+ ApiError extends unknown ? Ctx["_error"] : ApiError
139+ >,
140 ApiSuccess
141 >;
142 get<P, ApiSuccess, ApiError = unknown>(
143 req: { supervisor?: Supervisor },
144 fn: MiddlewareApiCo<Ctx>,
145 ): CreateActionWithPayload<
146- & Omit<Ctx, "payload" | "json">
147- & Payload<P>
148- & FetchJson<
149- ApiSuccess,
150- ApiError extends unknown ? Ctx["_error"] : ApiError
151- >,
152+ Omit<Ctx, "payload" | "json"> &
153+ Payload<P> &
154+ FetchJson<
155+ ApiSuccess,
156+ ApiError extends unknown ? Ctx["_error"] : ApiError
157+ >,
158 P,
159 ApiSuccess
160 >;
161@@ -147,28 +148,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
162 * Options only
163 */
164 post(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
165- post<P>(req: {
166- supervisor?: Supervisor;
167- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
168+ post<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
169+ Omit<Ctx, "payload"> & Payload<P>,
170+ P
171+ >;
172 post<P extends never, ApiSuccess, ApiError = unknown>(req: {
173 supervisor?: Supervisor;
174 }): CreateAction<
175- & Omit<Ctx, "json">
176- & FetchJson<
177- ApiSuccess,
178- ApiError extends unknown ? Ctx["_error"] : ApiError
179- >,
180+ Omit<Ctx, "json"> &
181+ FetchJson<
182+ ApiSuccess,
183+ ApiError extends unknown ? Ctx["_error"] : ApiError
184+ >,
185 ApiSuccess
186 >;
187 post<P, ApiSuccess, ApiError = unknown>(req: {
188 supervisor?: Supervisor;
189 }): CreateActionWithPayload<
190- & Omit<Ctx, "payload" | "json">
191- & Payload<P>
192- & FetchJson<
193- ApiSuccess,
194- ApiError extends unknown ? Ctx["_error"] : ApiError
195- >,
196+ Omit<Ctx, "payload" | "json"> &
197+ Payload<P> &
198+ FetchJson<
199+ ApiSuccess,
200+ ApiError extends unknown ? Ctx["_error"] : ApiError
201+ >,
202 P,
203 ApiSuccess
204 >;
205@@ -186,29 +188,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
206 ): CreateActionWithPayload<Gtx, P>;
207 post<P extends never, ApiSuccess, ApiError = unknown>(
208 fn: MiddlewareApiCo<
209- & Omit<Ctx, "json">
210- & FetchJson<
211- ApiSuccess,
212- ApiError extends unknown ? Ctx["_error"] : ApiError
213- >
214+ Omit<Ctx, "json"> &
215+ FetchJson<
216+ ApiSuccess,
217+ ApiError extends unknown ? Ctx["_error"] : ApiError
218+ >
219 >,
220 ): CreateAction<
221- & Omit<Ctx, "json">
222- & FetchJson<
223- ApiSuccess,
224- ApiError extends unknown ? Ctx["_error"] : ApiError
225- >,
226+ Omit<Ctx, "json"> &
227+ FetchJson<
228+ ApiSuccess,
229+ ApiError extends unknown ? Ctx["_error"] : ApiError
230+ >,
231 ApiSuccess
232 >;
233 post<P, ApiSuccess, ApiError = unknown>(
234 fn: MiddlewareApiCo<Ctx>,
235 ): CreateActionWithPayload<
236- & Omit<Ctx, "payload" | "json">
237- & Payload<P>
238- & FetchJson<
239- ApiSuccess,
240- ApiError extends unknown ? Ctx["_error"] : ApiError
241- >,
242+ Omit<Ctx, "payload" | "json"> &
243+ Payload<P> &
244+ FetchJson<
245+ ApiSuccess,
246+ ApiError extends unknown ? Ctx["_error"] : ApiError
247+ >,
248 P,
249 ApiSuccess
250 >;
251@@ -235,30 +237,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
252 post<P extends never, ApiSuccess, ApiError = unknown>(
253 req: { supervisor?: Supervisor },
254 fn: MiddlewareApiCo<
255- & Omit<Ctx, "json">
256- & FetchJson<
257- ApiSuccess,
258- ApiError extends unknown ? Ctx["_error"] : ApiError
259- >
260+ Omit<Ctx, "json"> &
261+ FetchJson<
262+ ApiSuccess,
263+ ApiError extends unknown ? Ctx["_error"] : ApiError
264+ >
265 >,
266 ): CreateAction<
267- & Omit<Ctx, "json">
268- & FetchJson<
269- ApiSuccess,
270- ApiError extends unknown ? Ctx["_error"] : ApiError
271- >,
272+ Omit<Ctx, "json"> &
273+ FetchJson<
274+ ApiSuccess,
275+ ApiError extends unknown ? Ctx["_error"] : ApiError
276+ >,
277 ApiSuccess
278 >;
279 post<P, ApiSuccess, ApiError = unknown>(
280 req: { supervisor?: Supervisor },
281 fn: MiddlewareApiCo<Ctx>,
282 ): CreateActionWithPayload<
283- & Omit<Ctx, "payload" | "json">
284- & Payload<P>
285- & FetchJson<
286- ApiSuccess,
287- ApiError extends unknown ? Ctx["_error"] : ApiError
288- >,
289+ Omit<Ctx, "payload" | "json"> &
290+ Payload<P> &
291+ FetchJson<
292+ ApiSuccess,
293+ ApiError extends unknown ? Ctx["_error"] : ApiError
294+ >,
295 P,
296 ApiSuccess
297 >;
298@@ -267,28 +269,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
299 * Options only
300 */
301 put(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
302- put<P>(req: {
303- supervisor?: Supervisor;
304- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
305+ put<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
306+ Omit<Ctx, "payload"> & Payload<P>,
307+ P
308+ >;
309 put<P extends never, ApiSuccess, ApiError = unknown>(req: {
310 supervisor?: Supervisor;
311 }): CreateAction<
312- & Omit<Ctx, "json">
313- & FetchJson<
314- ApiSuccess,
315- ApiError extends unknown ? Ctx["_error"] : ApiError
316- >,
317+ Omit<Ctx, "json"> &
318+ FetchJson<
319+ ApiSuccess,
320+ ApiError extends unknown ? Ctx["_error"] : ApiError
321+ >,
322 ApiSuccess
323 >;
324 put<P, ApiSuccess, ApiError = unknown>(req: {
325 supervisor?: Supervisor;
326 }): CreateActionWithPayload<
327- & Omit<Ctx, "payload" | "json">
328- & Payload<P>
329- & FetchJson<
330- ApiSuccess,
331- ApiError extends unknown ? Ctx["_error"] : ApiError
332- >,
333+ Omit<Ctx, "payload" | "json"> &
334+ Payload<P> &
335+ FetchJson<
336+ ApiSuccess,
337+ ApiError extends unknown ? Ctx["_error"] : ApiError
338+ >,
339 P,
340 ApiSuccess
341 >;
342@@ -306,29 +309,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
343 ): CreateActionWithPayload<Gtx, P>;
344 put<P extends never, ApiSuccess, ApiError = unknown>(
345 fn: MiddlewareApiCo<
346- & Omit<Ctx, "json">
347- & FetchJson<
348- ApiSuccess,
349- ApiError extends unknown ? Ctx["_error"] : ApiError
350- >
351+ Omit<Ctx, "json"> &
352+ FetchJson<
353+ ApiSuccess,
354+ ApiError extends unknown ? Ctx["_error"] : ApiError
355+ >
356 >,
357 ): CreateAction<
358- & Omit<Ctx, "json">
359- & FetchJson<
360- ApiSuccess,
361- ApiError extends unknown ? Ctx["_error"] : ApiError
362- >,
363+ Omit<Ctx, "json"> &
364+ FetchJson<
365+ ApiSuccess,
366+ ApiError extends unknown ? Ctx["_error"] : ApiError
367+ >,
368 ApiSuccess
369 >;
370 put<P, ApiSuccess, ApiError = unknown>(
371 fn: MiddlewareApiCo<Ctx>,
372 ): CreateActionWithPayload<
373- & Omit<Ctx, "payload" | "json">
374- & Payload<P>
375- & FetchJson<
376- ApiSuccess,
377- ApiError extends unknown ? Ctx["_error"] : ApiError
378- >,
379+ Omit<Ctx, "payload" | "json"> &
380+ Payload<P> &
381+ FetchJson<
382+ ApiSuccess,
383+ ApiError extends unknown ? Ctx["_error"] : ApiError
384+ >,
385 P,
386 ApiSuccess
387 >;
388@@ -355,30 +358,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
389 put<P extends never, ApiSuccess, ApiError = unknown>(
390 req: { supervisor?: Supervisor },
391 fn: MiddlewareApiCo<
392- & Omit<Ctx, "json">
393- & FetchJson<
394- ApiSuccess,
395- ApiError extends unknown ? Ctx["_error"] : ApiError
396- >
397+ Omit<Ctx, "json"> &
398+ FetchJson<
399+ ApiSuccess,
400+ ApiError extends unknown ? Ctx["_error"] : ApiError
401+ >
402 >,
403 ): CreateAction<
404- & Omit<Ctx, "json">
405- & FetchJson<
406- ApiSuccess,
407- ApiError extends unknown ? Ctx["_error"] : ApiError
408- >,
409+ Omit<Ctx, "json"> &
410+ FetchJson<
411+ ApiSuccess,
412+ ApiError extends unknown ? Ctx["_error"] : ApiError
413+ >,
414 ApiSuccess
415 >;
416 put<P, ApiSuccess, ApiError = unknown>(
417 req: { supervisor?: Supervisor },
418 fn: MiddlewareApiCo<Ctx>,
419 ): CreateActionWithPayload<
420- & Omit<Ctx, "payload" | "json">
421- & Payload<P>
422- & FetchJson<
423- ApiSuccess,
424- ApiError extends unknown ? Ctx["_error"] : ApiError
425- >,
426+ Omit<Ctx, "payload" | "json"> &
427+ Payload<P> &
428+ FetchJson<
429+ ApiSuccess,
430+ ApiError extends unknown ? Ctx["_error"] : ApiError
431+ >,
432 P,
433 ApiSuccess
434 >;
435@@ -387,28 +390,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
436 * Options only
437 */
438 patch(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
439- patch<P>(req: {
440- supervisor?: Supervisor;
441- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
442+ patch<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
443+ Omit<Ctx, "payload"> & Payload<P>,
444+ P
445+ >;
446 patch<P extends never, ApiSuccess, ApiError = unknown>(req: {
447 supervisor?: Supervisor;
448 }): CreateAction<
449- & Omit<Ctx, "json">
450- & FetchJson<
451- ApiSuccess,
452- ApiError extends unknown ? Ctx["_error"] : ApiError
453- >,
454+ Omit<Ctx, "json"> &
455+ FetchJson<
456+ ApiSuccess,
457+ ApiError extends unknown ? Ctx["_error"] : ApiError
458+ >,
459 ApiSuccess
460 >;
461 patch<P, ApiSuccess, ApiError = unknown>(req: {
462 supervisor?: Supervisor;
463 }): CreateActionWithPayload<
464- & Omit<Ctx, "payload" | "json">
465- & Payload<P>
466- & FetchJson<
467- ApiSuccess,
468- ApiError extends unknown ? Ctx["_error"] : ApiError
469- >,
470+ Omit<Ctx, "payload" | "json"> &
471+ Payload<P> &
472+ FetchJson<
473+ ApiSuccess,
474+ ApiError extends unknown ? Ctx["_error"] : ApiError
475+ >,
476 P,
477 ApiSuccess
478 >;
479@@ -426,29 +430,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
480 ): CreateActionWithPayload<Gtx, P>;
481 patch<P extends never, ApiSuccess, ApiError = unknown>(
482 fn: MiddlewareApiCo<
483- & Omit<Ctx, "json">
484- & FetchJson<
485- ApiSuccess,
486- ApiError extends unknown ? Ctx["_error"] : ApiError
487- >
488+ Omit<Ctx, "json"> &
489+ FetchJson<
490+ ApiSuccess,
491+ ApiError extends unknown ? Ctx["_error"] : ApiError
492+ >
493 >,
494 ): CreateAction<
495- & Omit<Ctx, "json">
496- & FetchJson<
497- ApiSuccess,
498- ApiError extends unknown ? Ctx["_error"] : ApiError
499- >,
500+ Omit<Ctx, "json"> &
501+ FetchJson<
502+ ApiSuccess,
503+ ApiError extends unknown ? Ctx["_error"] : ApiError
504+ >,
505 ApiSuccess
506 >;
507 patch<P, ApiSuccess, ApiError = unknown>(
508 fn: MiddlewareApiCo<Ctx>,
509 ): CreateActionWithPayload<
510- & Omit<Ctx, "payload" | "json">
511- & Payload<P>
512- & FetchJson<
513- ApiSuccess,
514- ApiError extends unknown ? Ctx["_error"] : ApiError
515- >,
516+ Omit<Ctx, "payload" | "json"> &
517+ Payload<P> &
518+ FetchJson<
519+ ApiSuccess,
520+ ApiError extends unknown ? Ctx["_error"] : ApiError
521+ >,
522 P,
523 ApiSuccess
524 >;
525@@ -475,30 +479,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
526 patch<P extends never, ApiSuccess, ApiError = unknown>(
527 req: { supervisor?: Supervisor },
528 fn: MiddlewareApiCo<
529- & Omit<Ctx, "json">
530- & FetchJson<
531- ApiSuccess,
532- ApiError extends unknown ? Ctx["_error"] : ApiError
533- >
534+ Omit<Ctx, "json"> &
535+ FetchJson<
536+ ApiSuccess,
537+ ApiError extends unknown ? Ctx["_error"] : ApiError
538+ >
539 >,
540 ): CreateAction<
541- & Omit<Ctx, "json">
542- & FetchJson<
543- ApiSuccess,
544- ApiError extends unknown ? Ctx["_error"] : ApiError
545- >,
546+ Omit<Ctx, "json"> &
547+ FetchJson<
548+ ApiSuccess,
549+ ApiError extends unknown ? Ctx["_error"] : ApiError
550+ >,
551 ApiSuccess
552 >;
553 patch<P, ApiSuccess, ApiError = unknown>(
554 req: { supervisor?: Supervisor },
555 fn: MiddlewareApiCo<Ctx>,
556 ): CreateActionWithPayload<
557- & Omit<Ctx, "payload" | "json">
558- & Payload<P>
559- & FetchJson<
560- ApiSuccess,
561- ApiError extends unknown ? Ctx["_error"] : ApiError
562- >,
563+ Omit<Ctx, "payload" | "json"> &
564+ Payload<P> &
565+ FetchJson<
566+ ApiSuccess,
567+ ApiError extends unknown ? Ctx["_error"] : ApiError
568+ >,
569 P,
570 ApiSuccess
571 >;
572@@ -507,28 +511,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
573 * Options only
574 */
575 delete(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
576- delete<P>(req: {
577- supervisor?: Supervisor;
578- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
579+ delete<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
580+ Omit<Ctx, "payload"> & Payload<P>,
581+ P
582+ >;
583 delete<P extends never, ApiSuccess, ApiError = unknown>(req: {
584 supervisor?: Supervisor;
585 }): CreateAction<
586- & Omit<Ctx, "json">
587- & FetchJson<
588- ApiSuccess,
589- ApiError extends unknown ? Ctx["_error"] : ApiError
590- >,
591+ Omit<Ctx, "json"> &
592+ FetchJson<
593+ ApiSuccess,
594+ ApiError extends unknown ? Ctx["_error"] : ApiError
595+ >,
596 ApiSuccess
597 >;
598 delete<P, ApiSuccess, ApiError = unknown>(req: {
599 supervisor?: Supervisor;
600 }): CreateActionWithPayload<
601- & Omit<Ctx, "payload" | "json">
602- & Payload<P>
603- & FetchJson<
604- ApiSuccess,
605- ApiError extends unknown ? Ctx["_error"] : ApiError
606- >,
607+ Omit<Ctx, "payload" | "json"> &
608+ Payload<P> &
609+ FetchJson<
610+ ApiSuccess,
611+ ApiError extends unknown ? Ctx["_error"] : ApiError
612+ >,
613 P,
614 ApiSuccess
615 >;
616@@ -546,29 +551,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
617 ): CreateActionWithPayload<Gtx, P>;
618 delete<P extends never, ApiSuccess, ApiError = unknown>(
619 fn: MiddlewareApiCo<
620- & Omit<Ctx, "json">
621- & FetchJson<
622- ApiSuccess,
623- ApiError extends unknown ? Ctx["_error"] : ApiError
624- >
625+ Omit<Ctx, "json"> &
626+ FetchJson<
627+ ApiSuccess,
628+ ApiError extends unknown ? Ctx["_error"] : ApiError
629+ >
630 >,
631 ): CreateAction<
632- & Omit<Ctx, "json">
633- & FetchJson<
634- ApiSuccess,
635- ApiError extends unknown ? Ctx["_error"] : ApiError
636- >,
637+ Omit<Ctx, "json"> &
638+ FetchJson<
639+ ApiSuccess,
640+ ApiError extends unknown ? Ctx["_error"] : ApiError
641+ >,
642 ApiSuccess
643 >;
644 delete<P, ApiSuccess, ApiError = unknown>(
645 fn: MiddlewareApiCo<Ctx>,
646 ): CreateActionWithPayload<
647- & Omit<Ctx, "payload" | "json">
648- & Payload<P>
649- & FetchJson<
650- ApiSuccess,
651- ApiError extends unknown ? Ctx["_error"] : ApiError
652- >,
653+ Omit<Ctx, "payload" | "json"> &
654+ Payload<P> &
655+ FetchJson<
656+ ApiSuccess,
657+ ApiError extends unknown ? Ctx["_error"] : ApiError
658+ >,
659 P,
660 ApiSuccess
661 >;
662@@ -595,30 +600,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
663 delete<P extends never, ApiSuccess, ApiError = unknown>(
664 req: { supervisor?: Supervisor },
665 fn: MiddlewareApiCo<
666- & Omit<Ctx, "json">
667- & FetchJson<
668- ApiSuccess,
669- ApiError extends unknown ? Ctx["_error"] : ApiError
670- >
671+ Omit<Ctx, "json"> &
672+ FetchJson<
673+ ApiSuccess,
674+ ApiError extends unknown ? Ctx["_error"] : ApiError
675+ >
676 >,
677 ): CreateAction<
678- & Omit<Ctx, "json">
679- & FetchJson<
680- ApiSuccess,
681- ApiError extends unknown ? Ctx["_error"] : ApiError
682- >,
683+ Omit<Ctx, "json"> &
684+ FetchJson<
685+ ApiSuccess,
686+ ApiError extends unknown ? Ctx["_error"] : ApiError
687+ >,
688 ApiSuccess
689 >;
690 delete<P, ApiSuccess, ApiError = unknown>(
691 req: { supervisor?: Supervisor },
692 fn: MiddlewareApiCo<Ctx>,
693 ): CreateActionWithPayload<
694- & Omit<Ctx, "payload" | "json">
695- & Payload<P>
696- & FetchJson<
697- ApiSuccess,
698- ApiError extends unknown ? Ctx["_error"] : ApiError
699- >,
700+ Omit<Ctx, "payload" | "json"> &
701+ Payload<P> &
702+ FetchJson<
703+ ApiSuccess,
704+ ApiError extends unknown ? Ctx["_error"] : ApiError
705+ >,
706 P,
707 ApiSuccess
708 >;
709@@ -627,28 +632,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
710 * Options only
711 */
712 options(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
713- options<P>(req: {
714- supervisor?: Supervisor;
715- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
716+ options<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
717+ Omit<Ctx, "payload"> & Payload<P>,
718+ P
719+ >;
720 options<P extends never, ApiSuccess, ApiError = unknown>(req: {
721 supervisor?: Supervisor;
722 }): CreateAction<
723- & Omit<Ctx, "json">
724- & FetchJson<
725- ApiSuccess,
726- ApiError extends unknown ? Ctx["_error"] : ApiError
727- >,
728+ Omit<Ctx, "json"> &
729+ FetchJson<
730+ ApiSuccess,
731+ ApiError extends unknown ? Ctx["_error"] : ApiError
732+ >,
733 ApiSuccess
734 >;
735 options<P, ApiSuccess, ApiError = unknown>(req: {
736 supervisor?: Supervisor;
737 }): CreateActionWithPayload<
738- & Omit<Ctx, "payload" | "json">
739- & Payload<P>
740- & FetchJson<
741- ApiSuccess,
742- ApiError extends unknown ? Ctx["_error"] : ApiError
743- >,
744+ Omit<Ctx, "payload" | "json"> &
745+ Payload<P> &
746+ FetchJson<
747+ ApiSuccess,
748+ ApiError extends unknown ? Ctx["_error"] : ApiError
749+ >,
750 P,
751 ApiSuccess
752 >;
753@@ -666,29 +672,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
754 ): CreateActionWithPayload<Gtx, P>;
755 options<P extends never, ApiSuccess, ApiError = unknown>(
756 fn: MiddlewareApiCo<
757- & Omit<Ctx, "json">
758- & FetchJson<
759- ApiSuccess,
760- ApiError extends unknown ? Ctx["_error"] : ApiError
761- >
762+ Omit<Ctx, "json"> &
763+ FetchJson<
764+ ApiSuccess,
765+ ApiError extends unknown ? Ctx["_error"] : ApiError
766+ >
767 >,
768 ): CreateAction<
769- & Omit<Ctx, "json">
770- & FetchJson<
771- ApiSuccess,
772- ApiError extends unknown ? Ctx["_error"] : ApiError
773- >,
774+ Omit<Ctx, "json"> &
775+ FetchJson<
776+ ApiSuccess,
777+ ApiError extends unknown ? Ctx["_error"] : ApiError
778+ >,
779 ApiSuccess
780 >;
781 options<P, ApiSuccess, ApiError = unknown>(
782 fn: MiddlewareApiCo<Ctx>,
783 ): CreateActionWithPayload<
784- & Omit<Ctx, "payload" | "json">
785- & Payload<P>
786- & FetchJson<
787- ApiSuccess,
788- ApiError extends unknown ? Ctx["_error"] : ApiError
789- >,
790+ Omit<Ctx, "payload" | "json"> &
791+ Payload<P> &
792+ FetchJson<
793+ ApiSuccess,
794+ ApiError extends unknown ? Ctx["_error"] : ApiError
795+ >,
796 P,
797 ApiSuccess
798 >;
799@@ -715,30 +721,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
800 options<P extends never, ApiSuccess, ApiError = unknown>(
801 req: { supervisor?: Supervisor },
802 fn: MiddlewareApiCo<
803- & Omit<Ctx, "json">
804- & FetchJson<
805- ApiSuccess,
806- ApiError extends unknown ? Ctx["_error"] : ApiError
807- >
808+ Omit<Ctx, "json"> &
809+ FetchJson<
810+ ApiSuccess,
811+ ApiError extends unknown ? Ctx["_error"] : ApiError
812+ >
813 >,
814 ): CreateAction<
815- & Omit<Ctx, "json">
816- & FetchJson<
817- ApiSuccess,
818- ApiError extends unknown ? Ctx["_error"] : ApiError
819- >,
820+ Omit<Ctx, "json"> &
821+ FetchJson<
822+ ApiSuccess,
823+ ApiError extends unknown ? Ctx["_error"] : ApiError
824+ >,
825 ApiSuccess
826 >;
827 options<P, ApiSuccess, ApiError = unknown>(
828 req: { supervisor?: Supervisor },
829 fn: MiddlewareApiCo<Ctx>,
830 ): CreateActionWithPayload<
831- & Omit<Ctx, "payload" | "json">
832- & Payload<P>
833- & FetchJson<
834- ApiSuccess,
835- ApiError extends unknown ? Ctx["_error"] : ApiError
836- >,
837+ Omit<Ctx, "payload" | "json"> &
838+ Payload<P> &
839+ FetchJson<
840+ ApiSuccess,
841+ ApiError extends unknown ? Ctx["_error"] : ApiError
842+ >,
843 P,
844 ApiSuccess
845 >;
846@@ -747,28 +753,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
847 * Options only
848 */
849 head(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
850- head<P>(req: {
851- supervisor?: Supervisor;
852- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
853+ head<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
854+ Omit<Ctx, "payload"> & Payload<P>,
855+ P
856+ >;
857 head<P extends never, ApiSuccess, ApiError = unknown>(req: {
858 supervisor?: Supervisor;
859 }): CreateAction<
860- & Omit<Ctx, "json">
861- & FetchJson<
862- ApiSuccess,
863- ApiError extends unknown ? Ctx["_error"] : ApiError
864- >,
865+ Omit<Ctx, "json"> &
866+ FetchJson<
867+ ApiSuccess,
868+ ApiError extends unknown ? Ctx["_error"] : ApiError
869+ >,
870 ApiSuccess
871 >;
872 head<P, ApiSuccess, ApiError = unknown>(req: {
873 supervisor?: Supervisor;
874 }): CreateActionWithPayload<
875- & Omit<Ctx, "payload" | "json">
876- & Payload<P>
877- & FetchJson<
878- ApiSuccess,
879- ApiError extends unknown ? Ctx["_error"] : ApiError
880- >,
881+ Omit<Ctx, "payload" | "json"> &
882+ Payload<P> &
883+ FetchJson<
884+ ApiSuccess,
885+ ApiError extends unknown ? Ctx["_error"] : ApiError
886+ >,
887 P,
888 ApiSuccess
889 >;
890@@ -786,29 +793,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
891 ): CreateActionWithPayload<Gtx, P>;
892 head<P extends never, ApiSuccess, ApiError = unknown>(
893 fn: MiddlewareApiCo<
894- & Omit<Ctx, "json">
895- & FetchJson<
896- ApiSuccess,
897- ApiError extends unknown ? Ctx["_error"] : ApiError
898- >
899+ Omit<Ctx, "json"> &
900+ FetchJson<
901+ ApiSuccess,
902+ ApiError extends unknown ? Ctx["_error"] : ApiError
903+ >
904 >,
905 ): CreateAction<
906- & Omit<Ctx, "json">
907- & FetchJson<
908- ApiSuccess,
909- ApiError extends unknown ? Ctx["_error"] : ApiError
910- >,
911+ Omit<Ctx, "json"> &
912+ FetchJson<
913+ ApiSuccess,
914+ ApiError extends unknown ? Ctx["_error"] : ApiError
915+ >,
916 ApiSuccess
917 >;
918 head<P, ApiSuccess, ApiError = unknown>(
919 fn: MiddlewareApiCo<Ctx>,
920 ): CreateActionWithPayload<
921- & Omit<Ctx, "payload" | "json">
922- & Payload<P>
923- & FetchJson<
924- ApiSuccess,
925- ApiError extends unknown ? Ctx["_error"] : ApiError
926- >,
927+ Omit<Ctx, "payload" | "json"> &
928+ Payload<P> &
929+ FetchJson<
930+ ApiSuccess,
931+ ApiError extends unknown ? Ctx["_error"] : ApiError
932+ >,
933 P,
934 ApiSuccess
935 >;
936@@ -835,30 +842,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
937 head<P extends never, ApiSuccess, ApiError = unknown>(
938 req: { supervisor?: Supervisor },
939 fn: MiddlewareApiCo<
940- & Omit<Ctx, "json">
941- & FetchJson<
942- ApiSuccess,
943- ApiError extends unknown ? Ctx["_error"] : ApiError
944- >
945+ Omit<Ctx, "json"> &
946+ FetchJson<
947+ ApiSuccess,
948+ ApiError extends unknown ? Ctx["_error"] : ApiError
949+ >
950 >,
951 ): CreateAction<
952- & Omit<Ctx, "json">
953- & FetchJson<
954- ApiSuccess,
955- ApiError extends unknown ? Ctx["_error"] : ApiError
956- >,
957+ Omit<Ctx, "json"> &
958+ FetchJson<
959+ ApiSuccess,
960+ ApiError extends unknown ? Ctx["_error"] : ApiError
961+ >,
962 ApiSuccess
963 >;
964 head<P, ApiSuccess, ApiError = unknown>(
965 req: { supervisor?: Supervisor },
966 fn: MiddlewareApiCo<Ctx>,
967 ): CreateActionWithPayload<
968- & Omit<Ctx, "payload" | "json">
969- & Payload<P>
970- & FetchJson<
971- ApiSuccess,
972- ApiError extends unknown ? Ctx["_error"] : ApiError
973- >,
974+ Omit<Ctx, "payload" | "json"> &
975+ Payload<P> &
976+ FetchJson<
977+ ApiSuccess,
978+ ApiError extends unknown ? Ctx["_error"] : ApiError
979+ >,
980 P,
981 ApiSuccess
982 >;
983@@ -867,28 +874,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
984 * Options only
985 */
986 connect(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
987- connect<P>(req: {
988- supervisor?: Supervisor;
989- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
990+ connect<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
991+ Omit<Ctx, "payload"> & Payload<P>,
992+ P
993+ >;
994 connect<P extends never, ApiSuccess, ApiError = unknown>(req: {
995 supervisor?: Supervisor;
996 }): CreateAction<
997- & Omit<Ctx, "json">
998- & FetchJson<
999- ApiSuccess,
1000- ApiError extends unknown ? Ctx["_error"] : ApiError
1001- >,
1002+ Omit<Ctx, "json"> &
1003+ FetchJson<
1004+ ApiSuccess,
1005+ ApiError extends unknown ? Ctx["_error"] : ApiError
1006+ >,
1007 ApiSuccess
1008 >;
1009 connect<P, ApiSuccess, ApiError = unknown>(req: {
1010 supervisor?: Supervisor;
1011 }): CreateActionWithPayload<
1012- & Omit<Ctx, "payload" | "json">
1013- & Payload<P>
1014- & FetchJson<
1015- ApiSuccess,
1016- ApiError extends unknown ? Ctx["_error"] : ApiError
1017- >,
1018+ Omit<Ctx, "payload" | "json"> &
1019+ Payload<P> &
1020+ FetchJson<
1021+ ApiSuccess,
1022+ ApiError extends unknown ? Ctx["_error"] : ApiError
1023+ >,
1024 P,
1025 ApiSuccess
1026 >;
1027@@ -906,29 +914,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1028 ): CreateActionWithPayload<Gtx, P>;
1029 connect<P extends never, ApiSuccess, ApiError = unknown>(
1030 fn: MiddlewareApiCo<
1031- & Omit<Ctx, "json">
1032- & FetchJson<
1033- ApiSuccess,
1034- ApiError extends unknown ? Ctx["_error"] : ApiError
1035- >
1036+ Omit<Ctx, "json"> &
1037+ FetchJson<
1038+ ApiSuccess,
1039+ ApiError extends unknown ? Ctx["_error"] : ApiError
1040+ >
1041 >,
1042 ): CreateAction<
1043- & Omit<Ctx, "json">
1044- & FetchJson<
1045- ApiSuccess,
1046- ApiError extends unknown ? Ctx["_error"] : ApiError
1047- >,
1048+ Omit<Ctx, "json"> &
1049+ FetchJson<
1050+ ApiSuccess,
1051+ ApiError extends unknown ? Ctx["_error"] : ApiError
1052+ >,
1053 ApiSuccess
1054 >;
1055 connect<P, ApiSuccess, ApiError = unknown>(
1056 fn: MiddlewareApiCo<Ctx>,
1057 ): CreateActionWithPayload<
1058- & Omit<Ctx, "payload" | "json">
1059- & Payload<P>
1060- & FetchJson<
1061- ApiSuccess,
1062- ApiError extends unknown ? Ctx["_error"] : ApiError
1063- >,
1064+ Omit<Ctx, "payload" | "json"> &
1065+ Payload<P> &
1066+ FetchJson<
1067+ ApiSuccess,
1068+ ApiError extends unknown ? Ctx["_error"] : ApiError
1069+ >,
1070 P,
1071 ApiSuccess
1072 >;
1073@@ -955,30 +963,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1074 connect<P extends never, ApiSuccess, ApiError = unknown>(
1075 req: { supervisor?: Supervisor },
1076 fn: MiddlewareApiCo<
1077- & Omit<Ctx, "json">
1078- & FetchJson<
1079- ApiSuccess,
1080- ApiError extends unknown ? Ctx["_error"] : ApiError
1081- >
1082+ Omit<Ctx, "json"> &
1083+ FetchJson<
1084+ ApiSuccess,
1085+ ApiError extends unknown ? Ctx["_error"] : ApiError
1086+ >
1087 >,
1088 ): CreateAction<
1089- & Omit<Ctx, "json">
1090- & FetchJson<
1091- ApiSuccess,
1092- ApiError extends unknown ? Ctx["_error"] : ApiError
1093- >,
1094+ Omit<Ctx, "json"> &
1095+ FetchJson<
1096+ ApiSuccess,
1097+ ApiError extends unknown ? Ctx["_error"] : ApiError
1098+ >,
1099 ApiSuccess
1100 >;
1101 connect<P, ApiSuccess, ApiError = unknown>(
1102 req: { supervisor?: Supervisor },
1103 fn: MiddlewareApiCo<Ctx>,
1104 ): CreateActionWithPayload<
1105- & Omit<Ctx, "payload" | "json">
1106- & Payload<P>
1107- & FetchJson<
1108- ApiSuccess,
1109- ApiError extends unknown ? Ctx["_error"] : ApiError
1110- >,
1111+ Omit<Ctx, "payload" | "json"> &
1112+ Payload<P> &
1113+ FetchJson<
1114+ ApiSuccess,
1115+ ApiError extends unknown ? Ctx["_error"] : ApiError
1116+ >,
1117 P,
1118 ApiSuccess
1119 >;
1120@@ -987,28 +995,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1121 * Options only
1122 */
1123 trace(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
1124- trace<P>(req: {
1125- supervisor?: Supervisor;
1126- }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
1127+ trace<P>(req: { supervisor?: Supervisor }): CreateActionWithPayload<
1128+ Omit<Ctx, "payload"> & Payload<P>,
1129+ P
1130+ >;
1131 trace<P extends never, ApiSuccess, ApiError = unknown>(req: {
1132 supervisor?: Supervisor;
1133 }): CreateAction<
1134- & Omit<Ctx, "json">
1135- & FetchJson<
1136- ApiSuccess,
1137- ApiError extends unknown ? Ctx["_error"] : ApiError
1138- >,
1139+ Omit<Ctx, "json"> &
1140+ FetchJson<
1141+ ApiSuccess,
1142+ ApiError extends unknown ? Ctx["_error"] : ApiError
1143+ >,
1144 ApiSuccess
1145 >;
1146 trace<P, ApiSuccess, ApiError = unknown>(req: {
1147 supervisor?: Supervisor;
1148 }): CreateActionWithPayload<
1149- & Omit<Ctx, "payload" | "json">
1150- & Payload<P>
1151- & FetchJson<
1152- ApiSuccess,
1153- ApiError extends unknown ? Ctx["_error"] : ApiError
1154- >,
1155+ Omit<Ctx, "payload" | "json"> &
1156+ Payload<P> &
1157+ FetchJson<
1158+ ApiSuccess,
1159+ ApiError extends unknown ? Ctx["_error"] : ApiError
1160+ >,
1161 P,
1162 ApiSuccess
1163 >;
1164@@ -1026,29 +1035,29 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1165 ): CreateActionWithPayload<Gtx, P>;
1166 trace<P extends never, ApiSuccess, ApiError = unknown>(
1167 fn: MiddlewareApiCo<
1168- & Omit<Ctx, "json">
1169- & FetchJson<
1170- ApiSuccess,
1171- ApiError extends unknown ? Ctx["_error"] : ApiError
1172- >
1173+ Omit<Ctx, "json"> &
1174+ FetchJson<
1175+ ApiSuccess,
1176+ ApiError extends unknown ? Ctx["_error"] : ApiError
1177+ >
1178 >,
1179 ): CreateAction<
1180- & Omit<Ctx, "json">
1181- & FetchJson<
1182- ApiSuccess,
1183- ApiError extends unknown ? Ctx["_error"] : ApiError
1184- >,
1185+ Omit<Ctx, "json"> &
1186+ FetchJson<
1187+ ApiSuccess,
1188+ ApiError extends unknown ? Ctx["_error"] : ApiError
1189+ >,
1190 ApiSuccess
1191 >;
1192 trace<P, ApiSuccess, ApiError = unknown>(
1193 fn: MiddlewareApiCo<Ctx>,
1194 ): CreateActionWithPayload<
1195- & Omit<Ctx, "payload" | "json">
1196- & Payload<P>
1197- & FetchJson<
1198- ApiSuccess,
1199- ApiError extends unknown ? Ctx["_error"] : ApiError
1200- >,
1201+ Omit<Ctx, "payload" | "json"> &
1202+ Payload<P> &
1203+ FetchJson<
1204+ ApiSuccess,
1205+ ApiError extends unknown ? Ctx["_error"] : ApiError
1206+ >,
1207 P,
1208 ApiSuccess
1209 >;
1210@@ -1075,30 +1084,30 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1211 trace<P extends never, ApiSuccess, ApiError = unknown>(
1212 req: { supervisor?: Supervisor },
1213 fn: MiddlewareApiCo<
1214- & Omit<Ctx, "json">
1215- & FetchJson<
1216- ApiSuccess,
1217- ApiError extends unknown ? Ctx["_error"] : ApiError
1218- >
1219+ Omit<Ctx, "json"> &
1220+ FetchJson<
1221+ ApiSuccess,
1222+ ApiError extends unknown ? Ctx["_error"] : ApiError
1223+ >
1224 >,
1225 ): CreateAction<
1226- & Omit<Ctx, "json">
1227- & FetchJson<
1228- ApiSuccess,
1229- ApiError extends unknown ? Ctx["_error"] : ApiError
1230- >,
1231+ Omit<Ctx, "json"> &
1232+ FetchJson<
1233+ ApiSuccess,
1234+ ApiError extends unknown ? Ctx["_error"] : ApiError
1235+ >,
1236 ApiSuccess
1237 >;
1238 trace<P, ApiSuccess, ApiError = unknown>(
1239 req: { supervisor?: Supervisor },
1240 fn: MiddlewareApiCo<Ctx>,
1241 ): CreateActionWithPayload<
1242- & Omit<Ctx, "payload" | "json">
1243- & Payload<P>
1244- & FetchJson<
1245- ApiSuccess,
1246- ApiError extends unknown ? Ctx["_error"] : ApiError
1247- >,
1248+ Omit<Ctx, "payload" | "json"> &
1249+ Payload<P> &
1250+ FetchJson<
1251+ ApiSuccess,
1252+ ApiError extends unknown ? Ctx["_error"] : ApiError
1253+ >,
1254 P,
1255 ApiSuccess
1256 >;
1257@@ -1114,22 +1123,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1258 get<P extends never, ApiSuccess, ApiError = unknown>(
1259 name: ApiName,
1260 ): CreateAction<
1261- & Omit<Ctx, "json">
1262- & FetchJson<
1263- ApiSuccess,
1264- ApiError extends unknown ? Ctx["_error"] : ApiError
1265- >,
1266+ Omit<Ctx, "json"> &
1267+ FetchJson<
1268+ ApiSuccess,
1269+ ApiError extends unknown ? Ctx["_error"] : ApiError
1270+ >,
1271 ApiSuccess
1272 >;
1273 get<P, ApiSuccess, ApiError = unknown>(
1274 name: ApiName,
1275 ): CreateActionWithPayload<
1276- & Omit<Ctx, "payload" | "json">
1277- & Payload<P>
1278- & FetchJson<
1279- ApiSuccess,
1280- ApiError extends unknown ? Ctx["_error"] : ApiError
1281- >,
1282+ Omit<Ctx, "payload" | "json"> &
1283+ Payload<P> &
1284+ FetchJson<
1285+ ApiSuccess,
1286+ ApiError extends unknown ? Ctx["_error"] : ApiError
1287+ >,
1288 P,
1289 ApiSuccess
1290 >;
1291@@ -1150,23 +1159,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1292 name: ApiName,
1293 req: { supervisor?: Supervisor },
1294 ): CreateAction<
1295- & Omit<Ctx, "json">
1296- & FetchJson<
1297- ApiSuccess,
1298- ApiError extends unknown ? Ctx["_error"] : ApiError
1299- >,
1300+ Omit<Ctx, "json"> &
1301+ FetchJson<
1302+ ApiSuccess,
1303+ ApiError extends unknown ? Ctx["_error"] : ApiError
1304+ >,
1305 ApiSuccess
1306 >;
1307 get<P, ApiSuccess, ApiError = unknown>(
1308 name: ApiName,
1309 req: { supervisor?: Supervisor },
1310 ): CreateActionWithPayload<
1311- & Omit<Ctx, "payload" | "json">
1312- & Payload<P>
1313- & FetchJson<
1314- ApiSuccess,
1315- ApiError extends unknown ? Ctx["_error"] : ApiError
1316- >,
1317+ Omit<Ctx, "payload" | "json"> &
1318+ Payload<P> &
1319+ FetchJson<
1320+ ApiSuccess,
1321+ ApiError extends unknown ? Ctx["_error"] : ApiError
1322+ >,
1323 P,
1324 ApiSuccess
1325 >;
1326@@ -1190,37 +1199,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1327 get<P extends never, ApiSuccess, ApiError = unknown>(
1328 name: ApiName,
1329 fn: MiddlewareApiCo<
1330- & Omit<Ctx, "json">
1331- & FetchJson<
1332- ApiSuccess,
1333- ApiError extends unknown ? Ctx["_error"] : ApiError
1334- >
1335+ Omit<Ctx, "json"> &
1336+ FetchJson<
1337+ ApiSuccess,
1338+ ApiError extends unknown ? Ctx["_error"] : ApiError
1339+ >
1340 >,
1341 ): CreateAction<
1342- & Omit<Ctx, "json">
1343- & FetchJson<
1344- ApiSuccess,
1345- ApiError extends unknown ? Ctx["_error"] : ApiError
1346- >,
1347+ Omit<Ctx, "json"> &
1348+ FetchJson<
1349+ ApiSuccess,
1350+ ApiError extends unknown ? Ctx["_error"] : ApiError
1351+ >,
1352 ApiSuccess
1353 >;
1354 get<P, ApiSuccess, ApiError = unknown>(
1355 name: ApiName,
1356 fn: MiddlewareApiCo<
1357- & Omit<Ctx, "payload" | "json">
1358- & Payload<P>
1359- & FetchJson<
1360- ApiSuccess,
1361- ApiError extends unknown ? Ctx["_error"] : ApiError
1362- >
1363+ Omit<Ctx, "payload" | "json"> &
1364+ Payload<P> &
1365+ FetchJson<
1366+ ApiSuccess,
1367+ ApiError extends unknown ? Ctx["_error"] : ApiError
1368+ >
1369 >,
1370 ): CreateActionWithPayload<
1371- & Omit<Ctx, "payload" | "json">
1372- & Payload<P>
1373- & FetchJson<
1374- ApiSuccess,
1375- ApiError extends unknown ? Ctx["_error"] : ApiError
1376- >,
1377+ Omit<Ctx, "payload" | "json"> &
1378+ Payload<P> &
1379+ FetchJson<
1380+ ApiSuccess,
1381+ ApiError extends unknown ? Ctx["_error"] : ApiError
1382+ >,
1383 P,
1384 ApiSuccess
1385 >;
1386@@ -1252,38 +1261,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1387 name: ApiName,
1388 req: { supervisor?: Supervisor },
1389 fn: MiddlewareApiCo<
1390- & Omit<Ctx, "json">
1391- & FetchJson<
1392- ApiSuccess,
1393- ApiError extends unknown ? Ctx["_error"] : ApiError
1394- >
1395+ Omit<Ctx, "json"> &
1396+ FetchJson<
1397+ ApiSuccess,
1398+ ApiError extends unknown ? Ctx["_error"] : ApiError
1399+ >
1400 >,
1401 ): CreateAction<
1402- & Omit<Ctx, "json">
1403- & FetchJson<
1404- ApiSuccess,
1405- ApiError extends unknown ? Ctx["_error"] : ApiError
1406- >,
1407+ Omit<Ctx, "json"> &
1408+ FetchJson<
1409+ ApiSuccess,
1410+ ApiError extends unknown ? Ctx["_error"] : ApiError
1411+ >,
1412 ApiSuccess
1413 >;
1414 get<P, ApiSuccess, ApiError = unknown>(
1415 name: ApiName,
1416 req: { supervisor?: Supervisor },
1417 fn: MiddlewareApiCo<
1418- & Omit<Ctx, "payload" | "json">
1419- & Payload<P>
1420- & FetchJson<
1421- ApiSuccess,
1422- ApiError extends unknown ? Ctx["_error"] : ApiError
1423- >
1424+ Omit<Ctx, "payload" | "json"> &
1425+ Payload<P> &
1426+ FetchJson<
1427+ ApiSuccess,
1428+ ApiError extends unknown ? Ctx["_error"] : ApiError
1429+ >
1430 >,
1431 ): CreateActionWithPayload<
1432- & Omit<Ctx, "payload" | "json">
1433- & Payload<P>
1434- & FetchJson<
1435- ApiSuccess,
1436- ApiError extends unknown ? Ctx["_error"] : ApiError
1437- >,
1438+ Omit<Ctx, "payload" | "json"> &
1439+ Payload<P> &
1440+ FetchJson<
1441+ ApiSuccess,
1442+ ApiError extends unknown ? Ctx["_error"] : ApiError
1443+ >,
1444 P,
1445 ApiSuccess
1446 >;
1447@@ -1298,22 +1307,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1448 post<P extends never, ApiSuccess, ApiError = unknown>(
1449 name: ApiName,
1450 ): CreateAction<
1451- & Omit<Ctx, "json">
1452- & FetchJson<
1453- ApiSuccess,
1454- ApiError extends unknown ? Ctx["_error"] : ApiError
1455- >,
1456+ Omit<Ctx, "json"> &
1457+ FetchJson<
1458+ ApiSuccess,
1459+ ApiError extends unknown ? Ctx["_error"] : ApiError
1460+ >,
1461 ApiSuccess
1462 >;
1463 post<P, ApiSuccess, ApiError = unknown>(
1464 name: ApiName,
1465 ): CreateActionWithPayload<
1466- & Omit<Ctx, "payload" | "json">
1467- & Payload<P>
1468- & FetchJson<
1469- ApiSuccess,
1470- ApiError extends unknown ? Ctx["_error"] : ApiError
1471- >,
1472+ Omit<Ctx, "payload" | "json"> &
1473+ Payload<P> &
1474+ FetchJson<
1475+ ApiSuccess,
1476+ ApiError extends unknown ? Ctx["_error"] : ApiError
1477+ >,
1478 P,
1479 ApiSuccess
1480 >;
1481@@ -1334,23 +1343,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1482 name: ApiName,
1483 req: { supervisor?: Supervisor },
1484 ): CreateAction<
1485- & Omit<Ctx, "json">
1486- & FetchJson<
1487- ApiSuccess,
1488- ApiError extends unknown ? Ctx["_error"] : ApiError
1489- >,
1490+ Omit<Ctx, "json"> &
1491+ FetchJson<
1492+ ApiSuccess,
1493+ ApiError extends unknown ? Ctx["_error"] : ApiError
1494+ >,
1495 ApiSuccess
1496 >;
1497 post<P, ApiSuccess, ApiError = unknown>(
1498 name: ApiName,
1499 req: { supervisor?: Supervisor },
1500 ): CreateActionWithPayload<
1501- & Omit<Ctx, "payload" | "json">
1502- & Payload<P>
1503- & FetchJson<
1504- ApiSuccess,
1505- ApiError extends unknown ? Ctx["_error"] : ApiError
1506- >,
1507+ Omit<Ctx, "payload" | "json"> &
1508+ Payload<P> &
1509+ FetchJson<
1510+ ApiSuccess,
1511+ ApiError extends unknown ? Ctx["_error"] : ApiError
1512+ >,
1513 P,
1514 ApiSuccess
1515 >;
1516@@ -1374,37 +1383,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1517 post<P extends never, ApiSuccess, ApiError = unknown>(
1518 name: ApiName,
1519 fn: MiddlewareApiCo<
1520- & Omit<Ctx, "json">
1521- & FetchJson<
1522- ApiSuccess,
1523- ApiError extends unknown ? Ctx["_error"] : ApiError
1524- >
1525+ Omit<Ctx, "json"> &
1526+ FetchJson<
1527+ ApiSuccess,
1528+ ApiError extends unknown ? Ctx["_error"] : ApiError
1529+ >
1530 >,
1531 ): CreateAction<
1532- & Omit<Ctx, "json">
1533- & FetchJson<
1534- ApiSuccess,
1535- ApiError extends unknown ? Ctx["_error"] : ApiError
1536- >,
1537+ Omit<Ctx, "json"> &
1538+ FetchJson<
1539+ ApiSuccess,
1540+ ApiError extends unknown ? Ctx["_error"] : ApiError
1541+ >,
1542 ApiSuccess
1543 >;
1544 post<P, ApiSuccess, ApiError = unknown>(
1545 name: ApiName,
1546 fn: MiddlewareApiCo<
1547- & Omit<Ctx, "payload" | "json">
1548- & Payload<P>
1549- & FetchJson<
1550- ApiSuccess,
1551- ApiError extends unknown ? Ctx["_error"] : ApiError
1552- >
1553+ Omit<Ctx, "payload" | "json"> &
1554+ Payload<P> &
1555+ FetchJson<
1556+ ApiSuccess,
1557+ ApiError extends unknown ? Ctx["_error"] : ApiError
1558+ >
1559 >,
1560 ): CreateActionWithPayload<
1561- & Omit<Ctx, "payload" | "json">
1562- & Payload<P>
1563- & FetchJson<
1564- ApiSuccess,
1565- ApiError extends unknown ? Ctx["_error"] : ApiError
1566- >,
1567+ Omit<Ctx, "payload" | "json"> &
1568+ Payload<P> &
1569+ FetchJson<
1570+ ApiSuccess,
1571+ ApiError extends unknown ? Ctx["_error"] : ApiError
1572+ >,
1573 P,
1574 ApiSuccess
1575 >;
1576@@ -1436,38 +1445,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1577 name: ApiName,
1578 req: { supervisor?: Supervisor },
1579 fn: MiddlewareApiCo<
1580- & Omit<Ctx, "json">
1581- & FetchJson<
1582- ApiSuccess,
1583- ApiError extends unknown ? Ctx["_error"] : ApiError
1584- >
1585+ Omit<Ctx, "json"> &
1586+ FetchJson<
1587+ ApiSuccess,
1588+ ApiError extends unknown ? Ctx["_error"] : ApiError
1589+ >
1590 >,
1591 ): CreateAction<
1592- & Omit<Ctx, "json">
1593- & FetchJson<
1594- ApiSuccess,
1595- ApiError extends unknown ? Ctx["_error"] : ApiError
1596- >,
1597+ Omit<Ctx, "json"> &
1598+ FetchJson<
1599+ ApiSuccess,
1600+ ApiError extends unknown ? Ctx["_error"] : ApiError
1601+ >,
1602 ApiSuccess
1603 >;
1604 post<P, ApiSuccess, ApiError = unknown>(
1605 name: ApiName,
1606 req: { supervisor?: Supervisor },
1607 fn: MiddlewareApiCo<
1608- & Omit<Ctx, "payload" | "json">
1609- & Payload<P>
1610- & FetchJson<
1611- ApiSuccess,
1612- ApiError extends unknown ? Ctx["_error"] : ApiError
1613- >
1614+ Omit<Ctx, "payload" | "json"> &
1615+ Payload<P> &
1616+ FetchJson<
1617+ ApiSuccess,
1618+ ApiError extends unknown ? Ctx["_error"] : ApiError
1619+ >
1620 >,
1621 ): CreateActionWithPayload<
1622- & Omit<Ctx, "payload" | "json">
1623- & Payload<P>
1624- & FetchJson<
1625- ApiSuccess,
1626- ApiError extends unknown ? Ctx["_error"] : ApiError
1627- >,
1628+ Omit<Ctx, "payload" | "json"> &
1629+ Payload<P> &
1630+ FetchJson<
1631+ ApiSuccess,
1632+ ApiError extends unknown ? Ctx["_error"] : ApiError
1633+ >,
1634 P,
1635 ApiSuccess
1636 >;
1637@@ -1482,22 +1491,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1638 put<P extends never, ApiSuccess, ApiError = unknown>(
1639 name: ApiName,
1640 ): CreateAction<
1641- & Omit<Ctx, "json">
1642- & FetchJson<
1643- ApiSuccess,
1644- ApiError extends unknown ? Ctx["_error"] : ApiError
1645- >,
1646+ Omit<Ctx, "json"> &
1647+ FetchJson<
1648+ ApiSuccess,
1649+ ApiError extends unknown ? Ctx["_error"] : ApiError
1650+ >,
1651 ApiSuccess
1652 >;
1653 put<P, ApiSuccess, ApiError = unknown>(
1654 name: ApiName,
1655 ): CreateActionWithPayload<
1656- & Omit<Ctx, "payload" | "json">
1657- & Payload<P>
1658- & FetchJson<
1659- ApiSuccess,
1660- ApiError extends unknown ? Ctx["_error"] : ApiError
1661- >,
1662+ Omit<Ctx, "payload" | "json"> &
1663+ Payload<P> &
1664+ FetchJson<
1665+ ApiSuccess,
1666+ ApiError extends unknown ? Ctx["_error"] : ApiError
1667+ >,
1668 P,
1669 ApiSuccess
1670 >;
1671@@ -1518,23 +1527,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1672 name: ApiName,
1673 req: { supervisor?: Supervisor },
1674 ): CreateAction<
1675- & Omit<Ctx, "json">
1676- & FetchJson<
1677- ApiSuccess,
1678- ApiError extends unknown ? Ctx["_error"] : ApiError
1679- >,
1680+ Omit<Ctx, "json"> &
1681+ FetchJson<
1682+ ApiSuccess,
1683+ ApiError extends unknown ? Ctx["_error"] : ApiError
1684+ >,
1685 ApiSuccess
1686 >;
1687 put<P, ApiSuccess, ApiError = unknown>(
1688 name: ApiName,
1689 req: { supervisor?: Supervisor },
1690 ): CreateActionWithPayload<
1691- & Omit<Ctx, "payload" | "json">
1692- & Payload<P>
1693- & FetchJson<
1694- ApiSuccess,
1695- ApiError extends unknown ? Ctx["_error"] : ApiError
1696- >,
1697+ Omit<Ctx, "payload" | "json"> &
1698+ Payload<P> &
1699+ FetchJson<
1700+ ApiSuccess,
1701+ ApiError extends unknown ? Ctx["_error"] : ApiError
1702+ >,
1703 P,
1704 ApiSuccess
1705 >;
1706@@ -1558,37 +1567,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1707 put<P extends never, ApiSuccess, ApiError = unknown>(
1708 name: ApiName,
1709 fn: MiddlewareApiCo<
1710- & Omit<Ctx, "json">
1711- & FetchJson<
1712- ApiSuccess,
1713- ApiError extends unknown ? Ctx["_error"] : ApiError
1714- >
1715+ Omit<Ctx, "json"> &
1716+ FetchJson<
1717+ ApiSuccess,
1718+ ApiError extends unknown ? Ctx["_error"] : ApiError
1719+ >
1720 >,
1721 ): CreateAction<
1722- & Omit<Ctx, "json">
1723- & FetchJson<
1724- ApiSuccess,
1725- ApiError extends unknown ? Ctx["_error"] : ApiError
1726- >,
1727+ Omit<Ctx, "json"> &
1728+ FetchJson<
1729+ ApiSuccess,
1730+ ApiError extends unknown ? Ctx["_error"] : ApiError
1731+ >,
1732 ApiSuccess
1733 >;
1734 put<P, ApiSuccess, ApiError = unknown>(
1735 name: ApiName,
1736 fn: MiddlewareApiCo<
1737- & Omit<Ctx, "payload" | "json">
1738- & Payload<P>
1739- & FetchJson<
1740- ApiSuccess,
1741- ApiError extends unknown ? Ctx["_error"] : ApiError
1742- >
1743+ Omit<Ctx, "payload" | "json"> &
1744+ Payload<P> &
1745+ FetchJson<
1746+ ApiSuccess,
1747+ ApiError extends unknown ? Ctx["_error"] : ApiError
1748+ >
1749 >,
1750 ): CreateActionWithPayload<
1751- & Omit<Ctx, "payload" | "json">
1752- & Payload<P>
1753- & FetchJson<
1754- ApiSuccess,
1755- ApiError extends unknown ? Ctx["_error"] : ApiError
1756- >,
1757+ Omit<Ctx, "payload" | "json"> &
1758+ Payload<P> &
1759+ FetchJson<
1760+ ApiSuccess,
1761+ ApiError extends unknown ? Ctx["_error"] : ApiError
1762+ >,
1763 P,
1764 ApiSuccess
1765 >;
1766@@ -1620,38 +1629,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1767 name: ApiName,
1768 req: { supervisor?: Supervisor },
1769 fn: MiddlewareApiCo<
1770- & Omit<Ctx, "json">
1771- & FetchJson<
1772- ApiSuccess,
1773- ApiError extends unknown ? Ctx["_error"] : ApiError
1774- >
1775+ Omit<Ctx, "json"> &
1776+ FetchJson<
1777+ ApiSuccess,
1778+ ApiError extends unknown ? Ctx["_error"] : ApiError
1779+ >
1780 >,
1781 ): CreateAction<
1782- & Omit<Ctx, "json">
1783- & FetchJson<
1784- ApiSuccess,
1785- ApiError extends unknown ? Ctx["_error"] : ApiError
1786- >,
1787+ Omit<Ctx, "json"> &
1788+ FetchJson<
1789+ ApiSuccess,
1790+ ApiError extends unknown ? Ctx["_error"] : ApiError
1791+ >,
1792 ApiSuccess
1793 >;
1794 put<P, ApiSuccess, ApiError = unknown>(
1795 name: ApiName,
1796 req: { supervisor?: Supervisor },
1797 fn: MiddlewareApiCo<
1798- & Omit<Ctx, "payload" | "json">
1799- & Payload<P>
1800- & FetchJson<
1801- ApiSuccess,
1802- ApiError extends unknown ? Ctx["_error"] : ApiError
1803- >
1804+ Omit<Ctx, "payload" | "json"> &
1805+ Payload<P> &
1806+ FetchJson<
1807+ ApiSuccess,
1808+ ApiError extends unknown ? Ctx["_error"] : ApiError
1809+ >
1810 >,
1811 ): CreateActionWithPayload<
1812- & Omit<Ctx, "payload" | "json">
1813- & Payload<P>
1814- & FetchJson<
1815- ApiSuccess,
1816- ApiError extends unknown ? Ctx["_error"] : ApiError
1817- >,
1818+ Omit<Ctx, "payload" | "json"> &
1819+ Payload<P> &
1820+ FetchJson<
1821+ ApiSuccess,
1822+ ApiError extends unknown ? Ctx["_error"] : ApiError
1823+ >,
1824 P,
1825 ApiSuccess
1826 >;
1827@@ -1666,22 +1675,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1828 patch<P extends never, ApiSuccess, ApiError = unknown>(
1829 name: ApiName,
1830 ): CreateAction<
1831- & Omit<Ctx, "json">
1832- & FetchJson<
1833- ApiSuccess,
1834- ApiError extends unknown ? Ctx["_error"] : ApiError
1835- >,
1836+ Omit<Ctx, "json"> &
1837+ FetchJson<
1838+ ApiSuccess,
1839+ ApiError extends unknown ? Ctx["_error"] : ApiError
1840+ >,
1841 ApiSuccess
1842 >;
1843 patch<P, ApiSuccess, ApiError = unknown>(
1844 name: ApiName,
1845 ): CreateActionWithPayload<
1846- & Omit<Ctx, "payload" | "json">
1847- & Payload<P>
1848- & FetchJson<
1849- ApiSuccess,
1850- ApiError extends unknown ? Ctx["_error"] : ApiError
1851- >,
1852+ Omit<Ctx, "payload" | "json"> &
1853+ Payload<P> &
1854+ FetchJson<
1855+ ApiSuccess,
1856+ ApiError extends unknown ? Ctx["_error"] : ApiError
1857+ >,
1858 P,
1859 ApiSuccess
1860 >;
1861@@ -1702,23 +1711,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1862 name: ApiName,
1863 req: { supervisor?: Supervisor },
1864 ): CreateAction<
1865- & Omit<Ctx, "json">
1866- & FetchJson<
1867- ApiSuccess,
1868- ApiError extends unknown ? Ctx["_error"] : ApiError
1869- >,
1870+ Omit<Ctx, "json"> &
1871+ FetchJson<
1872+ ApiSuccess,
1873+ ApiError extends unknown ? Ctx["_error"] : ApiError
1874+ >,
1875 ApiSuccess
1876 >;
1877 patch<P, ApiSuccess, ApiError = unknown>(
1878 name: ApiName,
1879 req: { supervisor?: Supervisor },
1880 ): CreateActionWithPayload<
1881- & Omit<Ctx, "payload" | "json">
1882- & Payload<P>
1883- & FetchJson<
1884- ApiSuccess,
1885- ApiError extends unknown ? Ctx["_error"] : ApiError
1886- >,
1887+ Omit<Ctx, "payload" | "json"> &
1888+ Payload<P> &
1889+ FetchJson<
1890+ ApiSuccess,
1891+ ApiError extends unknown ? Ctx["_error"] : ApiError
1892+ >,
1893 P,
1894 ApiSuccess
1895 >;
1896@@ -1742,37 +1751,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1897 patch<P extends never, ApiSuccess, ApiError = unknown>(
1898 name: ApiName,
1899 fn: MiddlewareApiCo<
1900- & Omit<Ctx, "json">
1901- & FetchJson<
1902- ApiSuccess,
1903- ApiError extends unknown ? Ctx["_error"] : ApiError
1904- >
1905+ Omit<Ctx, "json"> &
1906+ FetchJson<
1907+ ApiSuccess,
1908+ ApiError extends unknown ? Ctx["_error"] : ApiError
1909+ >
1910 >,
1911 ): CreateAction<
1912- & Omit<Ctx, "json">
1913- & FetchJson<
1914- ApiSuccess,
1915- ApiError extends unknown ? Ctx["_error"] : ApiError
1916- >,
1917+ Omit<Ctx, "json"> &
1918+ FetchJson<
1919+ ApiSuccess,
1920+ ApiError extends unknown ? Ctx["_error"] : ApiError
1921+ >,
1922 ApiSuccess
1923 >;
1924 patch<P, ApiSuccess, ApiError = unknown>(
1925 name: ApiName,
1926 fn: MiddlewareApiCo<
1927- & Omit<Ctx, "payload" | "json">
1928- & Payload<P>
1929- & FetchJson<
1930- ApiSuccess,
1931- ApiError extends unknown ? Ctx["_error"] : ApiError
1932- >
1933+ Omit<Ctx, "payload" | "json"> &
1934+ Payload<P> &
1935+ FetchJson<
1936+ ApiSuccess,
1937+ ApiError extends unknown ? Ctx["_error"] : ApiError
1938+ >
1939 >,
1940 ): CreateActionWithPayload<
1941- & Omit<Ctx, "payload" | "json">
1942- & Payload<P>
1943- & FetchJson<
1944- ApiSuccess,
1945- ApiError extends unknown ? Ctx["_error"] : ApiError
1946- >,
1947+ Omit<Ctx, "payload" | "json"> &
1948+ Payload<P> &
1949+ FetchJson<
1950+ ApiSuccess,
1951+ ApiError extends unknown ? Ctx["_error"] : ApiError
1952+ >,
1953 P,
1954 ApiSuccess
1955 >;
1956@@ -1804,38 +1813,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
1957 name: ApiName,
1958 req: { supervisor?: Supervisor },
1959 fn: MiddlewareApiCo<
1960- & Omit<Ctx, "json">
1961- & FetchJson<
1962- ApiSuccess,
1963- ApiError extends unknown ? Ctx["_error"] : ApiError
1964- >
1965+ Omit<Ctx, "json"> &
1966+ FetchJson<
1967+ ApiSuccess,
1968+ ApiError extends unknown ? Ctx["_error"] : ApiError
1969+ >
1970 >,
1971 ): CreateAction<
1972- & Omit<Ctx, "json">
1973- & FetchJson<
1974- ApiSuccess,
1975- ApiError extends unknown ? Ctx["_error"] : ApiError
1976- >,
1977+ Omit<Ctx, "json"> &
1978+ FetchJson<
1979+ ApiSuccess,
1980+ ApiError extends unknown ? Ctx["_error"] : ApiError
1981+ >,
1982 ApiSuccess
1983 >;
1984 patch<P, ApiSuccess, ApiError = unknown>(
1985 name: ApiName,
1986 req: { supervisor?: Supervisor },
1987 fn: MiddlewareApiCo<
1988- & Omit<Ctx, "payload" | "json">
1989- & Payload<P>
1990- & FetchJson<
1991- ApiSuccess,
1992- ApiError extends unknown ? Ctx["_error"] : ApiError
1993- >
1994+ Omit<Ctx, "payload" | "json"> &
1995+ Payload<P> &
1996+ FetchJson<
1997+ ApiSuccess,
1998+ ApiError extends unknown ? Ctx["_error"] : ApiError
1999+ >
2000 >,
2001 ): CreateActionWithPayload<
2002- & Omit<Ctx, "payload" | "json">
2003- & Payload<P>
2004- & FetchJson<
2005- ApiSuccess,
2006- ApiError extends unknown ? Ctx["_error"] : ApiError
2007- >,
2008+ Omit<Ctx, "payload" | "json"> &
2009+ Payload<P> &
2010+ FetchJson<
2011+ ApiSuccess,
2012+ ApiError extends unknown ? Ctx["_error"] : ApiError
2013+ >,
2014 P,
2015 ApiSuccess
2016 >;
2017@@ -1850,22 +1859,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2018 delete<P extends never, ApiSuccess, ApiError = unknown>(
2019 name: ApiName,
2020 ): CreateAction<
2021- & Omit<Ctx, "json">
2022- & FetchJson<
2023- ApiSuccess,
2024- ApiError extends unknown ? Ctx["_error"] : ApiError
2025- >,
2026+ Omit<Ctx, "json"> &
2027+ FetchJson<
2028+ ApiSuccess,
2029+ ApiError extends unknown ? Ctx["_error"] : ApiError
2030+ >,
2031 ApiSuccess
2032 >;
2033 delete<P, ApiSuccess, ApiError = unknown>(
2034 name: ApiName,
2035 ): CreateActionWithPayload<
2036- & Omit<Ctx, "payload" | "json">
2037- & Payload<P>
2038- & FetchJson<
2039- ApiSuccess,
2040- ApiError extends unknown ? Ctx["_error"] : ApiError
2041- >,
2042+ Omit<Ctx, "payload" | "json"> &
2043+ Payload<P> &
2044+ FetchJson<
2045+ ApiSuccess,
2046+ ApiError extends unknown ? Ctx["_error"] : ApiError
2047+ >,
2048 P,
2049 ApiSuccess
2050 >;
2051@@ -1886,23 +1895,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2052 name: ApiName,
2053 req: { supervisor?: Supervisor },
2054 ): CreateAction<
2055- & Omit<Ctx, "json">
2056- & FetchJson<
2057- ApiSuccess,
2058- ApiError extends unknown ? Ctx["_error"] : ApiError
2059- >,
2060+ Omit<Ctx, "json"> &
2061+ FetchJson<
2062+ ApiSuccess,
2063+ ApiError extends unknown ? Ctx["_error"] : ApiError
2064+ >,
2065 ApiSuccess
2066 >;
2067 delete<P, ApiSuccess, ApiError = unknown>(
2068 name: ApiName,
2069 req: { supervisor?: Supervisor },
2070 ): CreateActionWithPayload<
2071- & Omit<Ctx, "payload" | "json">
2072- & Payload<P>
2073- & FetchJson<
2074- ApiSuccess,
2075- ApiError extends unknown ? Ctx["_error"] : ApiError
2076- >,
2077+ Omit<Ctx, "payload" | "json"> &
2078+ Payload<P> &
2079+ FetchJson<
2080+ ApiSuccess,
2081+ ApiError extends unknown ? Ctx["_error"] : ApiError
2082+ >,
2083 P,
2084 ApiSuccess
2085 >;
2086@@ -1926,37 +1935,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2087 delete<P extends never, ApiSuccess, ApiError = unknown>(
2088 name: ApiName,
2089 fn: MiddlewareApiCo<
2090- & Omit<Ctx, "json">
2091- & FetchJson<
2092- ApiSuccess,
2093- ApiError extends unknown ? Ctx["_error"] : ApiError
2094- >
2095+ Omit<Ctx, "json"> &
2096+ FetchJson<
2097+ ApiSuccess,
2098+ ApiError extends unknown ? Ctx["_error"] : ApiError
2099+ >
2100 >,
2101 ): CreateAction<
2102- & Omit<Ctx, "json">
2103- & FetchJson<
2104- ApiSuccess,
2105- ApiError extends unknown ? Ctx["_error"] : ApiError
2106- >,
2107+ Omit<Ctx, "json"> &
2108+ FetchJson<
2109+ ApiSuccess,
2110+ ApiError extends unknown ? Ctx["_error"] : ApiError
2111+ >,
2112 ApiSuccess
2113 >;
2114 delete<P, ApiSuccess, ApiError = unknown>(
2115 name: ApiName,
2116 fn: MiddlewareApiCo<
2117- & Omit<Ctx, "payload" | "json">
2118- & Payload<P>
2119- & FetchJson<
2120- ApiSuccess,
2121- ApiError extends unknown ? Ctx["_error"] : ApiError
2122- >
2123+ Omit<Ctx, "payload" | "json"> &
2124+ Payload<P> &
2125+ FetchJson<
2126+ ApiSuccess,
2127+ ApiError extends unknown ? Ctx["_error"] : ApiError
2128+ >
2129 >,
2130 ): CreateActionWithPayload<
2131- & Omit<Ctx, "payload" | "json">
2132- & Payload<P>
2133- & FetchJson<
2134- ApiSuccess,
2135- ApiError extends unknown ? Ctx["_error"] : ApiError
2136- >,
2137+ Omit<Ctx, "payload" | "json"> &
2138+ Payload<P> &
2139+ FetchJson<
2140+ ApiSuccess,
2141+ ApiError extends unknown ? Ctx["_error"] : ApiError
2142+ >,
2143 P,
2144 ApiSuccess
2145 >;
2146@@ -1988,38 +1997,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2147 name: ApiName,
2148 req: { supervisor?: Supervisor },
2149 fn: MiddlewareApiCo<
2150- & Omit<Ctx, "json">
2151- & FetchJson<
2152- ApiSuccess,
2153- ApiError extends unknown ? Ctx["_error"] : ApiError
2154- >
2155+ Omit<Ctx, "json"> &
2156+ FetchJson<
2157+ ApiSuccess,
2158+ ApiError extends unknown ? Ctx["_error"] : ApiError
2159+ >
2160 >,
2161 ): CreateAction<
2162- & Omit<Ctx, "json">
2163- & FetchJson<
2164- ApiSuccess,
2165- ApiError extends unknown ? Ctx["_error"] : ApiError
2166- >,
2167+ Omit<Ctx, "json"> &
2168+ FetchJson<
2169+ ApiSuccess,
2170+ ApiError extends unknown ? Ctx["_error"] : ApiError
2171+ >,
2172 ApiSuccess
2173 >;
2174 delete<P, ApiSuccess, ApiError = unknown>(
2175 name: ApiName,
2176 req: { supervisor?: Supervisor },
2177 fn: MiddlewareApiCo<
2178- & Omit<Ctx, "payload" | "json">
2179- & Payload<P>
2180- & FetchJson<
2181- ApiSuccess,
2182- ApiError extends unknown ? Ctx["_error"] : ApiError
2183- >
2184+ Omit<Ctx, "payload" | "json"> &
2185+ Payload<P> &
2186+ FetchJson<
2187+ ApiSuccess,
2188+ ApiError extends unknown ? Ctx["_error"] : ApiError
2189+ >
2190 >,
2191 ): CreateActionWithPayload<
2192- & Omit<Ctx, "payload" | "json">
2193- & Payload<P>
2194- & FetchJson<
2195- ApiSuccess,
2196- ApiError extends unknown ? Ctx["_error"] : ApiError
2197- >,
2198+ Omit<Ctx, "payload" | "json"> &
2199+ Payload<P> &
2200+ FetchJson<
2201+ ApiSuccess,
2202+ ApiError extends unknown ? Ctx["_error"] : ApiError
2203+ >,
2204 P,
2205 ApiSuccess
2206 >;
2207@@ -2034,22 +2043,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2208 options<P extends never, ApiSuccess, ApiError = unknown>(
2209 name: ApiName,
2210 ): CreateAction<
2211- & Omit<Ctx, "json">
2212- & FetchJson<
2213- ApiSuccess,
2214- ApiError extends unknown ? Ctx["_error"] : ApiError
2215- >,
2216+ Omit<Ctx, "json"> &
2217+ FetchJson<
2218+ ApiSuccess,
2219+ ApiError extends unknown ? Ctx["_error"] : ApiError
2220+ >,
2221 ApiSuccess
2222 >;
2223 options<P, ApiSuccess, ApiError = unknown>(
2224 name: ApiName,
2225 ): CreateActionWithPayload<
2226- & Omit<Ctx, "payload" | "json">
2227- & Payload<P>
2228- & FetchJson<
2229- ApiSuccess,
2230- ApiError extends unknown ? Ctx["_error"] : ApiError
2231- >,
2232+ Omit<Ctx, "payload" | "json"> &
2233+ Payload<P> &
2234+ FetchJson<
2235+ ApiSuccess,
2236+ ApiError extends unknown ? Ctx["_error"] : ApiError
2237+ >,
2238 P,
2239 ApiSuccess
2240 >;
2241@@ -2070,23 +2079,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2242 name: ApiName,
2243 req: { supervisor?: Supervisor },
2244 ): CreateAction<
2245- & Omit<Ctx, "json">
2246- & FetchJson<
2247- ApiSuccess,
2248- ApiError extends unknown ? Ctx["_error"] : ApiError
2249- >,
2250+ Omit<Ctx, "json"> &
2251+ FetchJson<
2252+ ApiSuccess,
2253+ ApiError extends unknown ? Ctx["_error"] : ApiError
2254+ >,
2255 ApiSuccess
2256 >;
2257 options<P, ApiSuccess, ApiError = unknown>(
2258 name: ApiName,
2259 req: { supervisor?: Supervisor },
2260 ): CreateActionWithPayload<
2261- & Omit<Ctx, "payload" | "json">
2262- & Payload<P>
2263- & FetchJson<
2264- ApiSuccess,
2265- ApiError extends unknown ? Ctx["_error"] : ApiError
2266- >,
2267+ Omit<Ctx, "payload" | "json"> &
2268+ Payload<P> &
2269+ FetchJson<
2270+ ApiSuccess,
2271+ ApiError extends unknown ? Ctx["_error"] : ApiError
2272+ >,
2273 P,
2274 ApiSuccess
2275 >;
2276@@ -2110,37 +2119,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2277 options<P extends never, ApiSuccess, ApiError = unknown>(
2278 name: ApiName,
2279 fn: MiddlewareApiCo<
2280- & Omit<Ctx, "json">
2281- & FetchJson<
2282- ApiSuccess,
2283- ApiError extends unknown ? Ctx["_error"] : ApiError
2284- >
2285+ Omit<Ctx, "json"> &
2286+ FetchJson<
2287+ ApiSuccess,
2288+ ApiError extends unknown ? Ctx["_error"] : ApiError
2289+ >
2290 >,
2291 ): CreateAction<
2292- & Omit<Ctx, "json">
2293- & FetchJson<
2294- ApiSuccess,
2295- ApiError extends unknown ? Ctx["_error"] : ApiError
2296- >,
2297+ Omit<Ctx, "json"> &
2298+ FetchJson<
2299+ ApiSuccess,
2300+ ApiError extends unknown ? Ctx["_error"] : ApiError
2301+ >,
2302 ApiSuccess
2303 >;
2304 options<P, ApiSuccess, ApiError = unknown>(
2305 name: ApiName,
2306 fn: MiddlewareApiCo<
2307- & Omit<Ctx, "payload" | "json">
2308- & Payload<P>
2309- & FetchJson<
2310- ApiSuccess,
2311- ApiError extends unknown ? Ctx["_error"] : ApiError
2312- >
2313+ Omit<Ctx, "payload" | "json"> &
2314+ Payload<P> &
2315+ FetchJson<
2316+ ApiSuccess,
2317+ ApiError extends unknown ? Ctx["_error"] : ApiError
2318+ >
2319 >,
2320 ): CreateActionWithPayload<
2321- & Omit<Ctx, "payload" | "json">
2322- & Payload<P>
2323- & FetchJson<
2324- ApiSuccess,
2325- ApiError extends unknown ? Ctx["_error"] : ApiError
2326- >,
2327+ Omit<Ctx, "payload" | "json"> &
2328+ Payload<P> &
2329+ FetchJson<
2330+ ApiSuccess,
2331+ ApiError extends unknown ? Ctx["_error"] : ApiError
2332+ >,
2333 P,
2334 ApiSuccess
2335 >;
2336@@ -2172,38 +2181,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2337 name: ApiName,
2338 req: { supervisor?: Supervisor },
2339 fn: MiddlewareApiCo<
2340- & Omit<Ctx, "json">
2341- & FetchJson<
2342- ApiSuccess,
2343- ApiError extends unknown ? Ctx["_error"] : ApiError
2344- >
2345+ Omit<Ctx, "json"> &
2346+ FetchJson<
2347+ ApiSuccess,
2348+ ApiError extends unknown ? Ctx["_error"] : ApiError
2349+ >
2350 >,
2351 ): CreateAction<
2352- & Omit<Ctx, "json">
2353- & FetchJson<
2354- ApiSuccess,
2355- ApiError extends unknown ? Ctx["_error"] : ApiError
2356- >,
2357+ Omit<Ctx, "json"> &
2358+ FetchJson<
2359+ ApiSuccess,
2360+ ApiError extends unknown ? Ctx["_error"] : ApiError
2361+ >,
2362 ApiSuccess
2363 >;
2364 options<P, ApiSuccess, ApiError = unknown>(
2365 name: ApiName,
2366 req: { supervisor?: Supervisor },
2367 fn: MiddlewareApiCo<
2368- & Omit<Ctx, "payload" | "json">
2369- & Payload<P>
2370- & FetchJson<
2371- ApiSuccess,
2372- ApiError extends unknown ? Ctx["_error"] : ApiError
2373- >
2374+ Omit<Ctx, "payload" | "json"> &
2375+ Payload<P> &
2376+ FetchJson<
2377+ ApiSuccess,
2378+ ApiError extends unknown ? Ctx["_error"] : ApiError
2379+ >
2380 >,
2381 ): CreateActionWithPayload<
2382- & Omit<Ctx, "payload" | "json">
2383- & Payload<P>
2384- & FetchJson<
2385- ApiSuccess,
2386- ApiError extends unknown ? Ctx["_error"] : ApiError
2387- >,
2388+ Omit<Ctx, "payload" | "json"> &
2389+ Payload<P> &
2390+ FetchJson<
2391+ ApiSuccess,
2392+ ApiError extends unknown ? Ctx["_error"] : ApiError
2393+ >,
2394 P,
2395 ApiSuccess
2396 >;
2397@@ -2218,22 +2227,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2398 head<P extends never, ApiSuccess, ApiError = unknown>(
2399 name: ApiName,
2400 ): CreateAction<
2401- & Omit<Ctx, "json">
2402- & FetchJson<
2403- ApiSuccess,
2404- ApiError extends unknown ? Ctx["_error"] : ApiError
2405- >,
2406+ Omit<Ctx, "json"> &
2407+ FetchJson<
2408+ ApiSuccess,
2409+ ApiError extends unknown ? Ctx["_error"] : ApiError
2410+ >,
2411 ApiSuccess
2412 >;
2413 head<P, ApiSuccess, ApiError = unknown>(
2414 name: ApiName,
2415 ): CreateActionWithPayload<
2416- & Omit<Ctx, "payload" | "json">
2417- & Payload<P>
2418- & FetchJson<
2419- ApiSuccess,
2420- ApiError extends unknown ? Ctx["_error"] : ApiError
2421- >,
2422+ Omit<Ctx, "payload" | "json"> &
2423+ Payload<P> &
2424+ FetchJson<
2425+ ApiSuccess,
2426+ ApiError extends unknown ? Ctx["_error"] : ApiError
2427+ >,
2428 P,
2429 ApiSuccess
2430 >;
2431@@ -2254,23 +2263,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2432 name: ApiName,
2433 req: { supervisor?: Supervisor },
2434 ): CreateAction<
2435- & Omit<Ctx, "json">
2436- & FetchJson<
2437- ApiSuccess,
2438- ApiError extends unknown ? Ctx["_error"] : ApiError
2439- >,
2440+ Omit<Ctx, "json"> &
2441+ FetchJson<
2442+ ApiSuccess,
2443+ ApiError extends unknown ? Ctx["_error"] : ApiError
2444+ >,
2445 ApiSuccess
2446 >;
2447 head<P, ApiSuccess, ApiError = unknown>(
2448 name: ApiName,
2449 req: { supervisor?: Supervisor },
2450 ): CreateActionWithPayload<
2451- & Omit<Ctx, "payload" | "json">
2452- & Payload<P>
2453- & FetchJson<
2454- ApiSuccess,
2455- ApiError extends unknown ? Ctx["_error"] : ApiError
2456- >,
2457+ Omit<Ctx, "payload" | "json"> &
2458+ Payload<P> &
2459+ FetchJson<
2460+ ApiSuccess,
2461+ ApiError extends unknown ? Ctx["_error"] : ApiError
2462+ >,
2463 P,
2464 ApiSuccess
2465 >;
2466@@ -2294,37 +2303,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2467 head<P extends never, ApiSuccess, ApiError = unknown>(
2468 name: ApiName,
2469 fn: MiddlewareApiCo<
2470- & Omit<Ctx, "json">
2471- & FetchJson<
2472- ApiSuccess,
2473- ApiError extends unknown ? Ctx["_error"] : ApiError
2474- >
2475+ Omit<Ctx, "json"> &
2476+ FetchJson<
2477+ ApiSuccess,
2478+ ApiError extends unknown ? Ctx["_error"] : ApiError
2479+ >
2480 >,
2481 ): CreateAction<
2482- & Omit<Ctx, "json">
2483- & FetchJson<
2484- ApiSuccess,
2485- ApiError extends unknown ? Ctx["_error"] : ApiError
2486- >,
2487+ Omit<Ctx, "json"> &
2488+ FetchJson<
2489+ ApiSuccess,
2490+ ApiError extends unknown ? Ctx["_error"] : ApiError
2491+ >,
2492 ApiSuccess
2493 >;
2494 head<P, ApiSuccess, ApiError = unknown>(
2495 name: ApiName,
2496 fn: MiddlewareApiCo<
2497- & Omit<Ctx, "payload" | "json">
2498- & Payload<P>
2499- & FetchJson<
2500- ApiSuccess,
2501- ApiError extends unknown ? Ctx["_error"] : ApiError
2502- >
2503+ Omit<Ctx, "payload" | "json"> &
2504+ Payload<P> &
2505+ FetchJson<
2506+ ApiSuccess,
2507+ ApiError extends unknown ? Ctx["_error"] : ApiError
2508+ >
2509 >,
2510 ): CreateActionWithPayload<
2511- & Omit<Ctx, "payload" | "json">
2512- & Payload<P>
2513- & FetchJson<
2514- ApiSuccess,
2515- ApiError extends unknown ? Ctx["_error"] : ApiError
2516- >,
2517+ Omit<Ctx, "payload" | "json"> &
2518+ Payload<P> &
2519+ FetchJson<
2520+ ApiSuccess,
2521+ ApiError extends unknown ? Ctx["_error"] : ApiError
2522+ >,
2523 P,
2524 ApiSuccess
2525 >;
2526@@ -2356,38 +2365,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2527 name: ApiName,
2528 req: { supervisor?: Supervisor },
2529 fn: MiddlewareApiCo<
2530- & Omit<Ctx, "json">
2531- & FetchJson<
2532- ApiSuccess,
2533- ApiError extends unknown ? Ctx["_error"] : ApiError
2534- >
2535+ Omit<Ctx, "json"> &
2536+ FetchJson<
2537+ ApiSuccess,
2538+ ApiError extends unknown ? Ctx["_error"] : ApiError
2539+ >
2540 >,
2541 ): CreateAction<
2542- & Omit<Ctx, "json">
2543- & FetchJson<
2544- ApiSuccess,
2545- ApiError extends unknown ? Ctx["_error"] : ApiError
2546- >,
2547+ Omit<Ctx, "json"> &
2548+ FetchJson<
2549+ ApiSuccess,
2550+ ApiError extends unknown ? Ctx["_error"] : ApiError
2551+ >,
2552 ApiSuccess
2553 >;
2554 head<P, ApiSuccess, ApiError = unknown>(
2555 name: ApiName,
2556 req: { supervisor?: Supervisor },
2557 fn: MiddlewareApiCo<
2558- & Omit<Ctx, "payload" | "json">
2559- & Payload<P>
2560- & FetchJson<
2561- ApiSuccess,
2562- ApiError extends unknown ? Ctx["_error"] : ApiError
2563- >
2564+ Omit<Ctx, "payload" | "json"> &
2565+ Payload<P> &
2566+ FetchJson<
2567+ ApiSuccess,
2568+ ApiError extends unknown ? Ctx["_error"] : ApiError
2569+ >
2570 >,
2571 ): CreateActionWithPayload<
2572- & Omit<Ctx, "payload" | "json">
2573- & Payload<P>
2574- & FetchJson<
2575- ApiSuccess,
2576- ApiError extends unknown ? Ctx["_error"] : ApiError
2577- >,
2578+ Omit<Ctx, "payload" | "json"> &
2579+ Payload<P> &
2580+ FetchJson<
2581+ ApiSuccess,
2582+ ApiError extends unknown ? Ctx["_error"] : ApiError
2583+ >,
2584 P,
2585 ApiSuccess
2586 >;
2587@@ -2402,22 +2411,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2588 connect<P extends never, ApiSuccess, ApiError = unknown>(
2589 name: ApiName,
2590 ): CreateAction<
2591- & Omit<Ctx, "json">
2592- & FetchJson<
2593- ApiSuccess,
2594- ApiError extends unknown ? Ctx["_error"] : ApiError
2595- >,
2596+ Omit<Ctx, "json"> &
2597+ FetchJson<
2598+ ApiSuccess,
2599+ ApiError extends unknown ? Ctx["_error"] : ApiError
2600+ >,
2601 ApiSuccess
2602 >;
2603 connect<P, ApiSuccess, ApiError = unknown>(
2604 name: ApiName,
2605 ): CreateActionWithPayload<
2606- & Omit<Ctx, "payload" | "json">
2607- & Payload<P>
2608- & FetchJson<
2609- ApiSuccess,
2610- ApiError extends unknown ? Ctx["_error"] : ApiError
2611- >,
2612+ Omit<Ctx, "payload" | "json"> &
2613+ Payload<P> &
2614+ FetchJson<
2615+ ApiSuccess,
2616+ ApiError extends unknown ? Ctx["_error"] : ApiError
2617+ >,
2618 P,
2619 ApiSuccess
2620 >;
2621@@ -2438,23 +2447,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2622 name: ApiName,
2623 req: { supervisor?: Supervisor },
2624 ): CreateAction<
2625- & Omit<Ctx, "json">
2626- & FetchJson<
2627- ApiSuccess,
2628- ApiError extends unknown ? Ctx["_error"] : ApiError
2629- >,
2630+ Omit<Ctx, "json"> &
2631+ FetchJson<
2632+ ApiSuccess,
2633+ ApiError extends unknown ? Ctx["_error"] : ApiError
2634+ >,
2635 ApiSuccess
2636 >;
2637 connect<P, ApiSuccess, ApiError = unknown>(
2638 name: ApiName,
2639 req: { supervisor?: Supervisor },
2640 ): CreateActionWithPayload<
2641- & Omit<Ctx, "payload" | "json">
2642- & Payload<P>
2643- & FetchJson<
2644- ApiSuccess,
2645- ApiError extends unknown ? Ctx["_error"] : ApiError
2646- >,
2647+ Omit<Ctx, "payload" | "json"> &
2648+ Payload<P> &
2649+ FetchJson<
2650+ ApiSuccess,
2651+ ApiError extends unknown ? Ctx["_error"] : ApiError
2652+ >,
2653 P,
2654 ApiSuccess
2655 >;
2656@@ -2478,37 +2487,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2657 connect<P extends never, ApiSuccess, ApiError = unknown>(
2658 name: ApiName,
2659 fn: MiddlewareApiCo<
2660- & Omit<Ctx, "json">
2661- & FetchJson<
2662- ApiSuccess,
2663- ApiError extends unknown ? Ctx["_error"] : ApiError
2664- >
2665+ Omit<Ctx, "json"> &
2666+ FetchJson<
2667+ ApiSuccess,
2668+ ApiError extends unknown ? Ctx["_error"] : ApiError
2669+ >
2670 >,
2671 ): CreateAction<
2672- & Omit<Ctx, "json">
2673- & FetchJson<
2674- ApiSuccess,
2675- ApiError extends unknown ? Ctx["_error"] : ApiError
2676- >,
2677+ Omit<Ctx, "json"> &
2678+ FetchJson<
2679+ ApiSuccess,
2680+ ApiError extends unknown ? Ctx["_error"] : ApiError
2681+ >,
2682 ApiSuccess
2683 >;
2684 connect<P, ApiSuccess, ApiError = unknown>(
2685 name: ApiName,
2686 fn: MiddlewareApiCo<
2687- & Omit<Ctx, "payload" | "json">
2688- & Payload<P>
2689- & FetchJson<
2690- ApiSuccess,
2691- ApiError extends unknown ? Ctx["_error"] : ApiError
2692- >
2693+ Omit<Ctx, "payload" | "json"> &
2694+ Payload<P> &
2695+ FetchJson<
2696+ ApiSuccess,
2697+ ApiError extends unknown ? Ctx["_error"] : ApiError
2698+ >
2699 >,
2700 ): CreateActionWithPayload<
2701- & Omit<Ctx, "payload" | "json">
2702- & Payload<P>
2703- & FetchJson<
2704- ApiSuccess,
2705- ApiError extends unknown ? Ctx["_error"] : ApiError
2706- >,
2707+ Omit<Ctx, "payload" | "json"> &
2708+ Payload<P> &
2709+ FetchJson<
2710+ ApiSuccess,
2711+ ApiError extends unknown ? Ctx["_error"] : ApiError
2712+ >,
2713 P,
2714 ApiSuccess
2715 >;
2716@@ -2540,38 +2549,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2717 name: ApiName,
2718 req: { supervisor?: Supervisor },
2719 fn: MiddlewareApiCo<
2720- & Omit<Ctx, "json">
2721- & FetchJson<
2722- ApiSuccess,
2723- ApiError extends unknown ? Ctx["_error"] : ApiError
2724- >
2725+ Omit<Ctx, "json"> &
2726+ FetchJson<
2727+ ApiSuccess,
2728+ ApiError extends unknown ? Ctx["_error"] : ApiError
2729+ >
2730 >,
2731 ): CreateAction<
2732- & Omit<Ctx, "json">
2733- & FetchJson<
2734- ApiSuccess,
2735- ApiError extends unknown ? Ctx["_error"] : ApiError
2736- >,
2737+ Omit<Ctx, "json"> &
2738+ FetchJson<
2739+ ApiSuccess,
2740+ ApiError extends unknown ? Ctx["_error"] : ApiError
2741+ >,
2742 ApiSuccess
2743 >;
2744 connect<P, ApiSuccess, ApiError = unknown>(
2745 name: ApiName,
2746 req: { supervisor?: Supervisor },
2747 fn: MiddlewareApiCo<
2748- & Omit<Ctx, "payload" | "json">
2749- & Payload<P>
2750- & FetchJson<
2751- ApiSuccess,
2752- ApiError extends unknown ? Ctx["_error"] : ApiError
2753- >
2754+ Omit<Ctx, "payload" | "json"> &
2755+ Payload<P> &
2756+ FetchJson<
2757+ ApiSuccess,
2758+ ApiError extends unknown ? Ctx["_error"] : ApiError
2759+ >
2760 >,
2761 ): CreateActionWithPayload<
2762- & Omit<Ctx, "payload" | "json">
2763- & Payload<P>
2764- & FetchJson<
2765- ApiSuccess,
2766- ApiError extends unknown ? Ctx["_error"] : ApiError
2767- >,
2768+ Omit<Ctx, "payload" | "json"> &
2769+ Payload<P> &
2770+ FetchJson<
2771+ ApiSuccess,
2772+ ApiError extends unknown ? Ctx["_error"] : ApiError
2773+ >,
2774 P,
2775 ApiSuccess
2776 >;
2777@@ -2586,22 +2595,22 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2778 trace<P extends never, ApiSuccess, ApiError = unknown>(
2779 name: ApiName,
2780 ): CreateAction<
2781- & Omit<Ctx, "json">
2782- & FetchJson<
2783- ApiSuccess,
2784- ApiError extends unknown ? Ctx["_error"] : ApiError
2785- >,
2786+ Omit<Ctx, "json"> &
2787+ FetchJson<
2788+ ApiSuccess,
2789+ ApiError extends unknown ? Ctx["_error"] : ApiError
2790+ >,
2791 ApiSuccess
2792 >;
2793 trace<P, ApiSuccess, ApiError = unknown>(
2794 name: ApiName,
2795 ): CreateActionWithPayload<
2796- & Omit<Ctx, "payload" | "json">
2797- & Payload<P>
2798- & FetchJson<
2799- ApiSuccess,
2800- ApiError extends unknown ? Ctx["_error"] : ApiError
2801- >,
2802+ Omit<Ctx, "payload" | "json"> &
2803+ Payload<P> &
2804+ FetchJson<
2805+ ApiSuccess,
2806+ ApiError extends unknown ? Ctx["_error"] : ApiError
2807+ >,
2808 P,
2809 ApiSuccess
2810 >;
2811@@ -2622,23 +2631,23 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2812 name: ApiName,
2813 req: { supervisor?: Supervisor },
2814 ): CreateAction<
2815- & Omit<Ctx, "json">
2816- & FetchJson<
2817- ApiSuccess,
2818- ApiError extends unknown ? Ctx["_error"] : ApiError
2819- >,
2820+ Omit<Ctx, "json"> &
2821+ FetchJson<
2822+ ApiSuccess,
2823+ ApiError extends unknown ? Ctx["_error"] : ApiError
2824+ >,
2825 ApiSuccess
2826 >;
2827 trace<P, ApiSuccess, ApiError = unknown>(
2828 name: ApiName,
2829 req: { supervisor?: Supervisor },
2830 ): CreateActionWithPayload<
2831- & Omit<Ctx, "payload" | "json">
2832- & Payload<P>
2833- & FetchJson<
2834- ApiSuccess,
2835- ApiError extends unknown ? Ctx["_error"] : ApiError
2836- >,
2837+ Omit<Ctx, "payload" | "json"> &
2838+ Payload<P> &
2839+ FetchJson<
2840+ ApiSuccess,
2841+ ApiError extends unknown ? Ctx["_error"] : ApiError
2842+ >,
2843 P,
2844 ApiSuccess
2845 >;
2846@@ -2662,37 +2671,37 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2847 trace<P extends never, ApiSuccess, ApiError = unknown>(
2848 name: ApiName,
2849 fn: MiddlewareApiCo<
2850- & Omit<Ctx, "json">
2851- & FetchJson<
2852- ApiSuccess,
2853- ApiError extends unknown ? Ctx["_error"] : ApiError
2854- >
2855+ Omit<Ctx, "json"> &
2856+ FetchJson<
2857+ ApiSuccess,
2858+ ApiError extends unknown ? Ctx["_error"] : ApiError
2859+ >
2860 >,
2861 ): CreateAction<
2862- & Omit<Ctx, "json">
2863- & FetchJson<
2864- ApiSuccess,
2865- ApiError extends unknown ? Ctx["_error"] : ApiError
2866- >,
2867+ Omit<Ctx, "json"> &
2868+ FetchJson<
2869+ ApiSuccess,
2870+ ApiError extends unknown ? Ctx["_error"] : ApiError
2871+ >,
2872 ApiSuccess
2873 >;
2874 trace<P, ApiSuccess, ApiError = unknown>(
2875 name: ApiName,
2876 fn: MiddlewareApiCo<
2877- & Omit<Ctx, "payload" | "json">
2878- & Payload<P>
2879- & FetchJson<
2880- ApiSuccess,
2881- ApiError extends unknown ? Ctx["_error"] : ApiError
2882- >
2883+ Omit<Ctx, "payload" | "json"> &
2884+ Payload<P> &
2885+ FetchJson<
2886+ ApiSuccess,
2887+ ApiError extends unknown ? Ctx["_error"] : ApiError
2888+ >
2889 >,
2890 ): CreateActionWithPayload<
2891- & Omit<Ctx, "payload" | "json">
2892- & Payload<P>
2893- & FetchJson<
2894- ApiSuccess,
2895- ApiError extends unknown ? Ctx["_error"] : ApiError
2896- >,
2897+ Omit<Ctx, "payload" | "json"> &
2898+ Payload<P> &
2899+ FetchJson<
2900+ ApiSuccess,
2901+ ApiError extends unknown ? Ctx["_error"] : ApiError
2902+ >,
2903 P,
2904 ApiSuccess
2905 >;
2906@@ -2724,38 +2733,38 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
2907 name: ApiName,
2908 req: { supervisor?: Supervisor },
2909 fn: MiddlewareApiCo<
2910- & Omit<Ctx, "json">
2911- & FetchJson<
2912- ApiSuccess,
2913- ApiError extends unknown ? Ctx["_error"] : ApiError
2914- >
2915+ Omit<Ctx, "json"> &
2916+ FetchJson<
2917+ ApiSuccess,
2918+ ApiError extends unknown ? Ctx["_error"] : ApiError
2919+ >
2920 >,
2921 ): CreateAction<
2922- & Omit<Ctx, "json">
2923- & FetchJson<
2924- ApiSuccess,
2925- ApiError extends unknown ? Ctx["_error"] : ApiError
2926- >,
2927+ Omit<Ctx, "json"> &
2928+ FetchJson<
2929+ ApiSuccess,
2930+ ApiError extends unknown ? Ctx["_error"] : ApiError
2931+ >,
2932 ApiSuccess
2933 >;
2934 trace<P, ApiSuccess, ApiError = unknown>(
2935 name: ApiName,
2936 req: { supervisor?: Supervisor },
2937 fn: MiddlewareApiCo<
2938- & Omit<Ctx, "payload" | "json">
2939- & Payload<P>
2940- & FetchJson<
2941- ApiSuccess,
2942- ApiError extends unknown ? Ctx["_error"] : ApiError
2943- >
2944+ Omit<Ctx, "payload" | "json"> &
2945+ Payload<P> &
2946+ FetchJson<
2947+ ApiSuccess,
2948+ ApiError extends unknown ? Ctx["_error"] : ApiError
2949+ >
2950 >,
2951 ): CreateActionWithPayload<
2952- & Omit<Ctx, "payload" | "json">
2953- & Payload<P>
2954- & FetchJson<
2955- ApiSuccess,
2956- ApiError extends unknown ? Ctx["_error"] : ApiError
2957- >,
2958+ Omit<Ctx, "payload" | "json"> &
2959+ Payload<P> &
2960+ FetchJson<
2961+ ApiSuccess,
2962+ ApiError extends unknown ? Ctx["_error"] : ApiError
2963+ >,
2964 P,
2965 ApiSuccess
2966 >;
R query/api.ts =>
src/query/api.ts
+5,
-5
1@@ -1,9 +1,9 @@
2+import type { Next } from "../types.js";
3+import type { ApiName, QueryApi } from "./api-types.js";
4+import { createThunks } from "./thunk.js";
5+import type { ThunksApi } from "./thunk.js";
6 // deno-lint-ignore-file no-explicit-any
7-import type { ApiCtx, ApiRequest } from "./types.ts";
8-import type { Next } from "../types.ts";
9-import { createThunks } from "./thunk.ts";
10-import type { ThunksApi } from "./thunk.ts";
11-import type { ApiName, QueryApi } from "./api-types.ts";
12+import type { ApiCtx, ApiRequest } from "./types.js";
13
14 /**
15 * Creates a middleware thunksline for HTTP requests.
R query/create-key.ts =>
src/query/create-key.ts
+10,
-8
1@@ -1,4 +1,4 @@
2-import { isObject } from "./util.ts";
3+import { isObject } from "./util.js";
4
5 // deno-lint-ignore no-explicit-any
6 const deepSortObject = (opts?: any) => {
7@@ -15,16 +15,17 @@ const deepSortObject = (opts?: any) => {
8 };
9
10 function padStart(hash: string, len: number) {
11- while (hash.length < len) {
12- hash = "0" + hash;
13+ let hsh = hash;
14+ while (hsh.length < len) {
15+ hsh = `0${hsh}`;
16 }
17- return hash;
18+ return hsh;
19 }
20
21 // https://gist.github.com/iperelivskiy/4110988
22 const tinySimpleHash = (s: string) => {
23 let h = 9;
24- for (let i = 0; i < s.length;) {
25+ for (let i = 0; i < s.length; ) {
26 h = Math.imul(h ^ s.charCodeAt(i++), 9 ** 9);
27 }
28 return h ^ (h >>> 9);
29@@ -35,9 +36,10 @@ const tinySimpleHash = (s: string) => {
30 */
31 // deno-lint-ignore no-explicit-any
32 export const createKey = (name: string, payload?: any) => {
33- const normJsonString = typeof payload !== "undefined"
34- ? JSON.stringify(deepSortObject(payload))
35- : "";
36+ const normJsonString =
37+ typeof payload !== "undefined"
38+ ? JSON.stringify(deepSortObject(payload))
39+ : "";
40 const hash = normJsonString
41 ? padStart(tinySimpleHash(normJsonString).toString(16), 8)
42 : "";
+12,
-0
1@@ -0,0 +1,12 @@
2+import { type ThunksApi, createThunks } from "./thunk.js";
3+
4+export * from "./api.js";
5+export * from "./types.js";
6+export * from "./create-key.js";
7+
8+export { createThunks, type ThunksApi };
9+
10+/**
11+ * @deprecated Use {@link createThunks} instead;
12+ */
13+export const createPipe = createThunks;
R query/thunk.ts =>
src/query/thunk.ts
+17,
-20
1@@ -1,18 +1,18 @@
2-import { ActionContext, API_ACTION_PREFIX, takeEvery } from "../action.ts";
3-import { compose } from "../compose.ts";
4 import {
5 type Callable,
6- ensure,
7 Ok,
8 type Operation,
9 type Signal,
10+ ensure,
11 } from "effection";
12-import { keepAlive, supervise } from "../fx/mod.ts";
13-import { IdContext } from "../store/store.ts";
14-import { createKey } from "./create-key.ts";
15-import { isFn, isObject } from "./util.ts";
16-
17-import type { ActionWithPayload, AnyAction, Next, Payload } from "../types.ts";
18+import { API_ACTION_PREFIX, ActionContext, takeEvery } from "../action.js";
19+import { compose } from "../compose.js";
20+import { keepAlive, supervise } from "../fx/index.js";
21+import { IdContext } from "../store/store.js";
22+import { createKey } from "./create-key.js";
23+import { isFn, isObject } from "./util.js";
24+
25+import type { ActionWithPayload, AnyAction, Next, Payload } from "../types.js";
26 import type {
27 CreateAction,
28 CreateActionPayload,
29@@ -21,7 +21,7 @@ import type {
30 MiddlewareCo,
31 Supervisor,
32 ThunkCtx,
33-} from "./types.ts";
34+} from "./types.js";
35 export interface ThunksApi<Ctx extends ThunkCtx> {
36 use: (fn: Middleware<Ctx>) => void;
37 routes: () => Middleware<Ctx>;
38@@ -169,9 +169,8 @@ export function createThunks<Ctx extends ThunkCtx = ThunkCtx<any>>(
39 }
40
41 function create(name: string, ...args: any[]) {
42- if (Object.hasOwn(visors, name)) {
43- const msg =
44- `[${name}] already exists, do you have two thunks with the same name?`;
45+ if (visors[name]) {
46+ const msg = `[${name}] already exists, do you have two thunks with the same name?`;
47 console.warn(msg);
48 }
49
50@@ -180,7 +179,7 @@ export function createThunks<Ctx extends ThunkCtx = ThunkCtx<any>>(
51 return { type, payload };
52 };
53 let req = null;
54- let fn = null;
55+ let fn: any = null;
56 if (args.length === 2) {
57 req = args[0];
58 fn = args[1];
59@@ -223,9 +222,7 @@ export function createThunks<Ctx extends ThunkCtx = ThunkCtx<any>>(
60 });
61 }
62
63- const errMsg =
64- `[${name}] is being called before its thunk has been registered. ` +
65- "Run `store.run(thunks.register)` where `thunks` is the name of your `createThunks` or `createApi` variable.";
66+ const errMsg = `[${name}] is being called before its thunk has been registered. Run \`store.run(thunks.register)\` where \`thunks\` is the name of your \`createThunks\` or \`createApi\` variable.`;
67
68 const actionFn = (options?: Ctx["payload"]) => {
69 if (!signal) {
70@@ -235,7 +232,7 @@ export function createThunks<Ctx extends ThunkCtx = ThunkCtx<any>>(
71 return action({ name, key, options });
72 };
73 actionFn.run = (action?: unknown): Operation<Ctx> => {
74- if (action && Object.hasOwn(action, "type")) {
75+ if (action && (action as any).type) {
76 return onApi(action as ActionWithPayload<CreateActionPayload>);
77 }
78 return onApi(actionFn(action));
79@@ -261,13 +258,13 @@ export function createThunks<Ctx extends ThunkCtx = ThunkCtx<any>>(
80 }
81
82 function* register() {
83- storeId = yield* IdContext;
84+ storeId = yield* IdContext.expect();
85 if (storeId && storeMap.has(storeId)) {
86 console.warn("This thunk instance is already registered.");
87 return;
88 }
89
90- signal = yield* ActionContext;
91+ signal = yield* ActionContext.expect();
92 storeMap.set(storeId, signal);
93
94 yield* ensure(function* () {
R query/types.ts =>
src/query/types.ts
+9,
-8
1@@ -6,7 +6,7 @@ import type {
2 LoaderPayload,
3 Next,
4 Payload,
5-} from "../types.ts";
6+} from "../types.js";
7
8 type IfAny<T, Y, N> = 0 extends 1 & T ? Y : N;
9
10@@ -32,13 +32,13 @@ export interface LoaderCtx<P = unknown> extends ThunkCtx<P> {
11
12 export type ApiFetchResult<ApiSuccess = any, ApiError = any> =
13 | {
14- ok: true;
15- value: ApiSuccess;
16- }
17+ ok: true;
18+ value: ApiSuccess;
19+ }
20 | {
21- ok: false;
22- error: ApiError;
23- };
24+ ok: false;
25+ error: ApiError;
26+ };
27
28 export type ApiRequest = Partial<{ url: string } & RequestInit>;
29 export type RequiredApiRequest = {
30@@ -58,7 +58,8 @@ export interface FetchJson<ApiSuccess = any, ApiError = any> {
31 }
32
33 export interface FetchJsonCtx<P = any, ApiSuccess = any, ApiError = any>
34- extends FetchCtx<P>, FetchJson<ApiSuccess, ApiError> {}
35+ extends FetchCtx<P>,
36+ FetchJson<ApiSuccess, ApiError> {}
37
38 export interface ApiCtx<Payload = any, ApiSuccess = any, ApiError = any>
39 extends FetchJsonCtx<Payload, ApiSuccess, ApiError> {
R query/util.ts =>
src/query/util.ts
+1,
-1
1@@ -1,4 +1,4 @@
2-import type { ApiRequest, RequiredApiRequest } from "./types.ts";
3+import type { ApiRequest, RequiredApiRequest } from "./types.js";
4
5 export function* noop() {}
6 // deno-lint-ignore no-explicit-any
R queue.ts =>
src/queue.ts
+0,
-0
R react.ts =>
src/react.ts
+12,
-8
1@@ -1,15 +1,19 @@
2+import React, { type ReactElement } from "react";
3 import {
4 Provider as ReduxProvider,
5 useDispatch,
6- useSelector,
7 useStore as useReduxStore,
8+ useSelector,
9 } from "react-redux";
10-import React, { type ReactElement } from "react";
11-import type { AnyState, LoaderState } from "./types.ts";
12-import type { ThunkAction } from "./query/mod.ts";
13-import { type FxSchema, type FxStore, PERSIST_LOADER_ID } from "./store/mod.ts";
14-import { ActionFn, ActionFnWithPayload } from "./types.ts";
15-import { getIdFromAction } from "./action.ts";
16+import { getIdFromAction } from "./action.js";
17+import type { ThunkAction } from "./query/index.js";
18+import {
19+ type FxSchema,
20+ type FxStore,
21+ PERSIST_LOADER_ID,
22+} from "./store/index.js";
23+import type { AnyState, LoaderState } from "./types.js";
24+import type { ActionFn, ActionFnWithPayload } from "./types.js";
25
26 export { useDispatch, useSelector } from "react-redux";
27 export type { TypedUseSelectorHook } from "react-redux";
28@@ -264,7 +268,7 @@ export function PersistGate({
29 }: PersistGateProps) {
30 const schema = useSchema();
31 const ldr = useSelector((s: any) =>
32- schema.loaders.selectById(s, { id: PERSIST_LOADER_ID })
33+ schema.loaders.selectById(s, { id: PERSIST_LOADER_ID }),
34 );
35
36 if (ldr.status === "error") {
R store/batch.ts =>
src/store/batch.ts
+2,
-2
1@@ -1,6 +1,6 @@
2 import { action } from "effection";
3-import { UpdaterCtx } from "./types.ts";
4-import { AnyState, Next } from "../types.ts";
5+import type { AnyState, Next } from "../types.js";
6+import type { UpdaterCtx } from "./types.js";
7
8 export function createBatchMdw<S extends AnyState>(
9 queue: (send: () => void) => void,
R store/context.ts =>
src/store/context.ts
+2,
-2
1@@ -1,6 +1,6 @@
2 import { type Channel, createChannel, createContext } from "effection";
3-import type { AnyState } from "../types.ts";
4-import type { FxStore } from "./types.ts";
5+import type { AnyState } from "../types.js";
6+import type { FxStore } from "./types.js";
7
8 export const StoreUpdateContext = createContext<Channel<void, void>>(
9 "starfx:store:update",
R store/fx.ts =>
src/store/fx.ts
+10,
-10
1@@ -1,16 +1,16 @@
2-import { Operation, Result } from "effection";
3-import type { ActionFnWithPayload, AnyState } from "../types.ts";
4-import type { FxStore, StoreUpdater, UpdaterCtx } from "./types.ts";
5-import { StoreContext } from "./context.ts";
6-import { LoaderOutput } from "./slice/loaders.ts";
7-import { parallel, safe } from "../fx/mod.ts";
8-import { ThunkAction } from "../query/mod.ts";
9-import { getIdFromAction, take } from "../action.ts";
10+import type { Operation, Result } from "effection";
11+import { getIdFromAction, take } from "../action.js";
12+import { parallel, safe } from "../fx/index.js";
13+import type { ThunkAction } from "../query/index.js";
14+import type { ActionFnWithPayload, AnyState } from "../types.js";
15+import { StoreContext } from "./context.js";
16+import type { LoaderOutput } from "./slice/loaders.js";
17+import type { FxStore, StoreUpdater, UpdaterCtx } from "./types.js";
18
19 export function* updateStore<S extends AnyState>(
20 updater: StoreUpdater<S> | StoreUpdater<S>[],
21 ): Operation<UpdaterCtx<S>> {
22- const store = yield* StoreContext;
23+ const store = yield* StoreContext.expect();
24 // had to cast the store since StoreContext has a generic store type
25 const st = store as FxStore<S>;
26 const ctx = yield* st.update(updater);
27@@ -26,7 +26,7 @@ export function* select<S, R, P>(
28 selectorFn: (s: S, p?: P) => R,
29 p?: P,
30 ): Operation<R> {
31- const store = yield* StoreContext;
32+ const store = yield* StoreContext.expect();
33 return selectorFn(store.getState() as S, p);
34 }
35
+9,
-0
1@@ -0,0 +1,9 @@
2+export * from "./context.js";
3+export * from "./fx.js";
4+export * from "./store.js";
5+export * from "./types.js";
6+export { createSelector } from "reselect";
7+export * from "./slice/index.js";
8+export * from "./schema.js";
9+export * from "./batch.js";
10+export * from "./persist.js";
R store/persist.ts =>
src/store/persist.ts
+13,
-20
1@@ -1,7 +1,7 @@
2-import { Err, Ok, Operation, Result } from "effection";
3-import { select, updateStore } from "./fx.ts";
4-import type { AnyState, Next } from "../types.ts";
5-import type { UpdaterCtx } from "./types.ts";
6+import { Err, Ok, type Operation, type Result } from "effection";
7+import type { AnyState, Next } from "../types.js";
8+import { select, updateStore } from "./fx.js";
9+import type { UpdaterCtx } from "./types.js";
10
11 export const PERSIST_LOADER_ID = "@@starfx/persist";
12
13@@ -26,21 +26,15 @@ interface TransformFunctions<S extends AnyState> {
14
15 export function createTransform<S extends AnyState>() {
16 const transformers: TransformFunctions<S> = {
17- in: function (currentState: Partial<S>): Partial<S> {
18- return currentState;
19- },
20- out: function (currentState: Partial<S>): Partial<S> {
21- return currentState;
22- },
23+ in: (currentState: Partial<S>): Partial<S> => currentState,
24+ out: (currentState: Partial<S>): Partial<S> => currentState,
25 };
26
27- const inTransformer = function (state: Partial<S>): Partial<S> {
28- return transformers.in(state);
29- };
30+ const inTransformer = (state: Partial<S>): Partial<S> =>
31+ transformers.in(state);
32
33- const outTransformer = function (state: Partial<S>): Partial<S> {
34- return transformers.out(state);
35- };
36+ const outTransformer = (state: Partial<S>): Partial<S> =>
37+ transformers.out(state);
38
39 return {
40 in: inTransformer,
41@@ -85,9 +79,8 @@ export function createPersistor<S extends AnyState>({
42 reconciler = shallowReconciler,
43 allowlist = [],
44 transform,
45-}:
46- & Pick<PersistProps<S>, "adapter">
47- & Partial<PersistProps<S>>): PersistProps<S> {
48+}: Pick<PersistProps<S>, "adapter"> &
49+ Partial<PersistProps<S>>): PersistProps<S> {
50 function* rehydrate(): Operation<Result<undefined>> {
51 const persistedState = yield* adapter.getItem(key);
52 if (!persistedState.ok) {
53@@ -105,7 +98,7 @@ export function createPersistor<S extends AnyState>({
54
55 const state = yield* select((s) => s);
56 const nextState = reconciler(state as S, stateFromStorage);
57- yield* updateStore<S>(function (state) {
58+ yield* updateStore<S>((state) => {
59 Object.keys(nextState).forEach((key: keyof S) => {
60 state[key] = nextState[key];
61 });
R store/run.ts =>
src/store/run.ts
+2,
-2
1@@ -1,5 +1,5 @@
2-import { Callable, Operation, Result, Scope, Task } from "effection";
3-import { parallel, safe } from "../fx/mod.ts";
4+import type { Callable, Operation, Result, Scope, Task } from "effection";
5+import { parallel, safe } from "../fx/index.js";
6
7 export function createRun(scope: Scope) {
8 function run<T>(op: Callable<T>[]): Task<Result<T>[]>;
+34,
-0
1@@ -0,0 +1,34 @@
2+import { updateStore } from "./fx.js";
3+import { slice } from "./slice/index.js";
4+import type { FxMap, FxSchema, StoreUpdater } from "./types.js";
5+
6+const defaultSchema = <O>(): O =>
7+ ({ cache: slice.table(), loaders: slice.loaders() }) as O;
8+
9+export function createSchema<
10+ O extends FxMap,
11+ S extends { [key in keyof O]: ReturnType<O[key]>["initialState"] },
12+>(slices: O = defaultSchema<O>()): [FxSchema<S, O>, S] {
13+ const db = Object.keys(slices).reduce<FxSchema<S, O>>(
14+ (acc, key) => {
15+ // deno-lint-ignore no-explicit-any
16+ (acc as any)[key] = slices[key](key);
17+ return acc;
18+ },
19+ {} as FxSchema<S, O>,
20+ );
21+
22+ const initialState = Object.keys(db).reduce((acc, key) => {
23+ // deno-lint-ignore no-explicit-any
24+ (acc as any)[key] = db[key].initialState;
25+ return acc;
26+ }, {}) as S;
27+
28+ function* update(ups: StoreUpdater<S> | StoreUpdater<S>[]) {
29+ return yield* updateStore(ups);
30+ }
31+
32+ db.update = update;
33+
34+ return [db, initialState];
35+}
R store/slice/any.ts =>
src/store/slice/any.ts
+2,
-2
1@@ -1,5 +1,5 @@
2-import type { AnyState } from "../../types.ts";
3-import type { BaseSchema } from "../types.ts";
4+import type { AnyState } from "../../types.js";
5+import type { BaseSchema } from "../types.js";
6
7 export interface AnyOutput<V, S extends AnyState> extends BaseSchema<V> {
8 schema: "any";
R store/slice/mod.ts =>
src/store/slice/index.ts
+7,
-7
1@@ -1,14 +1,14 @@
2-import { str, StrOutput } from "./str.ts";
3-import { num, NumOutput } from "./num.ts";
4-import { table, TableOutput } from "./table.ts";
5-import { any, AnyOutput } from "./any.ts";
6-import { obj, ObjOutput } from "./obj.ts";
7+import { type AnyOutput, any } from "./any.js";
8 import {
9+ type LoaderOutput,
10 defaultLoader,
11 defaultLoaderItem,
12- LoaderOutput,
13 loaders,
14-} from "./loaders.ts";
15+} from "./loaders.js";
16+import { type NumOutput, num } from "./num.js";
17+import { type ObjOutput, obj } from "./obj.js";
18+import { type StrOutput, str } from "./str.js";
19+import { type TableOutput, table } from "./table.js";
20
21 export const slice = {
22 str,
R store/slice/loaders.ts =>
src/store/slice/loaders.ts
+4,
-5
1@@ -4,8 +4,8 @@ import type {
2 LoaderItemState,
3 LoaderPayload,
4 LoaderState,
5-} from "../../types.ts";
6-import { BaseSchema } from "../types.ts";
7+} from "../../types.js";
8+import type { BaseSchema } from "../types.js";
9
10 interface PropId {
11 id: string;
12@@ -109,9 +109,8 @@ function loaderSelectors<
13 export interface LoaderOutput<
14 M extends Record<string, unknown>,
15 S extends AnyState,
16-> extends
17- LoaderSelectors<M, S>,
18- BaseSchema<Record<string, LoaderItemState<M>>> {
19+> extends LoaderSelectors<M, S>,
20+ BaseSchema<Record<string, LoaderItemState<M>>> {
21 schema: "loader";
22 initialState: Record<string, LoaderItemState<M>>;
23 start: (e: LoaderPayload<M>) => (s: S) => void;
R store/slice/num.ts =>
src/store/slice/num.ts
+14,
-10
1@@ -1,5 +1,5 @@
2-import type { AnyState } from "../../types.ts";
3-import type { BaseSchema } from "../types.ts";
4+import type { AnyState } from "../../types.js";
5+import type { BaseSchema } from "../types.js";
6
7 export interface NumOutput<S extends AnyState> extends BaseSchema<number> {
8 schema: "num";
9@@ -26,14 +26,18 @@ export function createNum<S extends AnyState = AnyState>({
10 // deno-lint-ignore no-explicit-any
11 (state as any)[name] = value;
12 },
13- increment: (by = 1) => (state) => {
14- // deno-lint-ignore no-explicit-any
15- (state as any)[name] += by;
16- },
17- decrement: (by = 1) => (state) => {
18- // deno-lint-ignore no-explicit-any
19- (state as any)[name] -= by;
20- },
21+ increment:
22+ (by = 1) =>
23+ (state) => {
24+ // deno-lint-ignore no-explicit-any
25+ (state as any)[name] += by;
26+ },
27+ decrement:
28+ (by = 1) =>
29+ (state) => {
30+ // deno-lint-ignore no-explicit-any
31+ (state as any)[name] -= by;
32+ },
33 reset: () => (state) => {
34 // deno-lint-ignore no-explicit-any
35 (state as any)[name] = initialState;
R store/slice/obj.ts =>
src/store/slice/obj.ts
+8,
-6
1@@ -1,5 +1,5 @@
2-import type { AnyState } from "../../types.ts";
3-import type { BaseSchema } from "../types.ts";
4+import type { AnyState } from "../../types.js";
5+import type { BaseSchema } from "../types.js";
6
7 export interface ObjOutput<V extends AnyState, S extends AnyState>
8 extends BaseSchema<V> {
9@@ -30,10 +30,12 @@ export function createObj<V extends AnyState, S extends AnyState = AnyState>({
10 // deno-lint-ignore no-explicit-any
11 (state as any)[name] = initialState;
12 },
13- update: <P extends keyof V>(prop: { key: P; value: V[P] }) => (state) => {
14- // deno-lint-ignore no-explicit-any
15- (state as any)[name][prop.key] = prop.value;
16- },
17+ update:
18+ <P extends keyof V>(prop: { key: P; value: V[P] }) =>
19+ (state) => {
20+ // deno-lint-ignore no-explicit-any
21+ (state as any)[name][prop.key] = prop.value;
22+ },
23 select: (state) => {
24 // deno-lint-ignore no-explicit-any
25 return (state as any)[name];
R store/slice/str.ts =>
src/store/slice/str.ts
+2,
-2
1@@ -1,5 +1,5 @@
2-import type { AnyState } from "../../types.ts";
3-import type { BaseSchema } from "../types.ts";
4+import type { AnyState } from "../../types.js";
5+import type { BaseSchema } from "../types.js";
6
7 export interface StrOutput<S extends AnyState = AnyState>
8 extends BaseSchema<string> {
R store/slice/table.ts =>
src/store/slice/table.ts
+4,
-5
1@@ -1,6 +1,6 @@
2 import { createSelector } from "reselect";
3-import type { AnyState, IdProp } from "../../types.ts";
4-import { BaseSchema } from "../types.ts";
5+import type { AnyState, IdProp } from "../../types.js";
6+import type { BaseSchema } from "../types.js";
7
8 interface PropId {
9 id: IdProp;
10@@ -65,9 +65,8 @@ function tableSelectors<
11 findByIds,
12 tableAsList,
13 selectTable,
14- selectTableAsList: createSelector(
15- selectTable,
16- (data): Entity[] => tableAsList(data),
17+ selectTableAsList: createSelector(selectTable, (data): Entity[] =>
18+ tableAsList(data),
19 ),
20 selectById: sbi,
21 selectByIds: createSelector(
R store/store.ts =>
src/store/store.ts
+15,
-9
1@@ -1,16 +1,22 @@
2-import { createContext, createScope, createSignal, Ok, Scope } from "effection";
3+import {
4+ Ok,
5+ type Scope,
6+ createContext,
7+ createScope,
8+ createSignal,
9+} from "effection";
10 import { enablePatches, produceWithPatches } from "immer";
11-import { ActionContext, API_ACTION_PREFIX, emit } from "../action.ts";
12-import { BaseMiddleware, compose } from "../compose.ts";
13-import { StoreContext, StoreUpdateContext } from "./context.ts";
14-import { createRun } from "./run.ts";
15-import type { AnyAction, AnyState, Next } from "../types.ts";
16-import type { FxStore, Listener, StoreUpdater, UpdaterCtx } from "./types.ts";
17+import { API_ACTION_PREFIX, ActionContext, emit } from "../action.js";
18+import { type BaseMiddleware, compose } from "../compose.js";
19+import type { AnyAction, AnyState, Next } from "../types.js";
20+import { StoreContext, StoreUpdateContext } from "./context.js";
21+import { createRun } from "./run.js";
22+import type { FxStore, Listener, StoreUpdater, UpdaterCtx } from "./types.js";
23 const stubMsg = "This is merely a stub, not implemented";
24
25 let id = 0;
26
27-// https://github.com/reduxjs/redux/blob/4a6d2fb227ba119d3498a43fab8f53fe008be64c/src/createStore.ts#L344
28+// https://github.com/reduxjs/redux/blob/4a6d2fb227ba119d3498a43fab8f53fe008be64c/src/createStore.js#L344
29 function observable() {
30 return {
31 subscribe: (_observer: unknown) => {
32@@ -95,7 +101,7 @@ export function createStore<S extends AnyState>({
33 }
34
35 function* notifyChannelMdw(_: UpdaterCtx<S>, next: Next) {
36- const chan = yield* StoreUpdateContext;
37+ const chan = yield* StoreUpdateContext.expect();
38 yield* chan.send();
39 yield* next();
40 }
R store/types.ts =>
src/store/types.ts
+9,
-11
1@@ -1,10 +1,10 @@
2-import type { Patch } from "immer";
3 import type { Operation, Scope } from "effection";
4-import type { AnyAction, AnyState } from "../types.ts";
5-import type { LoaderOutput } from "./slice/loaders.ts";
6-import type { TableOutput } from "./slice/table.ts";
7-import { BaseCtx } from "../mod.ts";
8-import { createRun } from "./run.ts";
9+import type { Patch } from "immer";
10+import type { BaseCtx } from "../index.js";
11+import type { AnyAction, AnyState } from "../types.js";
12+import type { createRun } from "./run.js";
13+import type { LoaderOutput } from "./slice/loaders.js";
14+import type { TableOutput } from "./slice/table.js";
15
16 export type StoreUpdater<S extends AnyState> = (s: S) => S | void;
17
18@@ -37,11 +37,9 @@ export interface FxMap {
19 [key: string]: (name: string) => BaseSchema<unknown>;
20 }
21
22-export type FxSchema<S extends AnyState, O extends FxMap = FxMap> =
23- & {
24- [key in keyof O]: ReturnType<O[key]>;
25- }
26- & { update: FxStore<S>["update"] };
27+export type FxSchema<S extends AnyState, O extends FxMap = FxMap> = {
28+ [key in keyof O]: ReturnType<O[key]>;
29+} & { update: FxStore<S>["update"] };
30
31 export interface FxStore<S extends AnyState> {
32 getScope: () => Scope;
R supervisor.ts =>
src/supervisor.ts
+14,
-7
1@@ -1,8 +1,16 @@
2-import { createAction, take } from "./action.ts";
3-import { call, Callable, Operation, race, sleep, spawn, Task } from "effection";
4-import type { ActionWithPayload, AnyAction } from "./types.ts";
5-import type { CreateActionPayload } from "./query/mod.ts";
6-import { getIdFromAction } from "./action.ts";
7+import {
8+ type Callable,
9+ type Operation,
10+ type Task,
11+ call,
12+ race,
13+ sleep,
14+ spawn,
15+} from "effection";
16+import { createAction, take } from "./action.js";
17+import { getIdFromAction } from "./action.js";
18+import type { CreateActionPayload } from "./query/index.js";
19+import type { ActionWithPayload, AnyAction } from "./types.js";
20
21 const MS = 1000;
22 const SECONDS = 1 * MS;
23@@ -67,9 +75,8 @@ export function timer(timer: number = 5 * MINUTES) {
24 }
25 if (typeof id === "string") {
26 return idA === id;
27- } else {
28- return idA === getIdFromAction(id);
29 }
30+ return idA === getIdFromAction(id);
31 });
32 };
33 yield* race([sleep(timer), take(matchFn as any) as Operation<void>]);
R test.ts =>
src/test.ts
+3,
-7
1@@ -3,13 +3,9 @@ export {
2 beforeAll,
3 beforeEach,
4 describe,
5- it,
6-} from "jsr:@std/testing/bdd";
7-export * as assertType from "jsr:@std/testing/types";
8-export { assert } from "jsr:@std/assert";
9-export * as asserts from "jsr:@std/assert";
10-export { expect } from "jsr:@std/expect";
11-export { install, mock } from "https://deno.land/x/mock_fetch@0.3.0/mod.ts";
12+ expect,
13+ test,
14+} from "vitest";
15
16 export function isLikeSelector(selector: unknown) {
17 return (
+12,
-0
1@@ -0,0 +1,12 @@
2+import { createAction } from "../index.js";
3+import { expect, test } from "../test.js";
4+
5+test("should return action type when stringified", () => {
6+ const undo = createAction("UNDO");
7+ expect("UNDO").toEqual(`${undo}`);
8+});
9+
10+test("return object with type", () => {
11+ const undo = createAction("UNDO");
12+ expect(undo()).toEqual({ type: "UNDO", payload: undefined });
13+});
R test/api.test.ts =>
src/test/api.test.ts
+56,
-56
1@@ -1,18 +1,19 @@
2 import {
3- AnyState,
4 API_ACTION_PREFIX,
5- ApiCtx,
6+ type AnyState,
7+ type ApiCtx,
8+ type Operation,
9 call,
10+ createAction,
11 createApi,
12 createKey,
13 keepAlive,
14 mdw,
15- Operation,
16 safe,
17 takeEvery,
18 waitFor,
19-} from "../mod.ts";
20-import { useCache } from "../react.ts";
21+} from "../index.js";
22+import { useCache } from "../react.js";
23 import {
24 createSchema,
25 createStore,
26@@ -20,8 +21,8 @@ import {
27 slice,
28 updateStore,
29 waitForLoader,
30-} from "../store/mod.ts";
31-import { describe, expect, it } from "../test.ts";
32+} from "../store/index.js";
33+import { expect, test } from "../test.js";
34
35 interface User {
36 id: string;
37@@ -46,9 +47,7 @@ const jsonBlob = (data: unknown) => {
38 return JSON.stringify(data);
39 };
40
41-const tests = describe("createApi()");
42-
43-it(tests, "POST", async () => {
44+test("POST", async () => {
45 expect.assertions(2);
46 const query = createApi();
47 query.use(mdw.queryCtx);
48@@ -71,7 +70,7 @@ it(tests, "POST", async () => {
49 });
50
51 const createUser = query.post<{ email: string }, { users: User[] }>(
52- `/users`,
53+ "/users",
54 { supervisor: takeEvery },
55 function* processUsers(ctx, next) {
56 ctx.request = ctx.req({
57@@ -109,8 +108,11 @@ it(tests, "POST", async () => {
58
59 await store.run(
60 waitFor(function* (): Operation<boolean> {
61- const res = yield* select((state: AnyState) => state.users["1"].id);
62- return res !== "";
63+ const res = yield* select((state) => state);
64+ return (
65+ (res as { users: Record<string, User> }).users["1"]?.email ===
66+ mockUser.email
67+ );
68 }),
69 );
70
71@@ -119,7 +121,7 @@ it(tests, "POST", async () => {
72 });
73 });
74
75-it(tests, "POST with uri", () => {
76+test("POST with uri", () => {
77 expect.assertions(1);
78 const query = createApi();
79 query.use(mdw.queryCtx);
80@@ -167,7 +169,7 @@ it(tests, "POST with uri", () => {
81 store.dispatch(createUser({ email: mockUser.email }));
82 });
83
84-it(tests, "middleware - with request fn", () => {
85+test("middleware - with request fn", () => {
86 expect.assertions(2);
87 const query = createApi();
88 query.use(mdw.queryCtx);
89@@ -188,7 +190,7 @@ it(tests, "middleware - with request fn", () => {
90 store.dispatch(createUser());
91 });
92
93-it(tests, "run() on endpoint action - should run the effect", () => {
94+test("run() on endpoint action - should run the effect", () => {
95 expect.assertions(1);
96 const api = createApi<TestCtx>();
97 api.use(api.routes());
98@@ -217,7 +219,7 @@ it(tests, "run() on endpoint action - should run the effect", () => {
99 store.dispatch(action2());
100 });
101
102-it(tests, "run() from a normal saga", async () => {
103+test("run() from a normal saga", async () => {
104 expect.assertions(6);
105 const api = createApi();
106 api.use(api.routes());
107@@ -264,14 +266,16 @@ it(tests, "run() from a normal saga", async () => {
108 const payload = { name: "/users/:id [GET]", options: { id: "1" } };
109
110 expect(extractedResults.actionType).toEqual(`${API_ACTION_PREFIX}${action1}`);
111- expect(extractedResults.actionPayload!["name"]).toEqual(payload.name);
112- expect(extractedResults.actionPayload!["options"]).toEqual(payload.options);
113+ expect((extractedResults.actionPayload as any).name).toEqual(payload.name);
114+ expect((extractedResults.actionPayload as any).options).toEqual(
115+ payload.options,
116+ );
117 expect(extractedResults.name).toEqual("/users/:id [GET]");
118 expect(extractedResults.payload).toEqual({ id: "1" });
119 expect(acc).toEqual("ab");
120 });
121
122-it(tests, "with hash key on a large post", async () => {
123+test("with hash key on a large post", async () => {
124 const { store, schema } = testStore();
125 const query = createApi();
126 query.use(mdw.api({ schema }));
127@@ -284,7 +288,7 @@ it(tests, "with hash key on a large post", async () => {
128 yield* next();
129 });
130 const createUserDefaultKey = query.post<{ email: string; largetext: string }>(
131- `/users`,
132+ "/users",
133 { supervisor: takeEvery },
134 function* processUsers(ctx, next) {
135 ctx.cache = true;
136@@ -317,7 +321,7 @@ it(tests, "with hash key on a large post", async () => {
137 },
138 );
139
140- const email = mockUser.email + "9";
141+ const email = `${mockUser.email}9`;
142 const largetext = "abc-def-ghi-jkl-mno-pqr".repeat(100);
143
144 store.run(query.bootup);
145@@ -338,7 +342,7 @@ it(tests, "with hash key on a large post", async () => {
146 });
147 });
148
149-it(tests, "two identical endpoints", () => {
150+test("two identical endpoints", () => {
151 const actual: string[] = [];
152 const { store, schema } = testStore();
153 const api = createApi();
154@@ -367,7 +371,7 @@ interface TestCtx<P = any, S = any> extends ApiCtx<P, S, { message: string }> {
155 }
156
157 // this is strictly for testing types
158-it(tests, "ensure types for get() endpoint", () => {
159+test("ensure types for get() endpoint", () => {
160 const api = createApi<TestCtx>();
161 api.use(api.routes());
162 api.use(function* (ctx, next) {
163@@ -405,7 +409,7 @@ interface FetchUserProps {
164 type FetchUserCtx = TestCtx<FetchUserProps>;
165
166 // this is strictly for testing types
167-it(tests, "ensure ability to cast `ctx` in function definition", () => {
168+test("ensure ability to cast `ctx` in function definition", () => {
169 const api = createApi<TestCtx>();
170 api.use(api.routes());
171 api.use(function* (ctx, next) {
172@@ -439,41 +443,37 @@ it(tests, "ensure ability to cast `ctx` in function definition", () => {
173 type FetchUserSecondCtx = TestCtx<any, { result: string }>;
174
175 // this is strictly for testing types
176-it(
177- tests,
178- "ensure ability to cast `ctx` in function definition with no props",
179- () => {
180- const api = createApi<TestCtx>();
181- api.use(api.routes());
182- api.use(function* (ctx, next) {
183- yield* next();
184- const data = { result: "wow" };
185- ctx.json = { ok: true, value: data };
186- });
187+test("ensure ability to cast `ctx` in function definition with no props", () => {
188+ const api = createApi<TestCtx>();
189+ api.use(api.routes());
190+ api.use(function* (ctx, next) {
191+ yield* next();
192+ const data = { result: "wow" };
193+ ctx.json = { ok: true, value: data };
194+ });
195
196- const acc: string[] = [];
197- const action1 = api.get<never, { result: string }>(
198- "/users",
199- { supervisor: takeEvery },
200- function* (ctx: FetchUserSecondCtx, next) {
201- ctx.something = false;
202+ const acc: string[] = [];
203+ const action1 = api.get<never, { result: string }>(
204+ "/users",
205+ { supervisor: takeEvery },
206+ function* (ctx: FetchUserSecondCtx, next) {
207+ ctx.something = false;
208
209- yield* next();
210+ yield* next();
211
212- if (ctx.json.ok) {
213- acc.push(ctx.json.value.result);
214- }
215- },
216- );
217+ if (ctx.json.ok) {
218+ acc.push(ctx.json.value.result);
219+ }
220+ },
221+ );
222
223- const store = createStore({ initialState: { users: {} } });
224- store.run(api.bootup);
225- store.dispatch(action1());
226- expect(acc).toEqual(["wow"]);
227- },
228-);
229+ const store = createStore({ initialState: { users: {} } });
230+ store.run(api.bootup);
231+ store.dispatch(action1());
232+ expect(acc).toEqual(["wow"]);
233+});
234
235-it(tests, "should bubble up error", () => {
236+test("should bubble up error", () => {
237 let error: any = null;
238 const { store } = testStore();
239 const api = createApi();
240@@ -504,7 +504,7 @@ it(tests, "should bubble up error", () => {
241 });
242
243 // this is strictly for testing types
244-it(tests, "useCache - derive api success from endpoint", () => {
245+test("useCache - derive api success from endpoint", () => {
246 const api = createApi<TestCtx>();
247 api.use(api.routes());
248 api.use(function* (ctx, next) {
R test/batch.test.ts =>
src/test/batch.test.ts
+4,
-6
1@@ -1,15 +1,13 @@
2-import { describe, expect, it } from "../test.ts";
3+import { parallel } from "../index.js";
4 import {
5 createBatchMdw,
6 createSchema,
7 createStore,
8 slice,
9-} from "../store/mod.ts";
10-import { parallel } from "../mod.ts";
11+} from "../store/index.js";
12+import { expect, test } from "../test.js";
13
14-const batch = describe("batch mdw");
15-
16-it(batch, "should batch notify subscribers based on mdw", async () => {
17+test("should batch notify subscribers based on mdw", async () => {
18 const [schema, initialState] = createSchema({
19 cache: slice.table({ empty: {} }),
20 loaders: slice.loaders(),
R test/compose.test.ts =>
src/test/compose.test.ts
+6,
-8
1@@ -1,9 +1,7 @@
2-import { asserts, describe, expect, it } from "../test.ts";
3-import { compose, Err, Ok, Result, run, safe, sleep } from "../mod.ts";
4+import { Err, Ok, type Result, compose, run, safe, sleep } from "../index.js";
5+import { expect, test } from "../test.js";
6
7-const tests = describe("compose()");
8-
9-it(tests, "should compose middleware", async () => {
10+test("should compose middleware", async () => {
11 const mdw = compose<{ one: string; three: string; result: Result<void> }>([
12 function* (ctx, next) {
13 ctx.one = "two";
14@@ -29,7 +27,7 @@ it(tests, "should compose middleware", async () => {
15 expect(actual).toEqual(expected);
16 });
17
18-it(tests, "order of execution", async () => {
19+test("order of execution", async () => {
20 const mdw = compose<{ actual: string; result: Result<void> }>([
21 function* (ctx, next) {
22 ctx.actual += "a";
23@@ -64,12 +62,12 @@ it(tests, "order of execution", async () => {
24 expect(actual).toEqual(expected);
25 });
26
27-it(tests, "when error is discovered, it should throw", async () => {
28+test("when error is discovered, it should throw", async () => {
29 const err = new Error("boom");
30 const mdw = compose([
31 function* (_, next) {
32 yield* next();
33- asserts.fail();
34+ expect.fail();
35 },
36 function* (_, next) {
37 yield* next();
+328,
-0
1@@ -0,0 +1,328 @@
2+import { type ActionWithPayload, createApi } from "../index.js";
3+import { afterAll, beforeAll, expect, test } from "../test.js";
4+
5+const getKeyOf = (action: ActionWithPayload<{ key: string }>): string =>
6+ action.payload.key;
7+
8+const err = console.error;
9+beforeAll(() => {
10+ console.error = () => {};
11+});
12+
13+afterAll(() => {
14+ console.error = err;
15+});
16+
17+test("options object keys order for action key identity - 0: empty options", () => {
18+ console.warn = () => {};
19+ const api = createApi();
20+ api.use(api.routes());
21+ // no param
22+ const action0 = api.get("/users", function* (ctx, next) {
23+ ctx.request = {
24+ method: "GET",
25+ };
26+ yield* next();
27+ });
28+ const sendNop0 = action0();
29+ const sendNop1 = action0();
30+ expect(getKeyOf(sendNop0)).toEqual(getKeyOf(sendNop1));
31+});
32+
33+test("options object keys order for action key identity - 1: simple object", () => {
34+ const api = createApi();
35+ api.use(api.routes());
36+ // no param
37+ const action0 = api.get<{
38+ [key: string]: string | boolean | number | null | undefined;
39+ }>("/users", function* (ctx, next) {
40+ ctx.request = {
41+ method: "GET",
42+ };
43+ yield* next();
44+ });
45+ const sendPojo0 = action0({
46+ a: "a",
47+ b: "b",
48+ c: 1,
49+ d: 2,
50+ e: true,
51+ f: false,
52+ "100": 100,
53+ 101: "101",
54+ });
55+ const sendPojo1 = action0({
56+ a: "a",
57+ b: "b",
58+ c: 1,
59+ d: 2,
60+ e: true,
61+ f: false,
62+ 100: 100,
63+ 101: "101",
64+ });
65+ const sendPojo2 = action0({
66+ e: true,
67+ f: false,
68+ "100": 100,
69+ "101": "101",
70+ a: "a",
71+ b: "b",
72+ c: 1,
73+ d: 2,
74+ });
75+ const sendPojo3 = action0({
76+ e: true,
77+ f: false,
78+ "100": 100,
79+ "101": "101",
80+ a: "a",
81+ b: "b",
82+ c: 1,
83+ d: 2000000,
84+ });
85+ const sendPojo4 = action0({
86+ e: null,
87+ f: false,
88+ "100": undefined,
89+ "101": "101",
90+ a: "a",
91+ b: "b",
92+ c: 1,
93+ d: `Thomas O'Malley`,
94+ });
95+ const sendPojo5 = action0({
96+ d: `Thomas O'Malley`,
97+ e: null,
98+ f: false,
99+ "100": undefined,
100+ "101": "101",
101+ a: "a",
102+ b: "b",
103+ c: 1,
104+ });
105+ expect(getKeyOf(sendPojo0)).toEqual(getKeyOf(sendPojo1));
106+ expect(getKeyOf(sendPojo0)).toEqual(getKeyOf(sendPojo2));
107+ expect(getKeyOf(sendPojo0)).not.toEqual(getKeyOf(sendPojo3));
108+ expect(getKeyOf(sendPojo4)).toEqual(getKeyOf(sendPojo5));
109+});
110+
111+test("options object keys order for action key identity - 2: object (with array values)", () => {
112+ interface Ip0 {
113+ param1: string;
114+ param2: string[];
115+ }
116+ const api = createApi();
117+ api.use(api.routes());
118+ const action = api.get<Ip0>("/users/:param1/:param2", function* (ctx, next) {
119+ ctx.request = {
120+ method: "GET",
121+ };
122+ yield* next();
123+ });
124+ const sendFirst = action({ param1: "1", param2: ["2", "e", "f"] });
125+ const sendSecond = action({ param2: ["2", "f", "e"], param1: "1" });
126+ const sendThird = action({ param2: ["2", "e", "f"], param1: "1" });
127+ expect(getKeyOf(sendFirst)).not.toEqual(getKeyOf(sendSecond));
128+ expect(getKeyOf(sendFirst)).toEqual(getKeyOf(sendThird));
129+});
130+
131+test("options object keys order for action key identity - 3: nested object", () => {
132+ interface Ip0 {
133+ param1: string;
134+ param2: string[];
135+ }
136+ interface Ip1 {
137+ param1: string;
138+ param2: string;
139+ param3: number;
140+ param4: Ip0;
141+ param5: boolean;
142+ }
143+ const o1: Ip1 = {
144+ param1: "1",
145+ param2: "2",
146+ param3: 3,
147+ param4: {
148+ param1: "4",
149+ param2: ["5", "6"],
150+ },
151+ param5: true,
152+ };
153+ const o2: Ip1 = {
154+ param4: {
155+ param1: "4",
156+ param2: ["5", "6"],
157+ },
158+ param5: true,
159+ param2: "2",
160+ param1: "1",
161+ param3: 3,
162+ };
163+ const api = createApi();
164+ api.use(api.routes());
165+ //nested with array
166+ const action2 = api.get<Ip1>(
167+ "/users/:param1/:param2/:param3/:param4/:param5",
168+ function* (ctx, next) {
169+ ctx.request = {
170+ method: "GET",
171+ };
172+ yield* next();
173+ },
174+ );
175+ const sendO1 = action2(o1);
176+ const sendO2 = action2(o2);
177+ const sendO3 = action2({
178+ ...o1,
179+ param4: { ...o1.param4, param2: ["5", "6", "7"] },
180+ });
181+ expect(getKeyOf(sendO1)).toEqual(getKeyOf(sendO2));
182+ expect(getKeyOf(sendO1)).not.toEqual(getKeyOf(sendO3));
183+});
184+
185+test("options object keys order for action key identity - 4: deepNested object", () => {
186+ interface Ip0 {
187+ param1: string;
188+ param2: string[];
189+ }
190+ interface Ip1 {
191+ param1: string;
192+ param2: string;
193+ param3: number;
194+ param4: Ip0;
195+ param5: boolean;
196+ }
197+ interface Ip3 {
198+ param1: string;
199+ param2: {
200+ param3: Ip1;
201+ param4: Ip0;
202+ };
203+ }
204+ const o1: Ip1 = {
205+ param1: "1",
206+ param2: "2",
207+ param3: 3,
208+ param4: {
209+ param1: "4",
210+ param2: ["5", "6"],
211+ },
212+ param5: true,
213+ };
214+ const oo1: Ip3 = {
215+ param1: "1",
216+ param2: {
217+ param3: o1,
218+ param4: {
219+ param1: "4",
220+ param2: ["5", "6"],
221+ },
222+ },
223+ };
224+ const oo2: Ip3 = {
225+ param1: "1",
226+ param2: {
227+ param4: {
228+ param1: "4",
229+ param2: ["5", "6"],
230+ },
231+ param3: o1,
232+ },
233+ };
234+ const api = createApi();
235+ api.use(api.routes());
236+ // deepNested
237+ const action4 = api.get<Ip3>(
238+ "/users/:param1/:param2/:param3/:param4/:param5",
239+ function* (ctx, next) {
240+ ctx.request = {
241+ method: "GET",
242+ };
243+ yield* next();
244+ },
245+ );
246+ const send_oo1 = action4(oo1);
247+ const send_oo1_shuff = action4({ param2: oo1.param2, param1: oo1.param1 });
248+ const send_oo1_value_changed = action4({ ...oo1, param1: "x" });
249+ const send_oo2 = action4(oo2);
250+ expect(send_oo1.payload.options).toEqual(send_oo2.payload.options);
251+ expect(getKeyOf(send_oo1)).toEqual(getKeyOf(send_oo1_shuff));
252+ expect(getKeyOf(send_oo1)).not.toEqual(getKeyOf(send_oo1_value_changed));
253+ expect(getKeyOf(send_oo1)).toEqual(getKeyOf(send_oo2));
254+});
255+
256+test("options object keys order for action key identity - 5: other", () => {
257+ const api = createApi();
258+ api.use(api.routes());
259+ //array options
260+ const action5 = api.post<
261+ | number
262+ | boolean
263+ | string
264+ | undefined
265+ | null
266+ | { param1: string; param2: (string | number)[] }[]
267+ | string[]
268+ >("/users/:allRecords", function* (ctx, next) {
269+ ctx.request = {
270+ method: "POST",
271+ body: JSON.stringify(ctx.action.payload),
272+ };
273+ yield* next();
274+ });
275+ const falsy0 = action5(0);
276+ const falsy1 = action5(false);
277+ const falsy2 = action5("");
278+ const falsy3 = action5(undefined);
279+ const falsy4 = action5(null);
280+ const primNo0 = action5(Number.NaN);
281+ const primNo1 = action5(1);
282+ const primNo1bis = action5(1);
283+ const primNo2 = action5(2);
284+ const str1 = action5("1234");
285+ const str1bis = action5("1234");
286+ const str2 = action5("2345");
287+ const aStrings1 = action5(["1", "2", "3"]);
288+ const aStrings2 = action5(["1", "2", "3"]);
289+ const aStrings3 = action5(["1", "2", "1"]);
290+ const aObjects1 = action5([
291+ { param1: "1", param2: ["2", "3"] },
292+ { param1: "2", param2: ["2", "3"] },
293+ ]);
294+ const aObjects2 = action5([
295+ { param1: "1", param2: ["2", "3"] },
296+ { param1: "2", param2: ["2", "3"] },
297+ ]);
298+ // the objects are not identical.
299+ const aObjects3 = action5([
300+ { param1: "1", param2: ["2", "3"] },
301+ { param1: "2", param2: ["2", 3] },
302+ ]);
303+ //object inside the array is shuffled
304+ const aObjects4 = action5([
305+ { param2: ["2", "3"], param1: "1" },
306+ { param2: ["2", "3"], param1: "2" },
307+ ]);
308+ // cont the order of array elements is changed will get different keys.
309+ const aObjects5 = action5([
310+ { param1: "2", param2: ["2", "3"] },
311+ { param1: "1", param2: ["2", "3"] },
312+ ]);
313+ expect(getKeyOf(falsy0)).not.toEqual(getKeyOf(falsy1));
314+ expect(getKeyOf(falsy1)).not.toEqual(getKeyOf(falsy2));
315+ expect(getKeyOf(falsy1)).not.toEqual(getKeyOf(falsy3));
316+ expect(getKeyOf(falsy3)).not.toEqual(getKeyOf(falsy4));
317+ expect(getKeyOf(primNo0)).not.toEqual(getKeyOf(falsy0));
318+ expect(getKeyOf(primNo0)).not.toEqual(getKeyOf(primNo1));
319+ expect(getKeyOf(primNo1)).not.toEqual(getKeyOf(primNo2));
320+ expect(getKeyOf(primNo1)).toEqual(getKeyOf(primNo1bis));
321+ expect(getKeyOf(str1)).not.toEqual(getKeyOf(str2));
322+ expect(getKeyOf(str1)).toEqual(getKeyOf(str1bis));
323+ expect(getKeyOf(aStrings1)).toEqual(getKeyOf(aStrings2));
324+ expect(getKeyOf(aStrings1)).not.toEqual(getKeyOf(aStrings3));
325+ expect(getKeyOf(aObjects1)).toEqual(getKeyOf(aObjects2));
326+ expect(getKeyOf(aObjects1)).not.toEqual(getKeyOf(aObjects3));
327+ expect(getKeyOf(aObjects1)).toEqual(getKeyOf(aObjects4));
328+ expect(getKeyOf(aObjects1)).not.toEqual(getKeyOf(aObjects5));
329+});
R test/create-store.test.ts =>
src/test/create-store.test.ts
+5,
-7
1@@ -1,14 +1,12 @@
2-import { describe, expect, it } from "../test.ts";
3-import { createStore, select } from "../store/mod.ts";
4-import { call } from "../mod.ts";
5-
6-const tests = describe("createStore()");
7+import { call } from "../index.js";
8+import { createStore, select } from "../store/index.js";
9+import { expect, test } from "../test.js";
10
11 interface TestState {
12 user: { id: string };
13 }
14
15-it(tests, "should be able to grab values from store", async () => {
16+test("should be able to grab values from store", async () => {
17 let actual;
18 const store = createStore({ initialState: { user: { id: "1" } } });
19 await store.run(function* () {
20@@ -17,7 +15,7 @@ it(tests, "should be able to grab values from store", async () => {
21 expect(actual).toEqual({ id: "1" });
22 });
23
24-it(tests, "should be able to grab store from a nested call", async () => {
25+test("should be able to grab store from a nested call", async () => {
26 let actual;
27 const store = createStore({ initialState: { user: { id: "2" } } });
28 await store.run(function* () {
R test/fetch.test.ts =>
src/test/fetch.test.ts
+147,
-184
1@@ -1,14 +1,13 @@
2-import { describe, expect, install, it, mock } from "../test.ts";
3+import nock from "nock";
4+import { type ApiCtx, createApi, mdw, takeEvery } from "../index.js";
5 import {
6 createSchema,
7 createStore,
8 slice,
9 waitForLoader,
10 waitForLoaders,
11-} from "../store/mod.ts";
12-import { ApiCtx, createApi, mdw, takeEvery } from "../mod.ts";
13-
14-install();
15+} from "../store/index.js";
16+import { expect, test } from "../test.js";
17
18 const baseUrl = "https://starfx.com";
19 const mockUser = { id: "1", email: "test@starfx.com" };
20@@ -26,101 +25,85 @@ const getTestData = (ctx: ApiCtx) => {
21 return { request: { ...ctx.req() }, json: { ...ctx.json } };
22 };
23
24-const tests = describe("mdw.fetch()");
25-
26-it(
27- tests,
28- "should be able to fetch a resource and save automatically",
29- async () => {
30- mock(`GET@/users`, () => {
31- return new Response(JSON.stringify(mockUser));
32- });
33-
34- const { store, schema } = testStore();
35- const api = createApi();
36- api.use(mdw.api({ schema }));
37- api.use(api.routes());
38- api.use(mdw.headers);
39- api.use(mdw.fetch({ baseUrl }));
40-
41- const actual: any[] = [];
42- const fetchUsers = api.get(
43- "/users",
44- { supervisor: takeEvery },
45- function* (ctx, next) {
46- ctx.cache = true;
47- yield* next();
48-
49- actual.push(ctx.request);
50- actual.push(ctx.json);
51- },
52- );
53+test("should be able to fetch a resource and save automatically", async () => {
54+ nock(baseUrl).get("/users").reply(200, mockUser);
55
56- store.run(api.bootup);
57+ const { store, schema } = testStore();
58+ const api = createApi();
59+ api.use(mdw.api({ schema }));
60+ api.use(api.routes());
61+ api.use(mdw.headers);
62+ api.use(mdw.fetch({ baseUrl }));
63
64- const action = fetchUsers();
65- store.dispatch(action);
66+ const actual: any[] = [];
67+ const fetchUsers = api.get(
68+ "/users",
69+ { supervisor: takeEvery },
70+ function* (ctx, next) {
71+ ctx.cache = true;
72+ yield* next();
73
74- await store.run(waitForLoader(schema.loaders, action));
75+ actual.push(ctx.request);
76+ actual.push(ctx.json);
77+ },
78+ );
79
80- const state = store.getState();
81- expect(state.cache[action.payload.key]).toEqual(mockUser);
82- expect(actual).toEqual([
83- {
84- url: `${baseUrl}/users`,
85- method: "GET",
86- headers: {
87- "Content-Type": "application/json",
88- },
89- },
90- { ok: true, value: mockUser },
91- ]);
92- },
93-);
94-
95-it(
96- tests,
97- "should be able to fetch a resource and parse as text instead of json",
98- async () => {
99- mock(`GET@/users`, () => {
100- return new Response("this is some text");
101- });
102-
103- const { store, schema } = testStore();
104- const api = createApi();
105- api.use(mdw.api({ schema }));
106- api.use(api.routes());
107- api.use(mdw.fetch({ baseUrl }));
108-
109- let actual = null;
110- const fetchUsers = api.get(
111- "/users",
112- { supervisor: takeEvery },
113- function* (ctx, next) {
114- ctx.cache = true;
115- ctx.bodyType = "text";
116- yield* next();
117- actual = ctx.json;
118+ store.run(api.bootup);
119+
120+ const action = fetchUsers();
121+ store.dispatch(action);
122+
123+ await store.run(waitForLoader(schema.loaders, action));
124+
125+ const state = store.getState();
126+ expect(state.cache[action.payload.key]).toEqual(mockUser);
127+ expect(actual).toEqual([
128+ {
129+ url: `${baseUrl}/users`,
130+ method: "GET",
131+ headers: {
132+ "Content-Type": "application/json",
133 },
134- );
135+ },
136+ { ok: true, value: mockUser },
137+ ]);
138+});
139
140- store.run(api.bootup);
141+test("should be able to fetch a resource and parse as text instead of json", async () => {
142+ nock(baseUrl).get("/users").reply(200, "this is some text");
143
144- const action = fetchUsers();
145- store.dispatch(action);
146+ const { store, schema } = testStore();
147+ const api = createApi();
148+ api.use(mdw.api({ schema }));
149+ api.use(api.routes());
150+ api.use(mdw.fetch({ baseUrl }));
151
152- await store.run(waitForLoader(schema.loaders, action));
153+ let actual = null;
154+ const fetchUsers = api.get(
155+ "/users",
156+ { supervisor: takeEvery },
157+ function* (ctx, next) {
158+ ctx.cache = true;
159+ ctx.bodyType = "text";
160+ yield* next();
161+ actual = ctx.json;
162+ },
163+ );
164
165- const data = "this is some text";
166- expect(actual).toEqual({ ok: true, value: data });
167- },
168-);
169+ store.run(api.bootup);
170+
171+ const action = fetchUsers();
172+ store.dispatch(action);
173
174-it(tests, "error handling", async () => {
175+ await store.run(waitForLoader(schema.loaders, action));
176+
177+ const data = "this is some text";
178+ expect(actual).toEqual({ ok: true, value: data });
179+});
180+
181+test("error handling", async () => {
182 const errMsg = { message: "something happened" };
183- mock(`GET@/users`, () => {
184- return new Response(JSON.stringify(errMsg), { status: 500 });
185- });
186+ nock(baseUrl).get("/users").reply(500, errMsg);
187
188 const { schema, store } = testStore();
189 const api = createApi();
190@@ -152,10 +135,8 @@ it(tests, "error handling", async () => {
191 expect(actual).toEqual({ ok: false, error: errMsg });
192 });
193
194-it(tests, "status 204", async () => {
195- mock(`GET@/users`, () => {
196- return new Response(null, { status: 204 });
197- });
198+test("status 204", async () => {
199+ nock(baseUrl).get("/users").reply(204);
200
201 const { schema, store } = testStore();
202 const api = createApi();
203@@ -191,10 +172,8 @@ it(tests, "status 204", async () => {
204 expect(actual).toEqual({ ok: true, value: {} });
205 });
206
207-it(tests, "malformed json", async () => {
208- mock(`GET@/users`, () => {
209- return new Response("not json", { status: 200 });
210- });
211+test("malformed json", async () => {
212+ nock(baseUrl).get("/users").reply(200, "not json");
213
214 const { schema, store } = testStore();
215 const api = createApi();
216@@ -234,10 +213,8 @@ it(tests, "malformed json", async () => {
217 });
218 });
219
220-it(tests, "POST", async () => {
221- mock(`POST@/users`, () => {
222- return new Response(JSON.stringify(mockUser));
223- });
224+test("POST", async () => {
225+ nock(baseUrl).post("/users").reply(200, mockUser);
226
227 const { schema, store } = testStore();
228 const api = createApi();
229@@ -284,10 +261,8 @@ it(tests, "POST", async () => {
230 });
231 });
232
233-it(tests, "POST multiple endpoints with same uri", async () => {
234- mock(`POST@/users/1/something`, () => {
235- return new Response(JSON.stringify(mockUser));
236- });
237+test("POST multiple endpoints with same uri", async () => {
238+ nock(baseUrl).post("/users/1/something").reply(200, mockUser).persist();
239
240 const { store, schema } = testStore();
241 const api = createApi();
242@@ -370,7 +345,7 @@ it(tests, "POST multiple endpoints with same uri", async () => {
243 });
244 });
245
246-it(tests, "slug in url but payload has empty string for slug value", () => {
247+test("slug in url but payload has empty string for slug value", () => {
248 const { store, schema } = testStore();
249 const api = createApi();
250 api.use(mdw.api({ schema }));
251@@ -401,17 +376,16 @@ it(tests, "slug in url but payload has empty string for slug value", () => {
252 expect(actual).toEqual(data);
253 });
254
255-it(tests, "with success - should keep retrying fetch request", async () => {
256- let counter = 0;
257- mock(`GET@/users`, () => {
258- counter += 1;
259- if (counter > 4) {
260- return new Response(JSON.stringify(mockUser));
261- }
262- return new Response(JSON.stringify({ message: "error" }), {
263- status: 400,
264- });
265- });
266+test("with success - should keep retrying fetch request", async () => {
267+ nock(baseUrl)
268+ .get("/users")
269+ .reply(400, { message: "error" })
270+ .get("/users")
271+ .reply(400, { message: "error" })
272+ .get("/users")
273+ .reply(400, { message: "error" })
274+ .get("/users")
275+ .reply(200, mockUser);
276
277 const { schema, store } = testStore();
278 const api = createApi();
279@@ -449,76 +423,65 @@ it(tests, "with success - should keep retrying fetch request", async () => {
280 expect(actual).toEqual({ ok: true, value: mockUser });
281 });
282
283-it(
284- tests,
285- "fetch retry - with failure - should keep retrying and then quit",
286- async () => {
287- mock(`GET@/users`, () => {
288- return new Response(JSON.stringify({ message: "error" }), {
289- status: 400,
290- });
291- });
292-
293- const { schema, store } = testStore();
294- let actual = null;
295- const api = createApi();
296- api.use(mdw.api({ schema }));
297- api.use(api.routes());
298- api.use(mdw.fetch({ baseUrl }));
299-
300- const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
301- function* (ctx, next) {
302- ctx.cache = true;
303- yield* next();
304- actual = ctx.json;
305- },
306- mdw.fetchRetry((n) => (n > 2 ? -1 : 10)),
307- ]);
308-
309- store.run(api.bootup);
310- const action = fetchUsers();
311- store.dispatch(action);
312-
313- const loader = await store.run(waitForLoader(schema.loaders, action));
314- if (!loader.ok) {
315- throw loader.error;
316- }
317- const data = { message: "error" };
318- expect(actual).toEqual({ ok: false, error: data });
319- },
320-);
321-
322-it(
323- tests,
324- "should *not* make http request and instead simply mock response",
325- async () => {
326- const { schema, store } = testStore();
327- let actual = null;
328- const api = createApi();
329- api.use(mdw.api({ schema }));
330- api.use(api.routes());
331- api.use(mdw.fetch({ baseUrl }));
332-
333- const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
334- function* (ctx, next) {
335- yield* next();
336- actual = ctx.json;
337- },
338- mdw.response(new Response(JSON.stringify(mockUser))),
339- ]);
340+test("fetch retry - with failure - should keep retrying and then quit", async () => {
341+ expect.assertions(1);
342+ nock(baseUrl).get("/users").reply(400, { message: "error" }).persist();
343+
344+ const { schema, store } = testStore();
345+ let actual = null;
346+ const api = createApi();
347+ api.use(mdw.api({ schema }));
348+ api.use(api.routes());
349+ api.use(mdw.fetch({ baseUrl }));
350+
351+ const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
352+ function* (ctx, next) {
353+ ctx.cache = true;
354+ yield* next();
355+ actual = ctx.json;
356+ },
357+ mdw.fetchRetry((n) => (n > 2 ? -1 : 10)),
358+ ]);
359+
360+ store.run(api.bootup);
361+ const action = fetchUsers();
362+ store.dispatch(action);
363+
364+ const loader = await store.run(waitForLoader(schema.loaders, action));
365+ if (!loader.ok) {
366+ throw loader.error;
367+ }
368+ const data = { message: "error" };
369+ expect(actual).toEqual({ ok: false, error: data });
370+});
371
372- store.run(api.bootup);
373- store.dispatch(fetchUsers());
374+test("should *not* make http request and instead simply mock response", async () => {
375+ const { schema, store } = testStore();
376+ let actual = null;
377+ const api = createApi();
378+ api.use(mdw.api({ schema }));
379+ api.use(api.routes());
380+ api.use(mdw.fetch({ baseUrl }));
381
382- const loader = await store.run(waitForLoader(schema.loaders, fetchUsers));
383- if (!loader.ok) {
384- throw loader.error;
385- }
386- expect(actual).toEqual({ ok: true, value: mockUser });
387- },
388-);
389+ const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
390+ function* (ctx, next) {
391+ yield* next();
392+ actual = ctx.json;
393+ },
394+ mdw.response(new Response(JSON.stringify(mockUser))),
395+ ]);
396+
397+ store.run(api.bootup);
398+ store.dispatch(fetchUsers());
399+
400+ const loader = await store.run(waitForLoader(schema.loaders, fetchUsers));
401+ if (!loader.ok) {
402+ throw loader.error;
403+ }
404+ expect(actual).toEqual({ ok: true, value: mockUser });
405+});
406
407-it(tests, "should use dynamic mdw to mock response", async () => {
408+test("should use dynamic mdw to mock response", async () => {
409 const { schema, store } = testStore();
410 let actual = null;
411 const api = createApi();
R test/mdw.test.ts =>
src/test/mdw.test.ts
+38,
-49
1@@ -1,11 +1,3 @@
2-import { assertLike, asserts, describe, expect, it } from "../test.ts";
3-import {
4- createSchema,
5- createStore,
6- slice,
7- updateStore,
8- waitForLoader,
9-} from "../store/mod.ts";
10 import {
11 createApi,
12 createKey,
13@@ -15,8 +7,16 @@ import {
14 takeEvery,
15 takeLatest,
16 waitFor,
17-} from "../mod.ts";
18-import type { ApiCtx, Next, ThunkCtx } from "../mod.ts";
19+} from "../index.js";
20+import type { ApiCtx, Next, ThunkCtx } from "../index.js";
21+import {
22+ createSchema,
23+ createStore,
24+ slice,
25+ updateStore,
26+ waitForLoader,
27+} from "../store/index.js";
28+import { assertLike, expect, test } from "../test.js";
29
30 interface User {
31 id: string;
32@@ -43,9 +43,7 @@ const testStore = () => {
33 return { schema, store };
34 };
35
36-const tests = describe("middleware");
37-
38-it(tests, "basic", () => {
39+test("basic", () => {
40 const { store, schema } = testStore();
41 const query = createApi<ApiCtx>();
42 query.use(mdw.api({ schema }));
43@@ -64,7 +62,7 @@ it(tests, "basic", () => {
44 });
45
46 const fetchUsers = query.create(
47- `/users`,
48+ "/users",
49 { supervisor: takeEvery },
50 function* processUsers(ctx: ApiCtx<unknown, { users: User[] }>, next) {
51 yield* next();
52@@ -80,7 +78,7 @@ it(tests, "basic", () => {
53 );
54
55 const fetchUser = query.create<{ id: string }>(
56- `/users/:id`,
57+ "/users/:id",
58 {
59 supervisor: takeLatest,
60 },
61@@ -106,7 +104,7 @@ it(tests, "basic", () => {
62 });
63 });
64
65-it(tests, "with loader", () => {
66+test("with loader", () => {
67 const { schema, store } = testStore();
68 const api = createApi<ApiCtx>();
69 api.use(mdw.api({ schema }));
70@@ -119,7 +117,7 @@ it(tests, "with loader", () => {
71 });
72
73 const fetchUsers = api.create(
74- `/users`,
75+ "/users",
76 { supervisor: takeEvery },
77 function* processUsers(ctx: ApiCtx<unknown, { users: User[] }>, next) {
78 yield* next();
79@@ -148,7 +146,7 @@ it(tests, "with loader", () => {
80 });
81 });
82
83-it(tests, "with item loader", () => {
84+test("with item loader", () => {
85 const { store, schema } = testStore();
86 const api = createApi<ApiCtx>();
87 api.use(mdw.api({ schema }));
88@@ -161,7 +159,7 @@ it(tests, "with item loader", () => {
89 });
90
91 const fetchUser = api.create<{ id: string }>(
92- `/users/:id`,
93+ "/users/:id",
94 { supervisor: takeEvery },
95 function* processUsers(ctx: ApiCtx<unknown, { users: User[] }>, next) {
96 yield* next();
97@@ -193,7 +191,7 @@ it(tests, "with item loader", () => {
98 });
99 });
100
101-it(tests, "with POST", () => {
102+test("with POST", () => {
103 const { store, schema } = testStore();
104 const query = createApi();
105 query.use(mdw.queryCtx);
106@@ -201,7 +199,7 @@ it(tests, "with POST", () => {
107 query.use(query.routes());
108 query.use(function* fetchApi(ctx, next) {
109 const request = ctx.req();
110- asserts.assertEquals(request, {
111+ expect(request).toEqual({
112 url: "/users",
113 headers: {},
114 method: "POST",
115@@ -216,7 +214,7 @@ it(tests, "with POST", () => {
116 });
117
118 const createUser = query.create<{ email: string }>(
119- `/users [POST]`,
120+ "/users [POST]",
121 { supervisor: takeEvery },
122 function* processUsers(
123 ctx: ApiCtx<{ email: string }, { users: User[] }>,
124@@ -244,7 +242,7 @@ it(tests, "with POST", () => {
125 store.dispatch(createUser({ email: mockUser.email }));
126 });
127
128-it(tests, "simpleCache", () => {
129+test("simpleCache", () => {
130 const { store, schema } = testStore();
131 const api = createApi<ApiCtx>();
132 api.use(mdw.api({ schema }));
133@@ -273,7 +271,7 @@ it(tests, "simpleCache", () => {
134 });
135 });
136
137-it(tests, "overriding default loader behavior", () => {
138+test("overriding default loader behavior", () => {
139 const { store, schema } = testStore();
140 const api = createApi<ApiCtx>();
141 api.use(mdw.api({ schema }));
142@@ -286,7 +284,7 @@ it(tests, "overriding default loader behavior", () => {
143 });
144
145 const fetchUsers = api.create(
146- `/users`,
147+ "/users",
148 { supervisor: takeEvery },
149 function* (ctx: ApiCtx<unknown, { users: User[] }>, next) {
150 yield* next();
151@@ -319,14 +317,11 @@ it(tests, "overriding default loader behavior", () => {
152 });
153 });
154
155-it(tests, "mdw.api() - error handler", () => {
156+test("mdw.api() - error handler", () => {
157 let err = false;
158 console.error = (msg: string) => {
159 if (err) return;
160- asserts.assertEquals(
161- msg,
162- "Error: something happened. Check the endpoint [/users]",
163- );
164+ expect(msg).toBe("Error: something happened. Check the endpoint [/users]");
165 err = true;
166 };
167
168@@ -338,13 +333,13 @@ it(tests, "mdw.api() - error handler", () => {
169 throw new Error("something happened");
170 });
171
172- const fetchUsers = query.create(`/users`, { supervisor: takeEvery });
173+ const fetchUsers = query.create("/users", { supervisor: takeEvery });
174
175 store.run(query.bootup);
176 store.dispatch(fetchUsers());
177 });
178
179-it(tests, "createApi with own key", async () => {
180+test("createApi with own key", async () => {
181 const { schema, store } = testStore();
182 const query = createApi();
183 query.use(mdw.api({ schema }));
184@@ -361,7 +356,7 @@ it(tests, "createApi with own key", async () => {
185 const theTestKey = `some-custom-key-${Math.ceil(Math.random() * 1000)}`;
186
187 const createUserCustomKey = query.post<{ email: string }>(
188- `/users`,
189+ "/users",
190 { supervisor: takeEvery },
191 function* processUsers(ctx: ApiCtx, next) {
192 ctx.cache = true;
193@@ -392,7 +387,7 @@ it(tests, "createApi with own key", async () => {
194 };
195 },
196 );
197- const newUEmail = mockUser.email + ".org";
198+ const newUEmail = `${mockUser.email}.org`;
199
200 store.run(query.bootup);
201
202@@ -405,17 +400,14 @@ it(tests, "createApi with own key", async () => {
203 : createKey("/users [POST]", { email: newUEmail });
204
205 const s = store.getState();
206- asserts.assertEquals(schema.cache.selectById(s, { id: expectedKey }), {
207+ expect(schema.cache.selectById(s, { id: expectedKey })).toEqual({
208 "1": { id: "1", name: "test", email: newUEmail },
209 });
210
211- asserts.assert(
212- expectedKey.split("|")[1] === theTestKey,
213- "the keypart should match the input",
214- );
215+ expect(expectedKey.split("|")[1]).toEqual(theTestKey);
216 });
217
218-it(tests, "createApi with custom key but no payload", async () => {
219+test("createApi with custom key but no payload", async () => {
220 const { store, schema } = testStore();
221 const query = createApi();
222 query.use(mdw.api({ schema }));
223@@ -432,7 +424,7 @@ it(tests, "createApi with custom key but no payload", async () => {
224 const theTestKey = `some-custom-key-${Math.ceil(Math.random() * 1000)}`;
225
226 const getUsers = query.get(
227- `/users`,
228+ "/users",
229 { supervisor: takeEvery },
230 function* processUsers(ctx: ApiCtx, next) {
231 ctx.cache = true;
232@@ -474,17 +466,14 @@ it(tests, "createApi with custom key but no payload", async () => {
233 : createKey("/users [GET]", null);
234
235 const s = store.getState();
236- asserts.assertEquals(schema.cache.selectById(s, { id: expectedKey }), {
237+ expect(schema.cache.selectById(s, { id: expectedKey })).toEqual({
238 "1": mockUser,
239 });
240
241- asserts.assert(
242- expectedKey.split("|")[1] === theTestKey,
243- "the keypart should match the input",
244- );
245+ expect(expectedKey.split("|")[1]).toBe(theTestKey);
246 });
247
248-it(tests, "errorHandler", () => {
249+test("errorHandler", () => {
250 let a = 0;
251 const query = createApi<ApiCtx>();
252 query.use(function* errorHandler<Ctx extends ThunkCtx = ThunkCtx>(
253@@ -519,7 +508,7 @@ it(tests, "errorHandler", () => {
254 });
255
256 const fetchUsers = query.create(
257- `/users`,
258+ "/users",
259 { supervisor: takeEvery },
260 function* processUsers(_: ApiCtx<unknown, { users: User[] }>, next) {
261 // throw new Error("some error");
262@@ -540,7 +529,7 @@ it(tests, "errorHandler", () => {
263 expect(a).toEqual(2);
264 });
265
266-it(tests, "stub predicate", async () => {
267+test("stub predicate", async () => {
268 let actual: { ok: boolean } = { ok: false };
269 const { store, schema } = testStore();
270 const api = createApi();
+144,
-0
1@@ -0,0 +1,144 @@
2+import type { Operation, Result } from "../index.js";
3+import { Err, Ok, each, parallel, run, sleep, spawn } from "../index.js";
4+import { expect, test } from "../test.js";
5+
6+interface Defer<T> {
7+ promise: Promise<T>;
8+ resolve: (t: T) => void;
9+ reject: (t: Error) => void;
10+}
11+
12+function defer<T>(): Defer<T> {
13+ let resolve: (t: T) => void = () => {};
14+ let reject: (t: Error) => void = () => {};
15+ const promise = new Promise<T>((res, rej) => {
16+ resolve = res;
17+ reject = rej;
18+ });
19+
20+ return { resolve, reject, promise };
21+}
22+
23+test("should return an immediate channel with results as they are completed", async () => {
24+ const result = await run(function* () {
25+ const results = yield* parallel([
26+ function* () {
27+ yield* sleep(20);
28+ return "second";
29+ },
30+ function* () {
31+ yield* sleep(10);
32+ return "first";
33+ },
34+ ]);
35+
36+ const res: Result<string>[] = [];
37+ for (const val of yield* each(results.immediate)) {
38+ res.push(val);
39+ yield* each.next();
40+ }
41+
42+ yield* results;
43+ return res;
44+ });
45+
46+ expect(result).toEqual([Ok("first"), Ok("second")]);
47+});
48+
49+test("should return a sequence channel with results preserving array order as results", async () => {
50+ const result = await run(function* () {
51+ const results = yield* parallel([
52+ function* () {
53+ yield* sleep(20);
54+ return "second";
55+ },
56+ function* () {
57+ yield* sleep(10);
58+ return "first";
59+ },
60+ ]);
61+
62+ const res: Result<string>[] = [];
63+ for (const val of yield* each(results.sequence)) {
64+ res.push(val);
65+ yield* each.next();
66+ }
67+
68+ yield* results;
69+ return res;
70+ });
71+
72+ expect(result).toEqual([Ok("second"), Ok("first")]);
73+});
74+
75+test("should return all the result in an array, preserving order", async () => {
76+ const result = await run(function* () {
77+ const para = yield* parallel([
78+ function* () {
79+ yield* sleep(20);
80+ return "second";
81+ },
82+ function* () {
83+ yield* sleep(10);
84+ return "first";
85+ },
86+ ]);
87+
88+ return yield* para;
89+ });
90+
91+ expect(result).toEqual([Ok("second"), Ok("first")]);
92+});
93+
94+test("should return empty array", async () => {
95+ let actual;
96+ await run(function* (): Operation<void> {
97+ const results = yield* parallel([]);
98+ actual = yield* results;
99+ });
100+ expect(actual).toEqual([]);
101+});
102+
103+test("should resolve all async items", async () => {
104+ const two = defer();
105+
106+ function* one() {
107+ yield* sleep(5);
108+ return 1;
109+ }
110+
111+ const result = await run(function* () {
112+ yield* spawn(function* () {
113+ yield* sleep(15);
114+ two.resolve(2);
115+ });
116+ const results = yield* parallel([one, () => two.promise]);
117+ return yield* results;
118+ });
119+
120+ expect(result).toEqual([Ok(1), Ok(2)]);
121+});
122+
123+test("should stop all operations when there is an error", async () => {
124+ let actual: Result<number>[] = [];
125+ const one = defer<number>();
126+ const two = defer<number>();
127+
128+ function* genFn() {
129+ try {
130+ const results = yield* parallel([() => one.promise, () => two.promise]);
131+ actual = yield* results;
132+ } catch (_) {
133+ actual = [Err(new Error("should not get hit"))];
134+ }
135+ }
136+
137+ const err = new Error("error");
138+ one.reject(err);
139+ two.resolve(1);
140+
141+ await run(genFn);
142+
143+ const expected = [Err(err), Ok(1)];
144+ expect(actual).toEqual(expected);
145+});
R test/persist.test.ts =>
src/test/persist.test.ts
+248,
-255
1@@ -1,21 +1,20 @@
2 import { sleep } from "effection";
3-import { Ok, Operation, parallel, put, take } from "../mod.ts";
4+import { Ok, type Operation, parallel, put, take } from "../index.js";
5 import {
6+ PERSIST_LOADER_ID,
7+ type PersistAdapter,
8 createPersistor,
9 createSchema,
10 createStore,
11 createTransform,
12- PERSIST_LOADER_ID,
13- PersistAdapter,
14 persistStoreMdw,
15 slice,
16-} from "../store/mod.ts";
17-import { asserts, describe, it } from "../test.ts";
18-import type { LoaderItemState } from "../types.ts";
19+} from "../store/index.js";
20+import { expect, test } from "../test.js";
21+import type { LoaderItemState } from "../types.js";
22
23-const tests = describe("store");
24-
25-it(tests, "can persist to storage adapters", async () => {
26+test("can persist to storage adapters", async () => {
27+ expect.assertions(1);
28 const [schema, initialState] = createSchema({
29 token: slice.str(),
30 loaders: slice.loaders(),
31@@ -57,10 +56,11 @@ it(tests, "can persist to storage adapters", async () => {
32 yield* group;
33 });
34
35- asserts.assertEquals(ls, '{"token":"1234"}');
36+ expect(ls).toBe('{"token":"1234"}');
37 });
38
39-it(tests, "rehydrates state", async () => {
40+test("rehydrates state", async () => {
41+ expect.assertions(1);
42 const [schema, initialState] = createSchema({
43 token: slice.str(),
44 loaders: slice.loaders(),
45@@ -92,10 +92,11 @@ it(tests, "rehydrates state", async () => {
46 yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
47 });
48
49- asserts.assertEquals(store.getState().token, "123");
50+ expect(store.getState().token).toBe("123");
51 });
52
53-it(tests, "persists inbound state using transform 'in' function", async () => {
54+test("persists inbound state using transform 'in' function", async () => {
55+ expect.assertions(1);
56 const [schema, initialState] = createSchema({
57 token: slice.str(),
58 loaders: slice.loaders(),
59@@ -119,9 +120,10 @@ it(tests, "persists inbound state using transform 'in' function", async () => {
60
61 const transform = createTransform<State>();
62
63- transform.in = function (state) {
64- return { ...state, token: state?.token?.split("").reverse().join("") };
65- };
66+ transform.in = (state) => ({
67+ ...state,
68+ token: state?.token?.split("").reverse().join(""),
69+ });
70
71 const persistor = createPersistor<State>({
72 adapter,
73@@ -149,10 +151,12 @@ it(tests, "persists inbound state using transform 'in' function", async () => {
74 ]);
75 yield* group;
76 });
77- asserts.assertEquals(ls, '{"token":"4321","cache":{}}');
78+
79+ expect(ls).toBe('{"token":"4321","cache":{}}');
80 });
81
82-it(tests, "persists inbound state using tranform in (2)", async () => {
83+test("persists inbound state using tranform in (2)", async () => {
84+ expect.assertions(1);
85 const [schema, initialState] = createSchema({
86 token: slice.str(),
87 loaders: slice.loaders(),
88@@ -210,10 +214,11 @@ it(tests, "persists inbound state using tranform in (2)", async () => {
89 ]);
90 yield* group;
91 });
92- asserts.assertEquals(ls, '{"token":"4321","cache":{}}');
93+ expect(ls).toBe('{"token":"4321","cache":{}}');
94 });
95
96-it(tests, "persists a filtered nested part of a slice", async () => {
97+test("persists a filtered nested part of a slice", async () => {
98+ expect.assertions(5);
99 const [schema, initialState] = createSchema({
100 token: slice.str(),
101 loaders: slice.loaders(),
102@@ -305,14 +310,15 @@ it(tests, "persists a filtered nested part of a slice", async () => {
103 ]);
104 yield* group;
105 });
106- asserts.assertStringIncludes(ls, '{"token":"1"');
107- asserts.assertStringIncludes(ls, '"message":"loading A-second"');
108- asserts.assertStringIncludes(ls, '"id":"C"');
109- asserts.assertNotMatch(ls, /"message":"loading A-first"/);
110- asserts.assertNotMatch(ls, /"id":"B"/);
111+ expect(ls).toContain('{"token":"1"');
112+ expect(ls).toContain('"message":"loading A-second"');
113+ expect(ls).toContain('"id":"C"');
114+ expect(ls).not.toContain('"message":"loading A-first"');
115+ expect(ls).not.toMatch('"id":"B"');
116 });
117
118-it(tests, "handles the empty state correctly", async () => {
119+test("handles the empty state correctly", async () => {
120+ expect.assertions(1);
121 const [_schema, initialState] = createSchema({
122 token: slice.str(),
123 loaders: slice.loaders(),
124@@ -336,9 +342,7 @@ it(tests, "handles the empty state correctly", async () => {
125 };
126
127 const transform = createTransform<State>();
128- transform.in = function (_: Partial<State>) {
129- return {};
130- };
131+ transform.in = (_: Partial<State>) => ({});
132
133 const persistor = createPersistor<State>({
134 adapter,
135@@ -355,234 +359,220 @@ it(tests, "handles the empty state correctly", async () => {
136 yield* persistor.rehydrate();
137 });
138
139- asserts.assertEquals(ls, "{}");
140+ expect(ls).toBe("{}");
141 });
142
143-it(
144- tests,
145- "in absence of the inbound transformer, persists as it is",
146- async () => {
147- const [schema, initialState] = createSchema({
148- token: slice.str(),
149- loaders: slice.loaders(),
150- cache: slice.table({ empty: {} }),
151- });
152- type State = typeof initialState;
153- let ls = "{}";
154- const adapter: PersistAdapter<State> = {
155- getItem: function* (_: string) {
156- return Ok(JSON.parse(ls));
157- },
158- setItem: function* (_: string, s: Partial<State>) {
159- ls = JSON.stringify(s);
160- return Ok(undefined);
161- },
162- removeItem: function* (_: string) {
163- return Ok(undefined);
164- },
165- };
166- const persistor = createPersistor<State>({
167- adapter,
168- allowlist: ["token"],
169- transform: createTransform<State>(), // we deliberately do not set the inbound transformer
170- });
171-
172- const mdw = persistStoreMdw(persistor);
173- const store = createStore({
174- initialState,
175- middleware: [mdw],
176- });
177-
178- await store.run(function* (): Operation<void> {
179- yield* persistor.rehydrate();
180-
181- const group = yield* parallel([
182- function* (): Operation<void> {
183- const action = yield* take<string>("SET_TOKEN");
184- yield* schema.update(schema.token.set(action.payload));
185- },
186- function* () {
187- yield* put({ type: "SET_TOKEN", payload: "1234" });
188- },
189- ]);
190- yield* group;
191- });
192-
193- asserts.assertEquals(ls, '{"token":"1234"}');
194- },
195-);
196-
197-it(
198- tests,
199- "handles errors gracefully, defaluts to identity function",
200- async () => {
201- const [schema, initialState] = createSchema({
202- token: slice.str(),
203- loaders: slice.loaders(),
204- cache: slice.table({ empty: {} }),
205- });
206- type State = typeof initialState;
207- let ls = "{}";
208- const adapter: PersistAdapter<State> = {
209- getItem: function* (_: string) {
210- return Ok(JSON.parse(ls));
211- },
212- setItem: function* (_: string, s: Partial<State>) {
213- ls = JSON.stringify(s);
214- return Ok(undefined);
215- },
216- removeItem: function* (_: string) {
217- return Ok(undefined);
218- },
219- };
220+test("in absence of the inbound transformer, persists as it is", async () => {
221+ expect.assertions(1);
222+ const [schema, initialState] = createSchema({
223+ token: slice.str(),
224+ loaders: slice.loaders(),
225+ cache: slice.table({ empty: {} }),
226+ });
227+ type State = typeof initialState;
228+ let ls = "{}";
229+ const adapter: PersistAdapter<State> = {
230+ getItem: function* (_: string) {
231+ return Ok(JSON.parse(ls));
232+ },
233+ setItem: function* (_: string, s: Partial<State>) {
234+ ls = JSON.stringify(s);
235+ return Ok(undefined);
236+ },
237+ removeItem: function* (_: string) {
238+ return Ok(undefined);
239+ },
240+ };
241+ const persistor = createPersistor<State>({
242+ adapter,
243+ allowlist: ["token"],
244+ transform: createTransform<State>(), // we deliberately do not set the inbound transformer
245+ });
246
247- const transform = createTransform<State>();
248- transform.in = function (_: Partial<State>) {
249- throw new Error("testing the transform error");
250- };
251- const persistor = createPersistor<State>({
252- adapter,
253- transform,
254- });
255- const mdw = persistStoreMdw(persistor);
256- const store = createStore({
257- initialState,
258- middleware: [mdw],
259- });
260-
261- await store.run(function* (): Operation<void> {
262- yield* persistor.rehydrate();
263- yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
264- yield* schema.update(schema.token.set("1234"));
265- });
266- asserts.assertEquals(store.getState().token, "1234");
267- },
268-);
269-
270-it(
271- tests,
272- "allowdList is filtered out after the inbound transformer is applied",
273- async () => {
274- const [schema, initialState] = createSchema({
275- token: slice.str(),
276- counter: slice.num(0),
277- loaders: slice.loaders(),
278- cache: slice.table({ empty: {} }),
279- });
280- type State = typeof initialState;
281- let ls = "{}";
282- const adapter: PersistAdapter<State> = {
283- getItem: function* (_: string) {
284- return Ok(JSON.parse(ls));
285- },
286- setItem: function* (_: string, s: Partial<State>) {
287- ls = JSON.stringify(s);
288- return Ok(undefined);
289- },
290- removeItem: function* (_: string) {
291- return Ok(undefined);
292- },
293- };
294+ const mdw = persistStoreMdw(persistor);
295+ const store = createStore({
296+ initialState,
297+ middleware: [mdw],
298+ });
299
300- const transform = createTransform<State>();
301- transform.in = function (state) {
302- return {
303- ...state,
304- token: `${state.counter}${state?.token?.split("").reverse().join("")}`,
305- };
306- };
307+ await store.run(function* (): Operation<void> {
308+ yield* persistor.rehydrate();
309
310- const persistor = createPersistor<State>({
311- adapter,
312- allowlist: ["token"],
313- transform,
314- });
315-
316- const mdw = persistStoreMdw(persistor);
317- const store = createStore({
318- initialState,
319- middleware: [mdw],
320- });
321-
322- await store.run(function* (): Operation<void> {
323- yield* persistor.rehydrate();
324- yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
325- yield* schema.update(schema.token.set("1234"));
326- yield* schema.update(schema.counter.set(5));
327- });
328-
329- asserts.assertEquals(ls, '{"token":"54321"}');
330- },
331-);
332-
333-it(
334- tests,
335- "the inbound transformer can be redifined during runtime",
336- async () => {
337- const [schema, initialState] = createSchema({
338- token: slice.str(),
339- loaders: slice.loaders(),
340- cache: slice.table({ empty: {} }),
341- });
342- type State = typeof initialState;
343- let ls = "{}";
344- const adapter: PersistAdapter<State> = {
345- getItem: function* (_: string) {
346- return Ok(JSON.parse(ls));
347- },
348- setItem: function* (_: string, s: Partial<State>) {
349- ls = JSON.stringify(s);
350- return Ok(undefined);
351+ const group = yield* parallel([
352+ function* (): Operation<void> {
353+ const action = yield* take<string>("SET_TOKEN");
354+ yield* schema.update(schema.token.set(action.payload));
355 },
356- removeItem: function* (_: string) {
357- return Ok(undefined);
358+ function* () {
359+ yield* put({ type: "SET_TOKEN", payload: "1234" });
360 },
361- };
362+ ]);
363+ yield* group;
364+ });
365
366- const transform = createTransform<State>();
367- transform.in = function (state) {
368- return {
369- ...state,
370- token: `${state?.token?.split("").reverse().join("")}`,
371- };
372- };
373+ expect(ls).toBe('{"token":"1234"}');
374+});
375
376- const persistor = createPersistor<State>({
377- adapter,
378- allowlist: ["token"],
379- transform,
380- });
381-
382- const mdw = persistStoreMdw(persistor);
383- const store = createStore({
384- initialState,
385- middleware: [mdw],
386- });
387-
388- await store.run(function* (): Operation<void> {
389- yield* persistor.rehydrate();
390- yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
391- yield* schema.update(schema.token.set("01234"));
392- });
393-
394- asserts.assertEquals(ls, '{"token":"43210"}');
395-
396- transform.in = function (state) {
397- return {
398- ...state,
399- token: `${state?.token}56789`,
400- };
401- };
402+test("handles errors gracefully, defaluts to identity function", async () => {
403+ expect.assertions(1);
404+ const [schema, initialState] = createSchema({
405+ token: slice.str(),
406+ loaders: slice.loaders(),
407+ cache: slice.table({ empty: {} }),
408+ });
409+ type State = typeof initialState;
410+ let ls = "{}";
411+ const adapter: PersistAdapter<State> = {
412+ getItem: function* (_: string) {
413+ return Ok(JSON.parse(ls));
414+ },
415+ setItem: function* (_: string, s: Partial<State>) {
416+ ls = JSON.stringify(s);
417+ return Ok(undefined);
418+ },
419+ removeItem: function* (_: string) {
420+ return Ok(undefined);
421+ },
422+ };
423+
424+ const transform = createTransform<State>();
425+ transform.in = (_: Partial<State>) => {
426+ throw new Error("testing the transform error");
427+ };
428+ const persistor = createPersistor<State>({
429+ adapter,
430+ transform,
431+ });
432+ const mdw = persistStoreMdw(persistor);
433+ const store = createStore({
434+ initialState,
435+ middleware: [mdw],
436+ });
437
438- await store.run(function* (): Operation<void> {
439- yield* schema.update(schema.token.set("01234"));
440- });
441+ const err = console.error;
442+ console.error = () => {};
443+ await store.run(function* (): Operation<void> {
444+ yield* persistor.rehydrate();
445+ yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
446+ yield* schema.update(schema.token.set("1234"));
447+ });
448+ expect(store.getState().token).toBe("1234");
449+ console.error = err;
450+});
451
452- asserts.assertEquals(ls, '{"token":"0123456789"}');
453- },
454-);
455+test("allowdList is filtered out after the inbound transformer is applied", async () => {
456+ expect.assertions(1);
457+ const [schema, initialState] = createSchema({
458+ token: slice.str(),
459+ counter: slice.num(0),
460+ loaders: slice.loaders(),
461+ cache: slice.table({ empty: {} }),
462+ });
463+ type State = typeof initialState;
464+ let ls = "{}";
465+ const adapter: PersistAdapter<State> = {
466+ getItem: function* (_: string) {
467+ return Ok(JSON.parse(ls));
468+ },
469+ setItem: function* (_: string, s: Partial<State>) {
470+ ls = JSON.stringify(s);
471+ return Ok(undefined);
472+ },
473+ removeItem: function* (_: string) {
474+ return Ok(undefined);
475+ },
476+ };
477+
478+ const transform = createTransform<State>();
479+ transform.in = (state) => ({
480+ ...state,
481+ token: `${state.counter}${state?.token?.split("").reverse().join("")}`,
482+ });
483+
484+ const persistor = createPersistor<State>({
485+ adapter,
486+ allowlist: ["token"],
487+ transform,
488+ });
489+
490+ const mdw = persistStoreMdw(persistor);
491+ const store = createStore({
492+ initialState,
493+ middleware: [mdw],
494+ });
495+
496+ await store.run(function* (): Operation<void> {
497+ yield* persistor.rehydrate();
498+ yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
499+ yield* schema.update(schema.token.set("1234"));
500+ yield* schema.update(schema.counter.set(5));
501+ });
502+
503+ expect(ls).toBe('{"token":"54321"}');
504+});
505+
506+test("the inbound transformer can be redifined during runtime", async () => {
507+ expect.assertions(2);
508+ const [schema, initialState] = createSchema({
509+ token: slice.str(),
510+ loaders: slice.loaders(),
511+ cache: slice.table({ empty: {} }),
512+ });
513+ type State = typeof initialState;
514+ let ls = "{}";
515+ const adapter: PersistAdapter<State> = {
516+ getItem: function* (_: string) {
517+ return Ok(JSON.parse(ls));
518+ },
519+ setItem: function* (_: string, s: Partial<State>) {
520+ ls = JSON.stringify(s);
521+ return Ok(undefined);
522+ },
523+ removeItem: function* (_: string) {
524+ return Ok(undefined);
525+ },
526+ };
527+
528+ const transform = createTransform<State>();
529+ transform.in = (state) => ({
530+ ...state,
531+ token: `${state?.token?.split("").reverse().join("")}`,
532+ });
533+
534+ const persistor = createPersistor<State>({
535+ adapter,
536+ allowlist: ["token"],
537+ transform,
538+ });
539+
540+ const mdw = persistStoreMdw(persistor);
541+ const store = createStore({
542+ initialState,
543+ middleware: [mdw],
544+ });
545+
546+ await store.run(function* (): Operation<void> {
547+ yield* persistor.rehydrate();
548+ yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
549+ yield* schema.update(schema.token.set("01234"));
550+ });
551+
552+ expect(ls).toBe('{"token":"43210"}');
553+
554+ transform.in = (state) => ({
555+ ...state,
556+ token: `${state?.token}56789`,
557+ });
558+
559+ await store.run(function* (): Operation<void> {
560+ yield* schema.update(schema.token.set("01234"));
561+ });
562+
563+ expect(ls).toBe('{"token":"0123456789"}');
564+});
565
566-it(tests, "persists state using transform 'out' function", async () => {
567+test("persists state using transform 'out' function", async () => {
568+ expect.assertions(1);
569 const [schema, initialState] = createSchema({
570 token: slice.str(),
571 counter: slice.num(0),
572@@ -628,10 +618,11 @@ it(tests, "persists state using transform 'out' function", async () => {
573 yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
574 });
575
576- asserts.assertEquals(store.getState().token, "43210");
577+ expect(store.getState().token).toBe("43210");
578 });
579
580-it("persists outbound state using tranform setOutTransformer", async () => {
581+test("persists outbound state using tranform setOutTransformer", async () => {
582+ expect.assertions(1);
583 const [schema, initialState] = createSchema({
584 token: slice.str(),
585 counter: slice.num(0),
586@@ -683,10 +674,11 @@ it("persists outbound state using tranform setOutTransformer", async () => {
587 yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
588 });
589
590- asserts.assertEquals(ls, '{"token":"012345"}');
591+ expect(ls).toBe('{"token":"012345"}');
592 });
593
594-it(tests, "persists outbound a filtered nested part of a slice", async () => {
595+test("persists outbound a filtered nested part of a slice", async () => {
596+ expect.assertions(1);
597 const [schema, initialState] = createSchema({
598 token: slice.str(),
599 loaders: slice.loaders(),
600@@ -712,7 +704,7 @@ it(tests, "persists outbound a filtered nested part of a slice", async () => {
601 function extractMetaAndSetToken(state: Partial<State>): Partial<State> {
602 const nextState = { ...state };
603 if (state.loaders) {
604- const savedLoader = state.loaders["A"];
605+ const savedLoader = state.loaders.A;
606 if (savedLoader?.meta?.flag) {
607 nextState.token = savedLoader.meta.flag;
608 }
609@@ -738,10 +730,11 @@ it(tests, "persists outbound a filtered nested part of a slice", async () => {
610 yield* persistor.rehydrate();
611 yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
612 });
613- asserts.assertEquals(store.getState().token, "01234_FLAG_PERSISTED");
614+ expect(store.getState().token).toBe("01234_FLAG_PERSISTED");
615 });
616
617-it(tests, "the outbound transformer can be reset during runtime", async () => {
618+test("the outbound transformer can be reset during runtime", async () => {
619+ expect.assertions(3);
620 const [schema, initialState] = createSchema({
621 token: slice.str(),
622 counter: slice.num(0),
623@@ -793,13 +786,13 @@ it(tests, "the outbound transformer can be reset during runtime", async () => {
624 yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
625 });
626
627- asserts.assertEquals(store.getState().token, "4321_");
628+ expect(store.getState().token).toBe("4321_");
629
630 await store.run(function* (): Operation<void> {
631 yield* schema.update(schema.token.set("01234"));
632 });
633
634- asserts.assertEquals(ls, '{"token":"01234"}');
635+ expect(ls).toBe('{"token":"01234"}');
636
637 transform.out = postpendToken;
638
639@@ -808,5 +801,5 @@ it(tests, "the outbound transformer can be reset during runtime", async () => {
640 yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
641 });
642
643- asserts.assertEquals(store.getState().token, "0123456789");
644+ expect(store.getState().token).toBe("0123456789");
645 });
+100,
-0
1@@ -0,0 +1,100 @@
2+import { ActionContext, each, put, sleep, spawn, take } from "../index.js";
3+import { createStore } from "../store/index.js";
4+import { expect, test } from "../test.js";
5+
6+test("should send actions through channel", async () => {
7+ const actual: string[] = [];
8+
9+ function* genFn(arg: string) {
10+ const actions = yield* ActionContext.expect();
11+ const task = yield* spawn(function* () {
12+ for (const action of yield* each(actions)) {
13+ actual.push(action.type);
14+ yield* each.next();
15+ }
16+ });
17+
18+ yield* put({
19+ type: arg,
20+ });
21+ yield* put({
22+ type: "2",
23+ });
24+ actions.close();
25+ yield* task;
26+ }
27+
28+ const store = createStore({ initialState: {} });
29+ await store.run(() => genFn("arg"));
30+
31+ const expected = ["arg", "2"];
32+ expect(actual).toEqual(expected);
33+});
34+
35+test("should handle nested puts", async () => {
36+ const actual: string[] = [];
37+
38+ function* genA() {
39+ yield* put({
40+ type: "a",
41+ });
42+ actual.push("put a");
43+ }
44+
45+ function* genB() {
46+ yield* take(["a"]);
47+ yield* put({
48+ type: "b",
49+ });
50+ actual.push("put b");
51+ }
52+
53+ function* root() {
54+ yield* spawn(genB);
55+ yield* spawn(genA);
56+ }
57+
58+ const store = createStore({ initialState: {} });
59+ await store.run(() => root());
60+
61+ const expected = ["put b", "put a"];
62+ expect(actual).toEqual(expected);
63+});
64+
65+test("should not cause stack overflow when puts are emitted while dispatching saga", async () => {
66+ function* root() {
67+ for (let i = 0; i < 10_000; i += 1) {
68+ yield* put({ type: "test" });
69+ }
70+ yield* sleep(0);
71+ }
72+
73+ const store = createStore({ initialState: {} });
74+ await store.run(() => root());
75+ expect(true).toBe(true);
76+});
77+
78+test("should not miss `put` that was emitted directly after creating a task (caused by another `put`)", async () => {
79+ const actual: string[] = [];
80+
81+ function* root() {
82+ yield* spawn(function* firstspawn() {
83+ yield* sleep(10);
84+ yield* put({ type: "c" });
85+ yield* put({ type: "do not miss" });
86+ });
87+
88+ yield* take("c");
89+
90+ const tsk = yield* spawn(function* () {
91+ yield* take("do not miss");
92+ actual.push("didn't get missed");
93+ });
94+ yield* tsk;
95+ }
96+
97+ const store = createStore({ initialState: {} });
98+ await store.run(root);
99+ const expected = ["didn't get missed"];
100+ expect(actual).toEqual(expected);
101+});
R test/react.test.ts =>
src/test/react.test.ts
+5,
-7
1@@ -1,12 +1,10 @@
2 import React from "react";
3-import { asserts, describe, it } from "../test.ts";
4-import { Provider } from "../react.ts";
5-import { createSchema, createStore, slice } from "../store/mod.ts";
6-
7-const tests = describe("react");
8+import { Provider } from "../react.js";
9+import { createSchema, createStore, slice } from "../store/index.js";
10+import { expect, test } from "../test.js";
11
12 // typing test
13-it(tests, () => {
14+test("react types", () => {
15 const [schema, initialState] = createSchema({
16 cache: slice.table(),
17 loaders: slice.loaders(),
18@@ -17,5 +15,5 @@ it(tests, () => {
19 store,
20 children: React.createElement("div"),
21 });
22- asserts.equal(true, true);
23+ expect(true).toBe(true);
24 });
R test/safe.test.ts =>
src/test/safe.test.ts
+5,
-7
1@@ -1,9 +1,7 @@
2-import { describe, expect, it } from "../test.ts";
3-import { call, run } from "../mod.ts";
4+import { call, run } from "../index.js";
5+import { expect, test } from "../test.js";
6
7-const tests = describe("call()");
8-
9-it(tests, "should call the generator function", async () => {
10+test("should call the generator function", async () => {
11 expect.assertions(1);
12 function* me() {
13 return "valid";
14@@ -15,7 +13,7 @@ it(tests, "should call the generator function", async () => {
15 });
16 });
17
18-it(tests, "should return an Err()", async () => {
19+test("should return an Err()", async () => {
20 expect.assertions(1);
21 const err = new Error("bang!");
22 function* me() {
23@@ -31,7 +29,7 @@ it(tests, "should return an Err()", async () => {
24 });
25 });
26
27-it(tests, "should call a promise", async () => {
28+test("should call a promise", async () => {
29 expect.assertions(1);
30 const me = () =>
31 new Promise<string>((resolve) => {
R test/schema.test.ts =>
src/test/schema.test.ts
+5,
-7
1@@ -1,7 +1,5 @@
2-import { describe, expect, it } from "../test.ts";
3-import { createSchema, createStore, select, slice } from "../store/mod.ts";
4-
5-const tests = describe("createSchema()");
6+import { createSchema, createStore, select, slice } from "../store/index.js";
7+import { expect, test } from "../test.js";
8
9 interface User {
10 id: string;
11@@ -13,7 +11,7 @@ interface UserWithRoles extends User {
12
13 const emptyUser = { id: "", name: "" };
14
15-it(tests, "default schema", async () => {
16+test("default schema", async () => {
17 const [schema, initialState] = createSchema();
18 const store = createStore({ initialState });
19 expect(store.getState()).toEqual({
20@@ -35,7 +33,7 @@ it(tests, "default schema", async () => {
21 );
22 });
23
24-it(tests, "general types and functionality", async () => {
25+test("general types and functionality", async () => {
26 expect.assertions(8);
27 const [db, initialState] = createSchema({
28 users: slice.table<User>({
29@@ -93,7 +91,7 @@ it(tests, "general types and functionality", async () => {
30 });
31 });
32
33-it(tests, "can work with a nested object", async () => {
34+test("can work with a nested object", async () => {
35 expect.assertions(3);
36 const [db, initialState] = createSchema({
37 currentUser: slice.obj<UserWithRoles>({ id: "", name: "", roles: [] }),
R test/store.test.ts =>
src/test/store.test.ts
+60,
-57
1@@ -1,13 +1,18 @@
2-import { createScope, Operation, parallel, put, Result, take } from "../mod.ts";
3 import {
4- createStore,
5+ type Operation,
6+ type Result,
7+ createScope,
8+ parallel,
9+ put,
10+ take,
11+} from "../index.js";
12+import {
13 StoreContext,
14 StoreUpdateContext,
15+ createStore,
16 updateStore,
17-} from "../store/mod.ts";
18-import { describe, expect, it } from "../test.ts";
19-
20-const tests = describe("store");
21+} from "../store/index.js";
22+import { expect, test } from "../test.js";
23
24 interface User {
25 id: string;
26@@ -34,56 +39,54 @@ interface UpdateUserProps {
27 name: string;
28 }
29
30-const updateUser = ({ id, name }: UpdateUserProps) => (state: State) => {
31- // use selectors to find the data you want to mutate
32- const user = findUserById(state, { id });
33- user.name = name;
34-
35- // different ways to update a `zod` record
36- const users = findUsers(state);
37- users[id].name = name;
38-
39- delete users[2];
40- users[3] = { id: "", name: "" };
41-
42- // or mutate state directly without selectors
43- state.dev = true;
44-};
45-
46-it(
47- tests,
48- "update store and receives update from channel `StoreUpdateContext`",
49- async () => {
50- expect.assertions(1);
51- const [scope] = createScope();
52- const initialState: Partial<State> = {
53- users: { 1: { id: "1", name: "testing" }, 2: { id: "2", name: "wow" } },
54- dev: false,
55- };
56- createStore({ scope, initialState });
57- let store;
58- await scope.run(function* (): Operation<Result<void>[]> {
59- const result = yield* parallel([
60- function* () {
61- store = yield* StoreContext;
62- const chan = yield* StoreUpdateContext;
63- const msgList = yield* chan.subscribe();
64- yield* msgList.next();
65- },
66- function* () {
67- yield* updateStore(updateUser({ id: "1", name: "eric" }));
68- },
69- ]);
70- return yield* result;
71- });
72- expect(store!.getState()).toEqual({
73- users: { 1: { id: "1", name: "eric" }, 3: { id: "", name: "" } },
74- dev: true,
75- });
76- },
77-);
78+const updateUser =
79+ ({ id, name }: UpdateUserProps) =>
80+ (state: State) => {
81+ // use selectors to find the data you want to mutate
82+ const user = findUserById(state, { id });
83+ user.name = name;
84+
85+ // different ways to update a `zod` record
86+ const users = findUsers(state);
87+ users[id].name = name;
88+
89+ (users as any)[2] = undefined;
90+ users[3] = { id: "", name: "" };
91+
92+ // or mutate state directly without selectors
93+ state.dev = true;
94+ };
95+
96+test("update store and receives update from channel `StoreUpdateContext`", async () => {
97+ expect.assertions(1);
98+ const [scope] = createScope();
99+ const initialState: Partial<State> = {
100+ users: { 1: { id: "1", name: "testing" }, 2: { id: "2", name: "wow" } },
101+ dev: false,
102+ };
103+ createStore({ scope, initialState });
104+ let store;
105+ await scope.run(function* (): Operation<Result<void>[]> {
106+ const result = yield* parallel([
107+ function* () {
108+ store = yield* StoreContext.expect();
109+ const chan = yield* StoreUpdateContext.expect();
110+ const msgList = yield* chan;
111+ yield* msgList.next();
112+ },
113+ function* () {
114+ yield* updateStore(updateUser({ id: "1", name: "eric" }));
115+ },
116+ ]);
117+ return yield* result;
118+ });
119+ expect((store as any)?.getState()).toEqual({
120+ users: { 1: { id: "1", name: "eric" }, 3: { id: "", name: "" } },
121+ dev: true,
122+ });
123+});
124
125-it(tests, "update store and receives update from `subscribe()`", async () => {
126+test("update store and receives update from `subscribe()`", async () => {
127 expect.assertions(1);
128 const initialState: Partial<State> = {
129 users: { 1: { id: "1", name: "testing" }, 2: { id: "2", name: "wow" } },
130@@ -107,7 +110,7 @@ it(tests, "update store and receives update from `subscribe()`", async () => {
131 });
132 });
133
134-it(tests, "emit Action and update store", async () => {
135+test("emit Action and update store", async () => {
136 expect.assertions(1);
137 const initialState: Partial<State> = {
138 users: { 1: { id: "1", name: "testing" }, 2: { id: "2", name: "wow" } },
139@@ -138,7 +141,7 @@ it(tests, "emit Action and update store", async () => {
140 });
141 });
142
143-it(tests, "resets store", async () => {
144+test("resets store", async () => {
145 expect.assertions(2);
146 const initialState: Partial<State> = {
147 users: { 1: { id: "1", name: "testing" }, 2: { id: "2", name: "wow" } },
R store/slice/obj.test.ts =>
src/test/store/slice/obj.test.ts
+8,
-9
1@@ -1,10 +1,9 @@
2-import { asserts, describe, it } from "../../test.ts";
3-import { configureStore, updateStore } from "../mod.ts";
4+import { configureStore, updateStore } from "../../../store/index.js";
5+import { expect, test } from "../../../test.js";
6
7-import { createObj } from "./obj.ts";
8-const tests = describe("createObj()");
9+import { createObj } from "../../../store/slice/obj.js";
10
11-export interface ICurrentUser {
12+interface ICurrentUser {
13 username: string;
14 userId: number;
15 isadmin: boolean;
16@@ -24,7 +23,7 @@ const slice = createObj<ICurrentUser>({
17 initialState: crtInitialState,
18 });
19
20-it(tests, "sets up an obj", async () => {
21+test("sets up an obj", async () => {
22 const store = configureStore({
23 initialState: {
24 [NAME]: crtInitialState,
25@@ -42,7 +41,7 @@ it(tests, "sets up an obj", async () => {
26 );
27 });
28
29- asserts.assertEquals(store.getState()["currentUser"], {
30+ expect(store.getState().currentUser).toEqual({
31 username: "bob",
32 userId: 1,
33 isadmin: true,
34@@ -53,7 +52,7 @@ it(tests, "sets up an obj", async () => {
35 yield* updateStore(slice.update({ key: "username", value: "alice" }));
36 });
37
38- asserts.assertEquals(store.getState()["currentUser"], {
39+ expect(store.getState().currentUser).toEqual({
40 username: "alice",
41 userId: 1,
42 isadmin: true,
43@@ -66,7 +65,7 @@ it(tests, "sets up an obj", async () => {
44 );
45 });
46
47- asserts.assertEquals(store.getState()["currentUser"], {
48+ expect(store.getState().currentUser).toEqual({
49 username: "alice",
50 userId: 1,
51 isadmin: true,
R store/slice/table.test.ts =>
src/test/store/slice/table.test.ts
+26,
-28
1@@ -1,9 +1,7 @@
2-import { asserts, describe, it } from "../../test.ts";
3-import { configureStore } from "../store.ts";
4-import { updateStore } from "../fx.ts";
5-import { createTable, table } from "./table.ts";
6-
7-const tests = describe("createTable()");
8+import { updateStore } from "../../../store/fx.js";
9+import { createTable, table } from "../../../store/slice/table.js";
10+import { configureStore } from "../../../store/store.js";
11+import { expect, test } from "../../../test.js";
12
13 type TUser = {
14 id: number;
15@@ -25,7 +23,7 @@ const first = { id: 1, user: "A" };
16 const second = { id: 2, user: "B" };
17 const third = { id: 3, user: "C" };
18
19-it(tests, "sets up a table", async () => {
20+test("sets up a table", async () => {
21 const store = configureStore({
22 initialState,
23 });
24@@ -33,10 +31,10 @@ it(tests, "sets up a table", async () => {
25 await store.run(function* () {
26 yield* updateStore(slice.set({ [first.id]: first }));
27 });
28- asserts.assertEquals(store.getState()[NAME], { [first.id]: first });
29+ expect(store.getState()[NAME]).toEqual({ [first.id]: first });
30 });
31
32-it(tests, "adds a row", async () => {
33+test("adds a row", async () => {
34 const store = configureStore({
35 initialState,
36 });
37@@ -44,10 +42,10 @@ it(tests, "adds a row", async () => {
38 await store.run(function* () {
39 yield* updateStore(slice.set({ [second.id]: second }));
40 });
41- asserts.assertEquals(store.getState()[NAME], { 2: second });
42+ expect(store.getState()[NAME]).toEqual({ 2: second });
43 });
44
45-it(tests, "removes a row", async () => {
46+test("removes a row", async () => {
47 const store = configureStore({
48 initialState: {
49 ...initialState,
50@@ -61,10 +59,10 @@ it(tests, "removes a row", async () => {
51 await store.run(function* () {
52 yield* updateStore(slice.remove(["1"]));
53 });
54- asserts.assertEquals(store.getState()[NAME], { [second.id]: second });
55+ expect(store.getState()[NAME]).toEqual({ [second.id]: second });
56 });
57
58-it(tests, "updates a row", async () => {
59+test("updates a row", async () => {
60 const store = configureStore({
61 initialState,
62 });
63@@ -72,12 +70,12 @@ it(tests, "updates a row", async () => {
64 const updated = { id: second.id, user: "BB" };
65 yield* updateStore(slice.patch({ [updated.id]: updated }));
66 });
67- asserts.assertEquals(store.getState()[NAME], {
68+ expect(store.getState()[NAME]).toEqual({
69 [second.id]: { ...second, user: "BB" },
70 });
71 });
72
73-it(tests, "gets a row", async () => {
74+test("gets a row", async () => {
75 const store = configureStore({
76 initialState,
77 });
78@@ -88,19 +86,19 @@ it(tests, "gets a row", async () => {
79 });
80
81 const row = slice.selectById(store.getState(), { id: "2" });
82- asserts.assertEquals(row, second);
83+ expect(row).toEqual(second);
84 });
85
86-it(tests, "when the record doesnt exist, it returns empty record", () => {
87+test("when the record doesnt exist, it returns empty record", () => {
88 const store = configureStore({
89 initialState,
90 });
91
92 const row = slice.selectById(store.getState(), { id: "2" });
93- asserts.assertEquals(row, empty);
94+ expect(row).toEqual(empty);
95 });
96
97-it(tests, "gets all rows", async () => {
98+test("gets all rows", async () => {
99 const store = configureStore({
100 initialState,
101 });
102@@ -108,41 +106,41 @@ it(tests, "gets all rows", async () => {
103 await store.run(function* () {
104 yield* updateStore(slice.add(data));
105 });
106- asserts.assertEquals(store.getState()[NAME], data);
107+ expect(store.getState()[NAME]).toEqual(data);
108 });
109
110 // checking types of `result` here
111-it(tests, "with empty", async () => {
112+test("with empty", async () => {
113 const tbl = table<TUser>({ empty: first })("users");
114 const store = configureStore({
115 initialState,
116 });
117
118- asserts.assertEquals(tbl.empty, first);
119+ expect(tbl.empty).toEqual(first);
120 await store.run(function* () {
121 yield* updateStore(tbl.set({ [first.id]: first }));
122 });
123- asserts.assertEquals(tbl.selectTable(store.getState()), {
124+ expect(tbl.selectTable(store.getState())).toEqual({
125 [first.id]: first,
126 });
127 const result = tbl.selectById(store.getState(), { id: 1 });
128- asserts.assertEquals(result, first);
129+ expect(result).toEqual(first);
130 });
131
132 // checking types of `result` here
133-it(tests, "with no empty", async () => {
134+test("with no empty", async () => {
135 const tbl = table<TUser>()("users");
136 const store = configureStore({
137 initialState,
138 });
139
140- asserts.assertEquals(tbl.empty, undefined);
141+ expect(tbl.empty).toEqual(undefined);
142 await store.run(function* () {
143 yield* updateStore(tbl.set({ [first.id]: first }));
144 });
145- asserts.assertEquals(tbl.selectTable(store.getState()), {
146+ expect(tbl.selectTable(store.getState())).toEqual({
147 [first.id]: first,
148 });
149 const result = tbl.selectById(store.getState(), { id: 1 });
150- asserts.assertEquals(result, first);
151+ expect(result).toEqual(first);
152 });
R test/supervisor.test.ts =>
src/test/supervisor.test.ts
+9,
-24
1@@ -1,46 +1,31 @@
2-import { describe, expect, it } from "../test.ts";
3+import { take } from "../action.js";
4+import { API_ACTION_PREFIX } from "../action.js";
5 import {
6+ type Operation,
7 call,
8- Operation,
9 run,
10 spawn,
11 supervise,
12 superviseBackoff,
13-} from "../mod.ts";
14-import { ActionWithPayload } from "../types.ts";
15-import { take } from "../action.ts";
16-import { API_ACTION_PREFIX } from "../action.ts";
17-
18-const test = describe("supervise()");
19+} from "../index.js";
20+import { describe, expect, test } from "../test.js";
21+import type { ActionWithPayload } from "../types.js";
22
23 describe("superviseBackoff", () => {
24- it("should increase number exponentially", () => {
25+ test("should increase number exponentially", () => {
26 const actual: number[] = [];
27 for (let i = 1; i < 15; i += 1) {
28 actual.push(superviseBackoff(i));
29 }
30 expect(actual).toEqual([
31- 20,
32- 40,
33- 80,
34- 160,
35- 320,
36- 640,
37- 1280,
38- 2560,
39- 5120,
40- 10240,
41- -1,
42- -1,
43- -1,
44- -1,
45+ 20, 40, 80, 160, 320, 640, 1280, 2560, 5120, 10240, -1, -1, -1, -1,
46 ]);
47 });
48 });
49
50 type LogAction = ActionWithPayload<{ message: string }>;
51
52-it(test, "should recover with backoff pressure", async () => {
53+test("should recover with backoff pressure", async () => {
54 const err = console.error;
55 console.error = () => {};
56
R test/take-helper.test.ts =>
src/test/take-helper.test.ts
+8,
-12
1@@ -1,14 +1,10 @@
2 import { spawn } from "effection";
3-import { describe, expect, it } from "../test.ts";
4-import { createStore } from "../store/mod.ts";
5-import type { AnyAction } from "../mod.ts";
6-import { sleep, take, takeEvery, takeLatest, takeLeading } from "../mod.ts";
7+import type { AnyAction } from "../index.js";
8+import { sleep, take, takeEvery, takeLatest, takeLeading } from "../index.js";
9+import { createStore } from "../store/index.js";
10+import { expect, test } from "../test.js";
11
12-const testEvery = describe("takeEvery()");
13-const testLatest = describe("takeLatest()");
14-const testLeading = describe("takeLeading()");
15-
16-it(testLatest, "should cancel previous tasks and only use latest", async () => {
17+test("should cancel previous tasks and only use latest", async () => {
18 const actual: string[] = [];
19 function* worker(action: AnyAction) {
20 if (action.payload !== "3") {
21@@ -35,7 +31,7 @@ it(testLatest, "should cancel previous tasks and only use latest", async () => {
22 expect(actual).toEqual(["3"]);
23 });
24
25-it(testLeading, "should keep first action and discard the rest", async () => {
26+test("should keep first action and discard the rest", async () => {
27 let called = 0;
28 const actual: string[] = [];
29 function* worker(action: AnyAction) {
30@@ -62,13 +58,13 @@ it(testLeading, "should keep first action and discard the rest", async () => {
31 expect(called).toEqual(1);
32 });
33
34-it(testEvery, "should receive all actions", async () => {
35+test("should receive all actions", async () => {
36 const loop = 10;
37 const actual: string[][] = [];
38
39 function* root() {
40 const task = yield* spawn(() =>
41- takeEvery("ACTION", (action) => worker("a1", "a2", action))
42+ takeEvery("ACTION", (action) => worker("a1", "a2", action)),
43 );
44 yield* take("CANCEL_WATCHER");
45 yield* task.halt();
R test/take.test.ts =>
src/test/take.test.ts
+25,
-30
1@@ -1,40 +1,35 @@
2-import { describe, expect, it } from "../test.ts";
3-import type { AnyAction } from "../mod.ts";
4-import { put, sleep, spawn, take } from "../mod.ts";
5-import { createStore } from "../store/mod.ts";
6+import type { AnyAction } from "../index.js";
7+import { put, sleep, spawn, take } from "../index.js";
8+import { createStore } from "../store/index.js";
9+import { expect, test } from "../test.js";
10
11-const takeTests = describe("take()");
12-
13-it(
14- takeTests,
15- "a put should complete before more `take` are added and then consumed automatically",
16- async () => {
17- const actual: AnyAction[] = [];
18+test("a put should complete before more `take` are added and then consumed automatically", async () => {
19+ const actual: AnyAction[] = [];
20
21- function* channelFn() {
22- yield* sleep(10);
23- yield* put({ type: "action-1", payload: 1 });
24- yield* put({ type: "action-1", payload: 2 });
25- }
26+ function* channelFn() {
27+ yield* sleep(10);
28+ yield* put({ type: "action-1", payload: 1 });
29+ yield* put({ type: "action-1", payload: 2 });
30+ }
31
32- function* root() {
33- yield* spawn(channelFn);
34+ function* root() {
35+ yield* spawn(channelFn);
36
37- actual.push(yield* take("action-1"));
38- actual.push(yield* take("action-1"));
39- }
40+ actual.push(yield* take("action-1"));
41+ actual.push(yield* take("action-1"));
42+ }
43
44- const store = createStore({ initialState: {} });
45- await store.run(root);
46+ const store = createStore({ initialState: {} });
47+ await store.run(root);
48
49- expect(actual).toEqual([
50- { type: "action-1", payload: 1 },
51- { type: "action-1", payload: 2 },
52- ]);
53- },
54-);
55+ expect(actual).toEqual([
56+ { type: "action-1", payload: 1 },
57+ { type: "action-1", payload: 2 },
58+ ]);
59+});
60
61-it(takeTests, "take from default channel", async () => {
62+test("take from default channel", async () => {
63+ expect.assertions(1);
64 function* channelFn() {
65 yield* sleep(10);
66 yield* put({ type: "action-*" });
R test/thunk.test.ts =>
src/test/thunk.test.ts
+160,
-182
1@@ -1,16 +1,16 @@
2-import { API_ACTION_PREFIX } from "../action.ts";
3+import { API_ACTION_PREFIX } from "../action.js";
4 import {
5 call,
6 createThunks,
7- put,
8 sleep as delay,
9+ put,
10 takeEvery,
11 waitFor,
12-} from "../mod.ts";
13-import { createStore, updateStore } from "../store/mod.ts";
14-import { describe, expect, it } from "../test.ts";
15+} from "../index.js";
16+import { createStore, updateStore } from "../store/index.js";
17+import { expect, test } from "../test.js";
18
19-import type { Next, ThunkCtx } from "../mod.ts";
20+import type { Next, ThunkCtx } from "../index.js";
21 // deno-lint-ignore no-explicit-any
22 interface RoboCtx<D = Record<string, unknown>, P = any> extends ThunkCtx<P> {
23 url: string;
24@@ -122,77 +122,67 @@ function* processTickets(
25 yield* next();
26 }
27
28-const tests = describe("createThunks()");
29-
30-it(
31- tests,
32- "when create a query fetch pipeline - execute all middleware and save to redux",
33- () => {
34- expect.assertions(1);
35- const api = createThunks<RoboCtx>();
36- api.use(api.routes());
37- api.use(convertNameToUrl);
38- api.use(onFetchApi);
39- api.use(processUsers);
40- api.use(processTickets);
41- const fetchUsers = api.create(`/users`, { supervisor: takeEvery });
42-
43- const store = createStore<TestState>({
44- initialState: { users: {}, tickets: {} },
45- });
46- store.run(api.bootup);
47+test("when create a query fetch pipeline - execute all middleware and save to redux", () => {
48+ expect.assertions(1);
49+ const api = createThunks<RoboCtx>();
50+ api.use(api.routes());
51+ api.use(convertNameToUrl);
52+ api.use(onFetchApi);
53+ api.use(processUsers);
54+ api.use(processTickets);
55+ const fetchUsers = api.create("/users", { supervisor: takeEvery });
56+
57+ const store = createStore<TestState>({
58+ initialState: { users: {}, tickets: {} },
59+ });
60+ store.run(api.bootup);
61
62- store.dispatch(fetchUsers());
63+ store.dispatch(fetchUsers());
64
65- expect(store.getState()).toEqual({
66- users: { [mockUser.id]: deserializeUser(mockUser) },
67- tickets: {},
68- });
69- },
70-);
71-
72-it(
73- tests,
74- "when providing a generator the to api.create function - should call that generator before all other middleware",
75- () => {
76- expect.assertions(1);
77- const api = createThunks<RoboCtx>();
78- api.use(api.routes());
79- api.use(convertNameToUrl);
80- api.use(onFetchApi);
81- api.use(processUsers);
82- api.use(processTickets);
83- const fetchUsers = api.create(`/users`, { supervisor: takeEvery });
84- const fetchTickets = api.create(
85- `/ticket-wrong-url`,
86- {
87- supervisor: takeEvery,
88- },
89- function* (ctx, next) {
90- // before middleware has been triggered
91- ctx.url = "/tickets";
92+ expect(store.getState()).toEqual({
93+ users: { [mockUser.id]: deserializeUser(mockUser) },
94+ tickets: {},
95+ });
96+});
97
98- // triggers all middleware
99- yield* next();
100+test("when providing a generator the to api.create function - should call that generator before all other middleware", () => {
101+ expect.assertions(1);
102+ const api = createThunks<RoboCtx>();
103+ api.use(api.routes());
104+ api.use(convertNameToUrl);
105+ api.use(onFetchApi);
106+ api.use(processUsers);
107+ api.use(processTickets);
108+ const fetchUsers = api.create("/users", { supervisor: takeEvery });
109+ const fetchTickets = api.create(
110+ "/ticket-wrong-url",
111+ {
112+ supervisor: takeEvery,
113+ },
114+ function* (ctx, next) {
115+ // before middleware has been triggered
116+ ctx.url = "/tickets";
117
118- yield* put(fetchUsers());
119- },
120- );
121+ // triggers all middleware
122+ yield* next();
123
124- const store = createStore<TestState>({
125- initialState: { users: {}, tickets: {} },
126- });
127- store.run(api.bootup);
128+ yield* put(fetchUsers());
129+ },
130+ );
131
132- store.dispatch(fetchTickets());
133- expect(store.getState()).toEqual({
134- users: { [mockUser.id]: deserializeUser(mockUser) },
135- tickets: { [mockTicket.id]: deserializeTicket(mockTicket) },
136- });
137- },
138-);
139+ const store = createStore<TestState>({
140+ initialState: { users: {}, tickets: {} },
141+ });
142+ store.run(api.bootup);
143+
144+ store.dispatch(fetchTickets());
145+ expect(store.getState()).toEqual({
146+ users: { [mockUser.id]: deserializeUser(mockUser) },
147+ tickets: { [mockTicket.id]: deserializeTicket(mockTicket) },
148+ });
149+});
150
151-it(tests, "error handling", () => {
152+test("error handling", () => {
153 expect.assertions(1);
154 let called;
155 const api = createThunks<RoboCtx>();
156@@ -208,7 +198,7 @@ it(tests, "error handling", () => {
157 throw new Error("some error");
158 });
159
160- const action = api.create(`/error`, { supervisor: takeEvery });
161+ const action = api.create("/error", { supervisor: takeEvery });
162
163 const store = createStore({ initialState: {} });
164 store.run(api.bootup);
165@@ -216,7 +206,7 @@ it(tests, "error handling", () => {
166 expect(called).toBe(true);
167 });
168
169-it(tests, "error handling inside create", () => {
170+test("error handling inside create", () => {
171 expect.assertions(1);
172 let called = false;
173 const api = createThunks<RoboCtx>();
174@@ -226,7 +216,7 @@ it(tests, "error handling inside create", () => {
175 });
176
177 const action = api.create(
178- `/error`,
179+ "/error",
180 { supervisor: takeEvery },
181 function* (_, next) {
182 try {
183@@ -242,7 +232,7 @@ it(tests, "error handling inside create", () => {
184 expect(called).toBe(true);
185 });
186
187-it(tests, "error inside endpoint mdw", () => {
188+test("error inside endpoint mdw", () => {
189 expect.assertions(1);
190 let called = false;
191 const query = createThunks();
192@@ -257,7 +247,7 @@ it(tests, "error inside endpoint mdw", () => {
193 query.use(query.routes());
194
195 const fetchUsers = query.create(
196- `/users`,
197+ "/users",
198 { supervisor: takeEvery },
199 function* processUsers() {
200 throw new Error("some error");
201@@ -274,7 +264,7 @@ it(tests, "error inside endpoint mdw", () => {
202 expect(called).toBe(true);
203 });
204
205-it(tests, "create fn is an array", () => {
206+test("create fn is an array", () => {
207 expect.assertions(1);
208 const api = createThunks<RoboCtx>();
209 api.use(api.routes());
210@@ -305,7 +295,7 @@ it(tests, "create fn is an array", () => {
211 store.dispatch(action());
212 });
213
214-it(tests, "run() on endpoint action - should run the effect", () => {
215+test("run() on endpoint action - should run the effect", () => {
216 expect.assertions(4);
217 const api = createThunks<RoboCtx>();
218 api.use(api.routes());
219@@ -346,52 +336,48 @@ it(tests, "run() on endpoint action - should run the effect", () => {
220 expect(curCtx.request).toEqual({ method: "expect this" });
221 });
222
223-it(
224- tests,
225- "run() on endpoint action with payload - should run the effect",
226- () => {
227- expect.assertions(4);
228- const api = createThunks<RoboCtx>();
229- api.use(api.routes());
230-
231- let acc = "";
232- let curCtx: RoboCtx = {} as RoboCtx;
233-
234- const action1 = api.create<{ id: string }>(
235- "/users",
236- { supervisor: takeEvery },
237- function* (ctx, next) {
238- yield* next();
239- ctx.request = { method: "expect this" };
240- acc += "a";
241- },
242- );
243- const action2 = api.create(
244- "/users2",
245- { supervisor: takeEvery },
246- function* (_, next) {
247- yield* next();
248- curCtx = yield* call(() => action1.run({ id: "1" }));
249- acc += "b";
250- },
251- );
252-
253- const store = createStore({ initialState: {} });
254- store.run(api.bootup);
255- store.dispatch(action2());
256- expect(acc).toBe("ab");
257- expect(curCtx.action).toMatchObject({
258- type: `${API_ACTION_PREFIX}${action1}`,
259- payload: {
260- name: "/users",
261- },
262- });
263- expect(curCtx.name).toBe("/users");
264- expect(curCtx.request).toEqual({ method: "expect this" });
265- },
266-);
267+test("run() on endpoint action with payload - should run the effect", () => {
268+ expect.assertions(4);
269+ const api = createThunks<RoboCtx>();
270+ api.use(api.routes());
271+
272+ let acc = "";
273+ let curCtx: RoboCtx = {} as RoboCtx;
274+
275+ const action1 = api.create<{ id: string }>(
276+ "/users",
277+ { supervisor: takeEvery },
278+ function* (ctx, next) {
279+ yield* next();
280+ ctx.request = { method: "expect this" };
281+ acc += "a";
282+ },
283+ );
284+ const action2 = api.create(
285+ "/users2",
286+ { supervisor: takeEvery },
287+ function* (_, next) {
288+ yield* next();
289+ curCtx = yield* call(() => action1.run({ id: "1" }));
290+ acc += "b";
291+ },
292+ );
293+
294+ const store = createStore({ initialState: {} });
295+ store.run(api.bootup);
296+ store.dispatch(action2());
297+ expect(acc).toBe("ab");
298+ expect(curCtx.action).toMatchObject({
299+ type: `${API_ACTION_PREFIX}${action1}`,
300+ payload: {
301+ name: "/users",
302+ },
303+ });
304+ expect(curCtx.name).toBe("/users");
305+ expect(curCtx.request).toEqual({ method: "expect this" });
306+});
307
308-it(tests, "middleware order of execution", async () => {
309+test("middleware order of execution", async () => {
310 expect.assertions(1);
311 let acc = "";
312 const api = createThunks();
313@@ -432,7 +418,7 @@ it(tests, "middleware order of execution", async () => {
314 expect(acc).toBe("abcdefg");
315 });
316
317-it(tests, "retry with actionFn", async () => {
318+test("retry with actionFn", async () => {
319 expect.assertions(1);
320 let acc = "";
321 let called = false;
322@@ -462,7 +448,7 @@ it(tests, "retry with actionFn", async () => {
323 expect(acc).toBe("agag");
324 });
325
326-it(tests, "retry with actionFn with payload", async () => {
327+test("retry with actionFn with payload", async () => {
328 expect.assertions(1);
329 let acc = "";
330 const api = createThunks();
331@@ -470,7 +456,7 @@ it(tests, "retry with actionFn with payload", async () => {
332
333 api.use(function* (ctx: ThunkCtx<{ page: number }>, next) {
334 yield* next();
335- if (ctx.payload.page == 1) {
336+ if (ctx.payload.page === 1) {
337 yield* put(ctx.actionFn({ page: 2 }));
338 }
339 });
340@@ -493,7 +479,7 @@ it(tests, "retry with actionFn with payload", async () => {
341 expect(acc).toBe("agag");
342 });
343
344-it(tests, "should only call thunk once", () => {
345+test("should only call thunk once", () => {
346 expect.assertions(1);
347 const api = createThunks<RoboCtx>();
348 api.use(api.routes());
349@@ -522,7 +508,7 @@ it(tests, "should only call thunk once", () => {
350 expect(acc).toBe("a");
351 });
352
353-it(tests, "should be able to create thunk after `register()`", () => {
354+test("should be able to create thunk after `register()`", () => {
355 expect.assertions(1);
356 const api = createThunks<RoboCtx>();
357 api.use(api.routes());
358@@ -537,7 +523,7 @@ it(tests, "should be able to create thunk after `register()`", () => {
359 expect(acc).toBe("a");
360 });
361
362-it(tests, "should warn when calling thunk before registered", () => {
363+test("should warn when calling thunk before registered", () => {
364 expect.assertions(1);
365 const err = console.warn;
366 let called = false;
367@@ -554,7 +540,7 @@ it(tests, "should warn when calling thunk before registered", () => {
368 console.warn = err;
369 });
370
371-it(tests, "it should call the api once even if we register it twice", () => {
372+test("it should call the api once even if we register it twice", () => {
373 expect.assertions(1);
374 const api = createThunks<RoboCtx>();
375 api.use(api.routes());
376@@ -570,68 +556,60 @@ it(tests, "it should call the api once even if we register it twice", () => {
377 expect(acc).toBe("a");
378 });
379
380-it(
381- tests,
382- "Should call the API only once, even if registered multiple times, with multiple APIs defined.",
383- () => {
384- expect.assertions(2);
385- const api1 = createThunks<RoboCtx>();
386- api1.use(api1.routes());
387+test("should call the API only once, even if registered multiple times, with multiple APIs defined.", () => {
388+ expect.assertions(2);
389+ const api1 = createThunks<RoboCtx>();
390+ api1.use(api1.routes());
391
392- const api2 = createThunks<RoboCtx>();
393- api2.use(api2.routes());
394+ const api2 = createThunks<RoboCtx>();
395+ api2.use(api2.routes());
396
397- const store = createStore({ initialState: {} });
398+ const store = createStore({ initialState: {} });
399
400- store.run(api1.register);
401- store.run(api1.register);
402- store.run(api1.register);
403+ store.run(api1.register);
404+ store.run(api1.register);
405+ store.run(api1.register);
406
407- store.run(api2.register);
408- store.run(api2.register);
409+ store.run(api2.register);
410+ store.run(api2.register);
411
412- let acc = "";
413- const action = api1.create("/users", function* () {
414- acc += "b";
415- });
416- store.dispatch(action());
417+ let acc = "";
418+ const action = api1.create("/users", function* () {
419+ acc += "b";
420+ });
421+ store.dispatch(action());
422
423- expect(acc).toBe("b");
424+ expect(acc).toBe("b");
425
426- let acc2 = "";
427- const action2 = api2.create("/users", function* () {
428- acc2 += "c";
429- });
430- store.dispatch(action2());
431-
432- expect(acc2).toBe("c");
433- },
434-);
435-
436-it(
437- tests,
438- "should unregister the thunk when the registration function exits",
439- async () => {
440- expect.assertions(1);
441- const api1 = createThunks<RoboCtx>();
442- api1.use(api1.routes());
443-
444- const store = createStore({ initialState: {} });
445- const task = store.run(api1.register);
446- await task.halt();
447- store.run(api1.register);
448-
449- let acc = "";
450- const action = api1.create("/users", function* () {
451- acc += "b";
452- });
453- store.dispatch(action());
454+ let acc2 = "";
455+ const action2 = api2.create("/users", function* () {
456+ acc2 += "c";
457+ });
458+ store.dispatch(action2());
459+
460+ expect(acc2).toBe("c");
461+});
462
463- expect(acc).toBe("b");
464- },
465-);
466+test("should unregister the thunk when the registration function exits", async () => {
467+ expect.assertions(1);
468+ const api1 = createThunks<RoboCtx>();
469+ api1.use(api1.routes());
470+
471+ const store = createStore({ initialState: {} });
472+ const task = store.run(api1.register);
473+ await task.halt();
474+ store.run(api1.register);
475+
476+ let acc = "";
477+ const action = api1.create("/users", function* () {
478+ acc += "b";
479+ });
480+ store.dispatch(action());
481+
482+ expect(acc).toBe("b");
483+});
484
485-it(tests, "should allow multiple stores to register a thunk", () => {
486+test("should allow multiple stores to register a thunk", () => {
487 expect.assertions(1);
488 const api1 = createThunks<RoboCtx>();
489 api1.use(api1.routes());
R test/timer.test.ts =>
src/test/timer.test.ts
+10,
-8
1@@ -1,9 +1,8 @@
2-import { describe, expect, it } from "../test.ts";
3-import { clearTimers, put, run, sleep, spawn, timer } from "../mod.ts";
4+import { clearTimers, put, run, sleep, spawn, timer } from "../index.js";
5+import { expect, test } from "../test.js";
6
7-const tests = describe("timer()");
8-
9-it(tests, "should call thunk at most once every timer", async () => {
10+test("should call thunk at most once every timer", async () => {
11+ expect.assertions(1);
12 let called = 0;
13 await run(function* () {
14 yield* spawn(function* () {
15@@ -21,7 +20,8 @@ it(tests, "should call thunk at most once every timer", async () => {
16 expect(called).toBe(2);
17 });
18
19-it(tests, "should let user cancel timer", async () => {
20+test("should let user cancel timer", async () => {
21+ expect.assertions(1);
22 let called = 0;
23 await run(function* () {
24 yield* spawn(function* () {
25@@ -37,7 +37,8 @@ it(tests, "should let user cancel timer", async () => {
26 expect(called).toBe(2);
27 });
28
29-it(tests, "should let user cancel timer with action obj", async () => {
30+test("should let user cancel timer with action obj", async () => {
31+ expect.assertions(1);
32 let called = 0;
33 await run(function* () {
34 yield* spawn(function* () {
35@@ -54,7 +55,8 @@ it(tests, "should let user cancel timer with action obj", async () => {
36 expect(called).toBe(2);
37 });
38
39-it(tests, "should let user cancel timer with wildcard", async () => {
40+test("should let user cancel timer with wildcard", async () => {
41+ expect.assertions(1);
42 let called = 0;
43 await run(function* () {
44 yield* spawn(function* () {
R types.ts =>
src/types.ts
+2,
-3
1@@ -29,9 +29,8 @@ export interface LoaderState<M extends AnyState = AnyState>
2 isInitialLoading: boolean;
3 }
4
5-export type LoaderPayload<M extends AnyState> =
6- & Pick<LoaderItemState<M>, "id">
7- & Partial<Pick<LoaderItemState<M>, "message" | "meta">>;
8+export type LoaderPayload<M extends AnyState> = Pick<LoaderItemState<M>, "id"> &
9+ Partial<Pick<LoaderItemState<M>, "message" | "meta">>;
10
11 // deno-lint-ignore no-explicit-any
12 export type AnyState = Record<string, any>;
+0,
-9
1@@ -1,9 +0,0 @@
2-export * from "./context.ts";
3-export * from "./fx.ts";
4-export * from "./store.ts";
5-export * from "./types.ts";
6-export { createSelector } from "reselect";
7-export * from "./slice/mod.ts";
8-export * from "./schema.ts";
9-export * from "./batch.ts";
10-export * from "./persist.ts";
+0,
-38
1@@ -1,38 +0,0 @@
2-import { updateStore } from "./fx.ts";
3-import { slice } from "./slice/mod.ts";
4-import { FxMap, FxSchema, StoreUpdater } from "./types.ts";
5-
6-const defaultSchema = function <O>(): O {
7- return { cache: slice.table(), loaders: slice.loaders() } as O;
8-};
9-
10-export function createSchema<
11- O extends FxMap,
12- S extends { [key in keyof O]: ReturnType<O[key]>["initialState"] },
13->(
14- slices: O = defaultSchema<O>(),
15-): [FxSchema<S, O>, S] {
16- const db = Object.keys(slices).reduce<FxSchema<S, O>>((acc, key) => {
17- // deno-lint-ignore no-explicit-any
18- (acc as any)[key] = slices[key](key);
19- return acc;
20- }, {} as FxSchema<S, O>);
21-
22- const initialState = Object.keys(db).reduce((acc, key) => {
23- // deno-lint-ignore no-explicit-any
24- (acc as any)[key] = db[key].initialState;
25- return acc;
26- }, {}) as S;
27-
28- function* update(
29- ups:
30- | StoreUpdater<S>
31- | StoreUpdater<S>[],
32- ) {
33- return yield* updateStore(ups);
34- }
35-
36- db.update = update;
37-
38- return [db, initialState];
39-}
+0,
-14
1@@ -1,14 +0,0 @@
2-import { describe, expect, it } from "../test.ts";
3-import { createAction } from "../mod.ts";
4-
5-const tests = describe("createAction()");
6-
7-it(tests, "should return action type when stringified", () => {
8- const undo = createAction("UNDO");
9- expect(`UNDO`).toEqual(`${undo}`);
10-});
11-
12-it(tests, "return object with type", () => {
13- const undo = createAction("UNDO");
14- expect(undo()).toEqual({ type: `UNDO`, payload: undefined });
15-});
+0,
-357
1@@ -1,357 +0,0 @@
2-import { afterAll, beforeAll, describe, expect, it } from "../test.ts";
3-import { type ActionWithPayload, createApi } from "../mod.ts";
4-
5-const getKeyOf = (action: ActionWithPayload<{ key: string }>): string =>
6- action.payload.key;
7-
8-const err = console.error;
9-beforeAll(() => {
10- console.error = () => {};
11-});
12-
13-afterAll(() => {
14- console.error = err;
15-});
16-
17-const tests = describe("create-key");
18-
19-it(
20- tests,
21- "options object keys order for action key identity - 0: empty options",
22- () => {
23- console.warn = () => {};
24- const api = createApi();
25- api.use(api.routes());
26- // no param
27- const action0 = api.get("/users", function* (ctx, next) {
28- ctx.request = {
29- method: "GET",
30- };
31- yield* next();
32- });
33- const sendNop0 = action0();
34- const sendNop1 = action0();
35- expect(getKeyOf(sendNop0)).toEqual(getKeyOf(sendNop1));
36- },
37-);
38-
39-it(
40- tests,
41- "options object keys order for action key identity - 1: simple object",
42- () => {
43- const api = createApi();
44- api.use(api.routes());
45- // no param
46- const action0 = api.get<{
47- [key: string]: string | boolean | number | null | undefined;
48- }>("/users", function* (ctx, next) {
49- ctx.request = {
50- method: "GET",
51- };
52- yield* next();
53- });
54- const sendPojo0 = action0({
55- a: "a",
56- b: "b",
57- c: 1,
58- d: 2,
59- e: true,
60- f: false,
61- "100": 100,
62- 101: "101",
63- });
64- const sendPojo1 = action0({
65- a: "a",
66- b: "b",
67- c: 1,
68- d: 2,
69- e: true,
70- f: false,
71- 100: 100,
72- 101: "101",
73- });
74- const sendPojo2 = action0({
75- e: true,
76- f: false,
77- "100": 100,
78- "101": "101",
79- a: "a",
80- b: "b",
81- c: 1,
82- d: 2,
83- });
84- const sendPojo3 = action0({
85- e: true,
86- f: false,
87- "100": 100,
88- "101": "101",
89- a: "a",
90- b: "b",
91- c: 1,
92- d: 2000000,
93- });
94- const sendPojo4 = action0({
95- e: null,
96- f: false,
97- "100": undefined,
98- "101": "101",
99- a: "a",
100- b: "b",
101- c: 1,
102- d: `Thomas O'Malley`,
103- });
104- const sendPojo5 = action0({
105- d: `Thomas O'Malley`,
106- e: null,
107- f: false,
108- "100": undefined,
109- "101": "101",
110- a: "a",
111- b: "b",
112- c: 1,
113- });
114- expect(getKeyOf(sendPojo0)).toEqual(getKeyOf(sendPojo1));
115- expect(getKeyOf(sendPojo0)).toEqual(getKeyOf(sendPojo2));
116- expect(getKeyOf(sendPojo0)).not.toEqual(getKeyOf(sendPojo3));
117- expect(getKeyOf(sendPojo4)).toEqual(getKeyOf(sendPojo5));
118- },
119-);
120-
121-it(
122- tests,
123- "options object keys order for action key identity - 2: object (with array values)",
124- () => {
125- interface Ip0 {
126- param1: string;
127- param2: string[];
128- }
129- const api = createApi();
130- api.use(api.routes());
131- const action = api.get<Ip0>(
132- "/users/:param1/:param2",
133- function* (ctx, next) {
134- ctx.request = {
135- method: "GET",
136- };
137- yield* next();
138- },
139- );
140- const sendFirst = action({ param1: "1", param2: ["2", "e", "f"] });
141- const sendSecond = action({ param2: ["2", "f", "e"], param1: "1" });
142- const sendThird = action({ param2: ["2", "e", "f"], param1: "1" });
143- expect(getKeyOf(sendFirst)).not.toEqual(getKeyOf(sendSecond));
144- expect(getKeyOf(sendFirst)).toEqual(getKeyOf(sendThird));
145- },
146-);
147-
148-it(
149- tests,
150- "options object keys order for action key identity - 3: nested object",
151- () => {
152- interface Ip0 {
153- param1: string;
154- param2: string[];
155- }
156- interface Ip1 {
157- param1: string;
158- param2: string;
159- param3: number;
160- param4: Ip0;
161- param5: boolean;
162- }
163- const o1: Ip1 = {
164- param1: "1",
165- param2: "2",
166- param3: 3,
167- param4: {
168- param1: "4",
169- param2: ["5", "6"],
170- },
171- param5: true,
172- };
173- const o2: Ip1 = {
174- param4: {
175- param1: "4",
176- param2: ["5", "6"],
177- },
178- param5: true,
179- param2: "2",
180- param1: "1",
181- param3: 3,
182- };
183- const api = createApi();
184- api.use(api.routes());
185- //nested with array
186- const action2 = api.get<Ip1>(
187- "/users/:param1/:param2/:param3/:param4/:param5",
188- function* (ctx, next) {
189- ctx.request = {
190- method: "GET",
191- };
192- yield* next();
193- },
194- );
195- const sendO1 = action2(o1);
196- const sendO2 = action2(o2);
197- const sendO3 = action2({
198- ...o1,
199- param4: { ...o1.param4, param2: ["5", "6", "7"] },
200- });
201- expect(getKeyOf(sendO1)).toEqual(getKeyOf(sendO2));
202- expect(getKeyOf(sendO1)).not.toEqual(getKeyOf(sendO3));
203- },
204-);
205-
206-it(
207- tests,
208- "options object keys order for action key identity - 4: deepNested object",
209- () => {
210- interface Ip0 {
211- param1: string;
212- param2: string[];
213- }
214- interface Ip1 {
215- param1: string;
216- param2: string;
217- param3: number;
218- param4: Ip0;
219- param5: boolean;
220- }
221- interface Ip3 {
222- param1: string;
223- param2: {
224- param3: Ip1;
225- param4: Ip0;
226- };
227- }
228- const o1: Ip1 = {
229- param1: "1",
230- param2: "2",
231- param3: 3,
232- param4: {
233- param1: "4",
234- param2: ["5", "6"],
235- },
236- param5: true,
237- };
238- const oo1: Ip3 = {
239- param1: "1",
240- param2: {
241- param3: o1,
242- param4: {
243- param1: "4",
244- param2: ["5", "6"],
245- },
246- },
247- };
248- const oo2: Ip3 = {
249- param1: "1",
250- param2: {
251- param4: {
252- param1: "4",
253- param2: ["5", "6"],
254- },
255- param3: o1,
256- },
257- };
258- const api = createApi();
259- api.use(api.routes());
260- // deepNested
261- const action4 = api.get<Ip3>(
262- "/users/:param1/:param2/:param3/:param4/:param5",
263- function* (ctx, next) {
264- ctx.request = {
265- method: "GET",
266- };
267- yield* next();
268- },
269- );
270- const send_oo1 = action4(oo1);
271- const send_oo1_shuff = action4({ param2: oo1.param2, param1: oo1.param1 });
272- const send_oo1_value_changed = action4({ ...oo1, param1: "x" });
273- const send_oo2 = action4(oo2);
274- expect(send_oo1.payload.options).toEqual(send_oo2.payload.options);
275- expect(getKeyOf(send_oo1)).toEqual(getKeyOf(send_oo1_shuff));
276- expect(getKeyOf(send_oo1)).not.toEqual(getKeyOf(send_oo1_value_changed));
277- expect(getKeyOf(send_oo1)).toEqual(getKeyOf(send_oo2));
278- },
279-);
280-
281-it(
282- tests,
283- "options object keys order for action key identity - 5: other",
284- () => {
285- const api = createApi();
286- api.use(api.routes());
287- //array options
288- const action5 = api.post<
289- | number
290- | boolean
291- | string
292- | undefined
293- | null
294- | { param1: string; param2: (string | number)[] }[]
295- | string[]
296- >("/users/:allRecords", function* (ctx, next) {
297- ctx.request = {
298- method: "POST",
299- body: JSON.stringify(ctx.action.payload),
300- };
301- yield* next();
302- });
303- const falsy0 = action5(0);
304- const falsy1 = action5(false);
305- const falsy2 = action5("");
306- const falsy3 = action5(undefined);
307- const falsy4 = action5(null);
308- const primNo0 = action5(NaN);
309- const primNo1 = action5(1);
310- const primNo1bis = action5(1);
311- const primNo2 = action5(2);
312- const str1 = action5("1234");
313- const str1bis = action5("1234");
314- const str2 = action5("2345");
315- const aStrings1 = action5(["1", "2", "3"]);
316- const aStrings2 = action5(["1", "2", "3"]);
317- const aStrings3 = action5(["1", "2", "1"]);
318- const aObjects1 = action5([
319- { param1: "1", param2: ["2", "3"] },
320- { param1: "2", param2: ["2", "3"] },
321- ]);
322- const aObjects2 = action5([
323- { param1: "1", param2: ["2", "3"] },
324- { param1: "2", param2: ["2", "3"] },
325- ]);
326- // the objects are not identical.
327- const aObjects3 = action5([
328- { param1: "1", param2: ["2", "3"] },
329- { param1: "2", param2: ["2", 3] },
330- ]);
331- //object inside the array is shuffled
332- const aObjects4 = action5([
333- { param2: ["2", "3"], param1: "1" },
334- { param2: ["2", "3"], param1: "2" },
335- ]);
336- // cont the order of array elements is changed will get different keys.
337- const aObjects5 = action5([
338- { param1: "2", param2: ["2", "3"] },
339- { param1: "1", param2: ["2", "3"] },
340- ]);
341- expect(getKeyOf(falsy0)).not.toEqual(getKeyOf(falsy1));
342- expect(getKeyOf(falsy1)).not.toEqual(getKeyOf(falsy2));
343- expect(getKeyOf(falsy1)).not.toEqual(getKeyOf(falsy3));
344- expect(getKeyOf(falsy3)).not.toEqual(getKeyOf(falsy4));
345- expect(getKeyOf(primNo0)).not.toEqual(getKeyOf(falsy0));
346- expect(getKeyOf(primNo0)).not.toEqual(getKeyOf(primNo1));
347- expect(getKeyOf(primNo1)).not.toEqual(getKeyOf(primNo2));
348- expect(getKeyOf(primNo1)).toEqual(getKeyOf(primNo1bis));
349- expect(getKeyOf(str1)).not.toEqual(getKeyOf(str2));
350- expect(getKeyOf(str1)).toEqual(getKeyOf(str1bis));
351- expect(getKeyOf(aStrings1)).toEqual(getKeyOf(aStrings2));
352- expect(getKeyOf(aStrings1)).not.toEqual(getKeyOf(aStrings3));
353- expect(getKeyOf(aObjects1)).toEqual(getKeyOf(aObjects2));
354- expect(getKeyOf(aObjects1)).not.toEqual(getKeyOf(aObjects3));
355- expect(getKeyOf(aObjects1)).toEqual(getKeyOf(aObjects4));
356- expect(getKeyOf(aObjects1)).not.toEqual(getKeyOf(aObjects5));
357- },
358-);
+0,
-158
1@@ -1,158 +0,0 @@
2-import { describe, expect, it } from "../test.ts";
3-import type { Operation, Result } from "../mod.ts";
4-import { each, Err, Ok, parallel, run, sleep, spawn } from "../mod.ts";
5-
6-const test = describe("parallel()");
7-
8-interface Defer<T> {
9- promise: Promise<T>;
10- resolve: (t: T) => void;
11- reject: (t: Error) => void;
12-}
13-
14-function defer<T>(): Defer<T> {
15- let resolve: (t: T) => void = () => {};
16- let reject: (t: Error) => void = () => {};
17- const promise = new Promise<T>((res, rej) => {
18- resolve = res;
19- reject = rej;
20- });
21-
22- return { resolve, reject, promise };
23-}
24-
25-it(
26- test,
27- "should return an immediate channel with results as they are completed",
28- async () => {
29- const result = await run(function* () {
30- const results = yield* parallel([
31- function* () {
32- yield* sleep(20);
33- return "second";
34- },
35- function* () {
36- yield* sleep(10);
37- return "first";
38- },
39- ]);
40-
41- const res: Result<string>[] = [];
42- for (const val of yield* each(results.immediate)) {
43- res.push(val);
44- yield* each.next();
45- }
46-
47- yield* results;
48- return res;
49- });
50-
51- expect(result).toEqual([Ok("first"), Ok("second")]);
52- },
53-);
54-
55-it(
56- test,
57- "should return a sequence channel with results preserving array order as results",
58- async () => {
59- const result = await run(function* () {
60- const results = yield* parallel([
61- function* () {
62- yield* sleep(20);
63- return "second";
64- },
65- function* () {
66- yield* sleep(10);
67- return "first";
68- },
69- ]);
70-
71- const res: Result<string>[] = [];
72- for (const val of yield* each(results.sequence)) {
73- res.push(val);
74- yield* each.next();
75- }
76-
77- yield* results;
78- return res;
79- });
80-
81- expect(result).toEqual([Ok("second"), Ok("first")]);
82- },
83-);
84-
85-it(
86- test,
87- "should return all the result in an array, preserving order",
88- async () => {
89- const result = await run(function* () {
90- const para = yield* parallel([
91- function* () {
92- yield* sleep(20);
93- return "second";
94- },
95- function* () {
96- yield* sleep(10);
97- return "first";
98- },
99- ]);
100-
101- return yield* para;
102- });
103-
104- expect(result).toEqual([Ok("second"), Ok("first")]);
105- },
106-);
107-
108-it(test, "should return empty array", async () => {
109- let actual;
110- await run(function* (): Operation<void> {
111- const results = yield* parallel([]);
112- actual = yield* results;
113- });
114- expect(actual).toEqual([]);
115-});
116-
117-it(test, "should resolve all async items", async () => {
118- const two = defer();
119-
120- function* one() {
121- yield* sleep(5);
122- return 1;
123- }
124-
125- const result = await run(function* () {
126- yield* spawn(function* () {
127- yield* sleep(15);
128- two.resolve(2);
129- });
130- const results = yield* parallel([one, () => two.promise]);
131- return yield* results;
132- });
133-
134- expect(result).toEqual([Ok(1), Ok(2)]);
135-});
136-
137-it(test, "should stop all operations when there is an error", async () => {
138- let actual: Result<number>[] = [];
139- const one = defer<number>();
140- const two = defer<number>();
141-
142- function* genFn() {
143- try {
144- const results = yield* parallel([() => one.promise, () => two.promise]);
145- actual = yield* results;
146- } catch (_) {
147- actual = [Err(new Error("should not get hit"))];
148- }
149- }
150-
151- const err = new Error("error");
152- one.reject(err);
153- two.resolve(1);
154-
155- await run(genFn);
156-
157- const expected = [Err(err), Ok(1)];
158- expect(actual).toEqual(expected);
159-});
+0,
-110
1@@ -1,110 +0,0 @@
2-import { describe, expect, it } from "../test.ts";
3-import { ActionContext, each, put, sleep, spawn, take } from "../mod.ts";
4-import { createStore } from "../store/mod.ts";
5-
6-const putTests = describe("put()");
7-
8-it(putTests, "should send actions through channel", async () => {
9- const actual: string[] = [];
10-
11- function* genFn(arg: string) {
12- const actions = yield* ActionContext;
13- const task = yield* spawn(function* () {
14- for (const action of yield* each(actions)) {
15- actual.push(action.type);
16- yield* each.next();
17- }
18- });
19-
20- yield* put({
21- type: arg,
22- });
23- yield* put({
24- type: "2",
25- });
26- actions.close();
27- yield* task;
28- }
29-
30- const store = createStore({ initialState: {} });
31- await store.run(() => genFn("arg"));
32-
33- const expected = ["arg", "2"];
34- expect(actual).toEqual(expected);
35-});
36-
37-it(putTests, "should handle nested puts", async () => {
38- const actual: string[] = [];
39-
40- function* genA() {
41- yield* put({
42- type: "a",
43- });
44- actual.push("put a");
45- }
46-
47- function* genB() {
48- yield* take(["a"]);
49- yield* put({
50- type: "b",
51- });
52- actual.push("put b");
53- }
54-
55- function* root() {
56- yield* spawn(genB);
57- yield* spawn(genA);
58- }
59-
60- const store = createStore({ initialState: {} });
61- await store.run(() => root());
62-
63- const expected = ["put b", "put a"];
64- expect(actual).toEqual(expected);
65-});
66-
67-it(
68- putTests,
69- "should not cause stack overflow when puts are emitted while dispatching saga",
70- async () => {
71- function* root() {
72- for (let i = 0; i < 10_000; i += 1) {
73- yield* put({ type: "test" });
74- }
75- yield* sleep(0);
76- }
77-
78- const store = createStore({ initialState: {} });
79- await store.run(() => root());
80- expect(true).toBe(true);
81- },
82-);
83-
84-it(
85- putTests,
86- "should not miss `put` that was emitted directly after creating a task (caused by another `put`)",
87- async () => {
88- const actual: string[] = [];
89-
90- function* root() {
91- yield* spawn(function* firstspawn() {
92- yield* sleep(10);
93- yield* put({ type: "c" });
94- yield* put({ type: "do not miss" });
95- });
96-
97- yield* take("c");
98-
99- const tsk = yield* spawn(function* () {
100- yield* take("do not miss");
101- actual.push("didn't get missed");
102- });
103- yield* tsk;
104- }
105-
106- const store = createStore({ initialState: {} });
107- await store.run(root);
108- const expected = ["didn't get missed"];
109- expect(actual).toEqual(expected);
110- },
111-);
+11,
-0
1@@ -0,0 +1,11 @@
2+{
3+ "extends": "./tsconfig.json",
4+ "compilerOptions": {
5+ "rootDir": "./src",
6+ "module": "Node16",
7+ "moduleResolution": "node16",
8+ "outDir": "./dist/cjs"
9+ },
10+ "include": ["src"],
11+ "exclude": ["src/test/**"]
12+}
+11,
-0
1@@ -0,0 +1,11 @@
2+{
3+ "extends": "./tsconfig.json",
4+ "compilerOptions": {
5+ "rootDir": "./src",
6+ "module": "esnext",
7+ "moduleResolution": "bundler",
8+ "outDir": "./dist/esm"
9+ },
10+ "include": ["src"],
11+ "exclude": ["src/test/**"]
12+}
+19,
-0
1@@ -0,0 +1,19 @@
2+{
3+ "compilerOptions": {
4+ "target": "es2020",
5+ "lib": ["es6", "dom"],
6+ "module": "NodeNext",
7+ "moduleResolution": "NodeNext",
8+ "jsx": "react",
9+
10+ "esModuleInterop": true,
11+ "forceConsistentCasingInFileNames": true,
12+ "strict": true,
13+ "skipLibCheck": true,
14+ "resolveJsonModule": true,
15+ "emitDecoratorMetadata": true,
16+ "experimentalDecorators": true,
17+ "downlevelIteration": true,
18+ "isolatedModules": true
19+ }
20+}
+14,
-0
1@@ -0,0 +1,14 @@
2+{
3+ "extends": "./tsconfig.json",
4+ "compilerOptions": {
5+ "rootDir": "./src",
6+ "module": "Node16",
7+ "moduleResolution": "node16",
8+ "declaration": true,
9+ "emitDeclarationOnly": true,
10+ "outDir": "./dist/types",
11+ "removeComments": false
12+ },
13+ "include": ["src"],
14+ "exclude": ["src/test/**"]
15+}