repos / starfx

supercharged async flow control library.
git clone https://github.com/neurosnap/starfx.git

commit
8137f72
parent
8137f72
author
Eric Bower
date
2023-03-28 02:41:52 +0000 UTC
init
33 files changed,  +1838, -0
A mod.ts
A npm.ts
A .gitignore
+5, -0
1@@ -0,0 +1,5 @@
2+*.swp
3+*.log
4+node_modules/
5+npm/
6+.DS_Store
A Makefile
+3, -0
1@@ -0,0 +1,3 @@
2+npm:
3+	NPM_VERSION=0.0.1 deno run --allow-env --allow-read --allow-write --allow-run ./npm.ts
4+.PHONY: npm
A README.md
+1, -0
1@@ -0,0 +1 @@
2+# starfx
A context.ts
+12, -0
 1@@ -0,0 +1,12 @@
 2+import { createChannel, createContext, getframe } from "./deps.ts";
 3+import type { Channel } from "./deps.ts";
 4+
 5+export const ErrContext = createContext<Channel<Error, void>>(
 6+  "fx:err",
 7+  createChannel<Error, void>(),
 8+);
 9+
10+export function* contextualize(context: string, value: unknown) {
11+  let frame = yield* getframe();
12+  frame.context[context] = value;
13+}
A deps.ts
+3, -0
1@@ -0,0 +1,3 @@
2+import React from "https://esm.sh/react@18.2.0";
3+export { React };
4+export * from "../mod.ts";
A examples/basic/app.tsx
+100, -0
  1@@ -0,0 +1,100 @@
  2+import React from "react";
  3+import { createRoot } from "react-dom/client";
  4+import { Action, configureStore } from "@reduxjs/toolkit";
  5+import { sleep } from "effection";
  6+import {
  7+  Provider as ReduxProvider,
  8+  useDispatch,
  9+  useSelector,
 10+} from "react-redux";
 11+
 12+// run `make npm` in `saga/` folder first
 13+import { ErrContext, forEach, go } from "../../npm/src/saga/mod";
 14+import { createFxMiddleware, take } from "../../npm/src/saga/redux";
 15+import { Provider } from "../../npm/src/saga/react";
 16+
 17+interface User {
 18+  id: string;
 19+  name: string;
 20+}
 21+
 22+interface State {
 23+  users: { [key: string]: User };
 24+}
 25+
 26+function selectUser(s: State, props: { id: string }) {
 27+  return s.users[props.id];
 28+}
 29+
 30+function App({ id }: { id: string }) {
 31+  const dispatch = useDispatch();
 32+  const user = useSelector((s: State) => selectUser(s, { id }));
 33+  return (
 34+    <div>
 35+      <div>hi there, {user.name}</div>
 36+      <button
 37+        onClick={() => dispatch({ type: "fetch-user", payload: { id: "1" } })}
 38+      >
 39+        Fetch user
 40+      </button>
 41+      <button onClick={() => dispatch({ type: "fetch-mailboxes" })}>
 42+        Fetch mailboxes
 43+      </button>
 44+    </div>
 45+  );
 46+}
 47+
 48+const initState: State = {
 49+  users: {
 50+    "1": { id: "1", name: "joe" },
 51+  },
 52+};
 53+
 54+function main() {
 55+  const reducer = (s: State = initState, _: Action) => s;
 56+  const fx = createFxMiddleware();
 57+  const store = configureStore({
 58+    reducer,
 59+    middleware: [fx.middleware],
 60+  });
 61+
 62+  function* users() {
 63+    while (true) {
 64+      const action = yield* take("fetch-user");
 65+      yield* go(function* () {
 66+        console.log(action);
 67+      });
 68+    }
 69+  }
 70+  function* mailboxes() {
 71+    while (true) {
 72+      const action = yield* take("fetch-mailboxes");
 73+      yield* go(function* () {
 74+        console.log(action);
 75+        yield* sleep(1000);
 76+        throw new Error("wtf");
 77+      });
 78+    }
 79+  }
 80+  function* logErrors() {
 81+    yield* forEach(ErrContext, function* (err) {
 82+      console.error(err);
 83+    });
 84+  }
 85+
 86+  fx.run([users, mailboxes, logErrors]);
 87+
 88+  const domNode = document.getElementById("root");
 89+  const root = createRoot(domNode);
 90+  root.render(
 91+    <ReduxProvider store={store}>
 92+      <Provider scope={fx.scope}>
 93+        <App id="1" />
 94+      </Provider>
 95+    </ReduxProvider>,
 96+  );
 97+}
 98+
 99+addEventListener("DOMContentLoaded", () => {
100+  main();
101+});
A examples/basic/index.html
+12, -0
 1@@ -0,0 +1,12 @@
 2+<!DOCTYPE html>
 3+<html lang="en">
 4+  <head>
 5+    <meta charset="UTF-8" />
 6+    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
 7+    <title>Basic usage</title>
 8+  </head>
 9+  <body>
10+    <div id="root"></div>
11+    <script type="module" src="/app.tsx"></script>
12+  </body>
13+</html>
A examples/basic/package.json
+25, -0
 1@@ -0,0 +1,25 @@
 2+{
 3+  "name": "starfx-basic",
 4+  "private": true,
 5+  "version": "0.0.0",
 6+  "type": "module",
 7+  "scripts": {
 8+    "dev": "vite --host 0.0.0.0",
 9+    "build": "tsc && vite build",
10+    "preview": "vite preview"
11+  },
12+  "dependencies": {
13+    "@reduxjs/toolkit": "^1.9.3",
14+    "effection": "3.0.0-alpha.5",
15+    "react": "^18.2.0",
16+    "react-dom": "^18.2.0",
17+    "react-redux": "^8.0.5"
18+  },
19+  "devDependencies": {
20+    "@types/react": "^18.0.28",
21+    "@types/react-dom": "^18.0.11",
22+    "@vitejs/plugin-react": "^3.1.0",
23+    "typescript": "^4.9.3",
24+    "vite": "^4.2.1"
25+  }
26+}
A examples/basic/tsconfig.json
+21, -0
 1@@ -0,0 +1,21 @@
 2+{
 3+  "compilerOptions": {
 4+    "target": "ESNext",
 5+    "useDefineForClassFields": true,
 6+    "lib": ["DOM", "DOM.Iterable", "ESNext"],
 7+    "allowJs": false,
 8+    "skipLibCheck": true,
 9+    "esModuleInterop": false,
10+    "allowSyntheticDefaultImports": true,
11+    "strict": true,
12+    "forceConsistentCasingInFileNames": true,
13+    "module": "ESNext",
14+    "moduleResolution": "Node",
15+    "resolveJsonModule": true,
16+    "isolatedModules": true,
17+    "noEmit": true,
18+    "jsx": "react-jsx"
19+  },
20+  "include": ["src"],
21+  "references": [{ "path": "./tsconfig.node.json" }]
22+}
A examples/basic/tsconfig.node.json
+9, -0
 1@@ -0,0 +1,9 @@
 2+{
 3+  "compilerOptions": {
 4+    "composite": true,
 5+    "module": "ESNext",
 6+    "moduleResolution": "Node",
 7+    "allowSyntheticDefaultImports": true
 8+  },
 9+  "include": ["vite.config.ts"]
10+}
A examples/basic/vite.config.ts
+7, -0
1@@ -0,0 +1,7 @@
2+import { defineConfig } from "vite";
3+import react from "@vitejs/plugin-react";
4+
5+// https://vitejs.dev/config/
6+export default defineConfig({
7+  plugins: [react()],
8+});
A examples/basic/yarn.lock
+806, -0
  1@@ -0,0 +1,806 @@
  2+# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
  3+# yarn lockfile v1
  4+
  5+
  6+"@ampproject/remapping@^2.2.0":
  7+  version "2.2.0"
  8+  resolved "https://registry.yarnpkg.com/@ampproject/remapping/-/remapping-2.2.0.tgz#56c133824780de3174aed5ab6834f3026790154d"
  9+  integrity sha512-qRmjj8nj9qmLTQXXmaR1cck3UXSRMPrbsLJAasZpF+t3riI71BXed5ebIOYwQntykeZuhjsdweEc9BxH5Jc26w==
 10+  dependencies:
 11+    "@jridgewell/gen-mapping" "^0.1.0"
 12+    "@jridgewell/trace-mapping" "^0.3.9"
 13+
 14+"@babel/code-frame@^7.18.6":
 15+  version "7.18.6"
 16+  resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.18.6.tgz#3b25d38c89600baa2dcc219edfa88a74eb2c427a"
 17+  integrity sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==
 18+  dependencies:
 19+    "@babel/highlight" "^7.18.6"
 20+
 21+"@babel/compat-data@^7.20.5":
 22+  version "7.21.0"
 23+  resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.21.0.tgz#c241dc454e5b5917e40d37e525e2f4530c399298"
 24+  integrity sha512-gMuZsmsgxk/ENC3O/fRw5QY8A9/uxQbbCEypnLIiYYc/qVJtEV7ouxC3EllIIwNzMqAQee5tanFabWsUOutS7g==
 25+
 26+"@babel/core@^7.20.12":
 27+  version "7.21.3"
 28+  resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.21.3.tgz#cf1c877284a469da5d1ce1d1e53665253fae712e"
 29+  integrity sha512-qIJONzoa/qiHghnm0l1n4i/6IIziDpzqc36FBs4pzMhDUraHqponwJLiAKm1hGLP3OSB/TVNz6rMwVGpwxxySw==
 30+  dependencies:
 31+    "@ampproject/remapping" "^2.2.0"
 32+    "@babel/code-frame" "^7.18.6"
 33+    "@babel/generator" "^7.21.3"
 34+    "@babel/helper-compilation-targets" "^7.20.7"
 35+    "@babel/helper-module-transforms" "^7.21.2"
 36+    "@babel/helpers" "^7.21.0"
 37+    "@babel/parser" "^7.21.3"
 38+    "@babel/template" "^7.20.7"
 39+    "@babel/traverse" "^7.21.3"
 40+    "@babel/types" "^7.21.3"
 41+    convert-source-map "^1.7.0"
 42+    debug "^4.1.0"
 43+    gensync "^1.0.0-beta.2"
 44+    json5 "^2.2.2"
 45+    semver "^6.3.0"
 46+
 47+"@babel/generator@^7.21.3":
 48+  version "7.21.3"
 49+  resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.21.3.tgz#232359d0874b392df04045d72ce2fd9bb5045fce"
 50+  integrity sha512-QS3iR1GYC/YGUnW7IdggFeN5c1poPUurnGttOV/bZgPGV+izC/D8HnD6DLwod0fsatNyVn1G3EVWMYIF0nHbeA==
 51+  dependencies:
 52+    "@babel/types" "^7.21.3"
 53+    "@jridgewell/gen-mapping" "^0.3.2"
 54+    "@jridgewell/trace-mapping" "^0.3.17"
 55+    jsesc "^2.5.1"
 56+
 57+"@babel/helper-compilation-targets@^7.20.7":
 58+  version "7.20.7"
 59+  resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.20.7.tgz#a6cd33e93629f5eb473b021aac05df62c4cd09bb"
 60+  integrity sha512-4tGORmfQcrc+bvrjb5y3dG9Mx1IOZjsHqQVUz7XCNHO+iTmqxWnVg3KRygjGmpRLJGdQSKuvFinbIb0CnZwHAQ==
 61+  dependencies:
 62+    "@babel/compat-data" "^7.20.5"
 63+    "@babel/helper-validator-option" "^7.18.6"
 64+    browserslist "^4.21.3"
 65+    lru-cache "^5.1.1"
 66+    semver "^6.3.0"
 67+
 68+"@babel/helper-environment-visitor@^7.18.9":
 69+  version "7.18.9"
 70+  resolved "https://registry.yarnpkg.com/@babel/helper-environment-visitor/-/helper-environment-visitor-7.18.9.tgz#0c0cee9b35d2ca190478756865bb3528422f51be"
 71+  integrity sha512-3r/aACDJ3fhQ/EVgFy0hpj8oHyHpQc+LPtJoY9SzTThAsStm4Ptegq92vqKoE3vD706ZVFWITnMnxucw+S9Ipg==
 72+
 73+"@babel/helper-function-name@^7.21.0":
 74+  version "7.21.0"
 75+  resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.21.0.tgz#d552829b10ea9f120969304023cd0645fa00b1b4"
 76+  integrity sha512-HfK1aMRanKHpxemaY2gqBmL04iAPOPRj7DxtNbiDOrJK+gdwkiNRVpCpUJYbUT+aZyemKN8brqTOxzCaG6ExRg==
 77+  dependencies:
 78+    "@babel/template" "^7.20.7"
 79+    "@babel/types" "^7.21.0"
 80+
 81+"@babel/helper-hoist-variables@^7.18.6":
 82+  version "7.18.6"
 83+  resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.18.6.tgz#d4d2c8fb4baeaa5c68b99cc8245c56554f926678"
 84+  integrity sha512-UlJQPkFqFULIcyW5sbzgbkxn2FKRgwWiRexcuaR8RNJRy8+LLveqPjwZV/bwrLZCN0eUHD/x8D0heK1ozuoo6Q==
 85+  dependencies:
 86+    "@babel/types" "^7.18.6"
 87+
 88+"@babel/helper-module-imports@^7.18.6":
 89+  version "7.18.6"
 90+  resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.18.6.tgz#1e3ebdbbd08aad1437b428c50204db13c5a3ca6e"
 91+  integrity sha512-0NFvs3VkuSYbFi1x2Vd6tKrywq+z/cLeYC/RJNFrIX/30Bf5aiGYbtvGXolEktzJH8o5E5KJ3tT+nkxuuZFVlA==
 92+  dependencies:
 93+    "@babel/types" "^7.18.6"
 94+
 95+"@babel/helper-module-transforms@^7.21.2":
 96+  version "7.21.2"
 97+  resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.21.2.tgz#160caafa4978ac8c00ac66636cb0fa37b024e2d2"
 98+  integrity sha512-79yj2AR4U/Oqq/WOV7Lx6hUjau1Zfo4cI+JLAVYeMV5XIlbOhmjEk5ulbTc9fMpmlojzZHkUUxAiK+UKn+hNQQ==
 99+  dependencies:
