repos / starfx

a micro-mvc framework for react apps
git clone https://github.com/neurosnap/starfx.git

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>
135 files changed,  +6085, -3610
A .github/workflows/examples.yml
+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
M .github/workflows/preview.yml
+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/*'
D .github/workflows/test-ecosystem.yml
+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
M .github/workflows/test.yml
+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
M .gitignore
+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);
A biome.json
+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+}
A build.mts
+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.");
D deno.json
+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-}
D deno.lock
+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";
A examples/.gitignore
+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/
A examples/README.md
+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)
A examples/basic/.eslintrc.cjs
+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+};
A examples/basic/.gitignore
+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/**
A examples/basic/index.html
+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>
A examples/basic/package.json
+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+}
A examples/basic/src/main.tsx
+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+);
A examples/basic/src/vite-env.d.ts
+1, -0
1@@ -0,0 +1 @@
2+/// <reference types="vite/client" />
A examples/basic/tsconfig.json
+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+}
A examples/basic/tsconfig.node.json
+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+}
A examples/basic/vite.config.ts
+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+});
A examples/parcel-react/.gitignore
+2, -0
1@@ -0,0 +1,2 @@
2+.parcel-cache
3+dist
A examples/parcel-react/package.json
+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+}
A examples/parcel-react/src/api.js
+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+);
A examples/parcel-react/src/app.jsx
+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+}
A examples/parcel-react/src/index.html
+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>
A examples/parcel-react/src/index.jsx
+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+}
A examples/tests-rtl/.gitignore
+2, -0
1@@ -0,0 +1,2 @@
2+.parcel-cache
3+dist
A examples/tests-rtl/babel.config.js
+6, -0
1@@ -0,0 +1,6 @@
2+module.exports = {
3+  presets: [
4+    "@babel/preset-env",
5+    ["@babel/preset-react", { runtime: "automatic" }],
6+  ],
7+};
A examples/tests-rtl/jest.config.js
+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+};
A examples/tests-rtl/package.json
+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+}
A examples/tests-rtl/src/api.ts
+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+);
A examples/tests-rtl/src/app.tsx
+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+}
A examples/tests-rtl/src/store.ts
+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+}
A examples/tests-rtl/tests/app.test.ts
+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+});
A examples/tests-rtl/tests/setup.ts
+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";
A examples/tests-rtl/tests/utils.ts
+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 };
A examples/tests-rtl/tsconfig.json
+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+}
A examples/vite-react/.eslintrc.cjs
+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+};
A examples/vite-react/.gitignore
+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/**
A examples/vite-react/index.html
+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>
A examples/vite-react/package.json
+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+}
A examples/vite-react/src/App.css
+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+}
A examples/vite-react/src/App.tsx
+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;
A examples/vite-react/src/api.ts
+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+);
A examples/vite-react/src/index.css
+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+}
A examples/vite-react/src/main.tsx
+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+}
A examples/vite-react/src/vite-env.d.ts
+1, -0
1@@ -0,0 +1 @@
2+/// <reference types="vite/client" />
A examples/vite-react/tsconfig.json
+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+}
A examples/vite-react/tsconfig.node.json
+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+}
A examples/vite-react/vite.config.ts
+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+});
D fx/mod.ts
+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";
D mdw/mod.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 };
A package-lock.json
+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+}
A package.json
+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+}
D query/mod.ts
+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;
D scripts/branch-exists.ts
+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-});
D scripts/npm.ts
+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-}
D scripts/sync.ts
+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
A src/fx/index.ts
+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,
A src/mdw/index.ts
+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     : "";
A src/query/index.ts
+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 
A src/store/index.ts
+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>[]>;
A src/store/schema.ts
+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 (
A src/test/action.test.ts
+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();
A src/test/create-key.test.ts
+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();
A src/test/parallel.test.ts
+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 });
A src/test/put.test.ts
+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>;
D store/mod.ts
+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";
D store/schema.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-}
D test/action.test.ts
+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-});
D test/create-key.test.ts
+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-);
D test/parallel.test.ts
+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-});
D test/put.test.ts
+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-);
A tsconfig.cjs.json
+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+}
A tsconfig.esm.json
+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+}
A tsconfig.json
+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+}
A tsconfig.types.json
+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+}