repos / starfx

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

commit
ce7d484
parent
5d117f5
author
Jacob Bolda
date
2024-12-21 12:28:49 -0500 EST
refactor: deno v2 and imports

56 files changed,  +883, -896
M mod.ts
M .github/workflows/docs.yml
+3, -3
 1@@ -10,13 +10,13 @@ jobs:
 2       run:
 3         working-directory: ./docs
 4     steps:
 5-      - uses: actions/checkout@v3
 6+      - uses: actions/checkout@v4
 7         with:
 8           # need entire history
 9           fetch-depth: 0
10       - uses: actions/setup-go@v4
11         with:
12-          go-version: '1.22'
13+          go-version: "1.22"
14       - name: generate site
15         run: |
16           go mod tidy
17@@ -29,7 +29,7 @@ jobs:
18         with:
19           user: erock
20           key: ${{ secrets.PRIVATE_KEY }}
21-          src: './docs/public/'
22+          src: "./docs/public/"
23           project: "starfx-docs-${{ steps.vars.outputs.sha_short }}"
24           promote: "starfx-prod"
25           retain: "starfx-docs"
M .github/workflows/release.yml
+2, -4
 1@@ -12,11 +12,9 @@ jobs:
 2     runs-on: ubuntu-latest
 3     steps:
 4       - name: checkout
 5-        uses: actions/checkout@v3
 6+        uses: actions/checkout@v4
 7       - name: setup deno
 8-        uses: denoland/setup-deno@v1
 9-        with:
10-          deno-version: v1.x
11+        uses: denoland/setup-deno@v2
12       - name: get version
13         id: vars
14         run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^v//')
M .github/workflows/test-ecosystem.yml
+1, -3
 1@@ -34,9 +34,7 @@ jobs:
 2           path: "starfx"
 3 
 4       - name: setup deno
 5-        uses: denoland/setup-deno@v1
 6-        with:
 7-          deno-version: v1.x
 8+        uses: denoland/setup-deno@v2
 9 
10       # determines branch and sets it as output available through the `id`
11       - name: dynamically determine ${{ matrix.example.owner }}/${{ matrix.example.repo }} branch
M .github/workflows/test.yml
+2, -4
 1@@ -14,12 +14,10 @@ jobs:
 2     runs-on: ubuntu-latest
 3     steps:
 4       - name: checkout
 5-        uses: actions/checkout@v3
 6+        uses: actions/checkout@v4
 7 
 8       - name: setup deno
 9-        uses: denoland/setup-deno@v1
10-        with:
11-          deno-version: v1.x
12+        uses: denoland/setup-deno@v2
13 
14       - name: format
15         run: deno fmt --check
M action.ts
+2, -4
 1@@ -9,7 +9,7 @@ import {
 2   SignalQueueFactory,
 3   spawn,
 4   Stream,
 5-} from "./deps.ts";
 6+} from "effection";
 7 import { ActionPattern, matcher } from "./matcher.ts";
 8 import type { Action, ActionWithPayload, AnyAction } from "./types.ts";
 9 import { createFilterQueue } from "./queue.ts";