100+    "@babel/helper-environment-visitor" "^7.18.9"
101+    "@babel/helper-module-imports" "^7.18.6"
102+    "@babel/helper-simple-access" "^7.20.2"
103+    "@babel/helper-split-export-declaration" "^7.18.6"
104+    "@babel/helper-validator-identifier" "^7.19.1"
105+    "@babel/template" "^7.20.7"
106+    "@babel/traverse" "^7.21.2"
107+    "@babel/types" "^7.21.2"
108+
109+"@babel/helper-plugin-utils@^7.19.0", "@babel/helper-plugin-utils@^7.20.2":
110+  version "7.20.2"
111+  resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.20.2.tgz#d1b9000752b18d0877cff85a5c376ce5c3121629"
112+  integrity sha512-8RvlJG2mj4huQ4pZ+rU9lqKi9ZKiRmuvGuM2HlWmkmgOhbs6zEAw6IEiJ5cQqGbDzGZOhwuOQNtZMi/ENLjZoQ==
113+
114+"@babel/helper-simple-access@^7.20.2":
115+  version "7.20.2"
116+  resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.20.2.tgz#0ab452687fe0c2cfb1e2b9e0015de07fc2d62dd9"
117+  integrity sha512-+0woI/WPq59IrqDYbVGfshjT5Dmk/nnbdpcF8SnMhhXObpTq2KNBdLFRFrkVdbDOyUmHBCxzm5FHV1rACIkIbA==
118+  dependencies:
119+    "@babel/types" "^7.20.2"
120+
121+"@babel/helper-split-export-declaration@^7.18.6":
122+  version "7.18.6"
123+  resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.18.6.tgz#7367949bc75b20c6d5a5d4a97bba2824ae8ef075"
124+  integrity sha512-bde1etTx6ZyTmobl9LLMMQsaizFVZrquTEHOqKeQESMKo4PlObf+8+JA25ZsIpZhT/WEd39+vOdLXAFG/nELpA==
125+  dependencies:
126+    "@babel/types" "^7.18.6"
127+
128+"@babel/helper-string-parser@^7.19.4":
129+  version "7.19.4"
130+  resolved "https://registry.yarnpkg.com/@babel/helper-string-parser/-/helper-string-parser-7.19.4.tgz#38d3acb654b4701a9b77fb0615a96f775c3a9e63"
131+  integrity sha512-nHtDoQcuqFmwYNYPz3Rah5ph2p8PFeFCsZk9A/48dPc/rGocJ5J3hAAZ7pb76VWX3fZKu+uEr/FhH5jLx7umrw==
132+
133+"@babel/helper-validator-identifier@^7.18.6", "@babel/helper-validator-identifier@^7.19.1":
134+  version "7.19.1"
135+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz#7eea834cf32901ffdc1a7ee555e2f9c27e249ca2"
136+  integrity sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==
137+
138+"@babel/helper-validator-option@^7.18.6":
139+  version "7.21.0"
140+  resolved "https://registry.yarnpkg.com/@babel/helper-validator-option/-/helper-validator-option-7.21.0.tgz#8224c7e13ace4bafdc4004da2cf064ef42673180"
141+  integrity sha512-rmL/B8/f0mKS2baE9ZpyTcTavvEuWhTTW8amjzXNvYG4AwBsqTLikfXsEofsJEfKHf+HQVQbFOHy6o+4cnC/fQ==
142+
143+"@babel/helpers@^7.21.0":
144+  version "7.21.0"
145+  resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.21.0.tgz#9dd184fb5599862037917cdc9eecb84577dc4e7e"
146+  integrity sha512-XXve0CBtOW0pd7MRzzmoyuSj0e3SEzj8pgyFxnTT1NJZL38BD1MK7yYrm8yefRPIDvNNe14xR4FdbHwpInD4rA==
147+  dependencies:
148+    "@babel/template" "^7.20.7"
149+    "@babel/traverse" "^7.21.0"
150+    "@babel/types" "^7.21.0"
151+
152+"@babel/highlight@^7.18.6":
153+  version "7.18.6"
154+  resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.18.6.tgz#81158601e93e2563795adcbfbdf5d64be3f2ecdf"
155+  integrity sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==
156+  dependencies:
157+    "@babel/helper-validator-identifier" "^7.18.6"
158+    chalk "^2.0.0"
159+    js-tokens "^4.0.0"
160+
161+"@babel/parser@^7.20.7", "@babel/parser@^7.21.3":
162+  version "7.21.3"
163+  resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.21.3.tgz#1d285d67a19162ff9daa358d4cb41d50c06220b3"
164+  integrity sha512-lobG0d7aOfQRXh8AyklEAgZGvA4FShxo6xQbUrrT/cNBPUdIDojlokwJsQyCC/eKia7ifqM0yP+2DRZ4WKw2RQ==
165+
166+"@babel/plugin-transform-react-jsx-self@^7.18.6":
167+  version "7.21.0"
168+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.21.0.tgz#ec98d4a9baafc5a1eb398da4cf94afbb40254a54"
169+  integrity sha512-f/Eq+79JEu+KUANFks9UZCcvydOOGMgF7jBrcwjHa5jTZD8JivnhCJYvmlhR/WTXBWonDExPoW0eO/CR4QJirA==
170+  dependencies:
171+    "@babel/helper-plugin-utils" "^7.20.2"
172+
173+"@babel/plugin-transform-react-jsx-source@^7.19.6":
174+  version "7.19.6"
175+  resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.19.6.tgz#88578ae8331e5887e8ce28e4c9dc83fb29da0b86"
176+  integrity sha512-RpAi004QyMNisst/pvSanoRdJ4q+jMCWyk9zdw/CyLB9j8RXEahodR6l2GyttDRyEVWZtbN+TpLiHJ3t34LbsQ==
177+  dependencies:
178+    "@babel/helper-plugin-utils" "^7.19.0"
179+
180+"@babel/runtime@^7.12.1", "@babel/runtime@^7.9.2":
181+  version "7.21.0"
182+  resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.21.0.tgz#5b55c9d394e5fcf304909a8b00c07dc217b56673"
183+  integrity sha512-xwII0//EObnq89Ji5AKYQaRYiW/nZ3llSv29d49IuxPhKbtJoLP+9QUUZ4nVragQVtaVGeZrpB+ZtG/Pdy/POw==
184+  dependencies:
185+    regenerator-runtime "^0.13.11"
186+
187+"@babel/template@^7.20.7":
188+  version "7.20.7"
189+  resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.20.7.tgz#a15090c2839a83b02aa996c0b4994005841fd5a8"
190+  integrity sha512-8SegXApWe6VoNw0r9JHpSteLKTpTiLZ4rMlGIm9JQ18KiCtyQiAMEazujAHrUS5flrcqYZa75ukev3P6QmUwUw==
191+  dependencies:
192+    "@babel/code-frame" "^7.18.6"
193+    "@babel/parser" "^7.20.7"
194+    "@babel/types" "^7.20.7"
195+
196+"@babel/traverse@^7.21.0", "@babel/traverse@^7.21.2", "@babel/traverse@^7.21.3":
197+  version "7.21.3"
198+  resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.21.3.tgz#4747c5e7903d224be71f90788b06798331896f67"
199+  integrity sha512-XLyopNeaTancVitYZe2MlUEvgKb6YVVPXzofHgqHijCImG33b/uTurMS488ht/Hbsb2XK3U2BnSTxKVNGV3nGQ==
200+  dependencies:
201+    "@babel/code-frame" "^7.18.6"
202+    "@babel/generator" "^7.21.3"
203+    "@babel/helper-environment-visitor" "^7.18.9"
204+    "@babel/helper-function-name" "^7.21.0"
205+    "@babel/helper-hoist-variables" "^7.18.6"
206+    "@babel/helper-split-export-declaration" "^7.18.6"
207+    "@babel/parser" "^7.21.3"
208+    "@babel/types" "^7.21.3"
209+    debug "^4.1.0"
210+    globals "^11.1.0"
211+
212+"@babel/types@^7.18.6", "@babel/types@^7.20.2", "@babel/types@^7.20.7", "@babel/types@^7.21.0", "@babel/types@^7.21.2", "@babel/types@^7.21.3":
213+  version "7.21.3"
214+  resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.21.3.tgz#4865a5357ce40f64e3400b0f3b737dc6d4f64d05"
215+  integrity sha512-sBGdETxC+/M4o/zKC0sl6sjWv62WFR/uzxrJ6uYyMLZOUlPnwzw0tKgVHOXxaAd5l2g8pEDM5RZ495GPQI77kg==
216+  dependencies:
217+    "@babel/helper-string-parser" "^7.19.4"
218+    "@babel/helper-validator-identifier" "^7.19.1"
219+    to-fast-properties "^2.0.0"
220+
221+"@esbuild/android-arm64@0.17.12":
222+  version "0.17.12"
223+  resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.17.12.tgz#15a8e2b407d03989b899e325151dc2e96d19c620"
224+  integrity sha512-WQ9p5oiXXYJ33F2EkE3r0FRDFVpEdcDiwNX3u7Xaibxfx6vQE0Sb8ytrfQsA5WO6kDn6mDfKLh6KrPBjvkk7xA==
225+
226+"@esbuild/android-arm@0.17.12":
227+  version "0.17.12"
228+  resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.17.12.tgz#677a09297e1f4f37aba7b4fc4f31088b00484985"
229+  integrity sha512-E/sgkvwoIfj4aMAPL2e35VnUJspzVYl7+M1B2cqeubdBhADV4uPon0KCc8p2G+LqSJ6i8ocYPCqY3A4GGq0zkQ==
230+
231+"@esbuild/android-x64@0.17.12":
232+  version "0.17.12"
233+  resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.17.12.tgz#b292729eef4e0060ae1941f6a021c4d2542a3521"
234+  integrity sha512-m4OsaCr5gT+se25rFPHKQXARMyAehHTQAz4XX1Vk3d27VtqiX0ALMBPoXZsGaB6JYryCLfgGwUslMqTfqeLU0w==
235+
236+"@esbuild/darwin-arm64@0.17.12":
237+  version "0.17.12"
238+  resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.17.12.tgz#efa35318df931da05825894e1787b976d55adbe3"
239+  integrity sha512-O3GCZghRIx+RAN0NDPhyyhRgwa19MoKlzGonIb5hgTj78krqp9XZbYCvFr9N1eUxg0ZQEpiiZ4QvsOQwBpP+lg==
240+
241+"@esbuild/darwin-x64@0.17.12":
242+  version "0.17.12"
243+  resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.17.12.tgz#e7b54bb3f6dc81aadfd0485cd1623c648157e64d"
244+  integrity sha512-5D48jM3tW27h1qjaD9UNRuN+4v0zvksqZSPZqeSWggfMlsVdAhH3pwSfQIFJwcs9QJ9BRibPS4ViZgs3d2wsCA==
245+
246+"@esbuild/freebsd-arm64@0.17.12":
247+  version "0.17.12"
248+  resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.17.12.tgz#99a18a8579d6299c449566fe91d9b6a54cf2a591"
249+  integrity sha512-OWvHzmLNTdF1erSvrfoEBGlN94IE6vCEaGEkEH29uo/VoONqPnoDFfShi41Ew+yKimx4vrmmAJEGNoyyP+OgOQ==
250+
251+"@esbuild/freebsd-x64@0.17.12":
252+  version "0.17.12"
253+  resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.17.12.tgz#0e090190fede307fb4022f671791a50dd5121abd"
254+  integrity sha512-A0Xg5CZv8MU9xh4a+7NUpi5VHBKh1RaGJKqjxe4KG87X+mTjDE6ZvlJqpWoeJxgfXHT7IMP9tDFu7IZ03OtJAw==
255+
256+"@esbuild/linux-arm64@0.17.12":
257+  version "0.17.12"
258+  resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.17.12.tgz#7fe2a69f8a1a7153fa2b0f44aabcadb59475c7e0"
259+  integrity sha512-cK3AjkEc+8v8YG02hYLQIQlOznW+v9N+OI9BAFuyqkfQFR+DnDLhEM5N8QRxAUz99cJTo1rLNXqRrvY15gbQUg==
260+
261+"@esbuild/linux-arm@0.17.12":
262+  version "0.17.12"
263+  resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.17.12.tgz#b87c76ebf1fe03e01fd6bb5cfc2f3c5becd5ee93"
264+  integrity sha512-WsHyJ7b7vzHdJ1fv67Yf++2dz3D726oO3QCu8iNYik4fb5YuuReOI9OtA+n7Mk0xyQivNTPbl181s+5oZ38gyA==
265+
266+"@esbuild/linux-ia32@0.17.12":
267+  version "0.17.12"
268+  resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.17.12.tgz#9e9357090254524d32e6708883a47328f3037858"
269+  integrity sha512-jdOBXJqcgHlah/nYHnj3Hrnl9l63RjtQ4vn9+bohjQPI2QafASB5MtHAoEv0JQHVb/xYQTFOeuHnNYE1zF7tYw==
270+
271+"@esbuild/linux-loong64@0.17.12":
272+  version "0.17.12"
273+  resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.17.12.tgz#9deb605f9e2c82f59412ddfefb4b6b96d54b5b5b"
274+  integrity sha512-GTOEtj8h9qPKXCyiBBnHconSCV9LwFyx/gv3Phw0pa25qPYjVuuGZ4Dk14bGCfGX3qKF0+ceeQvwmtI+aYBbVA==
275+
276+"@esbuild/linux-mips64el@0.17.12":
277+  version "0.17.12"
278+  resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.17.12.tgz#6ef170b974ddf5e6acdfa5b05f22b6e9dfd2b003"
279+  integrity sha512-o8CIhfBwKcxmEENOH9RwmUejs5jFiNoDw7YgS0EJTF6kgPgcqLFjgoc5kDey5cMHRVCIWc6kK2ShUePOcc7RbA==
280+
281+"@esbuild/linux-ppc64@0.17.12":
282+  version "0.17.12"
283+  resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.17.12.tgz#1638d3d4acf1d34aaf37cf8908c2e1cefed16204"
284+  integrity sha512-biMLH6NR/GR4z+ap0oJYb877LdBpGac8KfZoEnDiBKd7MD/xt8eaw1SFfYRUeMVx519kVkAOL2GExdFmYnZx3A==
285+
286+"@esbuild/linux-riscv64@0.17.12":
287+  version "0.17.12"
288+  resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.17.12.tgz#135b6e9270a8e2de2b9094bb21a287517df520ef"
289+  integrity sha512-jkphYUiO38wZGeWlfIBMB72auOllNA2sLfiZPGDtOBb1ELN8lmqBrlMiucgL8awBw1zBXN69PmZM6g4yTX84TA==
290+
291+"@esbuild/linux-s390x@0.17.12":
292+  version "0.17.12"
293+  resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.17.12.tgz#21e40830770c5d08368e300842bde382ce97d615"
294+  integrity sha512-j3ucLdeY9HBcvODhCY4b+Ds3hWGO8t+SAidtmWu/ukfLLG/oYDMaA+dnugTVAg5fnUOGNbIYL9TOjhWgQB8W5g==
295+
296+"@esbuild/linux-x64@0.17.12":
297+  version "0.17.12"
298+  resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.17.12.tgz#76c1c199871d48e1aaa47a762fb9e0dca52e1f7a"
299+  integrity sha512-uo5JL3cgaEGotaqSaJdRfFNSCUJOIliKLnDGWaVCgIKkHxwhYMm95pfMbWZ9l7GeW9kDg0tSxcy9NYdEtjwwmA==
300+
301+"@esbuild/netbsd-x64@0.17.12":
302+  version "0.17.12"
303+  resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.17.12.tgz#c7c3b3017a4b938c76c35f66af529baf62eac527"
304+  integrity sha512-DNdoRg8JX+gGsbqt2gPgkgb00mqOgOO27KnrWZtdABl6yWTST30aibGJ6geBq3WM2TIeW6COs5AScnC7GwtGPg==
305+
306+"@esbuild/openbsd-x64@0.17.12":
307+  version "0.17.12"
308+  resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.17.12.tgz#05d04217d980e049001afdbeacbb58d31bb5cefb"
309+  integrity sha512-aVsENlr7B64w8I1lhHShND5o8cW6sB9n9MUtLumFlPhG3elhNWtE7M1TFpj3m7lT3sKQUMkGFjTQBrvDDO1YWA==
310+
311+"@esbuild/sunos-x64@0.17.12":
312+  version "0.17.12"
313+  resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.17.12.tgz#cf3862521600e4eb6c440ec3bad31ed40fb87ef3"
314+  integrity sha512-qbHGVQdKSwi0JQJuZznS4SyY27tYXYF0mrgthbxXrZI3AHKuRvU+Eqbg/F0rmLDpW/jkIZBlCO1XfHUBMNJ1pg==
315+
316+"@esbuild/win32-arm64@0.17.12":
317+  version "0.17.12"
318+  resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.17.12.tgz#43dd7fb5be77bf12a1550355ab2b123efd60868e"
319+  integrity sha512-zsCp8Ql+96xXTVTmm6ffvoTSZSV2B/LzzkUXAY33F/76EajNw1m+jZ9zPfNJlJ3Rh4EzOszNDHsmG/fZOhtqDg==
320+
321+"@esbuild/win32-ia32@0.17.12":
322+  version "0.17.12"
323+  resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.17.12.tgz#9940963d0bff4ea3035a84e2b4c6e41c5e6296eb"
324+  integrity sha512-FfrFjR4id7wcFYOdqbDfDET3tjxCozUgbqdkOABsSFzoZGFC92UK7mg4JKRc/B3NNEf1s2WHxJ7VfTdVDPN3ng==
325+
326+"@esbuild/win32-x64@0.17.12":
327+  version "0.17.12"
328+  resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.17.12.tgz#3a11d13e9a5b0c05db88991b234d8baba1f96487"
329+  integrity sha512-JOOxw49BVZx2/5tW3FqkdjSD/5gXYeVGPDcB0lvap0gLQshkh1Nyel1QazC+wNxus3xPlsYAgqU1BUmrmCvWtw==
330+
331+"@jridgewell/gen-mapping@^0.1.0":
332+  version "0.1.1"
333+  resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.1.1.tgz#e5d2e450306a9491e3bd77e323e38d7aff315996"
334+  integrity sha512-sQXCasFk+U8lWYEe66WxRDOE9PjVz4vSM51fTu3Hw+ClTpUSQb718772vH3pyS5pShp6lvQM7SxgIDXXXmOX7w==
335+  dependencies:
336+    "@jridgewell/set-array" "^1.0.0"
337+    "@jridgewell/sourcemap-codec" "^1.4.10"
338+
339+"@jridgewell/gen-mapping@^0.3.2":
340+  version "0.3.2"
341+  resolved "https://registry.yarnpkg.com/@jridgewell/gen-mapping/-/gen-mapping-0.3.2.tgz#c1aedc61e853f2bb9f5dfe6d4442d3b565b253b9"
342+  integrity sha512-mh65xKQAzI6iBcFzwv28KVWSmCkdRBWoOh+bYQGW3+6OZvbbN3TqMGo5hqYxQniRcH9F2VZIoJCm4pa3BPDK/A==
343+  dependencies:
344+    "@jridgewell/set-array" "^1.0.1"
345+    "@jridgewell/sourcemap-codec" "^1.4.10"
346+    "@jridgewell/trace-mapping" "^0.3.9"
347+
348+"@jridgewell/resolve-uri@3.1.0":
349+  version "3.1.0"
350+  resolved "https://registry.yarnpkg.com/@jridgewell/resolve-uri/-/resolve-uri-3.1.0.tgz#2203b118c157721addfe69d47b70465463066d78"
351+  integrity sha512-F2msla3tad+Mfht5cJq7LSXcdudKTWCVYUgw6pLFOOHSTtZlj6SWNYAp+AhuqLmWdBO2X5hPrLcu8cVP8fy28w==
352+
353+"@jridgewell/set-array@^1.0.0", "@jridgewell/set-array@^1.0.1":
354+  version "1.1.2"
355+  resolved "https://registry.yarnpkg.com/@jridgewell/set-array/-/set-array-1.1.2.tgz#7c6cf998d6d20b914c0a55a91ae928ff25965e72"
356+  integrity sha512-xnkseuNADM0gt2bs+BvhO0p78Mk762YnZdsuzFV018NoG1Sj1SCQvpSqa7XUaTam5vAGasABV9qXASMKnFMwMw==
357+
358+"@jridgewell/sourcemap-codec@1.4.14", "@jridgewell/sourcemap-codec@^1.4.10", "@jridgewell/sourcemap-codec@^1.4.13":
359+  version "1.4.14"
360+  resolved "https://registry.yarnpkg.com/@jridgewell/sourcemap-codec/-/sourcemap-codec-1.4.14.tgz#add4c98d341472a289190b424efbdb096991bb24"
361+  integrity sha512-XPSJHWmi394fuUuzDnGz1wiKqWfo1yXecHQMRf2l6hztTO+nPru658AyDngaBe7isIxEkRsPR3FZh+s7iVa4Uw==
362+
363+"@jridgewell/trace-mapping@^0.3.17", "@jridgewell/trace-mapping@^0.3.9":
364+  version "0.3.17"
365+  resolved "https://registry.yarnpkg.com/@jridgewell/trace-mapping/-/trace-mapping-0.3.17.tgz#793041277af9073b0951a7fe0f0d8c4c98c36985"
366+  integrity sha512-MCNzAp77qzKca9+W/+I0+sEpaUnZoeasnghNeVc41VZCEKaCH73Vq3BZZ/SzWIgrqE4H4ceI+p+b6C0mHf9T4g==
367+  dependencies:
368+    "@jridgewell/resolve-uri" "3.1.0"
369+    "@jridgewell/sourcemap-codec" "1.4.14"
370+
371+"@reduxjs/toolkit@^1.9.3":
372+  version "1.9.3"
373+  resolved "https://registry.yarnpkg.com/@reduxjs/toolkit/-/toolkit-1.9.3.tgz#27e1a33072b5a312e4f7fa19247fec160bbb2df9"
374+  integrity sha512-GU2TNBQVofL09VGmuSioNPQIu6Ml0YLf4EJhgj0AvBadRlCGzUWet8372LjvO4fqKZF2vH1xU0htAa7BrK9pZg==
375+  dependencies:
376+    immer "^9.0.16"
377+    redux "^4.2.0"
378+    redux-thunk "^2.4.2"
379+    reselect "^4.1.7"
380+
381+"@types/hoist-non-react-statics@^3.3.1":
382+  version "3.3.1"
383+  resolved "https://registry.yarnpkg.com/@types/hoist-non-react-statics/-/hoist-non-react-statics-3.3.1.tgz#1124aafe5118cb591977aeb1ceaaed1070eb039f"
384+  integrity sha512-iMIqiko6ooLrTh1joXodJK5X9xeEALT1kM5G3ZLhD3hszxBdIEd5C75U834D9mLcINgD4OyZf5uQXjkuYydWvA==
385+  dependencies:
386+    "@types/react" "*"
387+    hoist-non-react-statics "^3.3.0"
388+
389+"@types/prop-types@*":
390+  version "15.7.5"
391+  resolved "https://registry.yarnpkg.com/@types/prop-types/-/prop-types-15.7.5.tgz#5f19d2b85a98e9558036f6a3cacc8819420f05cf"
392+  integrity sha512-JCB8C6SnDoQf0cNycqd/35A7MjcnK+ZTqE7judS6o7utxUCg6imJg3QK2qzHKszlTjcj2cn+NwMB2i96ubpj7w==
393+
394+"@types/react-dom@^18.0.11":
395+  version "18.0.11"
396+  resolved "https://registry.yarnpkg.com/@types/react-dom/-/react-dom-18.0.11.tgz#321351c1459bc9ca3d216aefc8a167beec334e33"
397+  integrity sha512-O38bPbI2CWtgw/OoQoY+BRelw7uysmXbWvw3nLWO21H1HSh+GOlqPuXshJfjmpNlKiiSDG9cc1JZAaMmVdcTlw==
398+  dependencies:
399+    "@types/react" "*"
400+
401+"@types/react@*", "@types/react@^18.0.28":
402+  version "18.0.28"
403+  resolved "https://registry.yarnpkg.com/@types/react/-/react-18.0.28.tgz#accaeb8b86f4908057ad629a26635fe641480065"
404+  integrity sha512-RD0ivG1kEztNBdoAK7lekI9M+azSnitIn85h4iOiaLjaTrMjzslhaqCGaI4IyCJ1RljWiLCEu4jyrLLgqxBTew==
405+  dependencies:
406+    "@types/prop-types" "*"
407+    "@types/scheduler" "*"
408+    csstype "^3.0.2"
409+
410+"@types/scheduler@*":
411+  version "0.16.2"
412+  resolved "https://registry.yarnpkg.com/@types/scheduler/-/scheduler-0.16.2.tgz#1a62f89525723dde24ba1b01b092bf5df8ad4d39"
413+  integrity sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==
414+
415+"@types/use-sync-external-store@^0.0.3":
416+  version "0.0.3"
417+  resolved "https://registry.yarnpkg.com/@types/use-sync-external-store/-/use-sync-external-store-0.0.3.tgz#b6725d5f4af24ace33b36fafd295136e75509f43"
418+  integrity sha512-EwmlvuaxPNej9+T4v5AuBPJa2x2UOJVdjCtDHgcDqitUeOtjnJKJ+apYjVcAoBEMjKW1VVFGZLUb5+qqa09XFA==
419+
420+"@vitejs/plugin-react@^3.1.0":
421+  version "3.1.0"
422+  resolved "https://registry.yarnpkg.com/@vitejs/plugin-react/-/plugin-react-3.1.0.tgz#d1091f535eab8b83d6e74034d01e27d73c773240"
423+  integrity sha512-AfgcRL8ZBhAlc3BFdigClmTUMISmmzHn7sB2h9U1odvc5U/MjWXsAaz18b/WoppUTDBzxOJwo2VdClfUcItu9g==
424+  dependencies:
425+    "@babel/core" "^7.20.12"
426+    "@babel/plugin-transform-react-jsx-self" "^7.18.6"
427+    "@babel/plugin-transform-react-jsx-source" "^7.19.6"
428+    magic-string "^0.27.0"
429+    react-refresh "^0.14.0"
430+
431+ansi-styles@^3.2.1:
432+  version "3.2.1"
433+  resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
434+  integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
435+  dependencies:
436+    color-convert "^1.9.0"
437+
438+browserslist@^4.21.3:
439+  version "4.21.5"
440+  resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.21.5.tgz#75c5dae60063ee641f977e00edd3cfb2fb7af6a7"
441+  integrity sha512-tUkiguQGW7S3IhB7N+c2MV/HZPSCPAAiYBZXLsBhFB/PCy6ZKKsZrmBayHV9fdGV/ARIfJ14NkxKzRDjvp7L6w==
442+  dependencies:
443+    caniuse-lite "^1.0.30001449"
444+    electron-to-chromium "^1.4.284"
445+    node-releases "^2.0.8"
446+    update-browserslist-db "^1.0.10"
447+
448+caniuse-lite@^1.0.30001449:
449+  version "1.0.30001469"
450+  resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001469.tgz#3dd505430c8522fdc9f94b4a19518e330f5c945a"
451+  integrity sha512-Rcp7221ScNqQPP3W+lVOYDyjdR6dC+neEQCttoNr5bAyz54AboB4iwpnWgyi8P4YUsPybVzT4LgWiBbI3drL4g==
452+
453+chalk@^2.0.0:
454+  version "2.4.2"
455+  resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
456+  integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
457+  dependencies:
458+    ansi-styles "^3.2.1"
459+    escape-string-regexp "^1.0.5"
460+    supports-color "^5.3.0"
461+
462+color-convert@^1.9.0:
463+  version "1.9.3"
464+  resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
465+  integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
466+  dependencies:
467+    color-name "1.1.3"
468+
469+color-name@1.1.3:
470+  version "1.1.3"
471+  resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
472+  integrity sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==
473+
474+convert-source-map@^1.7.0:
475+  version "1.9.0"
476+  resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.9.0.tgz#7faae62353fb4213366d0ca98358d22e8368b05f"
477+  integrity sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==
478+
479+csstype@^3.0.2:
480+  version "3.1.1"
481+  resolved "https://registry.yarnpkg.com/csstype/-/csstype-3.1.1.tgz#841b532c45c758ee546a11d5bd7b7b473c8c30b9"
482+  integrity sha512-DJR/VvkAvSZW9bTouZue2sSxDwdTN92uHjqeKVm+0dAqdfNykRzQ95tay8aXMBAAPpUiq4Qcug2L7neoRh2Egw==
483+
484+debug@^4.1.0:
485+  version "4.3.4"
486+  resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865"
487+  integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==
488+  dependencies:
489+    ms "2.1.2"
490+
491+effection@3.0.0-alpha.5:
492+  version "3.0.0-alpha.5"
493+  resolved "https://registry.yarnpkg.com/effection/-/effection-3.0.0-alpha.5.tgz#b5974c56a58f1fb1a96f7cb612e7506ec50d811b"
494+  integrity sha512-LEux/eynsZgMxhP9E4cHBr6zOwl/fpb63CKkwXqLKRHwQyA/8EU/rYI6yKdK4zOrRQdkoalh8OAk0AtBN3rpYQ==
495+
496+electron-to-chromium@^1.4.284:
497+  version "1.4.334"
498+  resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.334.tgz#eacdcb1145534202d569610c5915b63a3fec0eb9"
499+  integrity sha512-laZ1odk+TRen6q0GeyQx/JEkpD3iSZT7ewopCpKqg9bTjP1l8XRfU3Bg20CFjNPZkp5+NDBl3iqd4o/kPO+Vew==
500+
501+esbuild@^0.17.5:
502+  version "0.17.12"
503+  resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.17.12.tgz#2ad7523bf1bc01881e9d904bc04e693bd3bdcf2f"
504+  integrity sha512-bX/zHl7Gn2CpQwcMtRogTTBf9l1nl+H6R8nUbjk+RuKqAE3+8FDulLA+pHvX7aA7Xe07Iwa+CWvy9I8Y2qqPKQ==
505+  optionalDependencies:
506+    "@esbuild/android-arm" "0.17.12"
507+    "@esbuild/android-arm64" "0.17.12"
508+    "@esbuild/android-x64" "0.17.12"
509+    "@esbuild/darwin-arm64" "0.17.12"
510+    "@esbuild/darwin-x64" "0.17.12"
511+    "@esbuild/freebsd-arm64" "0.17.12"
512+    "@esbuild/freebsd-x64" "0.17.12"
513+    "@esbuild/linux-arm" "0.17.12"
514+    "@esbuild/linux-arm64" "0.17.12"
515+    "@esbuild/linux-ia32" "0.17.12"
516+    "@esbuild/linux-loong64" "0.17.12"
517+    "@esbuild/linux-mips64el" "0.17.12"
518+    "@esbuild/linux-ppc64" "0.17.12"
519+    "@esbuild/linux-riscv64" "0.17.12"
520+    "@esbuild/linux-s390x" "0.17.12"
521+    "@esbuild/linux-x64" "0.17.12"
522+    "@esbuild/netbsd-x64" "0.17.12"
523+    "@esbuild/openbsd-x64" "0.17.12"
524+    "@esbuild/sunos-x64" "0.17.12"
525+    "@esbuild/win32-arm64" "0.17.12"
526+    "@esbuild/win32-ia32" "0.17.12"
527+    "@esbuild/win32-x64" "0.17.12"
528+
529+escalade@^3.1.1:
530+  version "3.1.1"
531+  resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
532+  integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
533+
534+escape-string-regexp@^1.0.5:
535+  version "1.0.5"
536+  resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
537+  integrity sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==
538+
539+fsevents@~2.3.2:
540+  version "2.3.2"
541+  resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.3.2.tgz#8a526f78b8fdf4623b709e0b975c52c24c02fd1a"
542+  integrity sha512-xiqMQR4xAeHTuB9uWm+fFRcIOgKBMiOBP+eXiyT7jsgVCq1bkVygt00oASowB7EdtpOHaaPgKt812P9ab+DDKA==
543+
544+function-bind@^1.1.1:
545+  version "1.1.1"
546+  resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d"
547+  integrity sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==
548+
549+gensync@^1.0.0-beta.2:
550+  version "1.0.0-beta.2"
551+  resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.2.tgz#32a6ee76c3d7f52d46b2b1ae5d93fea8580a25e0"
552+  integrity sha512-3hN7NaskYvMDLQY55gnW3NQ+mesEAepTqlg+VEbj7zzqEMBVNhzcGYYeqFo/TlYz6eQiFcp1HcsCZO+nGgS8zg==
553+
554+globals@^11.1.0:
555+  version "11.12.0"
556+  resolved "https://registry.yarnpkg.com/globals/-/globals-11.12.0.tgz#ab8795338868a0babd8525758018c2a7eb95c42e"
557+  integrity sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==
558+
559+has-flag@^3.0.0:
560+  version "3.0.0"
561+  resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
562+  integrity sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==
563+
564+has@^1.0.3:
565+  version "1.0.3"
566+  resolved "https://registry.yarnpkg.com/has/-/has-1.0.3.tgz#722d7cbfc1f6aa8241f16dd814e011e1f41e8796"
567+  integrity sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==
568+  dependencies:
569+    function-bind "^1.1.1"
570+
571+hoist-non-react-statics@^3.3.0, hoist-non-react-statics@^3.3.2:
572+  version "3.3.2"
573+  resolved "https://registry.yarnpkg.com/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz#ece0acaf71d62c2969c2ec59feff42a4b1a85b45"
574+  integrity sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==
575+  dependencies:
576+    react-is "^16.7.0"
577+
578+immer@^9.0.16:
579+  version "9.0.19"
580+  resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.19.tgz#67fb97310555690b5f9cd8380d38fc0aabb6b38b"
581+  integrity sha512-eY+Y0qcsB4TZKwgQzLaE/lqYMlKhv5J9dyd2RhhtGhNo2njPXDqU9XPfcNfa3MIDsdtZt5KlkIsirlo4dHsWdQ==
582+
583+is-core-module@^2.9.0:
584+  version "2.11.0"
585+  resolved "https://registry.yarnpkg.com/is-core-module/-/is-core-module-2.11.0.tgz#ad4cb3e3863e814523c96f3f58d26cc570ff0144"
586+  integrity sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==
587+  dependencies:
588+    has "^1.0.3"
589+
590+"js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
591+  version "4.0.0"
592+  resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
593+  integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
594+
595+jsesc@^2.5.1:
596+  version "2.5.2"
597+  resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-2.5.2.tgz#80564d2e483dacf6e8ef209650a67df3f0c283a4"
598+  integrity sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==
599+
600+json5@^2.2.2:
601+  version "2.2.3"
602+  resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.3.tgz#78cd6f1a19bdc12b73db5ad0c61efd66c1e29283"
603+  integrity sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==
604+
605+loose-envify@^1.1.0:
606+  version "1.4.0"
607+  resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
608+  integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
609+  dependencies:
610+    js-tokens "^3.0.0 || ^4.0.0"
611+
612+lru-cache@^5.1.1:
613+  version "5.1.1"
614+  resolved "https://registry.yarnpkg.com/lru-cache/-/lru-cache-5.1.1.tgz#1da27e6710271947695daf6848e847f01d84b920"
615+  integrity sha512-KpNARQA3Iwv+jTA0utUVVbrh+Jlrr1Fv0e56GGzAFOXN7dk/FviaDW8LHmK52DlcH4WP2n6gI8vN1aesBFgo9w==
616+  dependencies:
617+    yallist "^3.0.2"
618+
619+magic-string@^0.27.0:
620+  version "0.27.0"
621+  resolved "https://registry.yarnpkg.com/magic-string/-/magic-string-0.27.0.tgz#e4a3413b4bab6d98d2becffd48b4a257effdbbf3"
622+  integrity sha512-8UnnX2PeRAPZuN12svgR9j7M1uWMovg/CEnIwIG0LFkXSJJe4PdfUGiTGl8V9bsBHFUtfVINcSyYxd7q+kx9fA==
623+  dependencies:
624+    "@jridgewell/sourcemap-codec" "^1.4.13"
625+
626+ms@2.1.2:
627+  version "2.1.2"
628+  resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
629+  integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
630+
631+nanoid@^3.3.4:
632+  version "3.3.4"
633+  resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-3.3.4.tgz#730b67e3cd09e2deacf03c027c81c9d9dbc5e8ab"
634+  integrity sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==
635+
636+node-releases@^2.0.8:
637+  version "2.0.10"
638+  resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.10.tgz#c311ebae3b6a148c89b1813fd7c4d3c024ef537f"
639+  integrity sha512-5GFldHPXVG/YZmFzJvKK2zDSzPKhEp0+ZR5SVaoSag9fsL5YgHbUHDfnG5494ISANDcK4KwPXAx2xqVEydmd7w==
640+
641+path-parse@^1.0.7:
642+  version "1.0.7"
643+  resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.7.tgz#fbc114b60ca42b30d9daf5858e4bd68bbedb6735"
644+  integrity sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==
645+
646+picocolors@^1.0.0:
647+  version "1.0.0"
648+  resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
649+  integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
650+
651+postcss@^8.4.21:
652+  version "8.4.21"
653+  resolved "https://registry.yarnpkg.com/postcss/-/postcss-8.4.21.tgz#c639b719a57efc3187b13a1d765675485f4134f4"
654+  integrity sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==
655+  dependencies:
656+    nanoid "^3.3.4"
657+    picocolors "^1.0.0"
658+    source-map-js "^1.0.2"
659+
660+react-dom@^18.2.0:
661+  version "18.2.0"
662+  resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.2.0.tgz#22aaf38708db2674ed9ada224ca4aa708d821e3d"
663+  integrity sha512-6IMTriUmvsjHUjNtEDudZfuDQUoWXVxKHhlEGSk81n4YFS+r/Kl99wXiwlVXtPBtJenozv2P+hxDsw9eA7Xo6g==
664+  dependencies:
665+    loose-envify "^1.1.0"
666+    scheduler "^0.23.0"
667+
668+react-is@^16.7.0:
669+  version "16.13.1"
670+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.13.1.tgz#789729a4dc36de2999dc156dd6c1d9c18cea56a4"
671+  integrity sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==
672+
673+react-is@^18.0.0:
674+  version "18.2.0"
675+  resolved "https://registry.yarnpkg.com/react-is/-/react-is-18.2.0.tgz#199431eeaaa2e09f86427efbb4f1473edb47609b"
676+  integrity sha512-xWGDIW6x921xtzPkhiULtthJHoJvBbF3q26fzloPCK0hsvxtPVelvftw3zjbHWSkR2km9Z+4uxbDDK/6Zw9B8w==
677+
678+react-redux@^8.0.5:
679+  version "8.0.5"
680+  resolved "https://registry.yarnpkg.com/react-redux/-/react-redux-8.0.5.tgz#e5fb8331993a019b8aaf2e167a93d10af469c7bd"
681+  integrity sha512-Q2f6fCKxPFpkXt1qNRZdEDLlScsDWyrgSj0mliK59qU6W5gvBiKkdMEG2lJzhd1rCctf0hb6EtePPLZ2e0m1uw==
682+  dependencies:
683+    "@babel/runtime" "^7.12.1"
684+    "@types/hoist-non-react-statics" "^3.3.1"
685+    "@types/use-sync-external-store" "^0.0.3"
686+    hoist-non-react-statics "^3.3.2"
687+    react-is "^18.0.0"
688+    use-sync-external-store "^1.0.0"
689+
690+react-refresh@^0.14.0:
691+  version "0.14.0"
692+  resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.14.0.tgz#4e02825378a5f227079554d4284889354e5f553e"
693+  integrity sha512-wViHqhAd8OHeLS/IRMJjTSDHF3U9eWi62F/MledQGPdJGDhodXJ9PBLNGr6WWL7qlH12Mt3TyTpbS+hGXMjCzQ==
694+
695+react@^18.2.0:
696+  version "18.2.0"
697+  resolved "https://registry.yarnpkg.com/react/-/react-18.2.0.tgz#555bd98592883255fa00de14f1151a917b5d77d5"
698+  integrity sha512-/3IjMdb2L9QbBdWiW5e3P2/npwMBaU9mHCSCUzNln0ZCYbcfTsGbTJrU/kGemdH2IWmB2ioZ+zkxtmq6g09fGQ==
699+  dependencies:
700+    loose-envify "^1.1.0"
701+
702+redux-thunk@^2.4.2:
703+  version "2.4.2"
704+  resolved "https://registry.yarnpkg.com/redux-thunk/-/redux-thunk-2.4.2.tgz#b9d05d11994b99f7a91ea223e8b04cf0afa5ef3b"
705+  integrity sha512-+P3TjtnP0k/FEjcBL5FZpoovtvrTNT/UXd4/sluaSyrURlSlhLSzEdfsTBW7WsKB6yPvgd7q/iZPICFjW4o57Q==
706+
707+redux@^4.2.0:
708+  version "4.2.1"
709+  resolved "https://registry.yarnpkg.com/redux/-/redux-4.2.1.tgz#c08f4306826c49b5e9dc901dee0452ea8fce6197"
710+  integrity sha512-LAUYz4lc+Do8/g7aeRa8JkyDErK6ekstQaqWQrNRW//MY1TvCEpMtpTWvlQ+FPbWCx+Xixu/6SHt5N0HR+SB4w==
711+  dependencies:
712+    "@babel/runtime" "^7.9.2"
713+
714+regenerator-runtime@^0.13.11:
715+  version "0.13.11"
716+  resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.11.tgz#f6dca3e7ceec20590d07ada785636a90cdca17f9"
717+  integrity sha512-kY1AZVr2Ra+t+piVaJ4gxaFaReZVH40AKNo7UCX6W+dEwBo/2oZJzqfuN1qLq1oL45o56cPaTXELwrTh8Fpggg==
718+
719+reselect@^4.1.7:
720+  version "4.1.7"
721+  resolved "https://registry.yarnpkg.com/reselect/-/reselect-4.1.7.tgz#56480d9ff3d3188970ee2b76527bd94a95567a42"
722+  integrity sha512-Zu1xbUt3/OPwsXL46hvOOoQrap2azE7ZQbokq61BQfiXvhewsKDwhMeZjTX9sX0nvw1t/U5Audyn1I9P/m9z0A==
723+
724+resolve@^1.22.1:
725+  version "1.22.1"
726+  resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.22.1.tgz#27cb2ebb53f91abb49470a928bba7558066ac177"
727+  integrity sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==
728+  dependencies:
729+    is-core-module "^2.9.0"
730+    path-parse "^1.0.7"
731+    supports-preserve-symlinks-flag "^1.0.0"
732+
733+rollup@^3.18.0:
734+  version "3.20.0"
735+  resolved "https://registry.yarnpkg.com/rollup/-/rollup-3.20.0.tgz#ce7bd88449a776b9f75bf4e35959e25fbd3f51b1"
736+  integrity sha512-YsIfrk80NqUDrxrjWPXUa7PWvAfegZEXHuPsEZg58fGCdjL1I9C1i/NaG+L+27kxxwkrG/QEDEQc8s/ynXWWGQ==
737+  optionalDependencies:
738+    fsevents "~2.3.2"
739+
740+scheduler@^0.23.0:
741+  version "0.23.0"
742+  resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.23.0.tgz#ba8041afc3d30eb206a487b6b384002e4e61fdfe"
743+  integrity sha512-CtuThmgHNg7zIZWAXi3AsyIzA3n4xx7aNyjwC2VJldO2LMVDhFK+63xGqq6CsJH4rTAt6/M+N4GhZiDYPx9eUw==
744+  dependencies:
745+    loose-envify "^1.1.0"
746+
747+semver@^6.3.0:
748+  version "6.3.0"
749+  resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d"
750+  integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==
751+
752+source-map-js@^1.0.2:
753+  version "1.0.2"
754+  resolved "https://registry.yarnpkg.com/source-map-js/-/source-map-js-1.0.2.tgz#adbc361d9c62df380125e7f161f71c826f1e490c"
755+  integrity sha512-R0XvVJ9WusLiqTCEiGCmICCMplcCkIwwR11mOSD9CR5u+IXYdiseeEuXCVAjS54zqwkLcPNnmU4OeJ6tUrWhDw==
756+
757+supports-color@^5.3.0:
758+  version "5.5.0"
759+  resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
760+  integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
761+  dependencies:
762+    has-flag "^3.0.0"
763+
764+supports-preserve-symlinks-flag@^1.0.0:
765+  version "1.0.0"
766+  resolved "https://registry.yarnpkg.com/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz#6eda4bd344a3c94aea376d4cc31bc77311039e09"
767+  integrity sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==
768+
769+to-fast-properties@^2.0.0:
770+  version "2.0.0"
771+  resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-2.0.0.tgz#dc5e698cbd079265bc73e0377681a4e4e83f616e"
772+  integrity sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==
773+
774+typescript@^4.9.3:
775+  version "4.9.5"
776+  resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.9.5.tgz#095979f9bcc0d09da324d58d03ce8f8374cbe65a"
777+  integrity sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==
778+
779+update-browserslist-db@^1.0.10:
780+  version "1.0.10"
781+  resolved "https://registry.yarnpkg.com/update-browserslist-db/-/update-browserslist-db-1.0.10.tgz#0f54b876545726f17d00cd9a2561e6dade943ff3"
782+  integrity sha512-OztqDenkfFkbSG+tRxBeAnCVPckDBcvibKd35yDONx6OU8N7sqgwc7rCbkJ/WcYtVRZ4ba68d6byhC21GFh7sQ==
783+  dependencies:
784+    escalade "^3.1.1"
785+    picocolors "^1.0.0"
786+
787+use-sync-external-store@^1.0.0:
788+  version "1.2.0"
789+  resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
790+  integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
791+
792+vite@^4.2.1:
793+  version "4.2.1"
794+  resolved "https://registry.yarnpkg.com/vite/-/vite-4.2.1.tgz#6c2eb337b0dfd80a9ded5922163b94949d7fc254"
795+  integrity sha512-7MKhqdy0ISo4wnvwtqZkjke6XN4taqQ2TBaTccLIpOKv7Vp2h4Y+NpmWCnGDeSvvn45KxvWgGyb0MkHvY1vgbg==
796+  dependencies:
797+    esbuild "^0.17.5"
798+    postcss "^8.4.21"
799+    resolve "^1.22.1"
800+    rollup "^3.18.0"
801+  optionalDependencies:
802+    fsevents "~2.3.2"
803+
804+yallist@^3.0.2:
805+  version "3.1.1"
806+  resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd"
807+  integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g==
A fx/all.ts
+19, -0
 1@@ -0,0 +1,19 @@
 2+import type { Operation } from "../deps.ts";
 3+import { resource, spawn } from "../deps.ts";
 4+import type { OpFn } from "../types.ts";
 5+import { map } from "../iter.ts";
 6+
 7+import { toOperation } from "./call.ts";
 8+
 9+export function all<T>(operations: OpFn<T>[]): Operation<T[]> {
10+  return resource(function* All(provide) {
11+    const tasks = yield* map(
12+      operations.map((o) => () => toOperation(o)),
13+      spawn,
14+    );
15+
16+    const results = yield* map(tasks, (task) => task);
17+
18+    yield* provide(results);
19+  });
20+}
A fx/call.ts
+89, -0
 1@@ -0,0 +1,89 @@
 2+import type { Operation, Task } from "../deps.ts";
 3+import { action, expect, spawn } from "../deps.ts";
 4+import type { OpFn } from "../types.ts";
 5+import { ErrContext } from "../context.ts";
 6+
 7+export interface ResultOk<T> {
 8+  type: "ok";
 9+  value: T;
10+  isOk: true;
11+  isErr: false;
12+}
13+
14+export interface ResultErr {
15+  type: "err";
16+  value: Error;
17+  isOk: false;
18+  isErr: true;
19+}
20+
21+export type Result<T> = ResultOk<T> | ResultErr;
22+
23+export function Ok<T>(value: T): ResultOk<T> {
24+  return {
25+    type: "ok",
26+    value,
27+    isOk: true,
28+    isErr: false,
29+  };
30+}
31+
32+export function Err(value: Error): ResultErr {
33+  return {
34+    type: "err",
35+    value,
36+    isOk: false,
37+    isErr: true,
38+  };
39+}
40+
41+export const isFunc = (f: unknown) => typeof f === "function";
42+export const isPromise = (p: unknown) =>
43+  p && isFunc((p as PromiseLike<unknown>).then);
44+export const isIterator = (it: unknown) =>
45+  it &&
46+  isFunc((it as Iterator<unknown>).next) &&
47+  isFunc((it as Iterator<unknown>).throw);
48+
49+export function* toOperation<T>(opFn: OpFn<T>): Operation<T> {
50+  const op = opFn();
51+  let result: T;
52+  if (isPromise(op)) {
53+    result = yield* expect(op as Promise<T>);
54+  } else if (isIterator(op)) {
55+    result = yield* op as Operation<T>;
56+  } else {
57+    result = op as T;
58+  }
59+  return result;
60+}
61+
62+export function call<T>(op: OpFn<T>): Operation<T> {
63+  return action(function* (resolve) {
64+    const result = yield* toOperation(op);
65+    resolve(result);
66+  });
67+}
68+
69+export function* go<T>(op: OpFn<T>): Operation<Task<Result<T>>> {
70+  return yield* spawn(function* () {
71+    try {
72+      return Ok(yield* call(op));
73+    } catch (error) {
74+      let { input } = yield* ErrContext;
75+      yield* input.send(error);
76+      return Err(error);
77+    }
78+  });
79+}
80+
81+export function* safe<T>(opFn: OpFn<T>): Operation<Result<T>> {
82+  try {
83+    const value = yield* call(opFn);
84+    return Ok(value);
85+  } catch (error) {
86+    let { input } = yield* ErrContext;
87+    yield* input.send(error);
88+    return Err(error);
89+  }
90+}
A fx/cancel.ts
+7, -0
1@@ -0,0 +1,7 @@
2+import { contextualize } from "../context.ts";
3+import type { Task } from "../deps.ts";
4+
5+export function* cancel<T>(task: Task<T>) {
6+  yield* task.halt();
7+  yield* contextualize("cancelled", true);
8+}
A fx/cancelled.ts
+6, -0
1@@ -0,0 +1,6 @@
2+import { getframe } from "../deps.ts";
3+
4+export function* cancelled() {
5+  const frame = yield* getframe();
6+  return frame.context["cancelled"] || false;
7+}
A fx/emit.ts
+22, -0
 1@@ -0,0 +1,22 @@
 2+import type { Channel, Operation } from "../deps.ts";
 3+import type { Action } from "../types.ts";
 4+
 5+import { all } from "./all.ts";
 6+
 7+export function* emit({
 8+  channel,
 9+  action,
10+}: {
11+  channel: Operation<Channel<Action, void>>;
12+  action: Action | Action[];
13+}) {
14+  const { input } = yield* channel;
15+  if (Array.isArray(action)) {
16+    if (action.length === 0) {
17+      return;
18+    }
19+    yield* all(action.map((a) => () => input.send(a)));
20+  } else {
21+    yield* input.send(action);
22+  }
23+}
A fx/mod.ts
+8, -0
1@@ -0,0 +1,8 @@
2+export * from "./all.ts";
3+export * from "./call.ts";
4+export * from "./cancel.ts";
5+export * from "./cancelled.ts";
6+export * from "./race.ts";
7+export * from "./once.ts";
8+export * from "./emit.ts";
9+export * from "./request.ts";
A fx/once.ts
+22, -0
 1@@ -0,0 +1,22 @@
 2+import type { Channel, Operation } from "../deps.ts";
 3+import type { Action } from "../types.ts";
 4+import { ActionPattern, matcher } from "../matcher.ts";
 5+
 6+export function* once({
 7+  channel,
 8+  pattern,
 9+}: {
10+  channel: Operation<Channel<Action, void>>;
11+  pattern: ActionPattern;
12+}) {
13+  const { output } = yield* channel;
14+  const msgList = yield* output;
15+  let next = yield* msgList;
16+  while (!next.done) {
17+    const match = matcher(pattern);
18+    if (match(next.value)) {
19+      return next.value;
20+    }
21+    next = yield* msgList;
22+  }
23+}
A fx/race.ts
+31, -0
 1@@ -0,0 +1,31 @@
 2+import type { Operation } from "../deps.ts";
 3+import { action, resource, spawn } from "../deps.ts";
 4+
 5+import type { OpFn } from "../types.ts";
 6+import { map } from "../iter.ts";
 7+import { toOperation } from "./call.ts";
 8+
 9+export function race<T>(operations: OpFn<T>[]): Operation<T> {
10+  return resource(function* Race(provide) {
11+    const tasks = yield* map(
12+      operations.map((o) => () => toOperation(o)),
13+      spawn,
14+    );
15+
16+    const winner = yield* action<T>(function* (resolve) {
17+      for (let task of tasks) {
18+        yield* spawn(function* () {
19+          resolve(yield* task);
20+        });
21+      }
22+    });
23+
24+    for (let task of tasks) {
25+      if (task !== winner) {
26+        yield* spawn(() => task.halt());
27+      }
28+    }
29+
30+    yield* provide(winner);
31+  });
32+}
A fx/request.ts
+7, -0
1@@ -0,0 +1,7 @@
2+import { expect, useAbortSignal } from "../deps.ts";
3+
4+export function* request(url: string | URL | Request, opts?: RequestInit) {
5+  const signal = yield* useAbortSignal();
6+  const response = yield* expect(fetch(url, { signal, ...opts }));
7+  return response;
8+}
A iter.ts
+28, -0
 1@@ -0,0 +1,28 @@
 2+import type { Channel, Operation } from "./deps.ts";
 3+
 4+export function* forEach<T>(
 5+  chan: Operation<Channel<T, void>>,
 6+  each?: (val: T) => Operation<void>,
 7+) {
 8+  const { output } = yield* chan;
 9+  const msgList = yield* output;
10+  while (true) {
11+    const next = yield* msgList;
12+    if (next.done) {
13+      return next.value;
14+    } else if (each) {
15+      yield* each(next.value);
16+    }
17+  }
18+}
19+
20+export function* map<T, R>(
21+  values: T[],
22+  each: (value: T) => Operation<R>,
23+): Operation<R[]> {
24+  const results: R[] = [];
25+  for (let value of values) {
26+    results.push(yield* each(value));
27+  }
28+  return results;
29+}
A matcher.ts
+42, -0
 1@@ -0,0 +1,42 @@
 2+import type { Action, ActionType } from "./types.ts";
 3+
 4+type GuardPredicate<G extends T, T = unknown> = (arg: T) => arg is G;
 5+type Predicate<T> = (arg: T) => boolean;
 6+type StringableActionCreator<A extends Action = Action> = {
 7+  (...args: unknown[]): A;
 8+  toString(): string;
 9+};
