From ce7d48477a0b5fe89dbf0fa83948ee913cfa44a7 Mon Sep 17 00:00:00 2001 From: Jacob Bolda Date: Sat, 21 Dec 2024 11:28:49 -0600 Subject: [PATCH] refactor: deno v2 and imports --- .github/workflows/docs.yml | 6 +- .github/workflows/release.yml | 6 +- .github/workflows/test-ecosystem.yml | 4 +- .github/workflows/test.yml | 6 +- action.ts | 6 +- api-type-template.ts | 2 +- compose.ts | 2 +- deno.json | 19 +- deno.lock | 424 +++++++++++++++++++-------- deps.ts | 58 ---- docs/static/main.css | 14 +- fx/parallel.ts | 4 +- fx/race.ts | 8 +- fx/request.ts | 2 +- fx/safe.ts | 10 +- fx/supervisor.ts | 10 +- mdw/fetch.ts | 7 +- mdw/query.ts | 14 +- mdw/store.ts | 39 +-- mod.ts | 4 +- query/api-types.ts | 146 ++++----- query/thunk.ts | 8 +- query/types.ts | 8 +- queue.ts | 2 +- react.ts | 46 ++- scripts/branch-exists.ts | 2 +- scripts/deps.ts | 2 - npm.ts => scripts/npm.ts | 22 +- scripts/sync.ts | 2 +- store/batch.ts | 2 +- store/context.ts | 2 +- store/fx.ts | 2 +- store/mod.ts | 2 +- store/persist.ts | 39 +-- store/run.ts | 2 +- store/slice/any.ts | 11 +- store/slice/loaders.ts | 20 +- store/slice/num.ts | 11 +- store/slice/obj.test.ts | 16 +- store/slice/obj.ts | 11 +- store/slice/str.ts | 11 +- store/slice/table.ts | 27 +- store/store.ts | 23 +- store/types.ts | 5 +- supervisor.ts | 12 +- test.ts | 8 +- test/api.test.ts | 120 ++++---- test/create-key.test.ts | 30 +- test/fetch.test.ts | 151 +++++----- test/mdw.test.ts | 7 +- test/persist.test.ts | 234 ++++++--------- test/react.test.ts | 11 +- test/schema.test.ts | 4 +- test/take-helper.test.ts | 7 +- test/thunk.test.ts | 121 ++++---- types.ts | 7 +- 56 files changed, 883 insertions(+), 896 deletions(-) delete mode 100644 deps.ts delete mode 100644 scripts/deps.ts rename npm.ts => scripts/npm.ts (73%) diff --git a/.github/workflows/docs.yml b/.github/workflows/docs.yml index bc87ec83..04965434 100644 --- a/.github/workflows/docs.yml +++ b/.github/workflows/docs.yml @@ -10,13 +10,13 @@ jobs: run: working-directory: ./docs steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 with: # need entire history fetch-depth: 0 - uses: actions/setup-go@v4 with: - go-version: '1.22' + go-version: "1.22" - name: generate site run: | go mod tidy @@ -29,7 +29,7 @@ jobs: with: user: erock key: ${{ secrets.PRIVATE_KEY }} - src: './docs/public/' + src: "./docs/public/" project: "starfx-docs-${{ steps.vars.outputs.sha_short }}" promote: "starfx-prod" retain: "starfx-docs" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index fc990096..7ea33627 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -12,11 +12,9 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: setup deno - uses: denoland/setup-deno@v1 - with: - deno-version: v1.x + uses: denoland/setup-deno@v2 - name: get version id: vars run: echo ::set-output name=version::$(echo ${{github.ref_name}} | sed 's/^v//') diff --git a/.github/workflows/test-ecosystem.yml b/.github/workflows/test-ecosystem.yml index 72c4fb40..e4f7cb1d 100644 --- a/.github/workflows/test-ecosystem.yml +++ b/.github/workflows/test-ecosystem.yml @@ -34,9 +34,7 @@ jobs: path: "starfx" - name: setup deno - uses: denoland/setup-deno@v1 - with: - deno-version: v1.x + uses: denoland/setup-deno@v2 # determines branch and sets it as output available through the `id` - name: dynamically determine ${{ matrix.example.owner }}/${{ matrix.example.repo }} branch diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index c5b3953b..875b88bc 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -14,12 +14,10 @@ jobs: runs-on: ubuntu-latest steps: - name: checkout - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: setup deno - uses: denoland/setup-deno@v1 - with: - deno-version: v1.x + uses: denoland/setup-deno@v2 - name: format run: deno fmt --check diff --git a/action.ts b/action.ts index 52f14503..92862d8b 100644 --- a/action.ts +++ b/action.ts @@ -9,7 +9,7 @@ import { SignalQueueFactory, spawn, Stream, -} from "./deps.ts"; +} from "effection"; import { ActionPattern, matcher } from "./matcher.ts"; import type { Action, ActionWithPayload, AnyAction } from "./types.ts"; import { createFilterQueue } from "./queue.ts"; @@ -105,9 +105,7 @@ export function* takeLeading( } } -export function* waitFor( - predicate: Callable, -) { +export function* waitFor(predicate: Callable) { const init = yield* call(predicate as any); if (init) { return; diff --git a/api-type-template.ts b/api-type-template.ts index acb03f2c..5ebcd611 100644 --- a/api-type-template.ts +++ b/api-type-template.ts @@ -232,7 +232,7 @@ import type { Supervisor, } from "./types.ts"; import type { Next, Payload } from "../types.ts"; -import type { Operation } from "../deps.ts"; +import type { Operation } from "effection"; export type ApiName = string | string[]; diff --git a/compose.ts b/compose.ts index 990b8612..fe40e7cf 100644 --- a/compose.ts +++ b/compose.ts @@ -1,4 +1,4 @@ -import { Instruction, Operation } from "./deps.ts"; +import { Instruction, Operation } from "effection"; import type { Next } from "./types.ts"; export interface BaseCtx { diff --git a/deno.json b/deno.json index 29c1a46b..88f40a8e 100644 --- a/deno.json +++ b/deno.json @@ -1,8 +1,8 @@ { "tasks": { "types": "deno run --allow-write ./api-type-template.ts", - "npm": "deno run -A ./npm.ts", - "test": "deno test --allow-env --allow-read", + "npm": "deno run -A ./scripts/npm.ts", + "test": "deno test --allow-env --allow-read --allow-import", "sync-build-to": "deno run -A ./scripts/sync.ts" }, "lint": { @@ -14,5 +14,20 @@ }, "fmt": { "exclude": ["npm/", "examples/"] + }, + "compilerOptions": { + "strict": true, + "lib": ["deno.window", "dom"], + "jsx": "react", + "jsxFactory": "React.createElement", + "jsxFragmentFactory": "React.Fragment" + }, + "imports": { + "react": "npm:react@^18.2.0", + "react-dom": "npm:react-dom@^18.2.0", + "react-redux": "npm:react-redux@^8.0.5", + "reselect": "npm:reselect@^4.1.8", + "immer": "npm:immer@^10.0.2", + "effection": "https://deno.land/x/effection@3.0.0-beta.3/mod.ts" } } diff --git a/deno.lock b/deno.lock index 426ea446..338e31af 100644 --- a/deno.lock +++ b/deno.lock @@ -1,111 +1,272 @@ { - "version": "3", + "version": "4", + "specifiers": { + "jsr:@david/code-block-writer@^13.0.2": "13.0.3", + "jsr:@deno/cache-dir@~0.10.3": "0.10.3", + "jsr:@deno/dnt@0.41.3": "0.41.3", + "jsr:@std/assert@*": "1.0.10", + "jsr:@std/assert@0.223": "0.223.0", + "jsr:@std/assert@0.226": "0.226.0", + "jsr:@std/assert@^1.0.10": "1.0.10", + "jsr:@std/bytes@0.223": "0.223.0", + "jsr:@std/expect@*": "1.0.10", + "jsr:@std/fmt@0.223": "0.223.0", + "jsr:@std/fmt@1": "1.0.3", + "jsr:@std/fs@0.223": "0.223.0", + "jsr:@std/fs@1": "1.0.8", + "jsr:@std/fs@~0.229.3": "0.229.3", + "jsr:@std/internal@^1.0.5": "1.0.5", + "jsr:@std/io@0.223": "0.223.0", + "jsr:@std/path@0.223": "0.223.0", + "jsr:@std/path@1": "1.0.8", + "jsr:@std/path@1.0.0-rc.1": "1.0.0-rc.1", + "jsr:@std/path@^1.0.8": "1.0.8", + "jsr:@std/path@~0.225.2": "0.225.2", + "jsr:@std/testing@*": "1.0.8", + "jsr:@ts-morph/bootstrap@0.24": "0.24.0", + "jsr:@ts-morph/common@0.24": "0.24.0", + "npm:effection@*": "3.0.3", + "npm:immer@^10.0.2": "10.1.1", + "npm:react-dom@^18.2.0": "18.2.0_react@18.3.1", + "npm:react-redux@^8.0.5": "8.1.3_react@18.3.1_react-dom@18.2.0__react@18.3.1", + "npm:react@^18.2.0": "18.3.1", + "npm:reselect@^4.1.8": "4.1.8" + }, + "jsr": { + "@david/code-block-writer@13.0.3": { + "integrity": "f98c77d320f5957899a61bfb7a9bead7c6d83ad1515daee92dbacc861e13bb7f" + }, + "@deno/cache-dir@0.10.3": { + "integrity": "eb022f84ecc49c91d9d98131c6e6b118ff63a29e343624d058646b9d50404776", + "dependencies": [ + "jsr:@std/fmt@0.223", + "jsr:@std/fs@0.223", + "jsr:@std/io", + "jsr:@std/path@0.223" + ] + }, + "@deno/dnt@0.41.3": { + "integrity": "b2ef2c8a5111eef86cb5bfcae103d6a2938e8e649e2461634a7befb7fc59d6d2", + "dependencies": [ + "jsr:@david/code-block-writer", + "jsr:@deno/cache-dir", + "jsr:@std/fmt@1", + "jsr:@std/fs@1", + "jsr:@std/path@1", + "jsr:@ts-morph/bootstrap" + ] + }, + "@std/assert@0.223.0": { + "integrity": "eb8d6d879d76e1cc431205bd346ed4d88dc051c6366365b1af47034b0670be24" + }, + "@std/assert@0.226.0": { + "integrity": "0dfb5f7c7723c18cec118e080fec76ce15b4c31154b15ad2bd74822603ef75b3" + }, + "@std/assert@1.0.10": { + "integrity": "59b5cbac5bd55459a19045d95cc7c2ff787b4f8527c0dd195078ff6f9481fbb3", + "dependencies": [ + "jsr:@std/internal" + ] + }, + "@std/bytes@0.223.0": { + "integrity": "84b75052cd8680942c397c2631318772b295019098f40aac5c36cead4cba51a8" + }, + "@std/expect@1.0.10": { + "integrity": "7659b640447887cd1735f866962e10e434f12443b13595b149970c806e6f08db", + "dependencies": [ + "jsr:@std/assert@^1.0.10", + "jsr:@std/internal" + ] + }, + "@std/fmt@0.223.0": { + "integrity": "6deb37794127dfc7d7bded2586b9fc6f5d50e62a8134846608baf71ffc1a5208" + }, + "@std/fmt@1.0.3": { + "integrity": "97765c16aa32245ff4e2204ecf7d8562496a3cb8592340a80e7e554e0bb9149f" + }, + "@std/fs@0.223.0": { + "integrity": "3b4b0550b2c524cbaaa5a9170c90e96cbb7354e837ad1bdaf15fc9df1ae9c31c" + }, + "@std/fs@0.229.3": { + "integrity": "783bca21f24da92e04c3893c9e79653227ab016c48e96b3078377ebd5222e6eb", + "dependencies": [ + "jsr:@std/path@1.0.0-rc.1" + ] + }, + "@std/fs@1.0.8": { + "integrity": "161c721b6f9400b8100a851b6f4061431c538b204bb76c501d02c508995cffe0", + "dependencies": [ + "jsr:@std/path@^1.0.8" + ] + }, + "@std/internal@1.0.5": { + "integrity": "54a546004f769c1ac9e025abd15a76b6671ddc9687e2313b67376125650dc7ba" + }, + "@std/io@0.223.0": { + "integrity": "2d8c3c2ab3a515619b90da2c6ff5ea7b75a94383259ef4d02116b228393f84f1", + "dependencies": [ + "jsr:@std/assert@0.223", + "jsr:@std/bytes" + ] + }, + "@std/path@0.223.0": { + "integrity": "593963402d7e6597f5a6e620931661053572c982fc014000459edc1f93cc3989", + "dependencies": [ + "jsr:@std/assert@0.223" + ] + }, + "@std/path@0.225.2": { + "integrity": "0f2db41d36b50ef048dcb0399aac720a5348638dd3cb5bf80685bf2a745aa506", + "dependencies": [ + "jsr:@std/assert@0.226" + ] + }, + "@std/path@1.0.0-rc.1": { + "integrity": "b8c00ae2f19106a6bb7cbf1ab9be52aa70de1605daeb2dbdc4f87a7cbaf10ff6" + }, + "@std/path@1.0.8": { + "integrity": "548fa456bb6a04d3c1a1e7477986b6cffbce95102d0bb447c67c4ee70e0364be" + }, + "@std/testing@1.0.8": { + "integrity": "ceef535808fb7568e91b0f8263599bd29b1c5603ffb0377227f00a8ca9fe42a2", + "dependencies": [ + "jsr:@std/assert@^1.0.10", + "jsr:@std/internal" + ] + }, + "@ts-morph/bootstrap@0.24.0": { + "integrity": "a826a2ef7fa8a7c3f1042df2c034d20744d94da2ee32bf29275bcd4dffd3c060", + "dependencies": [ + "jsr:@ts-morph/common" + ] + }, + "@ts-morph/common@0.24.0": { + "integrity": "12b625b8e562446ba658cdbe9ad77774b4bd96b992ae8bd34c60dbf24d06c1f3", + "dependencies": [ + "jsr:@std/fs@~0.229.3", + "jsr:@std/path@~0.225.2" + ] + } + }, + "npm": { + "@babel/runtime@7.26.0": { + "integrity": "sha512-FDSOghenHTiToteC/QRlv2q3DhPZ/oOXTBoirfWNx1Cx3TMVcGWQtMMmQcSvb/JjpNeGzx8Pq/b4fKEJuWm1sw==", + "dependencies": [ + "regenerator-runtime" + ] + }, + "@types/hoist-non-react-statics@3.3.6": { + "integrity": "sha512-lPByRJUer/iN/xa4qpyL0qmL11DqNW81iU/IG1S3uvRUq4oKagz8VCxZjiWkumgt66YT3vOdDgZ0o32sGKtCEw==", + "dependencies": [ + "@types/react", + "hoist-non-react-statics" + ] + }, + "@types/prop-types@15.7.5": { + "integrity": "sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==" + }, + "@types/react@18.0.32": { + "integrity": "sha512-gYGXdtPQ9Cj0w2Fwqg5/ak6BcK3Z15YgjSqtyDizWUfx7mQ8drs0NBUzRRsAdoFVTO8kJ8L2TL8Skm7OFPnLUw==", + "dependencies": [ + "@types/prop-types", + "@types/scheduler", + "csstype" + ] + }, + "@types/scheduler@0.16.3": { + "integrity": "sha512-5cJ8CB4yAx7BH1oMvdU0Jh9lrEXyPkar6F9G/ERswkCuvP4KQZfZkSjcMbAICCpQTN4OuZn8tz0HiKv9TGZgrQ==" + }, + "@types/use-sync-external-store@0.0.3": { + "integrity": "sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==" + }, + "csstype@3.1.2": { + "integrity": "sha512-I7K1Uu0MBPzaFKg4nI5Q7Vs2t+3gWWW648spaF+Rg7pI9ds18Ugn+lvg4SHczUdKlHI5LWBXyqfS8+DufyBsgQ==" + }, + "effection@3.0.3": { + "integrity": "sha512-9ASCaJ44flDoEKUUJtn9drfIomn2z30sZUw7//crbq+eltMu09AyILcouXwpMkcHR8TsD5hDvTTsOLHswWRxXQ==" + }, + "hoist-non-react-statics@3.3.2": { + "integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==", + "dependencies": [ + "react-is@16.13.1" + ] + }, + "immer@10.1.1": { + "integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==" + }, + "js-tokens@4.0.0": { + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==" + }, + "loose-envify@1.4.0": { + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dependencies": [ + "js-tokens" + ] + }, + "react-dom@18.2.0_react@18.3.1": { + "integrity": "sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==", + "dependencies": [ + "loose-envify", + "react", + "scheduler" + ] + }, + "react-is@16.13.1": { + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" + }, + "react-is@18.3.1": { + "integrity": "sha512-/LLMVyas0ljjAtoYiPqYiL8VWXzUUdThrmU5+n20DZv+a+ClRoevUzw5JxU+Ieh5/c87ytoTBV9G1FiKfNJdmg==" + }, + "react-redux@8.1.3_react@18.3.1_react-dom@18.2.0__react@18.3.1": { + "integrity": "sha512-n0ZrutD7DaX/j9VscF+uTALI3oUPa/pO4Z3soOBIjuRn/FzVu6aehhysxZCLi6y7duMf52WNZGMl7CtuK5EnRw==", + "dependencies": [ + "@babel/runtime", + "@types/hoist-non-react-statics", + "@types/use-sync-external-store", + "hoist-non-react-statics", + "react", + "react-dom", + "react-is@18.3.1", + "use-sync-external-store" + ] + }, + "react@18.3.1": { + "integrity": "sha512-wS+hAgJShR0KhEvPJArfuPVN1+Hz1t0Y6n5jLrGQbkb4urgPE/0Rve+1kMB1v/oWgHgm4WIcV+i7F2pTVj+2iQ==", + "dependencies": [ + "loose-envify" + ] + }, + "regenerator-runtime@0.14.1": { + "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==" + }, + "reselect@4.1.8": { + "integrity": "sha512-ab9EmR80F/zQTMNeneUr4cv+jSwPJgIlvEmVwLerwrWVbpLlBuls9XHzIeTFy4cegU2NHBp3va0LKOzU5qFEYQ==" + }, + "scheduler@0.23.0": { + "integrity": "sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==", + "dependencies": [ + "loose-envify" + ] + }, + "use-sync-external-store@1.4.0_react@18.3.1": { + "integrity": "sha512-9WXSPC5fMv61vaupRkCKCxsPxBocVnwakBEkMIHHpkTTg6icbJtg6jzgtLDm4bl3cSHAca52rYWih0k4K3PfHw==", + "dependencies": [ + "react" + ] + } + }, "redirects": { "https://crux.land/api/get/2KNRVU": "https://crux.land/api/get/2KNRVU.ts", "https://crux.land/api/get/router@0.0.5": "https://crux.land/api/get/2KNRVU", - "https://crux.land/router@0.0.5": "https://crux.land/api/get/router@0.0.5", - "https://esm.sh/v135/@types/react@~18.2/index.d.ts": "https://esm.sh/v135/@types/react@18.2.38/index.d.ts" + "https://crux.land/router@0.0.5": "https://crux.land/api/get/router@0.0.5" }, "remote": { "https://crux.land/api/get/2KNRVU.ts": "6a77d55844aba78d01520c5ff0b2f0af7f24cc1716a0de8b3bb6bd918c47b5ba", - "https://deno.land/std@0.140.0/_util/assert.ts": "e94f2eb37cebd7f199952e242c77654e43333c1ac4c5c700e929ea3aa5489f74", - "https://deno.land/std@0.140.0/_util/os.ts": "3b4c6e27febd119d36a416d7a97bd3b0251b77c88942c8f16ee5953ea13e2e49", - "https://deno.land/std@0.140.0/bytes/bytes_list.ts": "67eb118e0b7891d2f389dad4add35856f4ad5faab46318ff99653456c23b025d", - "https://deno.land/std@0.140.0/bytes/equals.ts": "fc16dff2090cced02497f16483de123dfa91e591029f985029193dfaa9d894c9", - "https://deno.land/std@0.140.0/bytes/mod.ts": "763f97d33051cc3f28af1a688dfe2830841192a9fea0cbaa55f927b49d49d0bf", - "https://deno.land/std@0.140.0/fmt/colors.ts": "30455035d6d728394781c10755351742dd731e3db6771b1843f9b9e490104d37", - "https://deno.land/std@0.140.0/fs/_util.ts": "0fb24eb4bfebc2c194fb1afdb42b9c3dda12e368f43e8f2321f84fc77d42cb0f", - "https://deno.land/std@0.140.0/fs/ensure_dir.ts": "9dc109c27df4098b9fc12d949612ae5c9c7169507660dcf9ad90631833209d9d", - "https://deno.land/std@0.140.0/io/buffer.ts": "bd0c4bf53db4b4be916ca5963e454bddfd3fcd45039041ea161dbf826817822b", - "https://deno.land/std@0.140.0/path/_constants.ts": "df1db3ffa6dd6d1252cc9617e5d72165cd2483df90e93833e13580687b6083c3", - "https://deno.land/std@0.140.0/path/_interface.ts": "ee3b431a336b80cf445441109d089b70d87d5e248f4f90ff906820889ecf8d09", - "https://deno.land/std@0.140.0/path/_util.ts": "c1e9686d0164e29f7d880b2158971d805b6e0efc3110d0b3e24e4b8af2190d2b", - "https://deno.land/std@0.140.0/path/common.ts": "bee563630abd2d97f99d83c96c2fa0cca7cee103e8cb4e7699ec4d5db7bd2633", - "https://deno.land/std@0.140.0/path/glob.ts": "cb5255638de1048973c3e69e420c77dc04f75755524cb3b2e160fe9277d939ee", - "https://deno.land/std@0.140.0/path/mod.ts": "d3e68d0abb393fb0bf94a6d07c46ec31dc755b544b13144dee931d8d5f06a52d", - "https://deno.land/std@0.140.0/path/posix.ts": "293cdaec3ecccec0a9cc2b534302dfe308adb6f10861fa183275d6695faace44", - "https://deno.land/std@0.140.0/path/separator.ts": "fe1816cb765a8068afb3e8f13ad272351c85cbc739af56dacfc7d93d710fe0f9", - "https://deno.land/std@0.140.0/path/win32.ts": "31811536855e19ba37a999cd8d1b62078235548d67902ece4aa6b814596dd757", - "https://deno.land/std@0.140.0/streams/conversion.ts": "712585bfa0172a97fb68dd46e784ae8ad59d11b88079d6a4ab098ff42e697d21", "https://deno.land/std@0.158.0/fmt/colors.ts": "ff7dc9c9f33a72bd48bc24b21bbc1b4545d8494a431f17894dbc5fe92a938fc4", "https://deno.land/std@0.158.0/testing/_diff.ts": "a23e7fc2b4d8daa3e158fa06856bedf5334ce2a2831e8bf9e509717f455adb2c", "https://deno.land/std@0.158.0/testing/_format.ts": "cd11136e1797791045e639e9f0f4640d5b4166148796cad37e6ef75f7d7f3832", "https://deno.land/std@0.158.0/testing/asserts.ts": "8696c488bc98d8d175e74dc652a0ffbc7fca93858da01edc57ed33c1148345da", - "https://deno.land/std@0.163.0/testing/_test_suite.ts": "2d07073d5460a4e3ec50c55ae822cd9bd136926d7363091379947fef9c73c3e4", - "https://deno.land/std@0.163.0/testing/bdd.ts": "35060cefd9cc21b414f4d89453b3551a3d52ec50aeff25db432503c5485b2f72", - "https://deno.land/std@0.181.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", - "https://deno.land/std@0.181.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", - "https://deno.land/std@0.181.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", - "https://deno.land/std@0.181.0/fs/ensure_dir.ts": "dc64c4c75c64721d4e3fb681f1382f803ff3d2868f08563ff923fdd20d071c40", - "https://deno.land/std@0.181.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a", - "https://deno.land/std@0.181.0/fs/walk.ts": "ea95ffa6500c1eda6b365be488c056edc7c883a1db41ef46ec3bf057b1c0fe32", - "https://deno.land/std@0.181.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", - "https://deno.land/std@0.181.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", - "https://deno.land/std@0.181.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", - "https://deno.land/std@0.181.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", - "https://deno.land/std@0.181.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", - "https://deno.land/std@0.181.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c", - "https://deno.land/std@0.181.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", - "https://deno.land/std@0.181.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", - "https://deno.land/std@0.181.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", - "https://deno.land/std@0.182.0/_util/asserts.ts": "178dfc49a464aee693a7e285567b3d0b555dc805ff490505a8aae34f9cfb1462", - "https://deno.land/std@0.182.0/_util/os.ts": "d932f56d41e4f6a6093d56044e29ce637f8dcc43c5a90af43504a889cf1775e3", - "https://deno.land/std@0.182.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", - "https://deno.land/std@0.182.0/fs/_util.ts": "65381f341af1ff7f40198cee15c20f59951ac26e51ddc651c5293e24f9ce6f32", - "https://deno.land/std@0.182.0/fs/empty_dir.ts": "c3d2da4c7352fab1cf144a1ecfef58090769e8af633678e0f3fabaef98594688", - "https://deno.land/std@0.182.0/fs/expand_glob.ts": "e4f56259a0a70fe23f05215b00de3ac5e6ba46646ab2a06ebbe9b010f81c972a", - "https://deno.land/std@0.182.0/fs/walk.ts": "920be35a7376db6c0b5b1caf1486fb962925e38c9825f90367f8f26b5e5d0897", - "https://deno.land/std@0.182.0/path/_constants.ts": "e49961f6f4f48039c0dfed3c3f93e963ca3d92791c9d478ac5b43183413136e0", - "https://deno.land/std@0.182.0/path/_interface.ts": "6471159dfbbc357e03882c2266d21ef9afdb1e4aa771b0545e90db58a0ba314b", - "https://deno.land/std@0.182.0/path/_util.ts": "d7abb1e0dea065f427b89156e28cdeb32b045870acdf865833ba808a73b576d0", - "https://deno.land/std@0.182.0/path/common.ts": "ee7505ab01fd22de3963b64e46cff31f40de34f9f8de1fff6a1bd2fe79380000", - "https://deno.land/std@0.182.0/path/glob.ts": "d479e0a695621c94d3fd7fe7abd4f9499caf32a8de13f25073451c6ef420a4e1", - "https://deno.land/std@0.182.0/path/mod.ts": "bf718f19a4fdd545aee1b06409ca0805bd1b68ecf876605ce632e932fe54510c", - "https://deno.land/std@0.182.0/path/posix.ts": "8b7c67ac338714b30c816079303d0285dd24af6b284f7ad63da5b27372a2c94d", - "https://deno.land/std@0.182.0/path/separator.ts": "0fb679739d0d1d7bf45b68dacfb4ec7563597a902edbaf3c59b50d5bcadd93b1", - "https://deno.land/std@0.182.0/path/win32.ts": "d186344e5583bcbf8b18af416d13d82b35a317116e6460a5a3953508c3de5bba", - "https://deno.land/std@0.185.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", - "https://deno.land/std@0.185.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", - "https://deno.land/std@0.185.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", - "https://deno.land/std@0.185.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", - "https://deno.land/std@0.187.0/fmt/colors.ts": "d67e3cd9f472535241a8e410d33423980bec45047e343577554d3356e1f0ef4e", - "https://deno.land/std@0.187.0/testing/_diff.ts": "1a3c044aedf77647d6cac86b798c6417603361b66b54c53331b312caeb447aea", - "https://deno.land/std@0.187.0/testing/_format.ts": "a69126e8a469009adf4cf2a50af889aca364c349797e63174884a52ff75cf4c7", - "https://deno.land/std@0.187.0/testing/asserts.ts": "e16d98b4d73ffc4ed498d717307a12500ae4f2cbe668f1a215632d19fcffc22f", - "https://deno.land/std@0.97.0/fmt/colors.ts": "db22b314a2ae9430ae7460ce005e0a7130e23ae1c999157e3bb77cf55800f7e4", - "https://deno.land/std@0.97.0/testing/_diff.ts": "961eaf6d9f5b0a8556c9d835bbc6fa74f5addd7d3b02728ba7936ff93364f7a3", - "https://deno.land/std@0.97.0/testing/asserts.ts": "341292d12eebc44be4c3c2ca101ba8b6b5859cef2fa69d50c217f9d0bfbcfd1f", - "https://deno.land/x/code_block_writer@12.0.0/mod.ts": "2c3448060e47c9d08604c8f40dee34343f553f33edcdfebbf648442be33205e5", - "https://deno.land/x/code_block_writer@12.0.0/utils/string_utils.ts": "60cb4ec8bd335bf241ef785ccec51e809d576ff8e8d29da43d2273b69ce2a6ff", "https://deno.land/x/continuation@0.1.5/mod.ts": "690def2735046367b3e1b4bc6e51b5912f2ed09c41c7df7a55c060f23720ad33", - "https://deno.land/x/deno_cache@0.5.2/auth_tokens.ts": "5d1d56474c54a9d152e44d43ea17c2e6a398dd1e9682c69811a313567c01ee1e", - "https://deno.land/x/deno_cache@0.5.2/cache.ts": "92ce8511e1e5c00fdf53a41619aa77d632ea8e0fc711324322e4d5ebf8133911", - "https://deno.land/x/deno_cache@0.5.2/deno_dir.ts": "1ea355b8ba11c630d076b222b197cfc937dd81e5a4a260938997da99e8ff93a0", - "https://deno.land/x/deno_cache@0.5.2/deps.ts": "26a75905652510b76e54b6d5ef3cf824d1062031e00782efcd768978419224e7", - "https://deno.land/x/deno_cache@0.5.2/dirs.ts": "009c6f54e0b610914d6ce9f72f6f6ccfffd2d47a79a19061e0a9eb4253836069", - "https://deno.land/x/deno_cache@0.5.2/disk_cache.ts": "66a1e604a8d564b6dd0500326cac33d08b561d331036bf7272def80f2f7952aa", - "https://deno.land/x/deno_cache@0.5.2/file_fetcher.ts": "89616c50b6df73fb04e73d0b7cd99e5f2ed7967386913d65b9e8baa4238501f7", - "https://deno.land/x/deno_cache@0.5.2/http_cache.ts": "407135eaf2802809ed373c230d57da7ef8dff923c4abf205410b9b99886491fd", - "https://deno.land/x/deno_cache@0.5.2/lib/deno_cache_dir.generated.js": "18b6526d0c50791a73dd0eb894e99de1ac05ee79dcbd53298ff5b5b6b0757fe6", - "https://deno.land/x/deno_cache@0.5.2/lib/snippets/deno_cache_dir-77bed54ace8005e0/fs.js": "cbe3a976ed63c72c7cb34ef845c27013033a3b11f9d8d3e2c4aa5dda2c0c7af6", - "https://deno.land/x/deno_cache@0.5.2/mod.ts": "0b4d071ad095128bdc2b1bc6e5d2095222dcbae08287261690ee9757e6300db6", - "https://deno.land/x/deno_cache@0.5.2/util.ts": "f3f5a0cfc60051f09162942fb0ee87a0e27b11a12aec4c22076e3006be4cc1e2", - "https://deno.land/x/dir@1.5.1/data_local_dir/mod.ts": "91eb1c4bfadfbeda30171007bac6d85aadacd43224a5ed721bbe56bc64e9eb66", - "https://deno.land/x/dnt@0.38.1/lib/compiler.ts": "209ad2e1b294f93f87ec02ade9a0821f942d2e524104552d0aa8ff87021050a5", - "https://deno.land/x/dnt@0.38.1/lib/compiler_transforms.ts": "f21aba052f5dcf0b0595c734450842855c7f572e96165d3d34f8fed2fc1f7ba1", - "https://deno.land/x/dnt@0.38.1/lib/mod.deps.ts": "30367fc68bcd2acf3b7020cf5cdd26f817f7ac9ac35c4bfb6c4551475f91bc3e", - "https://deno.land/x/dnt@0.38.1/lib/npm_ignore.ts": "57fbb7e7b935417d225eec586c6aa240288905eb095847d3f6a88e290209df4e", - "https://deno.land/x/dnt@0.38.1/lib/package_json.ts": "61f35b06e374ed39ca776d29d67df4be7ee809d0bca29a8239687556c6d027c2", - "https://deno.land/x/dnt@0.38.1/lib/pkg/dnt_wasm.generated.js": "cfb352ae839865f5698c9b35099d4c783510195a1e3c9f9b04d94fac86394ed9", - "https://deno.land/x/dnt@0.38.1/lib/pkg/snippets/dnt-wasm-a15ef721fa5290c5/helpers.js": "45f74f00472b3a399bc16e5dc056966b55dcdd8fa2bd61505c6dfd2f5d33b9f4", - "https://deno.land/x/dnt@0.38.1/lib/shims.ts": "df1bd4d9a196dca4b2d512b1564fff64ac6c945189a273d706391f87f210d7e6", - "https://deno.land/x/dnt@0.38.1/lib/test_runner/get_test_runner_code.ts": "4dc7a73a13b027341c0688df2b29a4ef102f287c126f134c33f69f0339b46968", - "https://deno.land/x/dnt@0.38.1/lib/test_runner/test_runner.ts": "4d0da0500ec427d5f390d9a8d42fb882fbeccc92c92d66b6f2e758606dbd40e6", - "https://deno.land/x/dnt@0.38.1/lib/transform.deps.ts": "e42f2bdef46d098453bdba19261a67cf90b583f5d868f7fe83113c1380d9b85c", - "https://deno.land/x/dnt@0.38.1/lib/types.ts": "b8e228b2fac44c2ae902fbb73b1689f6ab889915bd66486c8a85c0c24255f5fb", - "https://deno.land/x/dnt@0.38.1/lib/utils.ts": "878b7ac7003a10c16e6061aa49dbef9b42bd43174853ebffc9b67ea47eeb11d8", - "https://deno.land/x/dnt@0.38.1/mod.ts": "b13349fe77847cf58e26b40bcd58797a8cec5d71b31a1ca567071329c8489de1", - "https://deno.land/x/dnt@0.38.1/transform.ts": "f68743a14cf9bf53bfc9c81073871d69d447a7f9e3453e0447ca2fb78926bb1d", "https://deno.land/x/effection@3.0.0-beta.3/lib/abort-signal.ts": "8be1b331b2bc417d70fe4c07e0b806e89972b8eab519ce58beed7ec632ae9048", "https://deno.land/x/effection@3.0.0-beta.3/lib/all.ts": "acadab8258228e290192f587c8c532428f9093337a9b7688ae55cbc2cacd5caf", "https://deno.land/x/effection@3.0.0-beta.3/lib/async.ts": "086b27b253be944c47c633d105f1657e243cd8c0d35b9a0dc5383528d7235dde", @@ -141,35 +302,46 @@ "https://deno.land/x/effection@3.0.0-beta.3/lib/sleep.ts": "44e3a80248dad7a47066a99a7daec9b318e87d5d211adf27776145544d455689", "https://deno.land/x/effection@3.0.0-beta.3/lib/types.ts": "9738143fe6bfd5709a6ff10b6dd065582cfaca1167bf57902cb7bcca89b53dc4", "https://deno.land/x/effection@3.0.0-beta.3/mod.ts": "ffae461c16d4a1bf24c2179582ab8d5c81ad0df61e4ae2fba51ef5e5bdf90345", - "https://deno.land/x/expect@v0.3.0/expect.ts": "5e6717eddc9df376f7b2c9be6403e016130bb2edbb1acd261a2d6ea9608ee196", - "https://deno.land/x/expect@v0.3.0/matchers.ts": "a37ef4577739247af77a852cdcd69484f999a41ad86ec16bb63a88a7a47a2372", - "https://deno.land/x/expect@v0.3.0/mock.ts": "562d4b1d735d15b0b8e935f342679096b64fe452f86e96714fe8616c0c884914", - "https://deno.land/x/expect@v0.3.0/mod.ts": "0304d2430e1e96ba669a8495e24ba606dcc3d152e1f81aaa8da898cea24e36c2", - "https://deno.land/x/mock_fetch@0.3.0/mod.ts": "7e7806c65ab17b2b684c334c4e565812bdaf504a3e9c938d2bb52bb67428bc89", - "https://deno.land/x/ts_morph@18.0.0/bootstrap/mod.ts": "b53aad517f106c4079971fcd4a81ab79fadc40b50061a3ab2b741a09119d51e9", - "https://deno.land/x/ts_morph@18.0.0/bootstrap/ts_morph_bootstrap.js": "6645ac03c5e6687dfa8c78109dc5df0250b811ecb3aea2d97c504c35e8401c06", - "https://deno.land/x/ts_morph@18.0.0/common/DenoRuntime.ts": "6a7180f0c6e90dcf23ccffc86aa8271c20b1c4f34c570588d08a45880b7e172d", - "https://deno.land/x/ts_morph@18.0.0/common/mod.ts": "01985d2ee7da8d1caee318a9d07664774fbee4e31602bc2bb6bb62c3489555ed", - "https://deno.land/x/ts_morph@18.0.0/common/ts_morph_common.js": "845671ca951073400ce142f8acefa2d39ea9a51e29ca80928642f3f8cf2b7700", - "https://deno.land/x/ts_morph@18.0.0/common/typescript.js": "d5c598b6a2db2202d0428fca5fd79fc9a301a71880831a805d778797d2413c59", - "https://deno.land/x/wasmbuild@0.15.0/cache.ts": "89eea5f3ce6035a1164b3e655c95f21300498920575ade23161421f5b01967f4", - "https://deno.land/x/wasmbuild@0.15.0/loader.ts": "d98d195a715f823151cbc8baa3f32127337628379a02d9eb2a3c5902dbccfc02", - "https://esm.sh/immer@10.0.2?pin=v135": "c9a37633ebd7643f9618f0e3263ca12dc16eecb898feb579f94cc81c4a367c20", - "https://esm.sh/react-redux@8.0.5?pin=v135": "c5a1b9dcf3c39bb53bdd3efadb7541b91830b736165c4ed6f5edb08b982fff9f", - "https://esm.sh/react@18.2.0?pin=v135": "04ad7dc6d11fa27b24c136686a334ecdd19e972fae627cd98cbdc13cdac238c2", - "https://esm.sh/reselect@4.1.8?pin=v135": "a88008b1d6ad1c4e4023172edebfe699cf9e8e0716132a48bb9f24617d478f4d", - "https://esm.sh/stable/react@18.2.0/denonext/react.mjs": "3c4f23bcfc53b256fcfaf6f834fa9f584c3bb7be667b2682c6cb6ba8ef88f8e6", - "https://esm.sh/v135/@babel/runtime@7.24.4/denonext/helpers/esm/extends.js": "6945975ff02714e9d9e48cc7b2b84215c7f0bcf77b407c7499e497b20d2d7f6b", - "https://esm.sh/v135/@babel/runtime@7.24.4/denonext/helpers/esm/objectWithoutPropertiesLoose.js": "476b0a7a26e15b0defbc5505ae3f4c7ef4a52e350eb861e090c4ea00f4a80670", - "https://esm.sh/v135/hoist-non-react-statics@3.3.2/denonext/hoist-non-react-statics.mjs": "1e1b0fbe9a9537eb408d6e7017e668b1381814eb9592a1dd18c39ee09a6d9fbb", - "https://esm.sh/v135/immer@10.0.2/denonext/immer.mjs": "e23064a10c38638e3fa18f56a8864b32a41551e0c4dd32b18008431c57629e88", - "https://esm.sh/v135/react-dom@18.2.0/denonext/react-dom.mjs": "8191fc377ea7083cca5640699c4abd75de033089eb932799e29aa04bb136838f", - "https://esm.sh/v135/react-is@16.13.1/denonext/react-is.mjs": "4fc2bb5cfecb53c0f28cd7b730101ff83c05ca06fdd373bc2d6a9bdf662f96d4", - "https://esm.sh/v135/react-is@18.2.0/denonext/react-is.mjs": "07ca6a7473ccbb06466e805c8253ade80bd664a0f486cf020864c22c27a60479", - "https://esm.sh/v135/react-redux@8.0.5/denonext/react-redux.mjs": "aad652363f5339e3814db446148deb093aadf80d57f8dc8d10d4c43b066b258c", - "https://esm.sh/v135/reselect@4.1.8/denonext/reselect.mjs": "f8199f9e44453876a9ea6b5d1caedc0fe1ae789a73217543b1e6193e1edc0db7", - "https://esm.sh/v135/scheduler@0.23.0/denonext/scheduler.mjs": "cdbc6d2823e2c6fffcb14501146ff2602a38c48d3c9dd9268f308e833ede2b49", - "https://esm.sh/v135/use-sync-external-store@1.2.0/denonext/shim.js": "ee51a93766077d32104ee8090cafb05c1bd2e23e256f3516368f8e9a8516f177", - "https://esm.sh/v135/use-sync-external-store@1.2.0/denonext/shim/with-selector.js": "6aaca98d5bc53815f1c14fb8d096f13d41ecf99d91923fa831bc19a880ba929d" + "https://deno.land/x/effection@3.0.3/lib/abort-signal.ts": "b404e2c4250edb6df67f757cf190c87915fd4edbd3200c47b11db762a4cc10cc", + "https://deno.land/x/effection@3.0.3/lib/all.ts": "e45b9701998212b8a97949b1a6f0defb71ce90e56eb57d5afb365e3bba2e3791", + "https://deno.land/x/effection@3.0.3/lib/async.ts": "ac4bed095e849584a6170ac9a47c9217c2e1e99543275cbc9407d92851120ada", + "https://deno.land/x/effection@3.0.3/lib/call.ts": "096705dfd01fa19b6ae01fe3e362c919308a011e6d4647029cdb31dac80eadb2", + "https://deno.land/x/effection@3.0.3/lib/channel.ts": "445b29c5cfc0b6bc48b1a7ea81e09d14c452ee4646c49c7753c8e5b34962ad50", + "https://deno.land/x/effection@3.0.3/lib/context.ts": "108989ac839d6756e30f6c0afc458bfa3975dd0f970d5173b6b8f8473ce4c335", + "https://deno.land/x/effection@3.0.3/lib/deps.ts": "91062b4b97089a8cf36550d4f9605d325a0fd19bebc72d15524481a3b56ea669", + "https://deno.land/x/effection@3.0.3/lib/each.ts": "0a32eaa8b54966a913c843714e669c1f1e8933a3570d54797cc20ee2c4b5de41", + "https://deno.land/x/effection@3.0.3/lib/ensure.ts": "8043d8e6e67ad27382cba05b3c8b886cf46436871831171b8a8eea66609a6313", + "https://deno.land/x/effection@3.0.3/lib/events.ts": "bdaf6c87c368aebff1e4287a9917ae0b6ba880c4008ecf0abf6b5af922233c62", + "https://deno.land/x/effection@3.0.3/lib/instructions.ts": "3e5316bb7f32a70f93b853673dd1192cdfa11a04037e630d07ddf8fd5eba5d08", + "https://deno.land/x/effection@3.0.3/lib/lazy.ts": "92ea526c5ad7d88290f2a87168e038d482f97421379508d85cf2e049ee60639b", + "https://deno.land/x/effection@3.0.3/lib/lift.ts": "06fafd92f3a8e87c34e9bb9d9dacbb0333b5213c9c65c7245b2cab2cf3cf99e9", + "https://deno.land/x/effection@3.0.3/lib/main.ts": "5f4793fe6d82dcbf991d3306334b784c2b2617f618295e8c368f3fe714e66c01", + "https://deno.land/x/effection@3.0.3/lib/mod.ts": "bbbffe1265d9848812feefa7b20307c448bd4ce1d4c6232d2312f3722dca0fa7", + "https://deno.land/x/effection@3.0.3/lib/pause.ts": "a690b0d67cf970c34f528df8c61d69eb43deda9817362776f6359f506dc0da45", + "https://deno.land/x/effection@3.0.3/lib/queue.ts": "80c6234cb6eaba9fd1abdae077e73f51897b099ea54f852b9a744e8eba51302f", + "https://deno.land/x/effection@3.0.3/lib/race.ts": "ab652679ee00fd3f4ca5156628bf3af7aea55b2e20bb6387693075f7ea27d5ca", + "https://deno.land/x/effection@3.0.3/lib/result.ts": "44e4bdadad155beb9bbfe41948819bbcb9e27a772283e52e89981bd6636a8687", + "https://deno.land/x/effection@3.0.3/lib/run.ts": "55070ed92c5881e86b9724f519986058286ef54b6c12adf82847023631ebcfd3", + "https://deno.land/x/effection@3.0.3/lib/run/create.ts": "be9139af2fbe15908256d2d159dec8dca079f94cf02d488074c94fa26fc651fa", + "https://deno.land/x/effection@3.0.3/lib/run/frame.ts": "132fdace9c00e6ad0e249d7faab1c33680336c5fa8e4a893f092ecec4e2df786", + "https://deno.land/x/effection@3.0.3/lib/run/scope.ts": "a968455e313ba9aa097ee5c18b4db0d8e2397b90c78e413fa08396baead7b74a", + "https://deno.land/x/effection@3.0.3/lib/run/task.ts": "7084b9cabdc338c776dc522ec8b677fb3ac41aa0c94e454d467731494cb68737", + "https://deno.land/x/effection@3.0.3/lib/run/types.ts": "010bea700f68fef99dd87ca5ca3cbbc90e026ac467889d8429d39cba0ee55fda", + "https://deno.land/x/effection@3.0.3/lib/run/value.ts": "d57428b45dfeecc9df1e68dadf8697dbc33cd412e6ffcab9d0ba4368e8c1fbd6", + "https://deno.land/x/effection@3.0.3/lib/shift-sync.ts": "74ecefa9cb2e145a3c52f363319f8d6296b804600852044b7d14bd53bc10b512", + "https://deno.land/x/effection@3.0.3/lib/signal.ts": "6aba1f372419e1540bd29a9ff992ffd2500e035b2e455d2c11d856a052f698d1", + "https://deno.land/x/effection@3.0.3/lib/sleep.ts": "ff8ba6a0266f2e8837a9ae5f63402f8db51a39ce573abf1335109bef772d6b4a", + "https://deno.land/x/effection@3.0.3/lib/types.ts": "06b435b6152b17ef7959a37e1901109b3c716e14ee5e0ae942314439f63bb630", + "https://deno.land/x/effection@3.0.3/mod.ts": "ffae461c16d4a1bf24c2179582ab8d5c81ad0df61e4ae2fba51ef5e5bdf90345", + "https://deno.land/x/mock_fetch@0.3.0/mod.ts": "7e7806c65ab17b2b684c334c4e565812bdaf504a3e9c938d2bb52bb67428bc89" + }, + "workspace": { + "dependencies": [ + "npm:immer@^10.0.2", + "npm:react-dom@^18.2.0", + "npm:react-redux@^8.0.5", + "npm:react@^18.2.0", + "npm:reselect@^4.1.8" + ] } } diff --git a/deps.ts b/deps.ts deleted file mode 100644 index 34169cd5..00000000 --- a/deps.ts +++ /dev/null @@ -1,58 +0,0 @@ -export type { - Callable, - Channel, - Instruction, - Operation, - Predicate, - Queue, - Reject, - Resolve, - Result, - Scope, - Signal, - Stream, - Subscription, - Task, -} from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts"; -export { - action, - call, - createChannel, - createContext, - createQueue, - createScope, - createSignal, - each, - ensure, - Err, - Ok, - race, - resource, - run, - SignalQueueFactory, - sleep, - spawn, - suspend, - useAbortSignal, - useScope, -} from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts"; - -import React from "https://esm.sh/react@18.2.0?pin=v135"; -export { React }; -export { - Provider, - useDispatch, - useSelector, - useStore, -} from "https://esm.sh/react-redux@8.0.5?pin=v135"; -export type { - TypedUseSelectorHook, -} from "https://esm.sh/react-redux@8.0.5?pin=v135"; -export { createSelector } from "https://esm.sh/reselect@4.1.8?pin=v135"; - -export { - enablePatches, - produce, - produceWithPatches, -} from "https://esm.sh/immer@10.0.2?pin=v135"; -export type { Patch } from "https://esm.sh/immer@10.0.2?pin=v135"; diff --git a/docs/static/main.css b/docs/static/main.css index ec1150ed..a46eef0c 100644 --- a/docs/static/main.css +++ b/docs/static/main.css @@ -1,8 +1,14 @@ @media (prefers-color-scheme: light) { - .logo { stroke: #414558; fill: none; } + .logo { + stroke: #414558; + fill: none; + } } @media (prefers-color-scheme: dark) { - .logo { stroke: #f2f2f2; fill: none; } + .logo { + stroke: #f2f2f2; + fill: none; + } } .logo-sm svg { @@ -36,12 +42,12 @@ margin: 0; overflow-y: scroll; padding-bottom: 2rem !important; - height: calc(100vh - 3px - (3 * var(--line-height))); + height: calc(100vh - 3px - 3 * var(--line-height)); } .post { max-width: 650px; - height: calc(100vh - 3px - (3 * var(--line-height))); + height: calc(100vh - 3px - 3 * var(--line-height)); overflow-y: auto; padding-right: 20px; } diff --git a/fx/parallel.ts b/fx/parallel.ts index d6de505b..bc548c35 100644 --- a/fx/parallel.ts +++ b/fx/parallel.ts @@ -1,6 +1,6 @@ -import type { Callable, Channel, Operation, Result } from "../deps.ts"; +import type { Callable, Channel, Operation, Result } from "effection"; +import { createChannel, resource, spawn } from "effection"; import type { Computation } from "../types.ts"; -import { createChannel, resource, spawn } from "../deps.ts"; import { safe } from "./safe.ts"; export interface ParallelRet extends Computation[]> { diff --git a/fx/race.ts b/fx/race.ts index 2c68c662..e898b8a4 100644 --- a/fx/race.ts +++ b/fx/race.ts @@ -1,13 +1,11 @@ -import type { Callable, Operation, Task } from "../deps.ts"; -import { action, call, resource, spawn } from "../deps.ts"; +import type { Callable, Operation, Task } from "effection"; +import { action, call, resource, spawn } from "effection"; interface OpMap { [key: string]: Callable; } -export function raceMap( - opMap: OpMap, -): Operation< +export function raceMap(opMap: OpMap): Operation< { [K in keyof OpMap]: OpMap[K] extends (...args: any[]) => any ? ReturnType diff --git a/fx/request.ts b/fx/request.ts index 32218ff1..0483922c 100644 --- a/fx/request.ts +++ b/fx/request.ts @@ -1,4 +1,4 @@ -import { call, useAbortSignal } from "../deps.ts"; +import { call, useAbortSignal } from "effection"; export function* request(url: string | URL | Request, opts?: RequestInit) { const signal = yield* useAbortSignal(); diff --git a/fx/safe.ts b/fx/safe.ts index fe2160ab..72a67d97 100644 --- a/fx/safe.ts +++ b/fx/safe.ts @@ -1,5 +1,5 @@ -import type { Callable, Operation, Result } from "../deps.ts"; -import { call, Err, Ok } from "../deps.ts"; +import type { Callable, Operation, Result } from "effection"; +import { call, Err, Ok } from "effection"; /** * The goal of `safe` is to wrap Operations to prevent them from raising @@ -19,11 +19,15 @@ import { call, Err, Ok } from "../deps.ts"; * } * ``` */ +function isError(error: unknown): error is Error { + return error instanceof Error; +} + export function* safe(operator: Callable): Operation> { try { const value = yield* call(operator as any); return Ok(value); } catch (error) { - return Err(error); + return Err(isError(error) ? error : new Error(String(error))); } } diff --git a/fx/supervisor.ts b/fx/supervisor.ts index 6e9b9fe4..5dbef3a6 100644 --- a/fx/supervisor.ts +++ b/fx/supervisor.ts @@ -1,8 +1,8 @@ -import { Callable, Operation, Result, sleep } from "../deps.ts"; +import { type Callable, type Operation, sleep } from "effection"; import { safe } from "./safe.ts"; import { parallel } from "./parallel.ts"; -import { put } from "../action.ts"; -import { API_ACTION_PREFIX } from "../action.ts"; +import { API_ACTION_PREFIX, put } from "../action.ts"; +import type { Result } from "effection"; // Adjust the import path as needed export function superviseBackoff(attempt: number, max = 10): number { if (attempt > max) return -1; @@ -54,9 +54,7 @@ export function* keepAlive( ops: Callable[], backoff?: (attempt: number) => number, ): Operation[]> { - const group = yield* parallel( - ops.map((op) => supervise(op, backoff)), - ); + const group = yield* parallel(ops.map((op) => supervise(op, backoff))); const results = yield* group; return results; } diff --git a/mdw/fetch.ts b/mdw/fetch.ts index 466900f5..8de9be22 100644 --- a/mdw/fetch.ts +++ b/mdw/fetch.ts @@ -1,4 +1,4 @@ -import { sleep } from "../deps.ts"; +import { sleep } from "effection"; import { safe } from "../fx/mod.ts"; import type { FetchCtx, FetchJsonCtx } from "../query/mod.ts"; import { isObject, noop } from "../query/util.ts"; @@ -202,10 +202,7 @@ export function* payload( export function response( response?: Response, ) { - return function* responseMdw( - ctx: CurCtx, - next: Next, - ) { + return function* responseMdw(ctx: CurCtx, next: Next) { if (response) { ctx.response = response; } diff --git a/mdw/query.ts b/mdw/query.ts index 98bb9f48..e845d073 100644 --- a/mdw/query.ts +++ b/mdw/query.ts @@ -1,5 +1,7 @@ +import { call, type Callable } from "effection"; import { safe } from "../fx/mod.ts"; import { compose } from "../compose.ts"; +import { put } from "../action.ts"; import type { ApiCtx, ApiRequest, @@ -12,8 +14,6 @@ import type { import type { AnyAction, Next } from "../types.ts"; import { mergeRequest } from "../query/util.ts"; import * as fetchMdw from "./fetch.ts"; -import { call, Callable } from "../deps.ts"; -import { put } from "../action.ts"; export * from "./fetch.ts"; /** @@ -27,10 +27,7 @@ export * from "./fetch.ts"; * middleware pipeline succeeded or not. Think the `.catch()` case for * `window.fetch`. */ -export function* err( - ctx: Ctx, - next: Next, -) { +export function* err(ctx: Ctx, next: Next) { ctx.result = yield* safe(next); if (!ctx.result.ok) { const message = @@ -114,10 +111,7 @@ export function* actions(ctx: { actions: AnyAction[] }, next: Next) { * This middleware will add `performance.now()` before and after your * middleware pipeline. */ -export function* perf( - ctx: Ctx, - next: Next, -) { +export function* perf(ctx: Ctx, next: Next) { const t0 = performance.now(); yield* next(); const t1 = performance.now(); diff --git a/mdw/store.ts b/mdw/store.ts index 763cec0c..bc7032aa 100644 --- a/mdw/store.ts +++ b/mdw/store.ts @@ -21,6 +21,14 @@ export interface ApiMdwProps< errorFn?: (ctx: Ctx) => string; } +interface ErrorLike { + message: string; +} + +function isErrorLike(err: unknown): err is ErrorLike { + return typeof err === "object" && err !== null && "message" in err; +} + /** * This middleware is a composition of many middleware used to faciliate * the {@link createApi}. @@ -54,15 +62,10 @@ export function api( * This middleware will automatically cache any data found inside `ctx.json` * which is where we store JSON data from the {@link mdw.fetch} middleware. */ -export function cache< - Ctx extends ApiCtx = ApiCtx, ->(schema: { +export function cache(schema: { cache: TableOutput; }) { - return function* cache( - ctx: Ctx, - next: Next, - ) { + return function* cache(ctx: Ctx, next: Next) { ctx.cacheData = yield* select(schema.cache.selectById, { id: ctx.key }); yield* next(); if (!ctx.cache) return; @@ -83,9 +86,10 @@ export function cache< export function loader(schema: { loaders: LoaderOutput; }) { - return function* < - Ctx extends ThunkCtxWLoader = ThunkCtxWLoader, - >(ctx: Ctx, next: Next) { + return function* ( + ctx: Ctx, + next: Next, + ) { yield* updateStore([ schema.loaders.start({ id: ctx.name }), schema.loaders.start({ id: ctx.key }), @@ -109,15 +113,16 @@ export function loader(schema: { ctx.loader = {}; } + const message = isErrorLike(err) ? err.message : "unknown exception"; yield* updateStore([ schema.loaders.error({ id: ctx.name, - message: err.message, + message, ...ctx.loader, }), schema.loaders.error({ id: ctx.key, - message: err.message, + message, ...ctx.loader, }), ]); @@ -148,9 +153,7 @@ function defaultErrorFn(ctx: Ctx) { export function loaderApi< Ctx extends ApiCtx = ApiCtx, S extends AnyState = AnyState, ->( - { schema, errorFn = defaultErrorFn }: ApiMdwProps, -) { +>({ schema, errorFn = defaultErrorFn }: ApiMdwProps) { return function* trackLoading(ctx: Ctx, next: Next) { try { yield* updateStore([ @@ -162,9 +165,7 @@ export function loaderApi< yield* next(); if (!ctx.response) { - yield* updateStore( - schema.loaders.resetByIds([ctx.name, ctx.key]), - ); + yield* updateStore(schema.loaders.resetByIds([ctx.name, ctx.key])); return; } @@ -193,7 +194,7 @@ export function loaderApi< schema.loaders.success({ id: ctx.key, ...ctx.loader }), ]); } catch (err) { - const message = err?.message || "unknown exception"; + const message = isErrorLike(err) ? err.message : "unknown exception"; yield* updateStore([ schema.loaders.error({ id: ctx.name, diff --git a/mod.ts b/mod.ts index b9e9c121..d14c4770 100644 --- a/mod.ts +++ b/mod.ts @@ -25,7 +25,7 @@ export { sleep, spawn, useAbortSignal, -} from "./deps.ts"; +} from "effection"; export type { Callable, Channel, @@ -36,4 +36,4 @@ export type { Stream, Subscription, Task, -} from "./deps.ts"; +} from "effection"; diff --git a/query/api-types.ts b/query/api-types.ts index 59a8eca1..db7d5f17 100644 --- a/query/api-types.ts +++ b/query/api-types.ts @@ -2,6 +2,7 @@ * This is an auto-generated file, do not edit directly! * Run "yarn template" to generate this file. */ +import type { Operation } from "effection"; import type { ThunksApi } from "./thunk.ts"; import type { ApiCtx, @@ -12,7 +13,6 @@ import type { Supervisor, } from "./types.ts"; import type { Next, Payload } from "../types.ts"; -import type { Operation } from "../deps.ts"; export type ApiName = string | string[]; @@ -27,12 +27,12 @@ export interface QueryApi extends ThunksApi { * Options only */ get(req: { supervisor?: Supervisor }): CreateAction; - get

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - get