10@@ -105,9 +105,7 @@ export function* takeLeading<T>(
11   }
12 }
13 
14-export function* waitFor(
15-  predicate: Callable<boolean>,
16-) {
17+export function* waitFor(predicate: Callable<boolean>) {
18   const init = yield* call(predicate as any);
19   if (init) {
20     return;
M api-type-template.ts
+1, -1
1@@ -232,7 +232,7 @@ import type {
2   Supervisor,
3 } from "./types.ts";
4 import type { Next, Payload } from "../types.ts";
5-import type { Operation } from "../deps.ts";
6+import type { Operation } from "effection";
7 
8 export type ApiName = string | string[];
9 
M compose.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { Instruction, Operation } from "./deps.ts";
3+import { Instruction, Operation } from "effection";
4 import type { Next } from "./types.ts";
5 
6 export interface BaseCtx {
M deno.json
+17, -2
 1@@ -1,8 +1,8 @@
 2 {
 3   "tasks": {
 4     "types": "deno run --allow-write ./api-type-template.ts",
 5-    "npm": "deno run -A ./npm.ts",
 6-    "test": "deno test --allow-env --allow-read",
 7+    "npm": "deno run -A ./scripts/npm.ts",
 8+    "test": "deno test --allow-env --allow-read --allow-import",
 9     "sync-build-to": "deno run -A ./scripts/sync.ts"
10   },
11   "lint": {
12@@ -14,5 +14,20 @@
13   },
14   "fmt": {
15     "exclude": ["npm/", "examples/"]
16+  },
17+  "compilerOptions": {
18+    "strict": true,
19+    "lib": ["deno.window", "dom"],
20+    "jsx": "react",
21+    "jsxFactory": "React.createElement",
22+    "jsxFragmentFactory": "React.Fragment"
23+  },
24+  "imports": {
25+    "react": "npm:react@^18.2.0",
26+    "react-dom": "npm:react-dom@^18.2.0",
27+    "react-redux": "npm:react-redux@^8.0.5",
28+    "reselect": "npm:reselect@^4.1.8",
29+    "immer": "npm:immer@^10.0.2",
30+    "effection": "https://deno.land/x/effection@3.0.0-beta.3/mod.ts"
31   }
32 }
M deno.lock
+298, -126
  1@@ -1,111 +1,272 @@
  2 {
  3-  "version": "3",
  4+  "version": "4",
  5+  "specifiers": {
  6+    "jsr:@david/code-block-writer@^13.0.2": "13.0.3",
  7+    "jsr:@deno/cache-dir@~0.10.3": "0.10.3",
  8+    "jsr:@deno/dnt@0.41.3": "0.41.3",
  9+    "jsr:@std/assert@*": "1.0.10",
 10+    "jsr:@std/assert@0.223": "0.223.0",
 11+    "jsr:@std/assert@0.226": "0.226.0",
 12+    "jsr:@std/assert@^1.0.10": "1.0.10",
 13+    "jsr:@std/bytes@0.223": "0.223.0",
 14+    "jsr:@std/expect@*": "1.0.10",
 15+    "jsr:@std/fmt@0.223": "0.223.0",
 16+    "jsr:@std/fmt@1": "1.0.3",
 17+    "jsr:@std/fs@0.223": "0.223.0",
 18+    "jsr:@std/fs@1": "1.0.8",
 19+    "jsr:@std/fs@~0.229.3": "0.229.3",
 20+    "jsr:@std/internal@^1.0.5": "1.0.5",
 21+    "jsr:@std/io@0.223": "0.223.0",
 22+    "jsr:@std/path@0.223": "0.223.0",
 23+    "jsr:@std/path@1": "1.0.8",
 24+    "jsr:@std/path@1.0.0-rc.1": "1.0.0-rc.1",
 25+    "jsr:@std/path@^1.0.8": "1.0.8",
 26+    "jsr:@std/path@~0.225.2": "0.225.2",
 27+    "jsr:@std/testing@*": "1.0.8",
 28+    "jsr:@ts-morph/bootstrap@0.24": "0.24.0",
 29+    "jsr:@ts-morph/common@0.24": "0.24.0",
 30+    "npm:effection@*": "3.0.3",
 31+    "npm:immer@^10.0.2": "10.1.1",
 32+    "npm:react-dom@^18.2.0": "18.2.0_react@18.3.1",
 33+    "npm:react-redux@^8.0.5": "8.1.3_react@18.3.1_react-dom@18.2.0__react@18.3.1",
 34+    "npm:react@^18.2.0": "18.3.1",
 35+    "npm:reselect@^4.1.8": "4.1.8"
 36+  },
 37+  "jsr": {
 38+    "@david/code-block-writer@13.0.3": {
 39+      "integrity": "f98c77d320f5957899a61bfb7a9bead7c6d83ad1515daee92dbacc861e13bb7f"
 40+    },
 41+    "@deno/cache-dir@0.10.3": {
 42+      "integrity": "eb022f84ecc49c91d9d98131c6e6b118ff63a29e343624d058646b9d50404776",
 43+      "dependencies": [
 44+        "jsr:@std/fmt@0.223",
 45+        "jsr:@std/fs@0.223",
 46+        "jsr:@std/io",
 47+        "jsr:@std/path@0.223"
 48+      ]
 49+    },
 50+    "@deno/dnt@0.41.3": {
 51+      "integrity": "b2ef2c8a5111eef86cb5bfcae103d6a2938e8e649e2461634a7befb7fc59d6d2",
 52+      "dependencies": [
 53+        "jsr:@david/code-block-writer",
 54+        "jsr:@deno/cache-dir",
 55+        "jsr:@std/fmt@1",
 56+        "jsr:@std/fs@1",
 57+        "jsr:@std/path@1",
 58+        "jsr:@ts-morph/bootstrap"
 59+      ]
 60+    },
 61+    "@std/assert@0.223.0": {
 62+      "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24"
 63+    },
 64+    "@std/assert@0.226.0": {
 65+      "integrity": "0dfb5f7c7723c18cec118e080fec76ce15b4c31154b15ad2bd74822603ef75b3"
 66+    },
 67+    "@std/assert@1.0.10": {
 68+      "integrity": "59b5cbac5bd55459a19045d95cc7c2ff787b4f8527c0dd195078ff6f9481fbb3",
 69+      "dependencies": [
 70+        "jsr:@std/internal"
 71+      ]
 72+    },
 73+    "@std/bytes@0.223.0": {
 74+      "integrity": "84b75052cd8680942c397c2631318772b295019098f40aac5c36cead4cba51a8"
 75+    },
 76+    "@std/expect@1.0.10": {
 77+      "integrity": "7659b640447887cd1735f866962e10e434f12443b13595b149970c806e6f08db",
 78+      "dependencies": [
 79+        "jsr:@std/assert@^1.0.10",
 80+        "jsr:@std/internal"
 81+      ]
 82+    },
 83+    "@std/fmt@0.223.0": {
 84+      "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208"
 85+    },
 86+    "@std/fmt@1.0.3": {
 87+      "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f"
 88+    },
 89+    "@std/fs@0.223.0": {
 90+      "integrity": "3b4b0550b2c524cbaaa5a9170c90e96cbb7354e837ad1bdaf15fc9df1ae9c31c"
 91+    },
 92+    "@std/fs@0.229.3": {
 93+      "integrity": "783bca21f24da92e04c3893c9e79653227ab016c48e96b3078377ebd5222e6eb",
 94+      "dependencies": [
 95+        "jsr:@std/path@1.0.0-rc.1"
 96+      ]
 97+    },
 98+    "@std/fs@1.0.8": {
 99+      "integrity": "161c721b6f9400b8100a851b6f4061431c538b204bb76c501d02c508995cffe0",
100+      "dependencies": [
101+        "jsr:@std/path@^1.0.8"
102+      ]
103+    },
104+    "@std/internal@1.0.5": {
105+      "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba"
106+    },
107+    "@std/io@0.223.0": {
108+      "integrity": "2d8c3c2ab3a515619b90da2c6ff5ea7b75a94383259ef4d02116b228393f84f1",
109+      "dependencies": [
110+        "jsr:@std/assert@0.223",
111+        "jsr:@std/bytes"
112+      ]
113+    },
114+    "@std/path@0.223.0": {
115+      "integrity": "593963402d7e6597f5a6e620931661053572c982fc014000459edc1f93cc3989",
116+      "dependencies": [
117+        "jsr:@std/assert@0.223"
118+      ]
119+    },
120+    "@std/path@0.225.2": {
121+      "integrity": "0f2db41d36b50ef048dcb0399aac720a5348638dd3cb5bf80685bf2a745aa506",
122+      "dependencies": [
123+        "jsr:@std/assert@0.226"
124+      ]
125+    },
126+    "@std/path@1.0.0-rc.1": {
127+      "integrity": "b8c00ae2f19106a6bb7cbf1ab9be52aa70de1605daeb2dbdc4f87a7cbaf10ff6"
128+    },
129+    "@std/path@1.0.8": {
130+      "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be"
131+    },
132+    "@std/testing@1.0.8": {
133+      "integrity": "ceef535808fb7568e91b0f8263599bd29b1c5603ffb0377227f00a8ca9fe42a2",
134+      "dependencies": [
135+        "jsr:@std/assert@^1.0.10",
136+        "jsr:@std/internal"
137+      ]
138+    },
139+    "@ts-morph/bootstrap@0.24.0": {
140+      "integrity": "a826a2ef7fa8a7c3f1042df2c034d20744d94da2ee32bf29275bcd4dffd3c060",
141+      "dependencies": [
142+        "jsr:@ts-morph/common"
143+      ]
144+    },
145+    "@ts-morph/common@0.24.0": {
146+      "integrity": "12b625b8e562446ba658cdbe9ad77774b4bd96b992ae8bd34c60dbf24d06c1f3",
147+      "dependencies": [
148+        "jsr:@std/fs@~0.229.3",
149+        "jsr:@std/path@~0.225.2"
150+      ]
151+    }
152+  },
153+  "npm": {
154+    "@babel/runtime@7.26.0": {
155+      "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==",
156+      "dependencies": [
157+        "regenerator-runtime"
158+      ]
159+    },
160+    "@types/hoist-non-react-statics@3.3.6": {
161+      "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==",
162+      "dependencies": [
163+        "@types/react",
164+        "hoist-non-react-statics"
165+      ]
166+    },
167+    "@types/prop-types@15.7.5": {
168+      "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w=="
169+    },
170+    "@types/react@18.0.32": {
171+      "integrity": "sha512-gYGXdtPQ9Cj0w2Fwqg5/ak6BcK3Z15YgjSqtyDizWUfx7mQ8drs0NBUzRRsAdoFVTO8kJ8L2TL8Skm7OFPnLUw==",
172+      "dependencies": [
173+        "@types/prop-types",
174+        "@types/scheduler",
175+        "csstype"
176+      ]
177+    },
178+    "@types/scheduler@0.16.3": {
179+      "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ=="
180+    },
181+    "@types/use-sync-external-store@0.0.3": {
182+      "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA=="
183+    },
184+    "csstype@3.1.2": {
185+      "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ=="
186+    },
187+    "effection@3.0.3": {
188+      "integrity": "sha512-9ASCaJ44flDoEKUUJtn9drfIomn2z30sZUw7//crbq+eltMu09AyILcouXwpMkcHR8TsD5hDvTTsOLHswWRxXQ=="
189+    },
190+    "hoist-non-react-statics@3.3.2": {
191+      "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
192+      "dependencies": [
193+        "react-is@16.13.1"
194+      ]
195+    },
196+    "immer@10.1.1": {
197+      "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw=="
198+    },
199+    "js-tokens@4.0.0": {
200+      "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ=="
201+    },
202+    "loose-envify@1.4.0": {
203+      "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==",
204+      "dependencies": [
205+        "js-tokens"
206+      ]
207+    },
208+    "react-dom@18.2.0_react@18.3.1": {
209+      "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==",
210+      "dependencies": [
211+        "loose-envify",
212+        "react",
213+        "scheduler"
214+      ]
215+    },
216+    "react-is@16.13.1": {
217+      "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ=="
218+    },
219+    "react-is@18.3.1": {
220+      "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg=="
221+    },
222+    "react-redux@8.1.3_react@18.3.1_react-dom@18.2.0__react@18.3.1": {
223+      "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==",
224+      "dependencies": [
225+        "@babel/runtime",
226+        "@types/hoist-non-react-statics",
227+        "@types/use-sync-external-store",
228+        "hoist-non-react-statics",
229+        "react",
230+        "react-dom",
231+        "react-is@18.3.1",
232+        "use-sync-external-store"
233+      ]
234+    },
235+    "react@18.3.1": {
236+      "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==",
237+      "dependencies": [
238+        "loose-envify"
239+      ]
240+    },
241+    "regenerator-runtime@0.14.1": {
242+      "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
243+    },
244+    "reselect@4.1.8": {
245+      "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ=="
246+    },
247+    "scheduler@0.23.0": {
248+      "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==",
249+      "dependencies": [
250+        "loose-envify"
251+      ]
252+    },
253+    "use-sync-external-store@1.4.0_react@18.3.1": {
254+      "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==",
255+      "dependencies": [
256+        "react"
257+      ]
258+    }
259+  },
260   "redirects": {
261     "https://crux.land/api/get/2KNRVU": "https://crux.land/api/get/2KNRVU.ts",
262     "https://crux.land/api/get/router@0.0.5": "https://crux.land/api/get/2KNRVU",
263-    "https://crux.land/router@0.0.5": "https://crux.land/api/get/router@0.0.5",
264-    "https://esm.sh/v135/@types/react@~18.2/index.d.ts": "https://esm.sh/v135/@types/react@18.2.38/index.d.ts"
265+    "https://crux.land/router@0.0.5": "https://crux.land/api/get/router@0.0.5"
266   },
267   "remote": {
268     "https://crux.land/api/get/2KNRVU.ts": "6a77d55844aba78d01520c5ff0b2f0af7f24cc1716a0de8b3bb6bd918c47b5ba",
269-    "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74",
270-    "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49",
271-    "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d",
272-    "https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9",
273-    "https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf",
274-    "https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37",
275-    "https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f",
276-    "https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d",
277-    "https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b",
278-    "https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3",
279-    "https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09",
280-    "https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b",
281-    "https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633",
282-    "https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee",
283-    "https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d",
284-    "https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44",
285-    "https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9",
286-    "https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757",
287-    "https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21",
288     "https://deno.land/std@0.158.0/fmt/colors.ts": "ff7dc9c9f33a72bd48bc24b21bbc1b4545d8494a431f17894dbc5fe92a938fc4",
289     "https://deno.land/std@0.158.0/testing/_diff.ts": "a23e7fc2b4d8daa3e158fa06856bedf5334ce2a2831e8bf9e509717f455adb2c",
290     "https://deno.land/std@0.158.0/testing/_format.ts": "cd11136e1797791045e639e9f0f4640d5b4166148796cad37e6ef75f7d7f3832",
291     "https://deno.land/std@0.158.0/testing/asserts.ts": "8696c488bc98d8d175e74dc652a0ffbc7fca93858da01edc57ed33c1148345da",
292-    "https://deno.land/std@0.163.0/testing/_test_suite.ts": "2d07073d5460a4e3ec50c55ae822cd9bd136926d7363091379947fef9c73c3e4",
293-    "https://deno.land/std@0.163.0/testing/bdd.ts": "35060cefd9cc21b414f4d89453b3551a3d52ec50aeff25db432503c5485b2f72",
294-    "https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
295-    "https://deno.land/std@0.181.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
296-    "https://deno.land/std@0.181.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32",
297-    "https://deno.land/std@0.181.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40",
298-    "https://deno.land/std@0.181.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a",
299-    "https://deno.land/std@0.181.0/fs/walk.ts": "ea95ffa6500c1eda6b365be488c056edc7c883a1db41ef46ec3bf057b1c0fe32",
300-    "https://deno.land/std@0.181.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
301-    "https://deno.land/std@0.181.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
302-    "https://deno.land/std@0.181.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
303-    "https://deno.land/std@0.181.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
304-    "https://deno.land/std@0.181.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
305-    "https://deno.land/std@0.181.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c",
306-    "https://deno.land/std@0.181.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
307-    "https://deno.land/std@0.181.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
308-    "https://deno.land/std@0.181.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
309-    "https://deno.land/std@0.182.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462",
310-    "https://deno.land/std@0.182.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3",
311-    "https://deno.land/std@0.182.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e",
312-    "https://deno.land/std@0.182.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32",
313-    "https://deno.land/std@0.182.0/fs/empty_dir.ts": "c3d2da4c7352fab1cf144a1ecfef58090769e8af633678e0f3fabaef98594688",
314-    "https://deno.land/std@0.182.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a",
315-    "https://deno.land/std@0.182.0/fs/walk.ts": "920be35a7376db6c0b5b1caf1486fb962925e38c9825f90367f8f26b5e5d0897",
316-    "https://deno.land/std@0.182.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0",
317-    "https://deno.land/std@0.182.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b",
318-    "https://deno.land/std@0.182.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0",
319-    "https://deno.land/std@0.182.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000",
320-    "https://deno.land/std@0.182.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1",
321-    "https://deno.land/std@0.182.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c",
322-    "https://deno.land/std@0.182.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d",
323-    "https://deno.land/std@0.182.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1",
324-    "https://deno.land/std@0.182.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba",
325-    "https://deno.land/std@0.185.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e",
326-    "https://deno.land/std@0.185.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea",
327-    "https://deno.land/std@0.185.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7",
328-    "https://deno.land/std@0.185.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f",
329-    "https://deno.land/std@0.187.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e",
330-    "https://deno.land/std@0.187.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea",
331-    "https://deno.land/std@0.187.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7",
332-    "https://deno.land/std@0.187.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f",
333-    "https://deno.land/std@0.97.0/fmt/colors.ts": "db22b314a2ae9430ae7460ce005e0a7130e23ae1c999157e3bb77cf55800f7e4",
334-    "https://deno.land/std@0.97.0/testing/_diff.ts": "961eaf6d9f5b0a8556c9d835bbc6fa74f5addd7d3b02728ba7936ff93364f7a3",
335-    "https://deno.land/std@0.97.0/testing/asserts.ts": "341292d12eebc44be4c3c2ca101ba8b6b5859cef2fa69d50c217f9d0bfbcfd1f",
336-    "https://deno.land/x/code_block_writer@12.0.0/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5",
337-    "https://deno.land/x/code_block_writer@12.0.0/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff",
338     "https://deno.land/x/continuation@0.1.5/mod.ts": "690def2735046367b3e1b4bc6e51b5912f2ed09c41c7df7a55c060f23720ad33",
339-    "https://deno.land/x/deno_cache@0.5.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e",
340-    "https://deno.land/x/deno_cache@0.5.2/cache.ts": "92ce8511e1e5c00fdf53a41619aa77d632ea8e0fc711324322e4d5ebf8133911",
341-    "https://deno.land/x/deno_cache@0.5.2/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0",
342-    "https://deno.land/x/deno_cache@0.5.2/deps.ts": "26a75905652510b76e54b6d5ef3cf824d1062031e00782efcd768978419224e7",
343-    "https://deno.land/x/deno_cache@0.5.2/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069",
344-    "https://deno.land/x/deno_cache@0.5.2/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa",
345-    "https://deno.land/x/deno_cache@0.5.2/file_fetcher.ts": "89616c50b6df73fb04e73d0b7cd99e5f2ed7967386913d65b9e8baa4238501f7",
346-    "https://deno.land/x/deno_cache@0.5.2/http_cache.ts": "407135eaf2802809ed373c230d57da7ef8dff923c4abf205410b9b99886491fd",
347-    "https://deno.land/x/deno_cache@0.5.2/lib/deno_cache_dir.generated.js": "18b6526d0c50791a73dd0eb894e99de1ac05ee79dcbd53298ff5b5b6b0757fe6",
348-    "https://deno.land/x/deno_cache@0.5.2/lib/snippets/deno_cache_dir-77bed54ace8005e0/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6",
349-    "https://deno.land/x/deno_cache@0.5.2/mod.ts": "0b4d071ad095128bdc2b1bc6e5d2095222dcbae08287261690ee9757e6300db6",
350-    "https://deno.land/x/deno_cache@0.5.2/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2",
351-    "https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66",
352-    "https://deno.land/x/dnt@0.38.1/lib/compiler.ts": "209ad2e1b294f93f87ec02ade9a0821f942d2e524104552d0aa8ff87021050a5",
353-    "https://deno.land/x/dnt@0.38.1/lib/compiler_transforms.ts": "f21aba052f5dcf0b0595c734450842855c7f572e96165d3d34f8fed2fc1f7ba1",
354-    "https://deno.land/x/dnt@0.38.1/lib/mod.deps.ts": "30367fc68bcd2acf3b7020cf5cdd26f817f7ac9ac35c4bfb6c4551475f91bc3e",
355-    "https://deno.land/x/dnt@0.38.1/lib/npm_ignore.ts": "57fbb7e7b935417d225eec586c6aa240288905eb095847d3f6a88e290209df4e",
356-    "https://deno.land/x/dnt@0.38.1/lib/package_json.ts": "61f35b06e374ed39ca776d29d67df4be7ee809d0bca29a8239687556c6d027c2",
357-    "https://deno.land/x/dnt@0.38.1/lib/pkg/dnt_wasm.generated.js": "cfb352ae839865f5698c9b35099d4c783510195a1e3c9f9b04d94fac86394ed9",
358-    "https://deno.land/x/dnt@0.38.1/lib/pkg/snippets/dnt-wasm-a15ef721fa5290c5/helpers.js": "45f74f00472b3a399bc16e5dc056966b55dcdd8fa2bd61505c6dfd2f5d33b9f4",
359-    "https://deno.land/x/dnt@0.38.1/lib/shims.ts": "df1bd4d9a196dca4b2d512b1564fff64ac6c945189a273d706391f87f210d7e6",
360-    "https://deno.land/x/dnt@0.38.1/lib/test_runner/get_test_runner_code.ts": "4dc7a73a13b027341c0688df2b29a4ef102f287c126f134c33f69f0339b46968",
361-    "https://deno.land/x/dnt@0.38.1/lib/test_runner/test_runner.ts": "4d0da0500ec427d5f390d9a8d42fb882fbeccc92c92d66b6f2e758606dbd40e6",
362-    "https://deno.land/x/dnt@0.38.1/lib/transform.deps.ts": "e42f2bdef46d098453bdba19261a67cf90b583f5d868f7fe83113c1380d9b85c",
363-    "https://deno.land/x/dnt@0.38.1/lib/types.ts": "b8e228b2fac44c2ae902fbb73b1689f6ab889915bd66486c8a85c0c24255f5fb",
364-    "https://deno.land/x/dnt@0.38.1/lib/utils.ts": "878b7ac7003a10c16e6061aa49dbef9b42bd43174853ebffc9b67ea47eeb11d8",
365-    "https://deno.land/x/dnt@0.38.1/mod.ts": "b13349fe77847cf58e26b40bcd58797a8cec5d71b31a1ca567071329c8489de1",
366-    "https://deno.land/x/dnt@0.38.1/transform.ts": "f68743a14cf9bf53bfc9c81073871d69d447a7f9e3453e0447ca2fb78926bb1d",
367     "https://deno.land/x/effection@3.0.0-beta.3/lib/abort-signal.ts": "8be1b331b2bc417d70fe4c07e0b806e89972b8eab519ce58beed7ec632ae9048",
368     "https://deno.land/x/effection@3.0.0-beta.3/lib/all.ts": "acadab8258228e290192f587c8c532428f9093337a9b7688ae55cbc2cacd5caf",
369     "https://deno.land/x/effection@3.0.0-beta.3/lib/async.ts": "086b27b253be944c47c633d105f1657e243cd8c0d35b9a0dc5383528d7235dde",
370@@ -141,35 +302,46 @@
371     "https://deno.land/x/effection@3.0.0-beta.3/lib/sleep.ts": "44e3a80248dad7a47066a99a7daec9b318e87d5d211adf27776145544d455689",
372     "https://deno.land/x/effection@3.0.0-beta.3/lib/types.ts": "9738143fe6bfd5709a6ff10b6dd065582cfaca1167bf57902cb7bcca89b53dc4",
373     "https://deno.land/x/effection@3.0.0-beta.3/mod.ts": "ffae461c16d4a1bf24c2179582ab8d5c81ad0df61e4ae2fba51ef5e5bdf90345",
374-    "https://deno.land/x/expect@v0.3.0/expect.ts": "5e6717eddc9df376f7b2c9be6403e016130bb2edbb1acd261a2d6ea9608ee196",
375-    "https://deno.land/x/expect@v0.3.0/matchers.ts": "a37ef4577739247af77a852cdcd69484f999a41ad86ec16bb63a88a7a47a2372",
376-    "https://deno.land/x/expect@v0.3.0/mock.ts": "562d4b1d735d15b0b8e935f342679096b64fe452f86e96714fe8616c0c884914",
377-    "https://deno.land/x/expect@v0.3.0/mod.ts": "0304d2430e1e96ba669a8495e24ba606dcc3d152e1f81aaa8da898cea24e36c2",
378-    "https://deno.land/x/mock_fetch@0.3.0/mod.ts": "7e7806c65ab17b2b684c334c4e565812bdaf504a3e9c938d2bb52bb67428bc89",
379-    "https://deno.land/x/ts_morph@18.0.0/bootstrap/mod.ts": "b53aad517f106c4079971fcd4a81ab79fadc40b50061a3ab2b741a09119d51e9",
380-    "https://deno.land/x/ts_morph@18.0.0/bootstrap/ts_morph_bootstrap.js": "6645ac03c5e6687dfa8c78109dc5df0250b811ecb3aea2d97c504c35e8401c06",
381-    "https://deno.land/x/ts_morph@18.0.0/common/DenoRuntime.ts": "6a7180f0c6e90dcf23ccffc86aa8271c20b1c4f34c570588d08a45880b7e172d",
382-    "https://deno.land/x/ts_morph@18.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed",
383-    "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700",
384-    "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59",
385-    "https://deno.land/x/wasmbuild@0.15.0/cache.ts": "89eea5f3ce6035a1164b3e655c95f21300498920575ade23161421f5b01967f4",
386-    "https://deno.land/x/wasmbuild@0.15.0/loader.ts": "d98d195a715f823151cbc8baa3f32127337628379a02d9eb2a3c5902dbccfc02",
387-    "https://esm.sh/immer@10.0.2?pin=v135": "c9a37633ebd7643f9618f0e3263ca12dc16eecb898feb579f94cc81c4a367c20",
388-    "https://esm.sh/react-redux@8.0.5?pin=v135": "c5a1b9dcf3c39bb53bdd3efadb7541b91830b736165c4ed6f5edb08b982fff9f",
389-    "https://esm.sh/react@18.2.0?pin=v135": "04ad7dc6d11fa27b24c136686a334ecdd19e972fae627cd98cbdc13cdac238c2",
390-    "https://esm.sh/reselect@4.1.8?pin=v135": "a88008b1d6ad1c4e4023172edebfe699cf9e8e0716132a48bb9f24617d478f4d",
391-    "https://esm.sh/stable/react@18.2.0/denonext/react.mjs": "3c4f23bcfc53b256fcfaf6f834fa9f584c3bb7be667b2682c6cb6ba8ef88f8e6",
392-    "https://esm.sh/v135/@babel/runtime@7.24.4/denonext/helpers/esm/extends.js": "6945975ff02714e9d9e48cc7b2b84215c7f0bcf77b407c7499e497b20d2d7f6b",
393-    "https://esm.sh/v135/@babel/runtime@7.24.4/denonext/helpers/esm/objectWithoutPropertiesLoose.js": "476b0a7a26e15b0defbc5505ae3f4c7ef4a52e350eb861e090c4ea00f4a80670",
394-    "https://esm.sh/v135/hoist-non-react-statics@3.3.2/denonext/hoist-non-react-statics.mjs": "1e1b0fbe9a9537eb408d6e7017e668b1381814eb9592a1dd18c39ee09a6d9fbb",
395-    "https://esm.sh/v135/immer@10.0.2/denonext/immer.mjs": "e23064a10c38638e3fa18f56a8864b32a41551e0c4dd32b18008431c57629e88",
396-    "https://esm.sh/v135/react-dom@18.2.0/denonext/react-dom.mjs": "8191fc377ea7083cca5640699c4abd75de033089eb932799e29aa04bb136838f",
397-    "https://esm.sh/v135/react-is@16.13.1/denonext/react-is.mjs": "4fc2bb5cfecb53c0f28cd7b730101ff83c05ca06fdd373bc2d6a9bdf662f96d4",
398-    "https://esm.sh/v135/react-is@18.2.0/denonext/react-is.mjs": "07ca6a7473ccbb06466e805c8253ade80bd664a0f486cf020864c22c27a60479",
399-    "https://esm.sh/v135/react-redux@8.0.5/denonext/react-redux.mjs": "aad652363f5339e3814db446148deb093aadf80d57f8dc8d10d4c43b066b258c",
400-    "https://esm.sh/v135/reselect@4.1.8/denonext/reselect.mjs": "f8199f9e44453876a9ea6b5d1caedc0fe1ae789a73217543b1e6193e1edc0db7",
401-    "https://esm.sh/v135/scheduler@0.23.0/denonext/scheduler.mjs": "cdbc6d2823e2c6fffcb14501146ff2602a38c48d3c9dd9268f308e833ede2b49",
402-    "https://esm.sh/v135/use-sync-external-store@1.2.0/denonext/shim.js": "ee51a93766077d32104ee8090cafb05c1bd2e23e256f3516368f8e9a8516f177",
403-    "https://esm.sh/v135/use-sync-external-store@1.2.0/denonext/shim/with-selector.js": "6aaca98d5bc53815f1c14fb8d096f13d41ecf99d91923fa831bc19a880ba929d"
404+    "https://deno.land/x/effection@3.0.3/lib/abort-signal.ts": "b404e2c4250edb6df67f757cf190c87915fd4edbd3200c47b11db762a4cc10cc",
405+    "https://deno.land/x/effection@3.0.3/lib/all.ts": "e45b9701998212b8a97949b1a6f0defb71ce90e56eb57d5afb365e3bba2e3791",
406+    "https://deno.land/x/effection@3.0.3/lib/async.ts": "ac4bed095e849584a6170ac9a47c9217c2e1e99543275cbc9407d92851120ada",
407+    "https://deno.land/x/effection@3.0.3/lib/call.ts": "096705dfd01fa19b6ae01fe3e362c919308a011e6d4647029cdb31dac80eadb2",
408+    "https://deno.land/x/effection@3.0.3/lib/channel.ts": "445b29c5cfc0b6bc48b1a7ea81e09d14c452ee4646c49c7753c8e5b34962ad50",
409+    "https://deno.land/x/effection@3.0.3/lib/context.ts": "108989ac839d6756e30f6c0afc458bfa3975dd0f970d5173b6b8f8473ce4c335",
410+    "https://deno.land/x/effection@3.0.3/lib/deps.ts": "91062b4b97089a8cf36550d4f9605d325a0fd19bebc72d15524481a3b56ea669",
411+    "https://deno.land/x/effection@3.0.3/lib/each.ts": "0a32eaa8b54966a913c843714e669c1f1e8933a3570d54797cc20ee2c4b5de41",
412+    "https://deno.land/x/effection@3.0.3/lib/ensure.ts": "8043d8e6e67ad27382cba05b3c8b886cf46436871831171b8a8eea66609a6313",
413+    "https://deno.land/x/effection@3.0.3/lib/events.ts": "bdaf6c87c368aebff1e4287a9917ae0b6ba880c4008ecf0abf6b5af922233c62",
414+    "https://deno.land/x/effection@3.0.3/lib/instructions.ts": "3e5316bb7f32a70f93b853673dd1192cdfa11a04037e630d07ddf8fd5eba5d08",
415+    "https://deno.land/x/effection@3.0.3/lib/lazy.ts": "92ea526c5ad7d88290f2a87168e038d482f97421379508d85cf2e049ee60639b",
416+    "https://deno.land/x/effection@3.0.3/lib/lift.ts": "06fafd92f3a8e87c34e9bb9d9dacbb0333b5213c9c65c7245b2cab2cf3cf99e9",
417+    "https://deno.land/x/effection@3.0.3/lib/main.ts": "5f4793fe6d82dcbf991d3306334b784c2b2617f618295e8c368f3fe714e66c01",
418+    "https://deno.land/x/effection@3.0.3/lib/mod.ts": "bbbffe1265d9848812feefa7b20307c448bd4ce1d4c6232d2312f3722dca0fa7",
419+    "https://deno.land/x/effection@3.0.3/lib/pause.ts": "a690b0d67cf970c34f528df8c61d69eb43deda9817362776f6359f506dc0da45",
420+    "https://deno.land/x/effection@3.0.3/lib/queue.ts": "80c6234cb6eaba9fd1abdae077e73f51897b099ea54f852b9a744e8eba51302f",
421+    "https://deno.land/x/effection@3.0.3/lib/race.ts": "ab652679ee00fd3f4ca5156628bf3af7aea55b2e20bb6387693075f7ea27d5ca",
422+    "https://deno.land/x/effection@3.0.3/lib/result.ts": "44e4bdadad155beb9bbfe41948819bbcb9e27a772283e52e89981bd6636a8687",
423+    "https://deno.land/x/effection@3.0.3/lib/run.ts": "55070ed92c5881e86b9724f519986058286ef54b6c12adf82847023631ebcfd3",
424+    "https://deno.land/x/effection@3.0.3/lib/run/create.ts": "be9139af2fbe15908256d2d159dec8dca079f94cf02d488074c94fa26fc651fa",
425+    "https://deno.land/x/effection@3.0.3/lib/run/frame.ts": "132fdace9c00e6ad0e249d7faab1c33680336c5fa8e4a893f092ecec4e2df786",
426+    "https://deno.land/x/effection@3.0.3/lib/run/scope.ts": "a968455e313ba9aa097ee5c18b4db0d8e2397b90c78e413fa08396baead7b74a",
427+    "https://deno.land/x/effection@3.0.3/lib/run/task.ts": "7084b9cabdc338c776dc522ec8b677fb3ac41aa0c94e454d467731494cb68737",
428+    "https://deno.land/x/effection@3.0.3/lib/run/types.ts": "010bea700f68fef99dd87ca5ca3cbbc90e026ac467889d8429d39cba0ee55fda",
429+    "https://deno.land/x/effection@3.0.3/lib/run/value.ts": "d57428b45dfeecc9df1e68dadf8697dbc33cd412e6ffcab9d0ba4368e8c1fbd6",
430+    "https://deno.land/x/effection@3.0.3/lib/shift-sync.ts": "74ecefa9cb2e145a3c52f363319f8d6296b804600852044b7d14bd53bc10b512",
431+    "https://deno.land/x/effection@3.0.3/lib/signal.ts": "6aba1f372419e1540bd29a9ff992ffd2500e035b2e455d2c11d856a052f698d1",
432+    "https://deno.land/x/effection@3.0.3/lib/sleep.ts": "ff8ba6a0266f2e8837a9ae5f63402f8db51a39ce573abf1335109bef772d6b4a",
433+    "https://deno.land/x/effection@3.0.3/lib/types.ts": "06b435b6152b17ef7959a37e1901109b3c716e14ee5e0ae942314439f63bb630",
434+    "https://deno.land/x/effection@3.0.3/mod.ts": "ffae461c16d4a1bf24c2179582ab8d5c81ad0df61e4ae2fba51ef5e5bdf90345",
435+    "https://deno.land/x/mock_fetch@0.3.0/mod.ts": "7e7806c65ab17b2b684c334c4e565812bdaf504a3e9c938d2bb52bb67428bc89"
436+  },
437+  "workspace": {
438+    "dependencies": [
439+      "npm:immer@^10.0.2",
440+      "npm:react-dom@^18.2.0",
441+      "npm:react-redux@^8.0.5",
442+      "npm:react@^18.2.0",
443+      "npm:reselect@^4.1.8"
444+    ]
445   }
446 }
D deps.ts
+0, -58
 1@@ -1,58 +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-export { React };
43-export {
44-  Provider,
45-  useDispatch,
46-  useSelector,
47-  useStore,
48-} from "https://esm.sh/react-redux@8.0.5?pin=v135";
49-export type {
50-  TypedUseSelectorHook,
51-} from "https://esm.sh/react-redux@8.0.5?pin=v135";
52-export { createSelector } from "https://esm.sh/reselect@4.1.8?pin=v135";
53-
54-export {
55-  enablePatches,
56-  produce,
57-  produceWithPatches,
58-} from "https://esm.sh/immer@10.0.2?pin=v135";
59-export type { Patch } from "https://esm.sh/immer@10.0.2?pin=v135";
M docs/static/main.css
+10, -4
 1@@ -1,8 +1,14 @@
 2 @media (prefers-color-scheme: light) {
 3-  .logo { stroke: #414558; fill: none; }
 4+  .logo {
 5+    stroke: #414558;
 6+    fill: none;
 7+  }
 8 }
 9 @media (prefers-color-scheme: dark) {
10-  .logo { stroke: #f2f2f2; fill: none; }
11+  .logo {
12+    stroke: #f2f2f2;
13+    fill: none;
14+  }
15 }
16 
17 .logo-sm svg {
18@@ -36,12 +42,12 @@
19   margin: 0;
20   overflow-y: scroll;
21   padding-bottom: 2rem !important;
22-  height: calc(100vh - 3px - (3 * var(--line-height)));
23+  height: calc(100vh - 3px - 3 * var(--line-height));
24 }
25 
26 .post {
27   max-width: 650px;
28-  height: calc(100vh - 3px - (3 * var(--line-height)));
29+  height: calc(100vh - 3px - 3 * var(--line-height));
30   overflow-y: auto;
31   padding-right: 20px;
32 }
M fx/parallel.ts
+2, -2
1@@ -1,6 +1,6 @@
2-import type { Callable, Channel, Operation, Result } from "../deps.ts";
3+import type { Callable, Channel, Operation, Result } from "effection";
4+import { createChannel, resource, spawn } from "effection";
5 import type { Computation } from "../types.ts";
6-import { createChannel, resource, spawn } from "../deps.ts";
7 import { safe } from "./safe.ts";
8 
9 export interface ParallelRet<T> extends Computation<Result<T>[]> {
M fx/race.ts
+3, -5
 1@@ -1,13 +1,11 @@
 2-import type { Callable, Operation, Task } from "../deps.ts";
 3-import { action, call, resource, spawn } from "../deps.ts";
 4+import type { Callable, Operation, Task } from "effection";
 5+import { action, call, resource, spawn } from "effection";
 6 
 7 interface OpMap<T = unknown> {
 8   [key: string]: Callable<T>;
 9 }
10 
11-export function raceMap<T>(
12-  opMap: OpMap,
13-): Operation<
14+export function raceMap<T>(opMap: OpMap): Operation<
15   {
16     [K in keyof OpMap<T>]: OpMap[K] extends (...args: any[]) => any
17       ? ReturnType<OpMap[K]>
M fx/request.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { call, useAbortSignal } from "../deps.ts";
3+import { call, useAbortSignal } from "effection";
4 
5 export function* request(url: string | URL | Request, opts?: RequestInit) {
6   const signal = yield* useAbortSignal();
M fx/safe.ts
+7, -3
 1@@ -1,5 +1,5 @@
 2-import type { Callable, Operation, Result } from "../deps.ts";
 3-import { call, Err, Ok } from "../deps.ts";
 4+import type { Callable, Operation, Result } from "effection";
 5+import { call, Err, Ok } from "effection";
 6 
 7 /**
 8  * The goal of `safe` is to wrap Operations to prevent them from raising
 9@@ -19,11 +19,15 @@ import { call, Err, Ok } from "../deps.ts";
10  * }
11  * ```
12  */
13+function isError(error: unknown): error is Error {
14+  return error instanceof Error;
15+}
16+
17 export function* safe<T>(operator: Callable<T>): Operation<Result<T>> {
18   try {
19     const value = yield* call<T>(operator as any);
20     return Ok(value);
21   } catch (error) {
22-    return Err(error);
23+    return Err(isError(error) ? error : new Error(String(error)));
24   }
25 }
M fx/supervisor.ts
+4, -6
 1@@ -1,8 +1,8 @@
 2-import { Callable, Operation, Result, sleep } from "../deps.ts";
 3+import { type Callable, type Operation, sleep } from "effection";
 4 import { safe } from "./safe.ts";
 5 import { parallel } from "./parallel.ts";
 6-import { put } from "../action.ts";
 7-import { API_ACTION_PREFIX } from "../action.ts";
 8+import { API_ACTION_PREFIX, put } from "../action.ts";
 9+import type { Result } from "effection"; // Adjust the import path as needed
10 
11 export function superviseBackoff(attempt: number, max = 10): number {
12   if (attempt > max) return -1;
13@@ -54,9 +54,7 @@ export function* keepAlive(
14   ops: Callable<unknown>[],
15   backoff?: (attempt: number) => number,
16 ): Operation<Result<void>[]> {
17-  const group = yield* parallel(
18-    ops.map((op) => supervise(op, backoff)),
19-  );
20+  const group = yield* parallel(ops.map((op) => supervise(op, backoff)));
21   const results = yield* group;
22   return results;
23 }
M mdw/fetch.ts
+2, -5
 1@@ -1,4 +1,4 @@
 2-import { sleep } from "../deps.ts";
 3+import { sleep } from "effection";
 4 import { safe } from "../fx/mod.ts";
 5 import type { FetchCtx, FetchJsonCtx } from "../query/mod.ts";
 6 import { isObject, noop } from "../query/util.ts";
 7@@ -202,10 +202,7 @@ export function* payload<CurCtx extends FetchJsonCtx = FetchJsonCtx>(
 8 export function response<CurCtx extends FetchCtx = FetchCtx>(
 9   response?: Response,
10 ) {
11-  return function* responseMdw(
12-    ctx: CurCtx,
13-    next: Next,
14-  ) {
15+  return function* responseMdw(ctx: CurCtx, next: Next) {
16     if (response) {
17       ctx.response = response;
18     }
M mdw/query.ts
+4, -10
 1@@ -1,5 +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 {
 7   ApiCtx,
 8   ApiRequest,
 9@@ -12,8 +14,6 @@ import type {
10 import type { AnyAction, Next } from "../types.ts";
11 import { mergeRequest } from "../query/util.ts";
12 import * as fetchMdw from "./fetch.ts";
13-import { call, Callable } from "../deps.ts";
14-import { put } from "../action.ts";
15 export * from "./fetch.ts";
16 
17 /**
18@@ -27,10 +27,7 @@ export * from "./fetch.ts";
19  * middleware pipeline succeeded or not. Think the `.catch()` case for
20  * `window.fetch`.
21  */
22-export function* err<Ctx extends ThunkCtx = ThunkCtx>(
23-  ctx: Ctx,
24-  next: Next,
25-) {
26+export function* err<Ctx extends ThunkCtx = ThunkCtx>(ctx: Ctx, next: Next) {
27   ctx.result = yield* safe(next);
28   if (!ctx.result.ok) {
29     const message =
30@@ -114,10 +111,7 @@ export function* actions(ctx: { actions: AnyAction[] }, next: Next) {
31  * This middleware will add `performance.now()` before and after your
32  * middleware pipeline.
33  */
34-export function* perf<Ctx extends PerfCtx = PerfCtx>(
35-  ctx: Ctx,
36-  next: Next,
37-) {
38+export function* perf<Ctx extends PerfCtx = PerfCtx>(ctx: Ctx, next: Next) {
39   const t0 = performance.now();
40   yield* next();
41   const t1 = performance.now();
M mdw/store.ts
+20, -19
 1@@ -21,6 +21,14 @@ export interface ApiMdwProps<
 2   errorFn?: (ctx: Ctx) => string;
 3 }
 4 
 5+interface ErrorLike {
 6+  message: string;
 7+}
 8+
 9+function isErrorLike(err: unknown): err is ErrorLike {
10+  return typeof err === "object" && err !== null && "message" in err;
11+}
12+
13 /**
14  * This middleware is a composition of many middleware used to faciliate
15  * the {@link createApi}.
16@@ -54,15 +62,10 @@ export function api<Ctx extends ApiCtx = ApiCtx, S extends AnyState = AnyState>(
17  * This middleware will automatically cache any data found inside `ctx.json`
18  * which is where we store JSON data from the {@link mdw.fetch} middleware.
19  */
20-export function cache<
21-  Ctx extends ApiCtx = ApiCtx,
22->(schema: {
23+export function cache<Ctx extends ApiCtx = ApiCtx>(schema: {
24   cache: TableOutput<any, AnyState>;
25 }) {
26-  return function* cache(
27-    ctx: Ctx,
28-    next: Next,
29-  ) {
30+  return function* cache(ctx: Ctx, next: Next) {
31     ctx.cacheData = yield* select(schema.cache.selectById, { id: ctx.key });
32     yield* next();
33     if (!ctx.cache) return;
34@@ -83,9 +86,10 @@ export function cache<
35 export function loader<M extends AnyState = AnyState>(schema: {
36   loaders: LoaderOutput<M, AnyState>;
37 }) {
38-  return function* <
39-    Ctx extends ThunkCtxWLoader = ThunkCtxWLoader,
40-  >(ctx: Ctx, next: Next) {
41+  return function* <Ctx extends ThunkCtxWLoader = ThunkCtxWLoader>(
42+    ctx: Ctx,
43+    next: Next,
44+  ) {
45     yield* updateStore([
46       schema.loaders.start({ id: ctx.name }),
47       schema.loaders.start({ id: ctx.key }),
48@@ -109,15 +113,16 @@ export function loader<M extends AnyState = AnyState>(schema: {
49         ctx.loader = {};
50       }
51 
52+      const message = isErrorLike(err) ? err.message : "unknown exception";
53       yield* updateStore([
54         schema.loaders.error({
55           id: ctx.name,
56-          message: err.message,
57+          message,
58           ...ctx.loader,
59         }),
60         schema.loaders.error({
61           id: ctx.key,
62-          message: err.message,
63+          message,
64           ...ctx.loader,
65         }),
66       ]);
67@@ -148,9 +153,7 @@ function defaultErrorFn<Ctx extends ApiCtx = ApiCtx>(ctx: Ctx) {
68 export function loaderApi<
69   Ctx extends ApiCtx = ApiCtx,
70   S extends AnyState = AnyState,
71->(
72-  { schema, errorFn = defaultErrorFn }: ApiMdwProps<Ctx, S>,
73-) {
74+>({ schema, errorFn = defaultErrorFn }: ApiMdwProps<Ctx, S>) {
75   return function* trackLoading(ctx: Ctx, next: Next) {
76     try {
77       yield* updateStore([
78@@ -162,9 +165,7 @@ export function loaderApi<
79       yield* next();
80 
81       if (!ctx.response) {
82-        yield* updateStore(
83-          schema.loaders.resetByIds([ctx.name, ctx.key]),
84-        );
85+        yield* updateStore(schema.loaders.resetByIds([ctx.name, ctx.key]));
86         return;
87       }
88 
89@@ -193,7 +194,7 @@ export function loaderApi<
90         schema.loaders.success({ id: ctx.key, ...ctx.loader }),
91       ]);
92     } catch (err) {
93-      const message = err?.message || "unknown exception";
94+      const message = isErrorLike(err) ? err.message : "unknown exception";
95       yield* updateStore([
96         schema.loaders.error({
97           id: ctx.name,
M mod.ts
+2, -2
 1@@ -25,7 +25,7 @@ export {
 2   sleep,
 3   spawn,
 4   useAbortSignal,
 5-} from "./deps.ts";
 6+} from "effection";
 7 export type {
 8   Callable,
 9   Channel,
10@@ -36,4 +36,4 @@ export type {
11   Stream,
12   Subscription,
13   Task,
14-} from "./deps.ts";
15+} from "effection";
M query/api-types.ts
+64, -82
  1@@ -2,6 +2,7 @@
  2  * This is an auto-generated file, do not edit directly!
  3  * Run "yarn template" to generate this file.
  4  */
  5+import type { Operation } from "effection";
  6 import type { ThunksApi } from "./thunk.ts";
  7 import type {
  8   ApiCtx,
  9@@ -12,7 +13,6 @@ import type {
 10   Supervisor,
 11 } from "./types.ts";
 12 import type { Next, Payload } from "../types.ts";
 13-import type { Operation } from "../deps.ts";
 14 
 15 export type ApiName = string | string[];
 16 
 17@@ -27,12 +27,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
 18      * Options only
 19      */
 20     get(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
 21-    get<P>(
 22-      req: { supervisor?: Supervisor },
 23-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 24-    get<P extends never, ApiSuccess, ApiError = unknown>(
 25-      req: { supervisor?: Supervisor },
 26-    ): CreateAction<
 27+    get<P>(req: {
 28+      supervisor?: Supervisor;
 29+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 30+    get<P extends never, ApiSuccess, ApiError = unknown>(req: {
 31+      supervisor?: Supervisor;
 32+    }): CreateAction<
 33       & Omit<Ctx, "json">
 34       & FetchJson<
 35         ApiSuccess,
 36@@ -57,9 +57,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
 37      * Middleware only
 38      */
 39     get(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
 40-    get<Gtx extends Ctx = Ctx>(
 41-      fn: MiddlewareApiCo<Gtx>,
 42-    ): CreateAction<Gtx>;
 43+    get<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
 44     get<P>(
 45       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
 46     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 47@@ -149,12 +147,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
 48      * Options only
 49      */
 50     post(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
 51-    post<P>(
 52-      req: { supervisor?: Supervisor },
 53-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 54-    post<P extends never, ApiSuccess, ApiError = unknown>(
 55-      req: { supervisor?: Supervisor },
 56-    ): CreateAction<
 57+    post<P>(req: {
 58+      supervisor?: Supervisor;
 59+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 60+    post<P extends never, ApiSuccess, ApiError = unknown>(req: {
 61+      supervisor?: Supervisor;
 62+    }): CreateAction<
 63       & Omit<Ctx, "json">
 64       & FetchJson<
 65         ApiSuccess,
 66@@ -179,9 +177,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
 67      * Middleware only
 68      */
 69     post(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
 70-    post<Gtx extends Ctx = Ctx>(
 71-      fn: MiddlewareApiCo<Gtx>,
 72-    ): CreateAction<Gtx>;
 73+    post<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
 74     post<P>(
 75       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
 76     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 77@@ -271,12 +267,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
 78      * Options only
 79      */
 80     put(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
 81-    put<P>(
 82-      req: { supervisor?: Supervisor },
 83-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 84-    put<P extends never, ApiSuccess, ApiError = unknown>(
 85-      req: { supervisor?: Supervisor },
 86-    ): CreateAction<
 87+    put<P>(req: {
 88+      supervisor?: Supervisor;
 89+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
 90+    put<P extends never, ApiSuccess, ApiError = unknown>(req: {
 91+      supervisor?: Supervisor;
 92+    }): CreateAction<
 93       & Omit<Ctx, "json">
 94       & FetchJson<
 95         ApiSuccess,
 96@@ -301,9 +297,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
 97      * Middleware only
 98      */
 99     put(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
100-    put<Gtx extends Ctx = Ctx>(
101-      fn: MiddlewareApiCo<Gtx>,
102-    ): CreateAction<Gtx>;
103+    put<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
104     put<P>(
105       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
106     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
107@@ -393,12 +387,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
108      * Options only
109      */
110     patch(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
111-    patch<P>(
112-      req: { supervisor?: Supervisor },
113-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
114-    patch<P extends never, ApiSuccess, ApiError = unknown>(
115-      req: { supervisor?: Supervisor },
116-    ): CreateAction<
117+    patch<P>(req: {
118+      supervisor?: Supervisor;
119+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
120+    patch<P extends never, ApiSuccess, ApiError = unknown>(req: {
121+      supervisor?: Supervisor;
122+    }): CreateAction<
123       & Omit<Ctx, "json">
124       & FetchJson<
125         ApiSuccess,
126@@ -423,9 +417,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
127      * Middleware only
128      */
129     patch(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
130-    patch<Gtx extends Ctx = Ctx>(
131-      fn: MiddlewareApiCo<Gtx>,
132-    ): CreateAction<Gtx>;
133+    patch<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
134     patch<P>(
135       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
136     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
137@@ -515,12 +507,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
138      * Options only
139      */
140     delete(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
141-    delete<P>(
142-      req: { supervisor?: Supervisor },
143-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
144-    delete<P extends never, ApiSuccess, ApiError = unknown>(
145-      req: { supervisor?: Supervisor },
146-    ): CreateAction<
147+    delete<P>(req: {
148+      supervisor?: Supervisor;
149+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
150+    delete<P extends never, ApiSuccess, ApiError = unknown>(req: {
151+      supervisor?: Supervisor;
152+    }): CreateAction<
153       & Omit<Ctx, "json">
154       & FetchJson<
155         ApiSuccess,
156@@ -545,9 +537,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
157      * Middleware only
158      */
159     delete(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
160-    delete<Gtx extends Ctx = Ctx>(
161-      fn: MiddlewareApiCo<Gtx>,
162-    ): CreateAction<Gtx>;
163+    delete<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
164     delete<P>(
165       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
166     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
167@@ -637,12 +627,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
168      * Options only
169      */
170     options(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
171-    options<P>(
172-      req: { supervisor?: Supervisor },
173-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
174-    options<P extends never, ApiSuccess, ApiError = unknown>(
175-      req: { supervisor?: Supervisor },
176-    ): CreateAction<
177+    options<P>(req: {
178+      supervisor?: Supervisor;
179+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
180+    options<P extends never, ApiSuccess, ApiError = unknown>(req: {
181+      supervisor?: Supervisor;
182+    }): CreateAction<
183       & Omit<Ctx, "json">
184       & FetchJson<
185         ApiSuccess,
186@@ -667,9 +657,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
187      * Middleware only
188      */
189     options(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
190-    options<Gtx extends Ctx = Ctx>(
191-      fn: MiddlewareApiCo<Gtx>,
192-    ): CreateAction<Gtx>;
193+    options<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
194     options<P>(
195       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
196     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
197@@ -759,12 +747,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
198      * Options only
199      */
200     head(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
201-    head<P>(
202-      req: { supervisor?: Supervisor },
203-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
204-    head<P extends never, ApiSuccess, ApiError = unknown>(
205-      req: { supervisor?: Supervisor },
206-    ): CreateAction<
207+    head<P>(req: {
208+      supervisor?: Supervisor;
209+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
210+    head<P extends never, ApiSuccess, ApiError = unknown>(req: {
211+      supervisor?: Supervisor;
212+    }): CreateAction<
213       & Omit<Ctx, "json">
214       & FetchJson<
215         ApiSuccess,
216@@ -789,9 +777,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
217      * Middleware only
218      */
219     head(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
220-    head<Gtx extends Ctx = Ctx>(
221-      fn: MiddlewareApiCo<Gtx>,
222-    ): CreateAction<Gtx>;
223+    head<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
224     head<P>(
225       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
226     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
227@@ -881,12 +867,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
228      * Options only
229      */
230     connect(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
231-    connect<P>(
232-      req: { supervisor?: Supervisor },
233-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
234-    connect<P extends never, ApiSuccess, ApiError = unknown>(
235-      req: { supervisor?: Supervisor },
236-    ): CreateAction<
237+    connect<P>(req: {
238+      supervisor?: Supervisor;
239+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
240+    connect<P extends never, ApiSuccess, ApiError = unknown>(req: {
241+      supervisor?: Supervisor;
242+    }): CreateAction<
243       & Omit<Ctx, "json">
244       & FetchJson<
245         ApiSuccess,
246@@ -911,9 +897,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
247      * Middleware only
248      */
249     connect(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
250-    connect<Gtx extends Ctx = Ctx>(
251-      fn: MiddlewareApiCo<Gtx>,
252-    ): CreateAction<Gtx>;
253+    connect<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
254     connect<P>(
255       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
256     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
257@@ -1003,12 +987,12 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
258      * Options only
259      */
260     trace(req: { supervisor?: Supervisor }): CreateAction<Ctx>;
261-    trace<P>(
262-      req: { supervisor?: Supervisor },
263-    ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
264-    trace<P extends never, ApiSuccess, ApiError = unknown>(
265-      req: { supervisor?: Supervisor },
266-    ): CreateAction<
267+    trace<P>(req: {
268+      supervisor?: Supervisor;
269+    }): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
270+    trace<P extends never, ApiSuccess, ApiError = unknown>(req: {
271+      supervisor?: Supervisor;
272+    }): CreateAction<
273       & Omit<Ctx, "json">
274       & FetchJson<
275         ApiSuccess,
276@@ -1033,9 +1017,7 @@ export interface QueryApi<Ctx extends ApiCtx = ApiCtx> extends ThunksApi<Ctx> {
277      * Middleware only
278      */
279     trace(fn: MiddlewareApiCo<Ctx>): CreateAction<Ctx>;
280-    trace<Gtx extends Ctx = Ctx>(
281-      fn: MiddlewareApiCo<Gtx>,
282-    ): CreateAction<Gtx>;
283+    trace<Gtx extends Ctx = Ctx>(fn: MiddlewareApiCo<Gtx>): CreateAction<Gtx>;
284     trace<P>(
285       fn: MiddlewareApiCo<Omit<Ctx, "payload"> & Payload<P>>,
286     ): CreateActionWithPayload<Omit<Ctx, "payload"> & Payload<P>, P>;
M query/thunk.ts
+7, -1
 1@@ -1,6 +1,12 @@
 2 import { ActionContext, API_ACTION_PREFIX, takeEvery } from "../action.ts";
 3 import { compose } from "../compose.ts";
 4-import { Callable, ensure, Ok, Operation, Signal } from "../deps.ts";
 5+import {
 6+  type Callable,
 7+  ensure,
 8+  Ok,
 9+  type Operation,
10+  type Signal,
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";
M query/types.ts
+3, -5
 1@@ -1,4 +1,4 @@
 2-import type { Operation, Result } from "../deps.ts";
 3+import type { Operation, Result } from "effection";
 4 import type {
 5   Action,
 6   ActionWithPayload,
 7@@ -105,10 +105,8 @@ export type CreateActionFn<ApiSuccess = any> = () => ActionWithPayload<
 8   CreateActionPayload<Record<string | number | symbol, never>, ApiSuccess>
 9 >;
10 
11-export interface CreateAction<
12-  Ctx extends ThunkCtx = ThunkCtx,
13-  ApiSuccess = any,
14-> extends CreateActionFn<ApiSuccess> {
15+export interface CreateAction<Ctx extends ThunkCtx = ThunkCtx, ApiSuccess = any>
16+  extends CreateActionFn<ApiSuccess> {
17   run: (
18     p?: ActionWithPayload<
19       CreateActionPayload<Record<string | number | symbol, never>, ApiSuccess>
M queue.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { createQueue } from "./deps.ts";
3+import { createQueue } from "effection";
4 
5 export function createFilterQueue<T, TClose>(predicate: (v: T) => boolean) {
6   const queue = createQueue<T, TClose>();
M react.ts
+22, -24
 1@@ -1,18 +1,18 @@
 2 import {
 3   Provider as ReduxProvider,
 4-  React,
 5   useDispatch,
 6   useSelector,
 7   useStore as useReduxStore,
 8-} from "./deps.ts";
 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 
17-export { useDispatch, useSelector } from "./deps.ts";
18-export type { TypedUseSelectorHook } from "./deps.ts";
19+export { useDispatch, useSelector } from "react-redux";
20+export type { TypedUseSelectorHook } from "react-redux";
21 
22 const {
23   useContext,
24@@ -47,22 +47,19 @@ export interface UseCacheResult<D = any, A extends ThunkAction = ThunkAction>
25 
26 const SchemaContext = createContext<FxSchema<any, any> | null>(null);
27 
28-export function Provider(
29-  { store, schema, children }: {
30-    store: FxStore<any>;
31-    schema: FxSchema<any, any>;
32-    children: React.ReactNode;
33-  },
34-) {
35-  return (
36-    h(ReduxProvider, {
37-      store,
38-      children: h(
39-        SchemaContext.Provider,
40-        { value: schema, children },
41-      ) as any,
42-    })
43-  );
44+export function Provider({
45+  store,
46+  schema,
47+  children,
48+}: {
49+  store: FxStore<any>;
50+  schema: FxSchema<any, any>;
51+  children: React.ReactNode;
52+}) {
53+  return h(ReduxProvider, {
54+    store,
55+    children: h(SchemaContext.Provider, { value: schema, children }) as any,
56+  });
57 }
58 
59 export function useSchema<S extends AnyState>() {
60@@ -254,16 +251,17 @@ export function useLoaderSuccess(
61 
62 interface PersistGateProps {
63   children: React.ReactNode;
64-  loading?: JSX.Element;
65+  loading?: ReactElement;
66 }
67 
68 function Loading({ text }: { text: string }) {
69   return h("div", null, text);
70 }
71 
72-export function PersistGate(
73-  { children, loading = h(Loading) }: PersistGateProps,
74-) {
75+export function PersistGate({
76+  children,
77+  loading = h(Loading),
78+}: PersistGateProps) {
79   const schema = useSchema();
80   const ldr = useSelector((s: any) =>
81     schema.loaders.selectById(s, { id: PERSIST_LOADER_ID })
M scripts/branch-exists.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { call, main, type Operation } from "./deps.ts";
3+import { call, main, type Operation } from "effection";
4 
5 await main(function* (): Operation<void> {
6   // based on env created from ${{ secrets.GITHUB_TOKEN }} in CI
D scripts/deps.ts
+0, -2
1@@ -1,2 +0,0 @@
2-export type { Operation } from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts";
3-export { call, main } from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts";
R npm.ts => scripts/npm.ts
+4, -18
 1@@ -1,4 +1,4 @@
 2-import { build, emptyDir } from "https://deno.land/x/dnt@0.38.1/mod.ts";
 3+import { build, emptyDir } from "jsr:@deno/dnt@0.41.3";
 4 
 5 const [version] = Deno.args;
 6 if (!version) {
 7@@ -23,33 +23,19 @@ async function init() {
 8       },
 9     ],
10     mappings: {
11+      // use the deno module in this repo, but use the npm module when publishing
12       "https://deno.land/x/effection@3.0.0-beta.3/mod.ts": {
13         name: "effection",
14         version: "3.0.0-beta.3",
15       },
16-      "https://esm.sh/react@18.2.0?pin=v135": {
17-        name: "react",
18-        version: "^18.2.0",
19-        peerDependency: true,
20-      },
21-      "https://esm.sh/react-redux@8.0.5?pin=v135": {
22-        name: "react-redux",
23-        version: "^8.0.5",
24-      },
25-      "https://esm.sh/immer@10.0.2?pin=v135": {
26-        name: "immer",
27-        version: "^10.0.2",
28-      },
29-      "https://esm.sh/reselect@4.1.8?pin=v135": {
30-        name: "reselect",
31-        version: "^4.1.8",
32-      },
33     },
34+    importMap: "deno.json",
35     outDir: "./npm",
36     shims: {
37       deno: false,
38     },
39     test: false,
40+
41     typeCheck: "both",
42     compilerOptions: {
43       target: "ES2020",
M scripts/sync.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { call, main, type Operation } from "./deps.ts";
3+import { call, main, type Operation } from "effection";
4 
5 await main(function* (): Operation<void> {
6   const [syncMethod, folderFromArgs] = Deno.args;
M store/batch.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { action } from "../deps.ts";
3+import { action } from "effection";
4 import { UpdaterCtx } from "./types.ts";
5 import { AnyState, Next } from "../types.ts";
6 
M store/context.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { Channel, createChannel, createContext } from "../deps.ts";
3+import { type Channel, createChannel, createContext } from "effection";
4 import type { AnyState } from "../types.ts";
5 import type { FxStore } from "./types.ts";
6 
M store/fx.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { Operation, Result } from "../deps.ts";
3+import { Operation, Result } from "effection";
4 import type { ActionFnWithPayload, AnyState } from "../types.ts";
5 import type { FxStore, StoreUpdater, UpdaterCtx } from "./types.ts";
6 import { StoreContext } from "./context.ts";
M store/mod.ts
+1, -1
1@@ -2,7 +2,7 @@ export * from "./context.ts";
2 export * from "./fx.ts";
3 export * from "./store.ts";
4 export * from "./types.ts";
5-export { createSelector } from "../deps.ts";
6+export { createSelector } from "reselect";
7 export * from "./slice/mod.ts";
8 export * from "./schema.ts";
9 export * from "./batch.ts";
M store/persist.ts
+20, -19
 1@@ -1,8 +1,8 @@
 2-import { Err, Ok, Operation, Result } from "../deps.ts";
 3+import { Err, Ok, Operation, Result } from "effection";
 4 import { select, updateStore } from "./fx.ts";
 5-
 6 import type { AnyState, Next } from "../types.ts";
 7 import type { UpdaterCtx } from "./types.ts";
 8+
 9 export const PERSIST_LOADER_ID = "@@starfx/persist";
10 
11 export interface PersistAdapter<S extends AnyState> {
12@@ -48,9 +48,9 @@ export function createTransform<S extends AnyState>() {
13   };
14 }
15 
16-export function createLocalStorageAdapter<S extends AnyState>(): PersistAdapter<
17-  S
18-> {
19+export function createLocalStorageAdapter<
20+  S extends AnyState,
21+>(): PersistAdapter<S> {
22   return {
23     getItem: function* (key: string) {
24       const storage = localStorage.getItem(key) || "{}";
25@@ -79,17 +79,15 @@ export function shallowReconciler<S extends AnyState>(
26   return { ...original, ...persisted };
27 }
28 
29-export function createPersistor<S extends AnyState>(
30-  {
31-    adapter,
32-    key = "starfx",
33-    reconciler = shallowReconciler,
34-    allowlist = [],
35-    transform,
36-  }:
37-    & Pick<PersistProps<S>, "adapter">
38-    & Partial<PersistProps<S>>,
39-): PersistProps<S> {
40+export function createPersistor<S extends AnyState>({
41+  adapter,
42+  key = "starfx",
43+  reconciler = shallowReconciler,
44+  allowlist = [],
45+  transform,
46+}:
47+  & Pick<PersistProps<S>, "adapter">
48+  & Partial<PersistProps<S>>): PersistProps<S> {
49   function* rehydrate(): Operation<Result<undefined>> {
50     const persistedState = yield* adapter.getItem(key);
51     if (!persistedState.ok) {
52@@ -126,9 +124,12 @@ export function createPersistor<S extends AnyState>(
53   };
54 }
55 
56-export function persistStoreMdw<S extends AnyState>(
57-  { allowlist, adapter, key, transform }: PersistProps<S>,
58-) {
59+export function persistStoreMdw<S extends AnyState>({
60+  allowlist,
61+  adapter,
62+  key,
63+  transform,
64+}: PersistProps<S>) {
65   return function* (_: UpdaterCtx<S>, next: Next) {
66     yield* next();
67     const state = yield* select((s: S) => s);
M store/run.ts
+1, -1
1@@ -1,4 +1,4 @@
2-import { Callable, Operation, Result, Scope, Task } from "../deps.ts";
3+import { Callable, Operation, Result, Scope, Task } from "effection";
4 import { parallel, safe } from "../fx/mod.ts";
5 
6 export function createRun(scope: Scope) {
M store/slice/any.ts
+7, -4
 1@@ -1,5 +1,4 @@
 2 import type { AnyState } from "../../types.ts";
 3-
 4 import type { BaseSchema } from "../types.ts";
 5 
 6 export interface AnyOutput<V, S extends AnyState> extends BaseSchema<V> {
 7@@ -10,9 +9,13 @@ export interface AnyOutput<V, S extends AnyState> extends BaseSchema<V> {
 8   select: (s: S) => V;
 9 }
10 
11-export function createAny<V, S extends AnyState = AnyState>(
12-  { name, initialState }: { name: keyof S; initialState: V },
13-): AnyOutput<V, S> {
14+export function createAny<V, S extends AnyState = AnyState>({
15+  name,
16+  initialState,
17+}: {
18+  name: keyof S;
19+  initialState: V;
20+}): AnyOutput<V, S> {
21   return {
22     schema: "any",
23     name: name as string,
M store/slice/loaders.ts
+9, -11
 1@@ -1,4 +1,4 @@
 2-import { createSelector } from "../../deps.ts";
 3+import { createSelector } from "reselect";
 4 import type {
 5   AnyState,
 6   LoaderItemState,
 7@@ -17,9 +17,9 @@ interface PropIds {
 8 
 9 const excludesFalse = <T>(n?: T): n is T => Boolean(n);
10 
11-export function defaultLoaderItem<
12-  M extends AnyState = AnyState,
13->(li: Partial<LoaderItemState<M>> = {}): LoaderItemState<M> {
14+export function defaultLoaderItem<M extends AnyState = AnyState>(
15+  li: Partial<LoaderItemState<M>> = {},
16+): LoaderItemState<M> {
17   return {
18     id: "",
19     status: "idle",
20@@ -76,10 +76,8 @@ function loaderSelectors<
21     data: Record<string, LoaderItemState<M>>,
22   ): LoaderItemState<M>[] => Object.values(data).filter(excludesFalse);
23 
24-  const findById = (
25-    data: Record<string, LoaderItemState<M>>,
26-    { id }: PropId,
27-  ) => (defaultLoader<M>(data[id]) || empty);
28+  const findById = (data: Record<string, LoaderItemState<M>>, { id }: PropId) =>
29+    defaultLoader<M>(data[id]) || empty;
30   const findByIds = (
31     data: Record<string, LoaderItemState<M>>,
32     { ids }: PropIds,
33@@ -184,8 +182,8 @@ export const createLoaders = <
34   };
35 };
36 
37-export function loaders<
38-  M extends AnyState = AnyState,
39->(initialState?: Record<string, LoaderItemState<M>>) {
40+export function loaders<M extends AnyState = AnyState>(
41+  initialState?: Record<string, LoaderItemState<M>>,
42+) {
43   return (name: string) => createLoaders<M>({ name, initialState });
44 }
M store/slice/num.ts
+7, -4
 1@@ -1,5 +1,4 @@
 2 import type { AnyState } from "../../types.ts";
 3-
 4 import type { BaseSchema } from "../types.ts";
 5 
 6 export interface NumOutput<S extends AnyState> extends BaseSchema<number> {
 7@@ -12,9 +11,13 @@ export interface NumOutput<S extends AnyState> extends BaseSchema<number> {
 8   select: (s: S) => number;
 9 }
10 
11-export function createNum<S extends AnyState = AnyState>(
12-  { name, initialState = 0 }: { name: keyof S; initialState?: number },
13-): NumOutput<S> {
14+export function createNum<S extends AnyState = AnyState>({
15+  name,
16+  initialState = 0,
17+}: {
18+  name: keyof S;
19+  initialState?: number;
20+}): NumOutput<S> {
21   return {
22     name: name as string,
23     schema: "num",
M store/slice/obj.test.ts
+9, -7
 1@@ -1,5 +1,5 @@
 2 import { asserts, describe, it } from "../../test.ts";
 3-import { configureStore, updateStore } from "../../store/mod.ts";
 4+import { configureStore, updateStore } from "../mod.ts";
 5 
 6 import { createObj } from "./obj.ts";
 7 const tests = describe("createObj()");
 8@@ -32,12 +32,14 @@ it(tests, "sets up an obj", async () => {
 9   });
10 
11   await store.run(function* () {
12-    yield* updateStore(slice.set({
13-      username: "bob",
14-      userId: 1,
15-      isadmin: true,
16-      roles: ["admin", "user"],
17-    }));
18+    yield* updateStore(
19+      slice.set({
20+        username: "bob",
21+        userId: 1,
22+        isadmin: true,
23+        roles: ["admin", "user"],
24+      }),
25+    );
26   });
27 
28   asserts.assertEquals(store.getState()["currentUser"], {
M store/slice/obj.ts
+7, -4
 1@@ -1,5 +1,4 @@
 2 import type { AnyState } from "../../types.ts";
 3-
 4 import type { BaseSchema } from "../types.ts";
 5 
 6 export interface ObjOutput<V extends AnyState, S extends AnyState>
 7@@ -12,9 +11,13 @@ export interface ObjOutput<V extends AnyState, S extends AnyState>
 8   select: (s: S) => V;
 9 }
10 
11-export function createObj<V extends AnyState, S extends AnyState = AnyState>(
12-  { name, initialState }: { name: keyof S; initialState: V },
13-): ObjOutput<V, S> {
14+export function createObj<V extends AnyState, S extends AnyState = AnyState>({
15+  name,
16+  initialState,
17+}: {
18+  name: keyof S;
19+  initialState: V;
20+}): ObjOutput<V, S> {
21   return {
22     schema: "obj",
23     name: name as string,
M store/slice/str.ts
+7, -4
 1@@ -1,5 +1,4 @@
 2 import type { AnyState } from "../../types.ts";
 3-
 4 import type { BaseSchema } from "../types.ts";
 5 
 6 export interface StrOutput<S extends AnyState = AnyState>
 7@@ -11,9 +10,13 @@ export interface StrOutput<S extends AnyState = AnyState>
 8   select: (s: S) => string;
 9 }
10 
11-export function createStr<S extends AnyState = AnyState>(
12-  { name, initialState = "" }: { name: keyof S; initialState?: string },
13-): StrOutput<S> {
14+export function createStr<S extends AnyState = AnyState>({
15+  name,
16+  initialState = "",
17+}: {
18+  name: keyof S;
19+  initialState?: string;
20+}): StrOutput<S> {
21   return {
22     schema: "str",
23     name: name as string,
M store/slice/table.ts
+11, -16
 1@@ -1,4 +1,4 @@
 2-import { createSelector } from "../../deps.ts";
 3+import { createSelector } from "reselect";
 4 import type { AnyState, IdProp } from "../../types.ts";
 5 import { BaseSchema } from "../types.ts";
 6 
 7@@ -53,7 +53,7 @@ function tableSelectors<
 8   const selectById = (
 9     state: S,
10     { id }: PropId,
11-  ): typeof empty extends undefined ? (Entity | undefined) : Entity => {
12+  ): typeof empty extends undefined ? Entity | undefined : Entity => {
13     const data = selectTable(state);
14     return findById(data, { id });
15   };
16@@ -92,18 +92,12 @@ export interface TableOutput<
17   patch: (e: PatchEntity<Record<IdProp, Entity>>) => (s: S) => void;
18   merge: (e: PatchEntity<Record<IdProp, Entity>>) => (s: S) => void;
19   reset: () => (s: S) => void;
20-  findById: (
21-    d: Record<IdProp, Entity>,
22-    { id }: PropId,
23-  ) => Empty;
24+  findById: (d: Record<IdProp, Entity>, { id }: PropId) => Empty;
25   findByIds: (d: Record<IdProp, Entity>, { ids }: PropIds) => Entity[];
26   tableAsList: (d: Record<IdProp, Entity>) => Entity[];
27   selectTable: (s: S) => Record<IdProp, Entity>;
28   selectTableAsList: (state: S) => Entity[];
29-  selectById: (
30-    s: S,
31-    p: PropId,
32-  ) => Empty;
33+  selectById: (s: S, p: PropId) => Empty;
34   selectByIds: (s: S, p: PropIds) => Entity[];
35 }
36 
37@@ -207,11 +201,12 @@ export function table<
38 export function table<
39   Entity extends AnyState = AnyState,
40   S extends AnyState = AnyState,
41->(
42-  { initialState, empty }: {
43-    initialState?: Record<IdProp, Entity>;
44-    empty?: Entity | (() => Entity);
45-  } = {},
46-): (n: string) => TableOutput<Entity, S, Entity | undefined> {
47+>({
48+  initialState,
49+  empty,
50+}: {
51+  initialState?: Record<IdProp, Entity>;
52+  empty?: Entity | (() => Entity);
53+} = {}): (n: string) => TableOutput<Entity, S, Entity | undefined> {
54   return (name: string) => createTable<Entity>({ name, empty, initialState });
55 }
M store/store.ts
+9, -14
 1@@ -1,17 +1,9 @@
 2+import { createContext, createScope, createSignal, Ok, Scope } from "effection";
 3+import { enablePatches, produceWithPatches } from "immer";
 4 import { ActionContext, API_ACTION_PREFIX, emit } from "../action.ts";
 5 import { BaseMiddleware, compose } from "../compose.ts";
 6-import {
 7-  createContext,
 8-  createScope,
 9-  createSignal,
10-  enablePatches,
11-  Ok,
12-  produceWithPatches,
13-  Scope,
14-} from "../deps.ts";
15 import { StoreContext, StoreUpdateContext } from "./context.ts";
16 import { createRun } from "./run.ts";
17-
18 import type { AnyAction, AnyState, Next } from "../types.ts";
19 import type { FxStore, Listener, StoreUpdater, UpdaterCtx } from "./types.ts";
20 const stubMsg = "This is merely a stub, not implemented";
21@@ -155,10 +147,13 @@ export function createStore<S extends AnyState>({
22 
23   function* reset(ignoreList: (keyof S)[] = []) {
24     return yield* update((s) => {
25-      const keep = ignoreList.reduce<S>((acc, key) => {
26-        acc[key] = s[key];
27-        return acc;
28-      }, { ...initialState });
29+      const keep = ignoreList.reduce<S>(
30+        (acc, key) => {
31+          acc[key] = s[key];
32+          return acc;
33+        },
34+        { ...initialState },
35+      );
36 
37       Object.keys(s).forEach((key: keyof S) => {
38         s[key] = keep[key];
M store/types.ts
+3, -2
 1@@ -1,8 +1,9 @@
 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 type { Operation, Patch, Scope } from "../deps.ts";
 8 import { BaseCtx } from "../mod.ts";
 9-import type { AnyAction, AnyState } from "../types.ts";
10 import { createRun } from "./run.ts";
11 
12 export type StoreUpdater<S extends AnyState> = (s: S) => S | void;
M supervisor.ts
+3, -9
 1@@ -1,5 +1,5 @@
 2 import { createAction, take } from "./action.ts";
 3-import { call, Callable, Operation, race, sleep, spawn, Task } from "./deps.ts";
 4+import { call, Callable, Operation, race, sleep, spawn, Task } from "effection";
 5 import type { ActionWithPayload, AnyAction } from "./types.ts";
 6 import type { CreateActionPayload } from "./query/mod.ts";
 7 import { getIdFromAction } from "./action.ts";
 8@@ -24,10 +24,7 @@ export function poll(parentTimer: number = 5 * SECONDS, cancelType?: string) {
 9     while (true) {
10       const action = yield* take<{ timer?: number }>(actionType);
11       const timer = action.payload?.timer || parentTimer;
12-      yield* race([
13-        fire(action, timer),
14-        take(`${cancel}`) as Operation<void>,
15-      ]);
16+      yield* race([fire(action, timer), take(`${cancel}`) as Operation<void>]);
17     }
18   };
19 }
20@@ -75,10 +72,7 @@ export function timer(timer: number = 5 * MINUTES) {
21           }
22         });
23       };
24-      yield* race([
25-        sleep(timer),
26-        take(matchFn as any) as Operation<void>,
27-      ]);
28+      yield* race([sleep(timer), take(matchFn as any) as Operation<void>]);
29 
30       delete map[action.payload.key];
31     }
M test.ts
+4, -4
 1@@ -1,13 +1,13 @@
 2-export { assert } from "https://deno.land/std@0.187.0/testing/asserts.ts";
 3 export {
 4   afterAll,
 5   beforeAll,
 6   beforeEach,
 7   describe,
 8   it,
 9-} from "https://deno.land/std@0.163.0/testing/bdd.ts";
10-export * as asserts from "https://deno.land/std@0.185.0/testing/asserts.ts";
11-export { expect } from "https://deno.land/x/expect@v0.3.0/mod.ts";
12+} from "jsr:@std/testing/bdd";
13+export { assert } from "jsr:@std/assert";
14+export * as asserts from "jsr:@std/assert";
15+export { expect } from "jsr:@std/expect";
16 export { install, mock } from "https://deno.land/x/mock_fetch@0.3.0/mod.ts";
17 
18 export function isLikeSelector(selector: unknown) {
M test/api.test.ts
+58, -62
  1@@ -9,7 +9,7 @@ import {
  2 } from "../store/mod.ts";
  3 import {
  4   AnyState,
  5-  type ApiCtx,
  6+  ApiCtx,
  7   call,
  8   createApi,
  9   createKey,
 10@@ -105,10 +105,12 @@ it(tests, "POST", async () => {
 11 
 12   store.dispatch(createUser({ email: mockUser.email }));
 13 
 14-  await store.run(waitFor(function* (): Operation<boolean> {
 15-    const res = yield* select((state: AnyState) => state.users["1"].id);
 16-    return res !== "";
 17-  }));
 18+  await store.run(
 19+    waitFor(function* (): Operation<boolean> {
 20+      const res = yield* select((state: AnyState) => state.users["1"].id);
 21+      return res !== "";
 22+    }),
 23+  );
 24 
 25   expect(store.getState().users).toEqual({
 26     "1": { id: "1", name: "test", email: "test@test.com" },
 27@@ -214,12 +216,16 @@ it(tests, "run() from a normal saga", () => {
 28   const api = createApi();
 29   api.use(api.routes());
 30   let acc = "";
 31-  const action1 = api.get<{ id: string }>("/users/:id", {
 32-    supervisor: takeEvery,
 33-  }, function* (_, next) {
 34-    yield* next();
 35-    acc += "a";
 36-  });
 37+  const action1 = api.get<{ id: string }>(
 38+    "/users/:id",
 39+    {
 40+      supervisor: takeEvery,
 41+    },
 42+    function* (_, next) {
 43+      yield* next();
 44+      acc += "a";
 45+    },
 46+  );
 47   const action2 = () => ({ type: "ACTION" });
 48   function* onAction() {
 49     const ctx = yield* safe(() => action1.run(action1({ id: "1" })));
 50@@ -318,21 +324,15 @@ it(tests, "two identical endpoints", () => {
 51   api.use(mdw.api({ schema }));
 52   api.use(api.routes());
 53 
 54-  const first = api.get(
 55-    "/health",
 56-    function* (ctx, next) {
 57-      actual.push(ctx.req().url);
 58-      yield* next();
 59-    },
 60-  );
 61+  const first = api.get("/health", function* (ctx, next) {
 62+    actual.push(ctx.req().url);
 63+    yield* next();
 64+  });
 65 
 66-  const second = api.get(
 67-    ["/health", "poll"],
 68-    function* (ctx, next) {
 69-      actual.push(ctx.req().url);
 70-      yield* next();
 71-    },
 72-  );
 73+  const second = api.get(["/health", "poll"], function* (ctx, next) {
 74+    actual.push(ctx.req().url);
 75+    yield* next();
 76+  });
 77 
 78   store.run(api.bootup);
 79   store.dispatch(first());
 80@@ -483,45 +483,41 @@ it(tests, "should bubble up error", () => {
 81 });
 82 
 83 // this is strictly for testing types
 84-it(
 85-  tests,
 86-  "useCache - derive api success from endpoint",
 87-  () => {
 88-    const api = createApi<TestCtx>();
 89-    api.use(api.routes());
 90-    api.use(function* (ctx, next) {
 91-      yield* next();
 92-      const data = { result: "wow" };
 93-      ctx.json = { ok: true, value: data };
 94-    });
 95+it(tests, "useCache - derive api success from endpoint", () => {
 96+  const api = createApi<TestCtx>();
 97+  api.use(api.routes());
 98+  api.use(function* (ctx, next) {
 99+    yield* next();
100+    const data = { result: "wow" };
101+    ctx.json = { ok: true, value: data };
102+  });
103 
104-    const acc: string[] = [];
105-    const action1 = api.get<never, { result: string }>(
106-      "/users",
107-      { supervisor: takeEvery },
108-      function* (ctx, next) {
109-        ctx.something = false;
110+  const acc: string[] = [];
111+  const action1 = api.get<never, { result: string }>(
112+    "/users",
113+    { supervisor: takeEvery },
114+    function* (ctx, next) {
115+      ctx.something = false;
116 
117-        yield* next();
118+      yield* next();
119 
120-        if (ctx.json.ok) {
121-          acc.push(ctx.json.value.result);
122-        } else {
123-          // EXPECT { message: string }
124-          ctx.json.error;
125-        }
126-      },
127-    );
128+      if (ctx.json.ok) {
129+        acc.push(ctx.json.value.result);
130+      } else {
131+        // EXPECT { message: string }
132+        ctx.json.error;
133+      }
134+    },
135+  );
136 
137-    const store = createStore({ initialState: { users: {} } });
138-    store.run(api.bootup);
139+  const store = createStore({ initialState: { users: {} } });
140+  store.run(api.bootup);
141 
142-    function _App() {
143-      const act = action1();
144-      act.payload._result;
145-      const users = useCache(act);
146-      // EXPECT { result: string } | undefined
147-      users.data;
148-    }
149-  },
150-);
151+  function _App() {
152+    const act = action1();
153+    act.payload._result;
154+    const users = useCache(act);
155+    // EXPECT { result: string } | undefined
156+    users.data;
157+  }
158+});
M test/create-key.test.ts
+12, -18
 1@@ -23,15 +23,12 @@ it(
 2     const api = createApi();
 3     api.use(api.routes());
 4     // no param
 5-    const action0 = api.get(
 6-      "/users",
 7-      function* (ctx, next) {
 8-        ctx.request = {
 9-          method: "GET",
10-        };
11-        yield* next();
12-      },
13-    );
14+    const action0 = api.get("/users", function* (ctx, next) {
15+      ctx.request = {
16+        method: "GET",
17+      };
18+      yield* next();
19+    });
20     const sendNop0 = action0();
21     const sendNop1 = action0();
22     expect(getKeyOf(sendNop0)).toEqual(getKeyOf(sendNop1));
23@@ -47,15 +44,12 @@ it(
24     // no param
25     const action0 = api.get<{
26       [key: string]: string | boolean | number | null | undefined;
27-    }>(
28-      "/users",
29-      function* (ctx, next) {
30-        ctx.request = {
31-          method: "GET",
32-        };
33-        yield* next();
34-      },
35-    );
36+    }>("/users", function* (ctx, next) {
37+      ctx.request = {
38+        method: "GET",
39+      };
40+      yield* next();
41+    });
42     const sendPojo0 = action0({
43       a: "a",
44       b: "b",
M test/fetch.test.ts
+73, -78
  1@@ -65,13 +65,16 @@ it(
  2 
  3     const state = store.getState();
  4     expect(state.cache[action.payload.key]).toEqual(mockUser);
  5-    expect(actual).toEqual([{
  6-      url: `${baseUrl}/users`,
  7-      method: "GET",
  8-      headers: {
  9-        "Content-Type": "application/json",
 10+    expect(actual).toEqual([
 11+      {
 12+        url: `${baseUrl}/users`,
 13+        method: "GET",
 14+        headers: {
 15+          "Content-Type": "application/json",
 16+        },
 17       },
 18-    }, { ok: true, value: mockUser }]);
 19+      { ok: true, value: mockUser },
 20+    ]);
 21   },
 22 );
 23 
 24@@ -367,92 +370,84 @@ it(tests, "POST multiple endpoints with same uri", async () => {
 25   });
 26 });
 27 
 28-it(
 29-  tests,
 30-  "slug in url but payload has empty string for slug value",
 31-  () => {
 32-    const { store, schema } = testStore();
 33-    const api = createApi();
 34-    api.use(mdw.api({ schema }));
 35-    api.use(api.routes());
 36-    api.use(mdw.fetch({ baseUrl }));
 37-    let actual = "";
 38+it(tests, "slug in url but payload has empty string for slug value", () => {
 39+  const { store, schema } = testStore();
 40+  const api = createApi();
 41+  api.use(mdw.api({ schema }));
 42+  api.use(api.routes());
 43+  api.use(mdw.fetch({ baseUrl }));
 44+  let actual = "";
 45 
 46-    const fetchUsers = api.post<{ id: string }>(
 47-      "/users/:id",
 48-      { supervisor: takeEvery },
 49-      function* (ctx, next) {
 50-        ctx.cache = true;
 51-        ctx.request = ctx.req({ body: JSON.stringify(mockUser) });
 52+  const fetchUsers = api.post<{ id: string }>(
 53+    "/users/:id",
 54+    { supervisor: takeEvery },
 55+    function* (ctx, next) {
 56+      ctx.cache = true;
 57+      ctx.request = ctx.req({ body: JSON.stringify(mockUser) });
 58 
 59-        yield* next();
 60-        if (!ctx.json.ok) {
 61-          actual = ctx.json.error;
 62-        }
 63-      },
 64-    );
 65+      yield* next();
 66+      if (!ctx.json.ok) {
 67+        actual = ctx.json.error;
 68+      }
 69+    },
 70+  );
 71 
 72-    store.run(api.bootup);
 73-    const action = fetchUsers({ id: "" });
 74-    store.dispatch(action);
 75+  store.run(api.bootup);
 76+  const action = fetchUsers({ id: "" });
 77+  store.dispatch(action);
 78 
 79-    const data =
 80-      "found :id in endpoint name (/users/:id [POST]) but payload has falsy value ()";
 81-    expect(actual).toEqual(data);
 82-  },
 83-);
 84+  const data =
 85+    "found :id in endpoint name (/users/:id [POST]) but payload has falsy value ()";
 86+  expect(actual).toEqual(data);
 87+});
 88 
 89-it(
 90-  tests,
 91-  "with success - should keep retrying fetch request",
 92-  async () => {
 93-    let counter = 0;
 94-    mock(`GET@/users`, () => {
 95-      counter += 1;
 96-      if (counter > 4) {
 97-        return new Response(JSON.stringify(mockUser));
 98-      }
 99-      return new Response(JSON.stringify({ message: "error" }), {
100-        status: 400,
101-      });
102+it(tests, "with success - should keep retrying fetch request", async () => {
103+  let counter = 0;
104+  mock(`GET@/users`, () => {
105+    counter += 1;
106+    if (counter > 4) {
107+      return new Response(JSON.stringify(mockUser));
108+    }
109+    return new Response(JSON.stringify({ message: "error" }), {
110+      status: 400,
111     });
112+  });
113 
114-    const { schema, store } = testStore();
115-    const api = createApi();
116-    api.use(mdw.api({ schema }));
117-    api.use(api.routes());
118-    api.use(mdw.fetch({ baseUrl }));
119+  const { schema, store } = testStore();
120+  const api = createApi();
121+  api.use(mdw.api({ schema }));
122+  api.use(api.routes());
123+  api.use(mdw.fetch({ baseUrl }));
124 
125-    let actual = null;
126-    const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
127-      function* (ctx, next) {
128-        ctx.cache = true;
129-        yield* next();
130+  let actual = null;
131+  const fetchUsers = api.get("/users", { supervisor: takeEvery }, [
132+    function* (ctx, next) {
133+      ctx.cache = true;
134+      yield* next();
135 
136-        if (!ctx.json.ok) {
137-          return;
138-        }
139+      if (!ctx.json.ok) {
140+        return;
141+      }
142 
143-        actual = ctx.json;
144-      },
145-      mdw.fetchRetry((n) => (n > 4 ? -1 : 10)),
146-    ]);
147+      actual = ctx.json;
148+    },
149+    mdw.fetchRetry((n) => (n > 4 ? -1 : 10)),
150+  ]);
151 
152-    store.run(api.bootup);
153+  store.run(api.bootup);
154 
155-    const action = fetchUsers();
156-    store.dispatch(action);
157+  const action = fetchUsers();
158+  store.dispatch(action);
159 
160-    const loader = await store.run(waitForLoader(schema.loaders, action));
161-    if (!loader.ok) {
162-      throw loader.error;
163-    }
164+  const loader = await store.run(waitForLoader(schema.loaders, action));
165+  if (!loader.ok) {
166+    throw loader.error;
167+  }
168 
169-    const state = store.getState();
170-    expect(state.cache[action.payload.key]).toEqual(mockUser);
171-    expect(actual).toEqual({ ok: true, value: mockUser });
172-  },
173-);
174+  const state = store.getState();
175+  expect(state.cache[action.payload.key]).toEqual(mockUser);
176+  expect(actual).toEqual({ ok: true, value: mockUser });
177+});
178 
179 it(
180   tests,
M test/mdw.test.ts
+3, -4
 1@@ -98,9 +98,7 @@ it(tests, "basic", () => {
 2   store.run(query.bootup);
 3 
 4   store.dispatch(fetchUsers());
 5-  expect(store.getState().users).toEqual(
 6-    { [mockUser.id]: mockUser },
 7-  );
 8+  expect(store.getState().users).toEqual({ [mockUser.id]: mockUser });
 9   store.dispatch(fetchUser({ id: "2" }));
10   expect(store.getState().users).toEqual({
11     [mockUser.id]: mockUser,
12@@ -498,8 +496,9 @@ it(tests, "errorHandler", () => {
13       yield* next();
14       a = 2;
15     } catch (err) {
16+      const errorMessage = err instanceof Error ? err.message : "Unknown error";
17       console.error(
18-        `Error: ${err.message}.  Check the endpoint [${ctx.name}]`,
19+        `Error: ${errorMessage}.  Check the endpoint [${ctx.name}]`,
20         ctx,
21       );
22     }
M test/persist.test.ts
+82, -152
  1@@ -1,4 +1,4 @@
  2-import { sleep } from "../deps.ts";
  3+import { sleep } from "effection";
  4 import { Ok, Operation, parallel, put, take } from "../mod.ts";
  5 import {
  6   createPersistor,
  7@@ -11,7 +11,7 @@ import {
  8   slice,
  9 } from "../store/mod.ts";
 10 import { asserts, describe, it } from "../test.ts";
 11-import { LoaderItemState } from "../types.ts";
 12+import type { LoaderItemState } from "../types.ts";
 13 
 14 const tests = describe("store");
 15 
 16@@ -57,10 +57,7 @@ it(tests, "can persist to storage adapters", async () => {
 17     yield* group;
 18   });
 19 
 20-  asserts.assertEquals(
 21-    ls,
 22-    '{"token":"1234"}',
 23-  );
 24+  asserts.assertEquals(ls, '{"token":"1234"}');
 25 });
 26 
 27 it(tests, "rehydrates state", async () => {
 28@@ -95,10 +92,7 @@ it(tests, "rehydrates state", async () => {
 29     yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
 30   });
 31 
 32-  asserts.assertEquals(
 33-    store.getState().token,
 34-    "123",
 35-  );
 36+  asserts.assertEquals(store.getState().token, "123");
 37 });
 38 
 39 it(tests, "persists inbound state using transform 'in' function", async () => {
 40@@ -155,79 +149,69 @@ it(tests, "persists inbound state using transform 'in' function", async () => {
 41     ]);
 42     yield* group;
 43   });
 44-  asserts.assertEquals(
 45-    ls,
 46-    '{"token":"4321","cache":{}}',
 47-  );
 48+  asserts.assertEquals(ls, '{"token":"4321","cache":{}}');
 49 });
 50 
 51-it(
 52-  tests,
 53-  "persists inbound state using tranform in (2)",
 54-  async () => {
 55-    const [schema, initialState] = createSchema({
 56-      token: slice.str(),
 57-      loaders: slice.loaders(),
 58-      cache: slice.table({ empty: {} }),
 59-    });
 60-    type State = typeof initialState;
 61-    let ls = "{}";
 62+it(tests, "persists inbound state using tranform in (2)", async () => {
 63+  const [schema, initialState] = createSchema({
 64+    token: slice.str(),
 65+    loaders: slice.loaders(),
 66+    cache: slice.table({ empty: {} }),
 67+  });
 68+  type State = typeof initialState;
 69+  let ls = "{}";
 70 
 71-    const adapter: PersistAdapter<State> = {
 72-      getItem: function* (_: string) {
 73-        return Ok(JSON.parse(ls));
 74-      },
 75-      setItem: function* (_: string, s: Partial<State>) {
 76-        ls = JSON.stringify(s);
 77-        return Ok(undefined);
 78-      },
 79-      removeItem: function* (_: string) {
 80-        return Ok(undefined);
 81-      },
 82-    };
 83+  const adapter: PersistAdapter<State> = {
 84+    getItem: function* (_: string) {
 85+      return Ok(JSON.parse(ls));
 86+    },
 87+    setItem: function* (_: string, s: Partial<State>) {
 88+      ls = JSON.stringify(s);
 89+      return Ok(undefined);
 90+    },
 91+    removeItem: function* (_: string) {
 92+      return Ok(undefined);
 93+    },
 94+  };
 95 
 96-    function revertToken(state: Partial<State>) {
 97-      const res = {
 98-        ...state,
 99-        token: state?.token?.split("").reverse().join(""),
100-      };
101-      return res;
102-    }
103-    const transform = createTransform<State>();
104-    transform.in = revertToken;
105+  function revertToken(state: Partial<State>) {
106+    const res = {
107+      ...state,
108+      token: state?.token?.split("").reverse().join(""),
109+    };
110+    return res;
111+  }
112+  const transform = createTransform<State>();
113+  transform.in = revertToken;
114 
115-    const persistor = createPersistor<State>({
116-      adapter,
117-      allowlist: ["token", "cache"],
118-      transform,
119-    });
120+  const persistor = createPersistor<State>({
121+    adapter,
122+    allowlist: ["token", "cache"],
123+    transform,
124+  });
125 
126-    const mdw = persistStoreMdw(persistor);
127-    const store = createStore({
128-      initialState,
129-      middleware: [mdw],
130-    });
131+  const mdw = persistStoreMdw(persistor);
132+  const store = createStore({
133+    initialState,
134+    middleware: [mdw],
135+  });
136 
137-    await store.run(function* (): Operation<void> {
138-      yield* persistor.rehydrate();
139+  await store.run(function* (): Operation<void> {
140+    yield* persistor.rehydrate();
141 
142-      const group = yield* parallel([
143-        function* (): Operation<void> {
144-          const action = yield* take<string>("SET_TOKEN");
145-          yield* schema.update(schema.token.set(action.payload));
146-        },
147-        function* () {
148-          yield* put({ type: "SET_TOKEN", payload: "1234" });
149-        },
150-      ]);
151-      yield* group;
152-    });
153-    asserts.assertEquals(
154-      ls,
155-      '{"token":"4321","cache":{}}',
156-    );
157-  },
158-);
159+    const group = yield* parallel([
160+      function* (): Operation<void> {
161+        const action = yield* take<string>("SET_TOKEN");
162+        yield* schema.update(schema.token.set(action.payload));
163+      },
164+      function* () {
165+        yield* put({ type: "SET_TOKEN", payload: "1234" });
166+      },
167+    ]);
168+    yield* group;
169+  });
170+  asserts.assertEquals(ls, '{"token":"4321","cache":{}}');
171+});
172 
173 it(tests, "persists a filtered nested part of a slice", async () => {
174   const [schema, initialState] = createSchema({
175@@ -251,9 +235,7 @@ it(tests, "persists a filtered nested part of a slice", async () => {
176     },
177   };
178 
179-  function pickLatestOfLoadersAandC(
180-    state: Partial<State>,
181-  ): Partial<State> {
182+  function pickLatestOfLoadersAandC(state: Partial<State>): Partial<State> {
183     const nextState = { ...state };
184 
185     if (state.loaders) {
186@@ -323,26 +305,11 @@ it(tests, "persists a filtered nested part of a slice", async () => {
187     ]);
188     yield* group;
189   });
190-  asserts.assertStringIncludes(
191-    ls,
192-    '{"token":"1"',
193-  );
194-  asserts.assertStringIncludes(
195-    ls,
196-    '"message":"loading A-second"',
197-  );
198-  asserts.assertStringIncludes(
199-    ls,
200-    '"id":"C"',
201-  );
202-  asserts.assertNotMatch(
203-    ls,
204-    /"message":"loading A-first"/,
205-  );
206-  asserts.assertNotMatch(
207-    ls,
208-    /"id":"B"/,
209-  );
210+  asserts.assertStringIncludes(ls, '{"token":"1"');
211+  asserts.assertStringIncludes(ls, '"message":"loading A-second"');
212+  asserts.assertStringIncludes(ls, '"id":"C"');
213+  asserts.assertNotMatch(ls, /"message":"loading A-first"/);
214+  asserts.assertNotMatch(ls, /"id":"B"/);
215 });
216 
217 it(tests, "handles the empty state correctly", async () => {
218@@ -388,10 +355,7 @@ it(tests, "handles the empty state correctly", async () => {
219     yield* persistor.rehydrate();
220   });
221 
222-  asserts.assertEquals(
223-    ls,
224-    "{}",
225-  );
226+  asserts.assertEquals(ls, "{}");
227 });
228 
229 it(
230@@ -444,10 +408,7 @@ it(
231       yield* group;
232     });
233 
234-    asserts.assertEquals(
235-      ls,
236-      '{"token":"1234"}',
237-    );
238+    asserts.assertEquals(ls, '{"token":"1234"}');
239   },
240 );
241 
242@@ -494,10 +455,7 @@ it(
243       yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
244       yield* schema.update(schema.token.set("1234"));
245     });
246-    asserts.assertEquals(
247-      store.getState().token,
248-      "1234",
249-    );
250+    asserts.assertEquals(store.getState().token, "1234");
251   },
252 );
253 
254@@ -553,10 +511,7 @@ it(
255       yield* schema.update(schema.counter.set(5));
256     });
257 
258-    asserts.assertEquals(
259-      ls,
260-      '{"token":"54321"}',
261-    );
262+    asserts.assertEquals(ls, '{"token":"54321"}');
263   },
264 );
265 
266@@ -610,10 +565,7 @@ it(
267       yield* schema.update(schema.token.set("01234"));
268     });
269 
270-    asserts.assertEquals(
271-      ls,
272-      '{"token":"43210"}',
273-    );
274+    asserts.assertEquals(ls, '{"token":"43210"}');
275 
276     transform.in = function (state) {
277       return {
278@@ -626,10 +578,7 @@ it(
279       yield* schema.update(schema.token.set("01234"));
280     });
281 
282-    asserts.assertEquals(
283-      ls,
284-      '{"token":"0123456789"}',
285-    );
286+    asserts.assertEquals(ls, '{"token":"0123456789"}');
287   },
288 );
289 
290@@ -679,10 +628,7 @@ it(tests, "persists state using transform 'out' function", async () => {
291     yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
292   });
293 
294-  asserts.assertEquals(
295-    store.getState().token,
296-    "43210",
297-  );
298+  asserts.assertEquals(store.getState().token, "43210");
299 });
300 
301 it("persists outbound state using tranform setOutTransformer", async () => {
302@@ -711,9 +657,10 @@ it("persists outbound state using tranform setOutTransformer", async () => {
303   function revertToken(state: Partial<State>) {
304     return {
305       ...state,
306-      token: (["5"].concat(...state?.token?.split("") || [])).reverse().join(
307-        "",
308-      ),
309+      token: ["5"]
310+        .concat(...(state?.token?.split("") || []))
311+        .reverse()
312+        .join(""),
313     };
314   }
315   const transform = createTransform<State>();
316@@ -736,10 +683,7 @@ it("persists outbound state using tranform setOutTransformer", async () => {
317     yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
318   });
319 
320-  asserts.assertEquals(
321-    ls,
322-    '{"token":"012345"}',
323-  );
324+  asserts.assertEquals(ls, '{"token":"012345"}');
325 });
326 
327 it(tests, "persists outbound a filtered nested part of a slice", async () => {
328@@ -765,9 +709,7 @@ it(tests, "persists outbound a filtered nested part of a slice", async () => {
329     },
330   };
331 
332-  function extractMetaAndSetToken(
333-    state: Partial<State>,
334-  ): Partial<State> {
335+  function extractMetaAndSetToken(state: Partial<State>): Partial<State> {
336     const nextState = { ...state };
337     if (state.loaders) {
338       const savedLoader = state.loaders["A"];
339@@ -796,10 +738,7 @@ it(tests, "persists outbound a filtered nested part of a slice", async () => {
340     yield* persistor.rehydrate();
341     yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
342   });
343-  asserts.assertEquals(
344-    store.getState().token,
345-    "01234_FLAG_PERSISTED",
346-  );
347+  asserts.assertEquals(store.getState().token, "01234_FLAG_PERSISTED");
348 });
349 
350 it(tests, "the outbound transformer can be reset during runtime", async () => {
351@@ -854,19 +793,13 @@ it(tests, "the outbound transformer can be reset during runtime", async () => {
352     yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
353   });
354 
355-  asserts.assertEquals(
356-    store.getState().token,
357-    "4321_",
358-  );
359+  asserts.assertEquals(store.getState().token, "4321_");
360 
361   await store.run(function* (): Operation<void> {
362     yield* schema.update(schema.token.set("01234"));
363   });
364 
365-  asserts.assertEquals(
366-    ls,
367-    '{"token":"01234"}',
368-  );
369+  asserts.assertEquals(ls, '{"token":"01234"}');
370 
371   transform.out = postpendToken;
372 
373@@ -875,8 +808,5 @@ it(tests, "the outbound transformer can be reset during runtime", async () => {
374     yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID }));
375   });
376 
377-  asserts.assertEquals(
378-    store.getState().token,
379-    "0123456789",
380-  );
381+  asserts.assertEquals(store.getState().token, "0123456789");
382 });
M test/react.test.ts
+6, -5
 1@@ -1,7 +1,7 @@
 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-import { React } from "../deps.ts";
 7 
 8 const tests = describe("react");
 9 
10@@ -12,9 +12,10 @@ it(tests, () => {
11     loaders: slice.loaders(),
12   });
13   const store = createStore({ initialState });
14-  React.createElement(
15-    Provider,
16-    { schema, store, children: React.createElement("div") },
17-  );
18+  React.createElement(Provider, {
19+    schema,
20+    store,
21+    children: React.createElement("div"),
22+  });
23   asserts.equal(true, true);
24 });
M test/schema.test.ts
+1, -3
 1@@ -104,9 +104,7 @@ it(tests, "can work with a nested object", async () => {
 2     const curUser = yield* select(db.currentUser.select);
 3     asserts.assertEquals(curUser, { id: "", name: "vvv", roles: [] });
 4 
 5-    yield* db.update(
 6-      db.currentUser.update({ key: "roles", value: ["admin"] }),
 7-    );
 8+    yield* db.update(db.currentUser.update({ key: "roles", value: ["admin"] }));
 9     const curUser2 = yield* select(db.currentUser.select);
10     asserts.assertEquals(curUser2, { id: "", name: "vvv", roles: ["admin"] });
11 
M test/take-helper.test.ts
+2, -5
 1@@ -1,8 +1,8 @@
 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 { spawn } from "../deps.ts";
 8 
 9 const testEvery = describe("takeEvery()");
10 const testLatest = describe("takeLatest()");
11@@ -68,10 +68,7 @@ it(testEvery, "should receive all actions", async () => {
12 
13   function* root() {
14     const task = yield* spawn(() =>
15-      takeEvery(
16-        "ACTION",
17-        (action) => worker("a1", "a2", action),
18-      )
19+      takeEvery("ACTION", (action) => worker("a1", "a2", action))
20     );
21     yield* take("CANCEL_WATCHER");
22     yield* task.halt();
M test/thunk.test.ts
+57, -64
  1@@ -161,17 +161,21 @@ it(
  2     api.use(processUsers);
  3     api.use(processTickets);
  4     const fetchUsers = api.create(`/users`, { supervisor: takeEvery });
  5-    const fetchTickets = api.create(`/ticket-wrong-url`, {
  6-      supervisor: takeEvery,
  7-    }, function* (ctx, next) {
  8-      // before middleware has been triggered
  9-      ctx.url = "/tickets";
 10+    const fetchTickets = api.create(
 11+      `/ticket-wrong-url`,
 12+      {
 13+        supervisor: takeEvery,
 14+      },
 15+      function* (ctx, next) {
 16+        // before middleware has been triggered
 17+        ctx.url = "/tickets";
 18 
 19-      // triggers all middleware
 20-      yield* next();
 21+        // triggers all middleware
 22+        yield* next();
 23 
 24-      yield* put(fetchUsers());
 25-    });
 26+        yield* put(fetchUsers());
 27+      },
 28+    );
 29 
 30     const store = createStore<TestState>({
 31       initialState: { users: {}, tickets: {} },
 32@@ -424,22 +428,19 @@ it(tests, "retry with actionFn", async () => {
 33   const api = createThunks();
 34   api.use(api.routes());
 35 
 36-  const action = api.create(
 37-    "/api",
 38-    function* (ctx, next) {
 39-      acc += "a";
 40-      yield* next();
 41-      acc += "g";
 42-      if (acc === "agag") {
 43-        yield* put({ type: "DONE" });
 44-      }
 45+  const action = api.create("/api", function* (ctx, next) {
 46+    acc += "a";
 47+    yield* next();
 48+    acc += "g";
 49+    if (acc === "agag") {
 50+      yield* put({ type: "DONE" });
 51+    }
 52 
 53-      if (!called) {
 54-        called = true;
 55-        yield* put(ctx.actionFn());
 56-      }
 57-    },
 58-  );
 59+    if (!called) {
 60+      called = true;
 61+      yield* put(ctx.actionFn());
 62+    }
 63+  });
 64 
 65   const store = createStore({ initialState: {} });
 66   store.run(api.bootup);
 67@@ -537,24 +538,20 @@ it(tests, "should warn when calling thunk before registered", () => {
 68   console.warn = err;
 69 });
 70 
 71-it(
 72-  tests,
 73-  "it should call the api once even if we register it twice",
 74-  () => {
 75-    const api = createThunks<RoboCtx>();
 76-    api.use(api.routes());
 77-    const store = createStore({ initialState: {} });
 78-    store.run(api.register);
 79-    store.run(api.register);
 80+it(tests, "it should call the api once even if we register it twice", () => {
 81+  const api = createThunks<RoboCtx>();
 82+  api.use(api.routes());
 83+  const store = createStore({ initialState: {} });
 84+  store.run(api.register);
 85+  store.run(api.register);
 86 
 87-    let acc = "";
 88-    const action = api.create("/users", function* () {
 89-      acc += "a";
 90-    });
 91-    store.dispatch(action());
 92-    asserts.assertEquals(acc, "a");
 93-  },
 94-);
 95+  let acc = "";
 96+  const action = api.create("/users", function* () {
 97+    acc += "a";
 98+  });
 99+  store.dispatch(action());
100+  asserts.assertEquals(acc, "a");
101+});
102 
103 it(
104   tests,
105@@ -627,27 +624,23 @@ it(
106   },
107 );
108 
109-it(
110-  tests,
111-  "should allow multiple stores to register a thunk",
112-  () => {
113-    const api1 = createThunks<RoboCtx>();
114-    api1.use(api1.routes());
115-    const storeA = createStore({ initialState: {} });
116-    const storeB = createStore({ initialState: {} });
117-    storeA.run(api1.register);
118-    storeB.run(api1.register);
119-    let acc = "";
120-    const action = api1.create("/users", function* () {
121-      acc += "b";
122-    });
123-    storeA.dispatch(action());
124-    storeB.dispatch(action());
125+it(tests, "should allow multiple stores to register a thunk", () => {
126+  const api1 = createThunks<RoboCtx>();
127+  api1.use(api1.routes());
128+  const storeA = createStore({ initialState: {} });
129+  const storeB = createStore({ initialState: {} });
130+  storeA.run(api1.register);
131+  storeB.run(api1.register);
132+  let acc = "";
133+  const action = api1.create("/users", function* () {
134+    acc += "b";
135+  });
136+  storeA.dispatch(action());
137+  storeB.dispatch(action());
138 
139-    asserts.assertEquals(
140-      acc,
141-      "bb",
142-      "Expected 'bb' after first API call, but got: " + acc,
143-    );
144-  },
145-);
146+  asserts.assertEquals(
147+    acc,
148+    "bb",
149+    "Expected 'bb' after first API call, but got: " + acc,
150+  );
151+});
M types.ts
+3, -4
 1@@ -1,4 +1,4 @@
 2-import type { Instruction, Operation } from "./deps.ts";
 3+import type { Instruction, Operation } from "effection";
 4 
 5 export interface Computation<T = unknown> {
 6   // deno-lint-ignore no-explicit-any
 7@@ -20,9 +20,8 @@ export interface LoaderItemState<
 8   meta: M;
 9 }
10 
11-export interface LoaderState<
12-  M extends AnyState = AnyState,
13-> extends LoaderItemState<M> {
14+export interface LoaderState<M extends AnyState = AnyState>
15+  extends LoaderItemState<M> {
16   isIdle: boolean;
17   isLoading: boolean;
18   isError: boolean;