- commit
- 8137f72
- parent
- 8137f72
- author
- Eric Bower
- date
- 2023-03-28 02:41:52 +0000 UTC
init
33 files changed,
+1838,
-0
+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
+1,
-0
1@@ -0,0 +1 @@
2+# starfx
+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";
+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+});
+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>
+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+}
+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+}
+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+}
+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+});
+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==
+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+}
+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+}
+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+}
+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+}
+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+}
+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";
+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+}
+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+}
+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+}
+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+}
+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+});
+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+});
+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+});
+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+);
+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+}