( - req: { supervisor?: Supervisor }, - ): CreateAction< + get

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + get

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -57,9 +57,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ get(fn: MiddlewareApiCo): CreateAction; - get( - fn: MiddlewareApiCo, - ): CreateAction; + get(fn: MiddlewareApiCo): CreateAction; get

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -149,12 +147,12 @@ export interface QueryApi extends ThunksApi { * Options only */ post(req: { supervisor?: Supervisor }): CreateAction; - post

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - post

( - req: { supervisor?: Supervisor }, - ): CreateAction< + post

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + post

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -179,9 +177,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ post(fn: MiddlewareApiCo): CreateAction; - post( - fn: MiddlewareApiCo, - ): CreateAction; + post(fn: MiddlewareApiCo): CreateAction; post

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -271,12 +267,12 @@ export interface QueryApi extends ThunksApi { * Options only */ put(req: { supervisor?: Supervisor }): CreateAction; - put

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - put

( - req: { supervisor?: Supervisor }, - ): CreateAction< + put

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + put

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -301,9 +297,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ put(fn: MiddlewareApiCo): CreateAction; - put( - fn: MiddlewareApiCo, - ): CreateAction; + put(fn: MiddlewareApiCo): CreateAction; put

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -393,12 +387,12 @@ export interface QueryApi extends ThunksApi { * Options only */ patch(req: { supervisor?: Supervisor }): CreateAction; - patch

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - patch

( - req: { supervisor?: Supervisor }, - ): CreateAction< + patch

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + patch

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -423,9 +417,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ patch(fn: MiddlewareApiCo): CreateAction; - patch( - fn: MiddlewareApiCo, - ): CreateAction; + patch(fn: MiddlewareApiCo): CreateAction; patch

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -515,12 +507,12 @@ export interface QueryApi extends ThunksApi { * Options only */ delete(req: { supervisor?: Supervisor }): CreateAction; - delete

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - delete

( - req: { supervisor?: Supervisor }, - ): CreateAction< + delete

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + delete

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -545,9 +537,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ delete(fn: MiddlewareApiCo): CreateAction; - delete( - fn: MiddlewareApiCo, - ): CreateAction; + delete(fn: MiddlewareApiCo): CreateAction; delete

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -637,12 +627,12 @@ export interface QueryApi extends ThunksApi { * Options only */ options(req: { supervisor?: Supervisor }): CreateAction; - options

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - options

( - req: { supervisor?: Supervisor }, - ): CreateAction< + options

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + options

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -667,9 +657,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ options(fn: MiddlewareApiCo): CreateAction; - options( - fn: MiddlewareApiCo, - ): CreateAction; + options(fn: MiddlewareApiCo): CreateAction; options

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -759,12 +747,12 @@ export interface QueryApi extends ThunksApi { * Options only */ head(req: { supervisor?: Supervisor }): CreateAction; - head

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - head

( - req: { supervisor?: Supervisor }, - ): CreateAction< + head

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + head

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -789,9 +777,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ head(fn: MiddlewareApiCo): CreateAction; - head( - fn: MiddlewareApiCo, - ): CreateAction; + head(fn: MiddlewareApiCo): CreateAction; head

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -881,12 +867,12 @@ export interface QueryApi extends ThunksApi { * Options only */ connect(req: { supervisor?: Supervisor }): CreateAction; - connect

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - connect

( - req: { supervisor?: Supervisor }, - ): CreateAction< + connect

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + connect

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -911,9 +897,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ connect(fn: MiddlewareApiCo): CreateAction; - connect( - fn: MiddlewareApiCo, - ): CreateAction; + connect(fn: MiddlewareApiCo): CreateAction; connect

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; @@ -1003,12 +987,12 @@ export interface QueryApi extends ThunksApi { * Options only */ trace(req: { supervisor?: Supervisor }): CreateAction; - trace

( - req: { supervisor?: Supervisor }, - ): CreateActionWithPayload & Payload

, P>; - trace

( - req: { supervisor?: Supervisor }, - ): CreateAction< + trace

(req: { + supervisor?: Supervisor; + }): CreateActionWithPayload & Payload

, P>; + trace

(req: { + supervisor?: Supervisor; + }): CreateAction< & Omit & FetchJson< ApiSuccess, @@ -1033,9 +1017,7 @@ export interface QueryApi extends ThunksApi { * Middleware only */ trace(fn: MiddlewareApiCo): CreateAction; - trace( - fn: MiddlewareApiCo, - ): CreateAction; + trace(fn: MiddlewareApiCo): CreateAction; trace

( fn: MiddlewareApiCo & Payload

>, ): CreateActionWithPayload & Payload

, P>; diff --git a/query/thunk.ts b/query/thunk.ts index 2f6ec6cf..344b9132 100644 --- a/query/thunk.ts +++ b/query/thunk.ts @@ -1,6 +1,12 @@ import { ActionContext, API_ACTION_PREFIX, takeEvery } from "../action.ts"; import { compose } from "../compose.ts"; -import { Callable, ensure, Ok, Operation, Signal } from "../deps.ts"; +import { + type Callable, + ensure, + Ok, + type Operation, + type Signal, +} from "effection"; import { keepAlive, supervise } from "../fx/mod.ts"; import { IdContext } from "../store/store.ts"; import { createKey } from "./create-key.ts"; diff --git a/query/types.ts b/query/types.ts index 489f61bc..e73374f6 100644 --- a/query/types.ts +++ b/query/types.ts @@ -1,4 +1,4 @@ -import type { Operation, Result } from "../deps.ts"; +import type { Operation, Result } from "effection"; import type { Action, ActionWithPayload, @@ -105,10 +105,8 @@ export type CreateActionFn = () => ActionWithPayload< CreateActionPayload, ApiSuccess> >; -export interface CreateAction< - Ctx extends ThunkCtx = ThunkCtx, - ApiSuccess = any, -> extends CreateActionFn { +export interface CreateAction + extends CreateActionFn { run: ( p?: ActionWithPayload< CreateActionPayload, ApiSuccess> diff --git a/queue.ts b/queue.ts index e8d701a4..6f4af9c9 100644 --- a/queue.ts +++ b/queue.ts @@ -1,4 +1,4 @@ -import { createQueue } from "./deps.ts"; +import { createQueue } from "effection"; export function createFilterQueue(predicate: (v: T) => boolean) { const queue = createQueue(); diff --git a/react.ts b/react.ts index 4c6bdb28..7026fcb3 100644 --- a/react.ts +++ b/react.ts @@ -1,18 +1,18 @@ import { Provider as ReduxProvider, - React, useDispatch, useSelector, useStore as useReduxStore, -} from "./deps.ts"; +} from "react-redux"; +import React, { type ReactElement } from "react"; import type { AnyState, LoaderState } from "./types.ts"; import type { ThunkAction } from "./query/mod.ts"; import { type FxSchema, type FxStore, PERSIST_LOADER_ID } from "./store/mod.ts"; import { ActionFn, ActionFnWithPayload } from "./types.ts"; import { getIdFromAction } from "./action.ts"; -export { useDispatch, useSelector } from "./deps.ts"; -export type { TypedUseSelectorHook } from "./deps.ts"; +export { useDispatch, useSelector } from "react-redux"; +export type { TypedUseSelectorHook } from "react-redux"; const { useContext, @@ -47,22 +47,19 @@ export interface UseCacheResult const SchemaContext = createContext | null>(null); -export function Provider( - { store, schema, children }: { - store: FxStore; - schema: FxSchema; - children: React.ReactNode; - }, -) { - return ( - h(ReduxProvider, { - store, - children: h( - SchemaContext.Provider, - { value: schema, children }, - ) as any, - }) - ); +export function Provider({ + store, + schema, + children, +}: { + store: FxStore; + schema: FxSchema; + children: React.ReactNode; +}) { + return h(ReduxProvider, { + store, + children: h(SchemaContext.Provider, { value: schema, children }) as any, + }); } export function useSchema() { @@ -254,16 +251,17 @@ export function useLoaderSuccess( interface PersistGateProps { children: React.ReactNode; - loading?: JSX.Element; + loading?: ReactElement; } function Loading({ text }: { text: string }) { return h("div", null, text); } -export function PersistGate( - { children, loading = h(Loading) }: PersistGateProps, -) { +export function PersistGate({ + children, + loading = h(Loading), +}: PersistGateProps) { const schema = useSchema(); const ldr = useSelector((s: any) => schema.loaders.selectById(s, { id: PERSIST_LOADER_ID }) diff --git a/scripts/branch-exists.ts b/scripts/branch-exists.ts index fd87d1b2..008cee4a 100644 --- a/scripts/branch-exists.ts +++ b/scripts/branch-exists.ts @@ -1,4 +1,4 @@ -import { call, main, type Operation } from "./deps.ts"; +import { call, main, type Operation } from "effection"; await main(function* (): Operation { // based on env created from ${{ secrets.GITHUB_TOKEN }} in CI diff --git a/scripts/deps.ts b/scripts/deps.ts deleted file mode 100644 index 178bd372..00000000 --- a/scripts/deps.ts +++ /dev/null @@ -1,2 +0,0 @@ -export type { Operation } from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts"; -export { call, main } from "https://deno.land/x/effection@3.0.0-beta.3/mod.ts"; diff --git a/npm.ts b/scripts/npm.ts similarity index 73% rename from npm.ts rename to scripts/npm.ts index 0983e3f8..4dd8bb41 100644 --- a/npm.ts +++ b/scripts/npm.ts @@ -1,4 +1,4 @@ -import { build, emptyDir } from "https://deno.land/x/dnt@0.38.1/mod.ts"; +import { build, emptyDir } from "jsr:@deno/dnt@0.41.3"; const [version] = Deno.args; if (!version) { @@ -23,33 +23,19 @@ async function init() { }, ], mappings: { + // use the deno module in this repo, but use the npm module when publishing "https://deno.land/x/effection@3.0.0-beta.3/mod.ts": { name: "effection", version: "3.0.0-beta.3", }, - "https://esm.sh/react@18.2.0?pin=v135": { - name: "react", - version: "^18.2.0", - peerDependency: true, - }, - "https://esm.sh/react-redux@8.0.5?pin=v135": { - name: "react-redux", - version: "^8.0.5", - }, - "https://esm.sh/immer@10.0.2?pin=v135": { - name: "immer", - version: "^10.0.2", - }, - "https://esm.sh/reselect@4.1.8?pin=v135": { - name: "reselect", - version: "^4.1.8", - }, }, + importMap: "deno.json", outDir: "./npm", shims: { deno: false, }, test: false, + typeCheck: "both", compilerOptions: { target: "ES2020", diff --git a/scripts/sync.ts b/scripts/sync.ts index 2c70de08..16200c2e 100644 --- a/scripts/sync.ts +++ b/scripts/sync.ts @@ -1,4 +1,4 @@ -import { call, main, type Operation } from "./deps.ts"; +import { call, main, type Operation } from "effection"; await main(function* (): Operation { const [syncMethod, folderFromArgs] = Deno.args; diff --git a/store/batch.ts b/store/batch.ts index cd56b272..2df4a94e 100644 --- a/store/batch.ts +++ b/store/batch.ts @@ -1,4 +1,4 @@ -import { action } from "../deps.ts"; +import { action } from "effection"; import { UpdaterCtx } from "./types.ts"; import { AnyState, Next } from "../types.ts"; diff --git a/store/context.ts b/store/context.ts index b8c6968a..7eeec81b 100644 --- a/store/context.ts +++ b/store/context.ts @@ -1,4 +1,4 @@ -import { Channel, createChannel, createContext } from "../deps.ts"; +import { type Channel, createChannel, createContext } from "effection"; import type { AnyState } from "../types.ts"; import type { FxStore } from "./types.ts"; diff --git a/store/fx.ts b/store/fx.ts index 623a24a3..85a884ec 100644 --- a/store/fx.ts +++ b/store/fx.ts @@ -1,4 +1,4 @@ -import { Operation, Result } from "../deps.ts"; +import { Operation, Result } from "effection"; import type { ActionFnWithPayload, AnyState } from "../types.ts"; import type { FxStore, StoreUpdater, UpdaterCtx } from "./types.ts"; import { StoreContext } from "./context.ts"; diff --git a/store/mod.ts b/store/mod.ts index 3666065e..4bd30116 100644 --- a/store/mod.ts +++ b/store/mod.ts @@ -2,7 +2,7 @@ export * from "./context.ts"; export * from "./fx.ts"; export * from "./store.ts"; export * from "./types.ts"; -export { createSelector } from "../deps.ts"; +export { createSelector } from "reselect"; export * from "./slice/mod.ts"; export * from "./schema.ts"; export * from "./batch.ts"; diff --git a/store/persist.ts b/store/persist.ts index 401d4367..1b02c1ae 100644 --- a/store/persist.ts +++ b/store/persist.ts @@ -1,8 +1,8 @@ -import { Err, Ok, Operation, Result } from "../deps.ts"; +import { Err, Ok, Operation, Result } from "effection"; import { select, updateStore } from "./fx.ts"; - import type { AnyState, Next } from "../types.ts"; import type { UpdaterCtx } from "./types.ts"; + export const PERSIST_LOADER_ID = "@@starfx/persist"; export interface PersistAdapter { @@ -48,9 +48,9 @@ export function createTransform() { }; } -export function createLocalStorageAdapter(): PersistAdapter< - S -> { +export function createLocalStorageAdapter< + S extends AnyState, +>(): PersistAdapter { return { getItem: function* (key: string) { const storage = localStorage.getItem(key) || "{}"; @@ -79,17 +79,15 @@ export function shallowReconciler( return { ...original, ...persisted }; } -export function createPersistor( - { - adapter, - key = "starfx", - reconciler = shallowReconciler, - allowlist = [], - transform, - }: - & Pick, "adapter"> - & Partial>, -): PersistProps { +export function createPersistor({ + adapter, + key = "starfx", + reconciler = shallowReconciler, + allowlist = [], + transform, +}: + & Pick, "adapter"> + & Partial>): PersistProps { function* rehydrate(): Operation> { const persistedState = yield* adapter.getItem(key); if (!persistedState.ok) { @@ -126,9 +124,12 @@ export function createPersistor( }; } -export function persistStoreMdw( - { allowlist, adapter, key, transform }: PersistProps, -) { +export function persistStoreMdw({ + allowlist, + adapter, + key, + transform, +}: PersistProps) { return function* (_: UpdaterCtx, next: Next) { yield* next(); const state = yield* select((s: S) => s); diff --git a/store/run.ts b/store/run.ts index 09bcada0..734c5dde 100644 --- a/store/run.ts +++ b/store/run.ts @@ -1,4 +1,4 @@ -import { Callable, Operation, Result, Scope, Task } from "../deps.ts"; +import { Callable, Operation, Result, Scope, Task } from "effection"; import { parallel, safe } from "../fx/mod.ts"; export function createRun(scope: Scope) { diff --git a/store/slice/any.ts b/store/slice/any.ts index 20d6aeca..b10148c5 100644 --- a/store/slice/any.ts +++ b/store/slice/any.ts @@ -1,5 +1,4 @@ import type { AnyState } from "../../types.ts"; - import type { BaseSchema } from "../types.ts"; export interface AnyOutput extends BaseSchema { @@ -10,9 +9,13 @@ export interface AnyOutput extends BaseSchema { select: (s: S) => V; } -export function createAny( - { name, initialState }: { name: keyof S; initialState: V }, -): AnyOutput { +export function createAny({ + name, + initialState, +}: { + name: keyof S; + initialState: V; +}): AnyOutput { return { schema: "any", name: name as string, diff --git a/store/slice/loaders.ts b/store/slice/loaders.ts index 5f754e22..a08df085 100644 --- a/store/slice/loaders.ts +++ b/store/slice/loaders.ts @@ -1,4 +1,4 @@ -import { createSelector } from "../../deps.ts"; +import { createSelector } from "reselect"; import type { AnyState, LoaderItemState, @@ -17,9 +17,9 @@ interface PropIds { const excludesFalse = (n?: T): n is T => Boolean(n); -export function defaultLoaderItem< - M extends AnyState = AnyState, ->(li: Partial> = {}): LoaderItemState { +export function defaultLoaderItem( + li: Partial> = {}, +): LoaderItemState { return { id: "", status: "idle", @@ -76,10 +76,8 @@ function loaderSelectors< data: Record>, ): LoaderItemState[] => Object.values(data).filter(excludesFalse); - const findById = ( - data: Record>, - { id }: PropId, - ) => (defaultLoader(data[id]) || empty); + const findById = (data: Record>, { id }: PropId) => + defaultLoader(data[id]) || empty; const findByIds = ( data: Record>, { ids }: PropIds, @@ -184,8 +182,8 @@ export const createLoaders = < }; }; -export function loaders< - M extends AnyState = AnyState, ->(initialState?: Record>) { +export function loaders( + initialState?: Record>, +) { return (name: string) => createLoaders({ name, initialState }); } diff --git a/store/slice/num.ts b/store/slice/num.ts index e64e2a54..f1baca0d 100644 --- a/store/slice/num.ts +++ b/store/slice/num.ts @@ -1,5 +1,4 @@ import type { AnyState } from "../../types.ts"; - import type { BaseSchema } from "../types.ts"; export interface NumOutput extends BaseSchema { @@ -12,9 +11,13 @@ export interface NumOutput extends BaseSchema { select: (s: S) => number; } -export function createNum( - { name, initialState = 0 }: { name: keyof S; initialState?: number }, -): NumOutput { +export function createNum({ + name, + initialState = 0, +}: { + name: keyof S; + initialState?: number; +}): NumOutput { return { name: name as string, schema: "num", diff --git a/store/slice/obj.test.ts b/store/slice/obj.test.ts index 17a38fbd..74ab2bdf 100644 --- a/store/slice/obj.test.ts +++ b/store/slice/obj.test.ts @@ -1,5 +1,5 @@ import { asserts, describe, it } from "../../test.ts"; -import { configureStore, updateStore } from "../../store/mod.ts"; +import { configureStore, updateStore } from "../mod.ts"; import { createObj } from "./obj.ts"; const tests = describe("createObj()"); @@ -32,12 +32,14 @@ it(tests, "sets up an obj", async () => { }); await store.run(function* () { - yield* updateStore(slice.set({ - username: "bob", - userId: 1, - isadmin: true, - roles: ["admin", "user"], - })); + yield* updateStore( + slice.set({ + username: "bob", + userId: 1, + isadmin: true, + roles: ["admin", "user"], + }), + ); }); asserts.assertEquals(store.getState()["currentUser"], { diff --git a/store/slice/obj.ts b/store/slice/obj.ts index ab36eee8..2946e25e 100644 --- a/store/slice/obj.ts +++ b/store/slice/obj.ts @@ -1,5 +1,4 @@ import type { AnyState } from "../../types.ts"; - import type { BaseSchema } from "../types.ts"; export interface ObjOutput @@ -12,9 +11,13 @@ export interface ObjOutput select: (s: S) => V; } -export function createObj( - { name, initialState }: { name: keyof S; initialState: V }, -): ObjOutput { +export function createObj({ + name, + initialState, +}: { + name: keyof S; + initialState: V; +}): ObjOutput { return { schema: "obj", name: name as string, diff --git a/store/slice/str.ts b/store/slice/str.ts index 816eeb62..a9eae3db 100644 --- a/store/slice/str.ts +++ b/store/slice/str.ts @@ -1,5 +1,4 @@ import type { AnyState } from "../../types.ts"; - import type { BaseSchema } from "../types.ts"; export interface StrOutput @@ -11,9 +10,13 @@ export interface StrOutput select: (s: S) => string; } -export function createStr( - { name, initialState = "" }: { name: keyof S; initialState?: string }, -): StrOutput { +export function createStr({ + name, + initialState = "", +}: { + name: keyof S; + initialState?: string; +}): StrOutput { return { schema: "str", name: name as string, diff --git a/store/slice/table.ts b/store/slice/table.ts index d405c1b8..a688365c 100644 --- a/store/slice/table.ts +++ b/store/slice/table.ts @@ -1,4 +1,4 @@ -import { createSelector } from "../../deps.ts"; +import { createSelector } from "reselect"; import type { AnyState, IdProp } from "../../types.ts"; import { BaseSchema } from "../types.ts"; @@ -53,7 +53,7 @@ function tableSelectors< const selectById = ( state: S, { id }: PropId, - ): typeof empty extends undefined ? (Entity | undefined) : Entity => { + ): typeof empty extends undefined ? Entity | undefined : Entity => { const data = selectTable(state); return findById(data, { id }); }; @@ -92,18 +92,12 @@ export interface TableOutput< patch: (e: PatchEntity>) => (s: S) => void; merge: (e: PatchEntity>) => (s: S) => void; reset: () => (s: S) => void; - findById: ( - d: Record, - { id }: PropId, - ) => Empty; + findById: (d: Record, { id }: PropId) => Empty; findByIds: (d: Record, { ids }: PropIds) => Entity[]; tableAsList: (d: Record) => Entity[]; selectTable: (s: S) => Record; selectTableAsList: (state: S) => Entity[]; - selectById: ( - s: S, - p: PropId, - ) => Empty; + selectById: (s: S, p: PropId) => Empty; selectByIds: (s: S, p: PropIds) => Entity[]; } @@ -207,11 +201,12 @@ export function table< export function table< Entity extends AnyState = AnyState, S extends AnyState = AnyState, ->( - { initialState, empty }: { - initialState?: Record; - empty?: Entity | (() => Entity); - } = {}, -): (n: string) => TableOutput { +>({ + initialState, + empty, +}: { + initialState?: Record; + empty?: Entity | (() => Entity); +} = {}): (n: string) => TableOutput { return (name: string) => createTable({ name, empty, initialState }); } diff --git a/store/store.ts b/store/store.ts index fcc8f8a1..9a637310 100644 --- a/store/store.ts +++ b/store/store.ts @@ -1,17 +1,9 @@ +import { createContext, createScope, createSignal, Ok, Scope } from "effection"; +import { enablePatches, produceWithPatches } from "immer"; import { ActionContext, API_ACTION_PREFIX, emit } from "../action.ts"; import { BaseMiddleware, compose } from "../compose.ts"; -import { - createContext, - createScope, - createSignal, - enablePatches, - Ok, - produceWithPatches, - Scope, -} from "../deps.ts"; import { StoreContext, StoreUpdateContext } from "./context.ts"; import { createRun } from "./run.ts"; - import type { AnyAction, AnyState, Next } from "../types.ts"; import type { FxStore, Listener, StoreUpdater, UpdaterCtx } from "./types.ts"; const stubMsg = "This is merely a stub, not implemented"; @@ -155,10 +147,13 @@ export function createStore({ function* reset(ignoreList: (keyof S)[] = []) { return yield* update((s) => { - const keep = ignoreList.reduce((acc, key) => { - acc[key] = s[key]; - return acc; - }, { ...initialState }); + const keep = ignoreList.reduce( + (acc, key) => { + acc[key] = s[key]; + return acc; + }, + { ...initialState }, + ); Object.keys(s).forEach((key: keyof S) => { s[key] = keep[key]; diff --git a/store/types.ts b/store/types.ts index 261c42b4..3e5f4615 100644 --- a/store/types.ts +++ b/store/types.ts @@ -1,8 +1,9 @@ +import type { Patch } from "immer"; +import type { Operation, Scope } from "effection"; +import type { AnyAction, AnyState } from "../types.ts"; import type { LoaderOutput } from "./slice/loaders.ts"; import type { TableOutput } from "./slice/table.ts"; -import type { Operation, Patch, Scope } from "../deps.ts"; import { BaseCtx } from "../mod.ts"; -import type { AnyAction, AnyState } from "../types.ts"; import { createRun } from "./run.ts"; export type StoreUpdater = (s: S) => S | void; diff --git a/supervisor.ts b/supervisor.ts index aa8f5976..b3af5c90 100644 --- a/supervisor.ts +++ b/supervisor.ts @@ -1,5 +1,5 @@ import { createAction, take } from "./action.ts"; -import { call, Callable, Operation, race, sleep, spawn, Task } from "./deps.ts"; +import { call, Callable, Operation, race, sleep, spawn, Task } from "effection"; import type { ActionWithPayload, AnyAction } from "./types.ts"; import type { CreateActionPayload } from "./query/mod.ts"; import { getIdFromAction } from "./action.ts"; @@ -24,10 +24,7 @@ export function poll(parentTimer: number = 5 * SECONDS, cancelType?: string) { while (true) { const action = yield* take<{ timer?: number }>(actionType); const timer = action.payload?.timer || parentTimer; - yield* race([ - fire(action, timer), - take(`${cancel}`) as Operation, - ]); + yield* race([fire(action, timer), take(`${cancel}`) as Operation]); } }; } @@ -75,10 +72,7 @@ export function timer(timer: number = 5 * MINUTES) { } }); }; - yield* race([ - sleep(timer), - take(matchFn as any) as Operation, - ]); + yield* race([sleep(timer), take(matchFn as any) as Operation]); delete map[action.payload.key]; } diff --git a/test.ts b/test.ts index 915a3a62..ad5eeea3 100644 --- a/test.ts +++ b/test.ts @@ -1,13 +1,13 @@ -export { assert } from "https://deno.land/std@0.187.0/testing/asserts.ts"; export { afterAll, beforeAll, beforeEach, describe, it, -} from "https://deno.land/std@0.163.0/testing/bdd.ts"; -export * as asserts from "https://deno.land/std@0.185.0/testing/asserts.ts"; -export { expect } from "https://deno.land/x/expect@v0.3.0/mod.ts"; +} from "jsr:@std/testing/bdd"; +export { assert } from "jsr:@std/assert"; +export * as asserts from "jsr:@std/assert"; +export { expect } from "jsr:@std/expect"; export { install, mock } from "https://deno.land/x/mock_fetch@0.3.0/mod.ts"; export function isLikeSelector(selector: unknown) { diff --git a/test/api.test.ts b/test/api.test.ts index cbf0eed0..299c85cf 100644 --- a/test/api.test.ts +++ b/test/api.test.ts @@ -9,7 +9,7 @@ import { } from "../store/mod.ts"; import { AnyState, - type ApiCtx, + ApiCtx, call, createApi, createKey, @@ -105,10 +105,12 @@ it(tests, "POST", async () => { store.dispatch(createUser({ email: mockUser.email })); - await store.run(waitFor(function* (): Operation { - const res = yield* select((state: AnyState) => state.users["1"].id); - return res !== ""; - })); + await store.run( + waitFor(function* (): Operation { + const res = yield* select((state: AnyState) => state.users["1"].id); + return res !== ""; + }), + ); expect(store.getState().users).toEqual({ "1": { id: "1", name: "test", email: "test@test.com" }, @@ -214,12 +216,16 @@ it(tests, "run() from a normal saga", () => { const api = createApi(); api.use(api.routes()); let acc = ""; - const action1 = api.get<{ id: string }>("/users/:id", { - supervisor: takeEvery, - }, function* (_, next) { - yield* next(); - acc += "a"; - }); + const action1 = api.get<{ id: string }>( + "/users/:id", + { + supervisor: takeEvery, + }, + function* (_, next) { + yield* next(); + acc += "a"; + }, + ); const action2 = () => ({ type: "ACTION" }); function* onAction() { const ctx = yield* safe(() => action1.run(action1({ id: "1" }))); @@ -318,21 +324,15 @@ it(tests, "two identical endpoints", () => { api.use(mdw.api({ schema })); api.use(api.routes()); - const first = api.get( - "/health", - function* (ctx, next) { - actual.push(ctx.req().url); - yield* next(); - }, - ); + const first = api.get("/health", function* (ctx, next) { + actual.push(ctx.req().url); + yield* next(); + }); - const second = api.get( - ["/health", "poll"], - function* (ctx, next) { - actual.push(ctx.req().url); - yield* next(); - }, - ); + const second = api.get(["/health", "poll"], function* (ctx, next) { + actual.push(ctx.req().url); + yield* next(); + }); store.run(api.bootup); store.dispatch(first()); @@ -483,45 +483,41 @@ it(tests, "should bubble up error", () => { }); // this is strictly for testing types -it( - tests, - "useCache - derive api success from endpoint", - () => { - const api = createApi(); - api.use(api.routes()); - api.use(function* (ctx, next) { - yield* next(); - const data = { result: "wow" }; - ctx.json = { ok: true, value: data }; - }); +it(tests, "useCache - derive api success from endpoint", () => { + const api = createApi(); + api.use(api.routes()); + api.use(function* (ctx, next) { + yield* next(); + const data = { result: "wow" }; + ctx.json = { ok: true, value: data }; + }); - const acc: string[] = []; - const action1 = api.get( - "/users", - { supervisor: takeEvery }, - function* (ctx, next) { - ctx.something = false; + const acc: string[] = []; + const action1 = api.get( + "/users", + { supervisor: takeEvery }, + function* (ctx, next) { + ctx.something = false; - yield* next(); + yield* next(); - if (ctx.json.ok) { - acc.push(ctx.json.value.result); - } else { - // EXPECT { message: string } - ctx.json.error; - } - }, - ); + if (ctx.json.ok) { + acc.push(ctx.json.value.result); + } else { + // EXPECT { message: string } + ctx.json.error; + } + }, + ); - const store = createStore({ initialState: { users: {} } }); - store.run(api.bootup); + const store = createStore({ initialState: { users: {} } }); + store.run(api.bootup); - function _App() { - const act = action1(); - act.payload._result; - const users = useCache(act); - // EXPECT { result: string } | undefined - users.data; - } - }, -); + function _App() { + const act = action1(); + act.payload._result; + const users = useCache(act); + // EXPECT { result: string } | undefined + users.data; + } +}); diff --git a/test/create-key.test.ts b/test/create-key.test.ts index e9f929cd..b9414a28 100644 --- a/test/create-key.test.ts +++ b/test/create-key.test.ts @@ -23,15 +23,12 @@ it( const api = createApi(); api.use(api.routes()); // no param - const action0 = api.get( - "/users", - function* (ctx, next) { - ctx.request = { - method: "GET", - }; - yield* next(); - }, - ); + const action0 = api.get("/users", function* (ctx, next) { + ctx.request = { + method: "GET", + }; + yield* next(); + }); const sendNop0 = action0(); const sendNop1 = action0(); expect(getKeyOf(sendNop0)).toEqual(getKeyOf(sendNop1)); @@ -47,15 +44,12 @@ it( // no param const action0 = api.get<{ [key: string]: string | boolean | number | null | undefined; - }>( - "/users", - function* (ctx, next) { - ctx.request = { - method: "GET", - }; - yield* next(); - }, - ); + }>("/users", function* (ctx, next) { + ctx.request = { + method: "GET", + }; + yield* next(); + }); const sendPojo0 = action0({ a: "a", b: "b", diff --git a/test/fetch.test.ts b/test/fetch.test.ts index 7fe2d3dd..f7a64888 100644 --- a/test/fetch.test.ts +++ b/test/fetch.test.ts @@ -65,13 +65,16 @@ it( const state = store.getState(); expect(state.cache[action.payload.key]).toEqual(mockUser); - expect(actual).toEqual([{ - url: `${baseUrl}/users`, - method: "GET", - headers: { - "Content-Type": "application/json", + expect(actual).toEqual([ + { + url: `${baseUrl}/users`, + method: "GET", + headers: { + "Content-Type": "application/json", + }, }, - }, { ok: true, value: mockUser }]); + { ok: true, value: mockUser }, + ]); }, ); @@ -367,92 +370,84 @@ it(tests, "POST multiple endpoints with same uri", async () => { }); }); -it( - tests, - "slug in url but payload has empty string for slug value", - () => { - const { store, schema } = testStore(); - const api = createApi(); - api.use(mdw.api({ schema })); - api.use(api.routes()); - api.use(mdw.fetch({ baseUrl })); - let actual = ""; +it(tests, "slug in url but payload has empty string for slug value", () => { + const { store, schema } = testStore(); + const api = createApi(); + api.use(mdw.api({ schema })); + api.use(api.routes()); + api.use(mdw.fetch({ baseUrl })); + let actual = ""; - const fetchUsers = api.post<{ id: string }>( - "/users/:id", - { supervisor: takeEvery }, - function* (ctx, next) { - ctx.cache = true; - ctx.request = ctx.req({ body: JSON.stringify(mockUser) }); + const fetchUsers = api.post<{ id: string }>( + "/users/:id", + { supervisor: takeEvery }, + function* (ctx, next) { + ctx.cache = true; + ctx.request = ctx.req({ body: JSON.stringify(mockUser) }); - yield* next(); - if (!ctx.json.ok) { - actual = ctx.json.error; - } - }, - ); + yield* next(); + if (!ctx.json.ok) { + actual = ctx.json.error; + } + }, + ); - store.run(api.bootup); - const action = fetchUsers({ id: "" }); - store.dispatch(action); + store.run(api.bootup); + const action = fetchUsers({ id: "" }); + store.dispatch(action); - const data = - "found :id in endpoint name (/users/:id [POST]) but payload has falsy value ()"; - expect(actual).toEqual(data); - }, -); + const data = + "found :id in endpoint name (/users/:id [POST]) but payload has falsy value ()"; + expect(actual).toEqual(data); +}); -it( - tests, - "with success - should keep retrying fetch request", - async () => { - let counter = 0; - mock(`GET@/users`, () => { - counter += 1; - if (counter > 4) { - return new Response(JSON.stringify(mockUser)); - } - return new Response(JSON.stringify({ message: "error" }), { - status: 400, - }); +it(tests, "with success - should keep retrying fetch request", async () => { + let counter = 0; + mock(`GET@/users`, () => { + counter += 1; + if (counter > 4) { + return new Response(JSON.stringify(mockUser)); + } + return new Response(JSON.stringify({ message: "error" }), { + status: 400, }); + }); - const { schema, store } = testStore(); - const api = createApi(); - api.use(mdw.api({ schema })); - api.use(api.routes()); - api.use(mdw.fetch({ baseUrl })); + const { schema, store } = testStore(); + const api = createApi(); + api.use(mdw.api({ schema })); + api.use(api.routes()); + api.use(mdw.fetch({ baseUrl })); - let actual = null; - const fetchUsers = api.get("/users", { supervisor: takeEvery }, [ - function* (ctx, next) { - ctx.cache = true; - yield* next(); + let actual = null; + const fetchUsers = api.get("/users", { supervisor: takeEvery }, [ + function* (ctx, next) { + ctx.cache = true; + yield* next(); - if (!ctx.json.ok) { - return; - } + if (!ctx.json.ok) { + return; + } - actual = ctx.json; - }, - mdw.fetchRetry((n) => (n > 4 ? -1 : 10)), - ]); + actual = ctx.json; + }, + mdw.fetchRetry((n) => (n > 4 ? -1 : 10)), + ]); - store.run(api.bootup); + store.run(api.bootup); - const action = fetchUsers(); - store.dispatch(action); + const action = fetchUsers(); + store.dispatch(action); - const loader = await store.run(waitForLoader(schema.loaders, action)); - if (!loader.ok) { - throw loader.error; - } + const loader = await store.run(waitForLoader(schema.loaders, action)); + if (!loader.ok) { + throw loader.error; + } - const state = store.getState(); - expect(state.cache[action.payload.key]).toEqual(mockUser); - expect(actual).toEqual({ ok: true, value: mockUser }); - }, -); + const state = store.getState(); + expect(state.cache[action.payload.key]).toEqual(mockUser); + expect(actual).toEqual({ ok: true, value: mockUser }); +}); it( tests, diff --git a/test/mdw.test.ts b/test/mdw.test.ts index f4b3fe2f..2fa707f3 100644 --- a/test/mdw.test.ts +++ b/test/mdw.test.ts @@ -98,9 +98,7 @@ it(tests, "basic", () => { store.run(query.bootup); store.dispatch(fetchUsers()); - expect(store.getState().users).toEqual( - { [mockUser.id]: mockUser }, - ); + expect(store.getState().users).toEqual({ [mockUser.id]: mockUser }); store.dispatch(fetchUser({ id: "2" })); expect(store.getState().users).toEqual({ [mockUser.id]: mockUser, @@ -498,8 +496,9 @@ it(tests, "errorHandler", () => { yield* next(); a = 2; } catch (err) { + const errorMessage = err instanceof Error ? err.message : "Unknown error"; console.error( - `Error: ${err.message}. Check the endpoint [${ctx.name}]`, + `Error: ${errorMessage}. Check the endpoint [${ctx.name}]`, ctx, ); } diff --git a/test/persist.test.ts b/test/persist.test.ts index 7d8f3429..bd66aa90 100644 --- a/test/persist.test.ts +++ b/test/persist.test.ts @@ -1,4 +1,4 @@ -import { sleep } from "../deps.ts"; +import { sleep } from "effection"; import { Ok, Operation, parallel, put, take } from "../mod.ts"; import { createPersistor, @@ -11,7 +11,7 @@ import { slice, } from "../store/mod.ts"; import { asserts, describe, it } from "../test.ts"; -import { LoaderItemState } from "../types.ts"; +import type { LoaderItemState } from "../types.ts"; const tests = describe("store"); @@ -57,10 +57,7 @@ it(tests, "can persist to storage adapters", async () => { yield* group; }); - asserts.assertEquals( - ls, - '{"token":"1234"}', - ); + asserts.assertEquals(ls, '{"token":"1234"}'); }); it(tests, "rehydrates state", async () => { @@ -95,10 +92,7 @@ it(tests, "rehydrates state", async () => { yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); }); - asserts.assertEquals( - store.getState().token, - "123", - ); + asserts.assertEquals(store.getState().token, "123"); }); it(tests, "persists inbound state using transform 'in' function", async () => { @@ -155,79 +149,69 @@ it(tests, "persists inbound state using transform 'in' function", async () => { ]); yield* group; }); - asserts.assertEquals( - ls, - '{"token":"4321","cache":{}}', - ); + asserts.assertEquals(ls, '{"token":"4321","cache":{}}'); }); -it( - tests, - "persists inbound state using tranform in (2)", - async () => { - const [schema, initialState] = createSchema({ - token: slice.str(), - loaders: slice.loaders(), - cache: slice.table({ empty: {} }), - }); - type State = typeof initialState; - let ls = "{}"; +it(tests, "persists inbound state using tranform in (2)", async () => { + const [schema, initialState] = createSchema({ + token: slice.str(), + loaders: slice.loaders(), + cache: slice.table({ empty: {} }), + }); + type State = typeof initialState; + let ls = "{}"; - const adapter: PersistAdapter = { - getItem: function* (_: string) { - return Ok(JSON.parse(ls)); - }, - setItem: function* (_: string, s: Partial) { - ls = JSON.stringify(s); - return Ok(undefined); - }, - removeItem: function* (_: string) { - return Ok(undefined); - }, - }; + const adapter: PersistAdapter = { + getItem: function* (_: string) { + return Ok(JSON.parse(ls)); + }, + setItem: function* (_: string, s: Partial) { + ls = JSON.stringify(s); + return Ok(undefined); + }, + removeItem: function* (_: string) { + return Ok(undefined); + }, + }; - function revertToken(state: Partial) { - const res = { - ...state, - token: state?.token?.split("").reverse().join(""), - }; - return res; - } - const transform = createTransform(); - transform.in = revertToken; + function revertToken(state: Partial) { + const res = { + ...state, + token: state?.token?.split("").reverse().join(""), + }; + return res; + } + const transform = createTransform(); + transform.in = revertToken; - const persistor = createPersistor({ - adapter, - allowlist: ["token", "cache"], - transform, - }); + const persistor = createPersistor({ + adapter, + allowlist: ["token", "cache"], + transform, + }); - const mdw = persistStoreMdw(persistor); - const store = createStore({ - initialState, - middleware: [mdw], - }); + const mdw = persistStoreMdw(persistor); + const store = createStore({ + initialState, + middleware: [mdw], + }); - await store.run(function* (): Operation { - yield* persistor.rehydrate(); + await store.run(function* (): Operation { + yield* persistor.rehydrate(); - const group = yield* parallel([ - function* (): Operation { - const action = yield* take("SET_TOKEN"); - yield* schema.update(schema.token.set(action.payload)); - }, - function* () { - yield* put({ type: "SET_TOKEN", payload: "1234" }); - }, - ]); - yield* group; - }); - asserts.assertEquals( - ls, - '{"token":"4321","cache":{}}', - ); - }, -); + const group = yield* parallel([ + function* (): Operation { + const action = yield* take("SET_TOKEN"); + yield* schema.update(schema.token.set(action.payload)); + }, + function* () { + yield* put({ type: "SET_TOKEN", payload: "1234" }); + }, + ]); + yield* group; + }); + asserts.assertEquals(ls, '{"token":"4321","cache":{}}'); +}); it(tests, "persists a filtered nested part of a slice", async () => { const [schema, initialState] = createSchema({ @@ -251,9 +235,7 @@ it(tests, "persists a filtered nested part of a slice", async () => { }, }; - function pickLatestOfLoadersAandC( - state: Partial, - ): Partial { + function pickLatestOfLoadersAandC(state: Partial): Partial { const nextState = { ...state }; if (state.loaders) { @@ -323,26 +305,11 @@ it(tests, "persists a filtered nested part of a slice", async () => { ]); yield* group; }); - asserts.assertStringIncludes( - ls, - '{"token":"1"', - ); - asserts.assertStringIncludes( - ls, - '"message":"loading A-second"', - ); - asserts.assertStringIncludes( - ls, - '"id":"C"', - ); - asserts.assertNotMatch( - ls, - /"message":"loading A-first"/, - ); - asserts.assertNotMatch( - ls, - /"id":"B"/, - ); + asserts.assertStringIncludes(ls, '{"token":"1"'); + asserts.assertStringIncludes(ls, '"message":"loading A-second"'); + asserts.assertStringIncludes(ls, '"id":"C"'); + asserts.assertNotMatch(ls, /"message":"loading A-first"/); + asserts.assertNotMatch(ls, /"id":"B"/); }); it(tests, "handles the empty state correctly", async () => { @@ -388,10 +355,7 @@ it(tests, "handles the empty state correctly", async () => { yield* persistor.rehydrate(); }); - asserts.assertEquals( - ls, - "{}", - ); + asserts.assertEquals(ls, "{}"); }); it( @@ -444,10 +408,7 @@ it( yield* group; }); - asserts.assertEquals( - ls, - '{"token":"1234"}', - ); + asserts.assertEquals(ls, '{"token":"1234"}'); }, ); @@ -494,10 +455,7 @@ it( yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); yield* schema.update(schema.token.set("1234")); }); - asserts.assertEquals( - store.getState().token, - "1234", - ); + asserts.assertEquals(store.getState().token, "1234"); }, ); @@ -553,10 +511,7 @@ it( yield* schema.update(schema.counter.set(5)); }); - asserts.assertEquals( - ls, - '{"token":"54321"}', - ); + asserts.assertEquals(ls, '{"token":"54321"}'); }, ); @@ -610,10 +565,7 @@ it( yield* schema.update(schema.token.set("01234")); }); - asserts.assertEquals( - ls, - '{"token":"43210"}', - ); + asserts.assertEquals(ls, '{"token":"43210"}'); transform.in = function (state) { return { @@ -626,10 +578,7 @@ it( yield* schema.update(schema.token.set("01234")); }); - asserts.assertEquals( - ls, - '{"token":"0123456789"}', - ); + asserts.assertEquals(ls, '{"token":"0123456789"}'); }, ); @@ -679,10 +628,7 @@ it(tests, "persists state using transform 'out' function", async () => { yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); }); - asserts.assertEquals( - store.getState().token, - "43210", - ); + asserts.assertEquals(store.getState().token, "43210"); }); it("persists outbound state using tranform setOutTransformer", async () => { @@ -711,9 +657,10 @@ it("persists outbound state using tranform setOutTransformer", async () => { function revertToken(state: Partial) { return { ...state, - token: (["5"].concat(...state?.token?.split("") || [])).reverse().join( - "", - ), + token: ["5"] + .concat(...(state?.token?.split("") || [])) + .reverse() + .join(""), }; } const transform = createTransform(); @@ -736,10 +683,7 @@ it("persists outbound state using tranform setOutTransformer", async () => { yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); }); - asserts.assertEquals( - ls, - '{"token":"012345"}', - ); + asserts.assertEquals(ls, '{"token":"012345"}'); }); it(tests, "persists outbound a filtered nested part of a slice", async () => { @@ -765,9 +709,7 @@ it(tests, "persists outbound a filtered nested part of a slice", async () => { }, }; - function extractMetaAndSetToken( - state: Partial, - ): Partial { + function extractMetaAndSetToken(state: Partial): Partial { const nextState = { ...state }; if (state.loaders) { const savedLoader = state.loaders["A"]; @@ -796,10 +738,7 @@ it(tests, "persists outbound a filtered nested part of a slice", async () => { yield* persistor.rehydrate(); yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); }); - asserts.assertEquals( - store.getState().token, - "01234_FLAG_PERSISTED", - ); + asserts.assertEquals(store.getState().token, "01234_FLAG_PERSISTED"); }); it(tests, "the outbound transformer can be reset during runtime", async () => { @@ -854,19 +793,13 @@ it(tests, "the outbound transformer can be reset during runtime", async () => { yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); }); - asserts.assertEquals( - store.getState().token, - "4321_", - ); + asserts.assertEquals(store.getState().token, "4321_"); await store.run(function* (): Operation { yield* schema.update(schema.token.set("01234")); }); - asserts.assertEquals( - ls, - '{"token":"01234"}', - ); + asserts.assertEquals(ls, '{"token":"01234"}'); transform.out = postpendToken; @@ -875,8 +808,5 @@ it(tests, "the outbound transformer can be reset during runtime", async () => { yield* schema.update(schema.loaders.success({ id: PERSIST_LOADER_ID })); }); - asserts.assertEquals( - store.getState().token, - "0123456789", - ); + asserts.assertEquals(store.getState().token, "0123456789"); }); diff --git a/test/react.test.ts b/test/react.test.ts index a3dcdf3c..0e798fd4 100644 --- a/test/react.test.ts +++ b/test/react.test.ts @@ -1,7 +1,7 @@ +import React from "react"; import { asserts, describe, it } from "../test.ts"; import { Provider } from "../react.ts"; import { createSchema, createStore, slice } from "../store/mod.ts"; -import { React } from "../deps.ts"; const tests = describe("react"); @@ -12,9 +12,10 @@ it(tests, () => { loaders: slice.loaders(), }); const store = createStore({ initialState }); - React.createElement( - Provider, - { schema, store, children: React.createElement("div") }, - ); + React.createElement(Provider, { + schema, + store, + children: React.createElement("div"), + }); asserts.equal(true, true); }); diff --git a/test/schema.test.ts b/test/schema.test.ts index 1e2dd60c..12091209 100644 --- a/test/schema.test.ts +++ b/test/schema.test.ts @@ -104,9 +104,7 @@ it(tests, "can work with a nested object", async () => { const curUser = yield* select(db.currentUser.select); asserts.assertEquals(curUser, { id: "", name: "vvv", roles: [] }); - yield* db.update( - db.currentUser.update({ key: "roles", value: ["admin"] }), - ); + yield* db.update(db.currentUser.update({ key: "roles", value: ["admin"] })); const curUser2 = yield* select(db.currentUser.select); asserts.assertEquals(curUser2, { id: "", name: "vvv", roles: ["admin"] }); diff --git a/test/take-helper.test.ts b/test/take-helper.test.ts index a71f8fa9..f79c906f 100644 --- a/test/take-helper.test.ts +++ b/test/take-helper.test.ts @@ -1,8 +1,8 @@ +import { spawn } from "effection"; import { describe, expect, it } from "../test.ts"; import { createStore } from "../store/mod.ts"; import type { AnyAction } from "../mod.ts"; import { sleep, take, takeEvery, takeLatest, takeLeading } from "../mod.ts"; -import { spawn } from "../deps.ts"; const testEvery = describe("takeEvery()"); const testLatest = describe("takeLatest()"); @@ -68,10 +68,7 @@ it(testEvery, "should receive all actions", async () => { function* root() { const task = yield* spawn(() => - takeEvery( - "ACTION", - (action) => worker("a1", "a2", action), - ) + takeEvery("ACTION", (action) => worker("a1", "a2", action)) ); yield* take("CANCEL_WATCHER"); yield* task.halt(); diff --git a/test/thunk.test.ts b/test/thunk.test.ts index f3790435..d4b13440 100644 --- a/test/thunk.test.ts +++ b/test/thunk.test.ts @@ -161,17 +161,21 @@ it( api.use(processUsers); api.use(processTickets); const fetchUsers = api.create(`/users`, { supervisor: takeEvery }); - const fetchTickets = api.create(`/ticket-wrong-url`, { - supervisor: takeEvery, - }, function* (ctx, next) { - // before middleware has been triggered - ctx.url = "/tickets"; + const fetchTickets = api.create( + `/ticket-wrong-url`, + { + supervisor: takeEvery, + }, + function* (ctx, next) { + // before middleware has been triggered + ctx.url = "/tickets"; - // triggers all middleware - yield* next(); + // triggers all middleware + yield* next(); - yield* put(fetchUsers()); - }); + yield* put(fetchUsers()); + }, + ); const store = createStore({ initialState: { users: {}, tickets: {} }, @@ -424,22 +428,19 @@ it(tests, "retry with actionFn", async () => { const api = createThunks(); api.use(api.routes()); - const action = api.create( - "/api", - function* (ctx, next) { - acc += "a"; - yield* next(); - acc += "g"; - if (acc === "agag") { - yield* put({ type: "DONE" }); - } + const action = api.create("/api", function* (ctx, next) { + acc += "a"; + yield* next(); + acc += "g"; + if (acc === "agag") { + yield* put({ type: "DONE" }); + } - if (!called) { - called = true; - yield* put(ctx.actionFn()); - } - }, - ); + if (!called) { + called = true; + yield* put(ctx.actionFn()); + } + }); const store = createStore({ initialState: {} }); store.run(api.bootup); @@ -537,24 +538,20 @@ it(tests, "should warn when calling thunk before registered", () => { console.warn = err; }); -it( - tests, - "it should call the api once even if we register it twice", - () => { - const api = createThunks(); - api.use(api.routes()); - const store = createStore({ initialState: {} }); - store.run(api.register); - store.run(api.register); +it(tests, "it should call the api once even if we register it twice", () => { + const api = createThunks(); + api.use(api.routes()); + const store = createStore({ initialState: {} }); + store.run(api.register); + store.run(api.register); - let acc = ""; - const action = api.create("/users", function* () { - acc += "a"; - }); - store.dispatch(action()); - asserts.assertEquals(acc, "a"); - }, -); + let acc = ""; + const action = api.create("/users", function* () { + acc += "a"; + }); + store.dispatch(action()); + asserts.assertEquals(acc, "a"); +}); it( tests, @@ -627,27 +624,23 @@ it( }, ); -it( - tests, - "should allow multiple stores to register a thunk", - () => { - const api1 = createThunks(); - api1.use(api1.routes()); - const storeA = createStore({ initialState: {} }); - const storeB = createStore({ initialState: {} }); - storeA.run(api1.register); - storeB.run(api1.register); - let acc = ""; - const action = api1.create("/users", function* () { - acc += "b"; - }); - storeA.dispatch(action()); - storeB.dispatch(action()); +it(tests, "should allow multiple stores to register a thunk", () => { + const api1 = createThunks(); + api1.use(api1.routes()); + const storeA = createStore({ initialState: {} }); + const storeB = createStore({ initialState: {} }); + storeA.run(api1.register); + storeB.run(api1.register); + let acc = ""; + const action = api1.create("/users", function* () { + acc += "b"; + }); + storeA.dispatch(action()); + storeB.dispatch(action()); - asserts.assertEquals( - acc, - "bb", - "Expected 'bb' after first API call, but got: " + acc, - ); - }, -); + asserts.assertEquals( + acc, + "bb", + "Expected 'bb' after first API call, but got: " + acc, + ); +}); diff --git a/types.ts b/types.ts index d3417356..313f2012 100644 --- a/types.ts +++ b/types.ts @@ -1,4 +1,4 @@ -import type { Instruction, Operation } from "./deps.ts"; +import type { Instruction, Operation } from "effection"; export interface Computation { // deno-lint-ignore no-explicit-any @@ -20,9 +20,8 @@ export interface LoaderItemState< meta: M; } -export interface LoaderState< - M extends AnyState = AnyState, -> extends LoaderItemState { +export interface LoaderState + extends LoaderItemState { isIdle: boolean; isLoading: boolean; isError: boolean;