10+type SubPattern<T> = Predicate<T> | StringableActionCreator | ActionType;
11+export type Pattern<T> = SubPattern<T> | SubPattern<T>[];
12+type ActionSubPattern<Guard extends Action = Action> =
13+  | GuardPredicate<Guard, Action>
14+  | StringableActionCreator<Guard>
15+  | Predicate<Action>
16+  | ActionType;
17+export type ActionPattern<Guard extends Action = Action> =
18+  | ActionSubPattern<Guard>
19+  | ActionSubPattern<Guard>[];
20+
21+export function matcher(pattern: ActionPattern): (input: Action) => boolean {
22+  if (pattern === "*") {
23+    return (input: Action) => !!input;
24+  }
25+
26+  if (typeof pattern === "string") {
27+    return (input: Action) => pattern === input.type;
28+  }
29+
30+  if (Array.isArray(pattern)) {
31+    return (input: Action) => pattern.some((p) => matcher(p)(input));
32+  }
33+
34+  if (typeof pattern === "function" && Object.hasOwn(pattern, "toString")) {
35+    return (input: Action) => pattern.toString() === input.type;
36+  }
37+
38+  if (typeof pattern === "function") {
39+    return (input: Action) => pattern(input) as boolean;
40+  }
41+
42+  throw new Error("invalid pattern");
43+}
A mod.ts
+4, -0
1@@ -0,0 +1,4 @@
2+export * from "./fx/mod.ts";
3+export * from "./types.ts";
4+export * from "./iter.ts";
5+export * from "./context.ts";
A npm.ts
+40, -0
 1@@ -0,0 +1,40 @@
 2+import { build, emptyDir } from "https://deno.land/x/dnt@0.17.0/mod.ts";
 3+import { assert } from "https://deno.land/std@0.129.0/testing/asserts.ts";
 4+await emptyDir("./npm");
 5+
 6+let version = Deno.env.get("NPM_VERSION");
 7+assert(version, "NPM_VERSION is required to build npm package");
 8+
 9+await build({
10+  entryPoints: ["./mod.ts", "./react.ts", "./redux.ts"],
11+  outDir: "./npm",
12+  shims: {
13+    deno: false,
14+  },
15+  test: false,
16+  typeCheck: false,
17+  compilerOptions: {
18+    target: "ES2020",
19+    sourceMap: true,
20+  },
21+  package: {
22+    // package.json properties
23+    name: "starfx",
24+    version,
25+    description: "Declarative side-effects for your apps",
26+    license: "MIT",
27+    repository: {
28+      author: "me@erock.io",
29+      type: "git",
30+      url: "git+https://github.com/neurosnap/starfx.git",
31+    },
32+    bugs: {
33+      url: "https://github.com/neurosnap/starfx/issues",
34+    },
35+    engines: {
36+      node: ">= 14",
37+    },
38+  },
39+});
40+
41+await Deno.copyFile("README.md", "npm/README.md");
A react.ts
+45, -0
 1@@ -0,0 +1,45 @@
 2+import { React } from "./deps.ts";
 3+const { createContext, createElement: h, useContext } = React;
 4+
 5+import type { Operation, Scope } from "./deps.ts";
 6+import type { Action } from "./types.ts";
 7+import { ActionContext } from "./redux.ts";
 8+
 9+const ScopeContext = createContext<Scope | null>(null);
10+
11+export function Provider({
12+  scope,
13+  children,
14+}: {
15+  scope: Scope;
16+  children: React.ReactNode;
17+}) {
18+  return h(ScopeContext.Provider, { value: scope }, children);
19+}
20+
21+export function useScope(): Scope {
22+  const scope = useContext(ScopeContext);
23+  if (!scope) {
24+    throw new Error("scope is null");
25+  }
26+  return scope;
27+}
28+
29+/**
30+ * This hook dispatches actions directly to the Action channel we use
31+ * for redux.  This makes it so you don't have to dispatch a redux action
32+ * in order to trigger an fx.
33+ */
34+export function useDispatchFx() {
35+  const scope = useScope();
36+  return (action: Action) =>
37+    scope.run(function* () {
38+      let { input } = yield* ActionContext;
39+      yield* input.send(action);
40+    });
41+}
42+
43+export function useFx<T>(op: () => Operation<T>) {
44+  const scope = useScope();
45+  return scope.run(op);
46+}
A redux.ts
+66, -0
 1@@ -0,0 +1,66 @@
 2+import type { Channel, Operation, Scope } from "./deps.ts";
 3+import { createChannel, createContext, createScope } from "./deps.ts";
 4+import { contextualize } from "./context.ts";
 5+import { all, emit, once, safe } from "./fx/mod.ts";
 6+import type { Action, StoreLike } from "./types.ts";
 7+import { ActionPattern } from "./matcher.ts";
 8+
 9+export const ActionContext = createContext<Channel<Action, void>>(
10+  "redux:action",
11+  createChannel<Action, void>(),
12+);
13+
14+export const StoreContext = createContext<StoreLike>("redux:store");
15+
16+export function* select<S, R>(selectorFn: (s: S) => R) {
17+  const store = yield* StoreContext;
18+  return selectorFn(store.getState() as S);
19+}
20+
21+export function* take(pattern: ActionPattern) {
22+  return yield* once({
23+    channel: ActionContext,
24+    pattern,
25+  });
26+}
27+
28+export function* put(action: Action | Action[]) {
29+  yield* emit({
30+    channel: ActionContext,
31+    action,
32+  });
33+}
34+
35+function supervise(op: () => Operation<void>) {
36+  return function* keepAlive() {
37+    while (true) {
38+      yield* safe(op);
39+    }
40+  };
41+}
42+
43+export function createFxMiddleware(scope: Scope = createScope()) {
44+  function run(ops: (() => Operation<void>)[]) {
45+    const task = scope.run(function* runner() {
46+      yield* all(ops.map(supervise));
47+    });
48+
49+    return task;
50+  }
51+
52+  function middleware<S = unknown, T = unknown>(store: StoreLike<S>) {
53+    scope.run(function* () {
54+      yield* contextualize("store", store);
55+    });
56+
57+    return (next: (a: Action) => T) => (action: Action) => {
58+      const result = next(action); // hit reducers
59+      scope.run(function* () {
60+        yield* put(action);
61+      });
62+      return result;
63+    };
64+  }
65+
66+  return { run, scope, middleware };
67+}
A test/all.test.ts
+55, -0
 1@@ -0,0 +1,55 @@
 2+import { createFuture, run, sleep, spawn } from "../deps.ts";
 3+import { describe, expect, it } from "../../test/suite.ts";
 4+
 5+import { all } from "../mod.ts";
 6+
 7+describe("all()", () => {
 8+  it("should return empty array", async () => {
 9+    let actual;
10+    await run(function* () {
11+      actual = yield* all([]);
12+    });
13+    expect(actual).toEqual([]);
14+  });
15+
16+  it("should resolve all async items", async () => {
17+    const two = createFuture<number>();
18+
19+    function* one() {
20+      yield* sleep(5);
21+      return 1;
22+    }
23+
24+    const result = await run(function* () {
25+      yield* spawn(function* () {
26+        yield* sleep(15);
27+        two.resolve(2);
28+      });
29+      return yield* all([one, () => two.future]);
30+    });
31+
32+    expect(result).toEqual([1, 2]);
33+  });
34+
35+  it("should stop all operations when there is an error", async () => {
36+    let actual: number[] = [];
37+    const one = createFuture<number>();
38+    const two = createFuture<number>();
39+
40+    function* genFn() {
41+      try {
42+        actual = yield* all([() => one.future, () => two.future]);
43+      } catch (err) {
44+        actual = [err];
45+      }
46+    }
47+
48+    one.reject(new Error("error"));
49+    two.resolve(1);
50+
51+    await run(genFn);
52+
53+    const expected = [new Error("error")];
54+    expect(actual).toEqual(expected);
55+  });
56+});
A test/call.test.ts
+53, -0
 1@@ -0,0 +1,53 @@
 2+import { describe, expect, it } from "../../test/suite.ts";
 3+
 4+import { run } from "../deps.ts";
 5+import { call } from "../mod.ts";
 6+
 7+describe("call()", () => {
 8+  it("should call the generator function", async () => {
 9+    function* me() {
10+      return "valid";
11+    }
12+
13+    await run(function* () {
14+      const result = yield* call(me);
15+      expect(result).toBe("valid");
16+    });
17+  });
18+
19+  it("should call a normal function with no params", async () => {
20+    function me() {
21+      return "valid";
22+    }
23+
24+    await run(function* () {
25+      const result = yield* call(me);
26+      expect(result).toBe("valid");
27+    });
28+  });
29+
30+  it("should call a normal function with params", async () => {
31+    function me(v: string) {
32+      return "valid " + v;
33+    }
34+
35+    await run(function* () {
36+      const result = yield* call(() => me("fn"));
37+      expect(result).toBe("valid fn");
38+    });
39+  });
40+
41+  it("should call a promise", async () => {
42+    const me = () =>
43+      new Promise((resolve) => {
44+        setTimeout(() => {
45+          resolve("valid");
46+        }, 10);
47+      });
48+
49+    await run(function* () {
50+      const result = yield* call(me);
51+      expect(result).toBe("valid");
52+    });
53+  });
54+});
A test/middleware.test.ts
+53, -0
 1@@ -0,0 +1,53 @@
 2+import { describe, expect, it } from "../../test/suite.ts";
 3+
 4+import { call } from "../mod.ts";
 5+import { createFxMiddleware, select } from "../redux.ts";
 6+import { Action } from "../types.ts";
 7+
 8+const tests = describe("createMiddleware()");
 9+
10+interface Store<S> {
11+  getState(): S;
12+  dispatch(a: Action): void;
13+}
14+
15+interface TestState {
16+  user: { id: string };
17+}
18+
19+function createStore<S>(state: S): Store<S> {
20+  const store = {
21+    getState(): S {
22+      return state;
23+    },
24+    dispatch(_: Action) {},
25+  };
26+
27+  return store;
28+}
29+
30+it(tests, "should be able to grab values from store", async () => {
31+  const store = createStore({ user: { id: "1" } });
32+  const { run, middleware } = createFxMiddleware();
33+  middleware(store);
34+  await run([
35+    function* () {
36+      const actual = yield* select((s: TestState) => s["user"]);
37+      expect(actual).toEqual({ id: "1" });
38+    },
39+  ]);
40+});
41+
42+it(tests, "should be able to grab store from a nested call", async () => {
43+  const store = createStore({ user: { id: "2" } });
44+  const { run, middleware } = createFxMiddleware();
45+  middleware(store);
46+  await run([
47+    function* () {
48+      const actual = yield* call(function* () {
49+        return yield* select((s: TestState) => s["user"]);
50+      });
51+      expect(actual).toEqual({ id: "2" });
52+    },
53+  ]);
54+});
A test/put.test.ts
+107, -0
  1@@ -0,0 +1,107 @@
  2+import { describe, expect, it } from "../../test/suite.ts";
  3+
  4+import { run, sleep, spawn } from "../deps.ts";
  5+import { ActionContext, put, take } from "../redux.ts";
  6+
  7+const putTests = describe("put()");
  8+
  9+it(putTests, "should send actions through channel", async () => {
 10+  let actual: string[] = [];
 11+
 12+  function* genFn(arg: string) {
 13+    yield* spawn(function* () {
 14+      const actions = yield* ActionContext;
 15+      const msgs = yield* actions.output;
 16+      let action = yield* msgs;
 17+      while (!action.done) {
 18+        actual.push(action.value.type);
 19+        action = yield* msgs;
 20+      }
 21+    });
 22+
 23+    yield* put({
 24+      type: arg,
 25+    });
 26+    yield* put({
 27+      type: "2",
 28+    });
 29+  }
 30+
 31+  await run(() => genFn("arg"));
 32+
 33+  const expected = ["arg", "2"];
 34+  expect(actual).toEqual(expected);
 35+});
 36+
 37+it(putTests, "should handle nested puts", async () => {
 38+  const actual: string[] = [];
 39+
 40+  function* genA() {
 41+    yield* put({
 42+      type: "a",
 43+    });
 44+    actual.push("put a");
 45+  }
 46+
 47+  function* genB() {
 48+    yield* take(["a"]);
 49+    yield* put({
 50+      type: "b",
 51+    });
 52+    actual.push("put b");
 53+  }
 54+
 55+  function* root() {
 56+    yield* spawn(genB);
 57+    yield* spawn(genA);
 58+  }
 59+
 60+  await run(root);
 61+
 62+  const expected = ["put b", "put a"];
 63+  expect(actual).toEqual(expected);
 64+});
 65+
 66+it(
 67+  putTests,
 68+  "should not cause stack overflow when puts are emitted while dispatching saga",
 69+  async () => {
 70+    function* root() {
 71+      for (let i = 0; i < 40_000; i += 1) {
 72+        yield* put({ type: "test" });
 73+      }
 74+      yield* sleep(0);
 75+    }
 76+
 77+    await run(root);
 78+    expect(true).toBe(true);
 79+  },
 80+);
 81+
 82+it(
 83+  putTests,
 84+  "should not miss `put` that was emitted directly after creating a task (caused by another `put`)",
 85+  async () => {
 86+    const actual: string[] = [];
 87+
 88+    function* root() {
 89+      yield* spawn(function* firstspawn() {
 90+        yield* sleep(1000);
 91+        yield* put({ type: "c" });
 92+        yield* put({ type: "do not miss" });
 93+      });
 94+
 95+      yield* take("c");
 96+
 97+      const tsk = yield* spawn(function* () {
 98+        yield* take("do not miss");
 99+        actual.push("didn't get missed");
100+      });
101+      yield* tsk;
102+    }
103+
104+    await run(root);
105+    const expected = ["didn't get missed"];
106+    expect(actual).toEqual(expected);
107+  },
108+);
A test/take.test.ts
+117, -0
  1@@ -0,0 +1,117 @@
  2+import { describe, expect, it } from "../../test/suite.ts";
  3+
  4+import { run, sleep, spawn } from "../deps.ts";
  5+import { put, take } from "../redux.ts";
  6+import type { Action } from "../types.ts";
  7+
  8+const takeTests = describe("take()");
  9+
 10+it(
 11+  takeTests,
 12+  "a put should complete before more `take` are added and then consumed automatically",
 13+  async () => {
 14+    const actual: any[] = [];
 15+
 16+    function* channelFn() {
 17+      yield* sleep(10);
 18+      yield* put({ type: "action-1", payload: 1 });
 19+      yield* put({ type: "action-1", payload: 2 });
 20+    }
 21+
 22+    function* root() {
 23+      yield* spawn(channelFn);
 24+
 25+      actual.push(yield* take("action-1"));
 26+      actual.push(yield* take("action-1"));
 27+    }
 28+
 29+    await run(root);
 30+    expect(actual).toEqual([
 31+      { type: "action-1", payload: 1 },
 32+      { type: "action-1", payload: 2 },
 33+    ]); // actual: [ { type: "action-1", payload: 1 }, { type: "action-1", payload: 1 } ]
 34+  },
 35+);
 36+
 37+it(takeTests, "take from default channel", async () => {
 38+  function* channelFn() {
 39+    yield* sleep(10);
 40+    yield* put({ type: "action-*" });
 41+    yield* put({ type: "action-1" });
 42+    yield* put({ type: "action-2" });
 43+    yield* put({ type: "unnoticeable-action" });
 44+    yield* put({
 45+      type: "",
 46+      payload: {
 47+        isAction: true,
 48+      },
 49+    });
 50+    yield* put({
 51+      type: "",
 52+      payload: {
 53+        isMixedWithPredicate: true,
 54+      },
 55+    });
 56+    yield* put({
 57+      type: "action-3",
 58+    });
 59+  }
 60+
 61+  const actual: any[] = [];
 62+  function* genFn() {
 63+    yield* spawn(channelFn);
 64+
 65+    try {
 66+      actual.push(yield* take("*")); // take all actions
 67+      actual.push(yield* take("action-1")); // take only actions of type 'action-1'
 68+      actual.push(yield* take(["action-2", "action-2222"])); // take either type
 69+      actual.push(yield* take((a: Action) => a.payload?.isAction)); // take if match predicate
 70+      actual.push(
 71+        yield* take([
 72+          "action-3",
 73+          (a: Action) => a.payload?.isMixedWithPredicate,
 74+        ]),
 75+      ); // take if match any from the mixed array
 76+      actual.push(
 77+        yield* take([
 78+          "action-3",
 79+          (a: Action) => a.payload?.isMixedWithPredicate,
 80+        ]),
 81+      ); // take if match any from the mixed array
 82+    } finally {
 83+      actual.push("auto ended");
 84+    }
 85+  }
 86+
 87+  await run(genFn);
 88+
 89+  const expected = [
 90+    {
 91+      type: "action-*",
 92+    },
 93+    {
 94+      type: "action-1",
 95+    },
 96+    {
 97+      type: "action-2",
 98+    },
 99+    {
100+      type: "",
101+      payload: {
102+        isAction: true,
103+      },
104+    },
105+    {
106+      type: "",
107+      payload: {
108+        isMixedWithPredicate: true,
109+      },
110+    },
111+    {
112+      type: "action-3",
113+    },
114+    "auto ended",
115+  ];
116+  console.log(actual);
117+  expect(actual).toEqual(expected);
118+});
A types.ts
+13, -0
 1@@ -0,0 +1,13 @@
 2+import type { Operation } from "./deps.ts";
 3+
 4+export type ActionType = string;
 5+export interface Action<P = any> {
 6+  type: ActionType;
 7+  payload?: P;
 8+}
 9+export type OpFn<T> = (() => Operation<T>) | (() => PromiseLike<T>) | (() => T);
10+
11+export interface StoreLike<S = unknown> {
12+  getState: () => S;
13+  dispatch: (action: Action) => void;
14+}