├── .gitignore
├── LICENSE
├── README.md
├── babel.config.js
├── examples
└── react
│ ├── .gitignore
│ ├── index.html
│ ├── index.js
│ ├── package.json
│ └── yarn.lock
├── package.json
├── src
├── index.ts
├── store.ts
├── sync-queue.ts
├── transaction.ts
├── transactions-manager.ts
└── types.ts
├── tsconfig.json
└── yarn.lock
/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 | dist
3 | .DS_Store
4 | .env
5 | yarn-error.log
6 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2022 Webstudio
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | The core idea is to use [patches](https://immerjs.github.io/immer/patches) to keep the UI in sync between client and server, multiple clients, or multiple windows.
6 |
7 | It uses [Immer](https://immerjs.github.io/immer/) as an interface for state mutations and provides a convenient way to group mutations into a single transaction, and enables undo/redo out of the box.
8 |
9 | [Play with it on Codesandbox](https://codesandbox.io/s/github/webstudio-is/immerhin/tree/main/examples/react)
10 |
11 | [Read the article](https://dev.to/oleg008/synchronized-immutable-state-with-time-travel-2c6o)
12 |
13 | ## Features
14 |
15 | 1. Sync application state using [patches](https://immerjs.github.io/immer/patches)
16 | 1. Get undo/redo for free
17 | 1. Sync to the server
18 | 1. Server agnostic
19 | 1. State management libraries agnostic (a container interface)
20 | 1. Small bundle size
21 | 1. Sync between iframes (not implemented yet)
22 | 1. Sync between tabs (not implemented yet)
23 | 1. Resolve conflicts (not implemented yet)
24 | 1. Provide server handler (not implemented yet)
25 |
26 | ## Example
27 |
28 | ```js
29 | import store, { sync } from "immerhin";
30 |
31 | // Create containers for each state. Sync engine only cares that the result has a "get()" and a "set(newValue)"
32 | const container1 = atom(initialValue);
33 | const container2 = atom(initialValue);
34 |
35 | // - Explicitely enable containers for transactions
36 | // - Define a namespace for each container, so that server knows which object it has to patch.
37 | store.register("container1", container1);
38 | store.register("container2", container2);
39 |
40 | // Creating the actual transaction that will:
41 | // - generate patches
42 | // - update states
43 | // - inform all subscribers
44 | // - register a transaction for potential undo/redo and sync calls
45 | store.createTransaction(
46 | [container1, container2, ...rest],
47 | (value1, value2, ...rest) => {
48 | mutateValue(value1);
49 | mutateValue(value2);
50 | // ...
51 | }
52 | );
53 |
54 | // Setup periodic sync with a fetch, or do this with Websocket
55 | setInterval(async () => {
56 | const entries = sync();
57 | await fetch("/patch", { method: "POST", payload: JSON.stringify(entries) });
58 | }, 1000);
59 |
60 | // Undo/redo
61 |
62 | store.undo();
63 | store.redo();
64 | ```
65 |
66 | ## How it works
67 |
68 | ### Containers
69 |
70 | A container is an interface that implements `.get()` and `.set(value)` methods so that a value can be updated and propagated to all consumers.
71 |
72 | You can use anything to create containers, it could be a Redux store, could be an observable, a [nano state](https://github.com/kof/react-nano-state) or [nanostores](https://github.com/nanostores/nanostores).
73 |
74 | You can use the same container instance to subscribe to the changes across the entire application.
75 |
76 | Example using nano state:
77 |
78 | ```js
79 | import { atom } from "nanostores";
80 | import { useStore } from "@nanostores/react";
81 | const myContainer = atom(initialValue);
82 |
83 | // I can call a set from anywhere
84 | myContainer.set(newValue);
85 |
86 | // I can subscribe to updates in React
87 | const Component = () => {
88 | const value = useStore(myContainer);
89 | };
90 | ```
91 |
92 | ### Container registration
93 |
94 | We register containers for two reasons:
95 |
96 | 1. To define a namespace for each container so that whoever consumes the changes knows which object to apply the patches to.
97 | 2. Ensure that the container was intentionally registered to be synced to the server and be part of undo/redo transactions. You may not want this for every container since you can use them for ephemeral states.
98 |
99 | Example
100 |
101 | ```js
102 | store.register("myName", myContainer);
103 | ```
104 |
105 | ### Creating a transaction
106 |
107 | A transaction is a set of changes applied to a set of states. When you apply changes to the states inside a transaction, you are essentially telling the engine which changes are associated with the same user action so that undo/redo can use that as a single step to work with.
108 |
109 | A call into `store.createTransaction()`does all of this:
110 |
111 | - generate patches (using Immer)
112 | - update states and inform all subscribers (by calling `container.set(newValue)`)
113 | - register a transaction for potential undo/redo and calls
114 |
115 | Example
116 |
117 | ```js
118 | store.createTransaction(
119 | [container1, container2, ...rest],
120 | (value1, value2, ...rest) => {
121 | mutateValue(value1);
122 | mutateValue(value2);
123 | // ...
124 | }
125 | );
126 | ```
127 |
128 | ### Undo/redo
129 |
130 | Calling undo() and redo() functions will essentially apply the right patch for the value and dispatch the update.
131 |
132 | ### Sync
133 |
134 | The `sync(`) function returns you all changes queued up for a sync since the last call.
135 | With the return from `sync(),` you can do anything you want, for example, send it to your server.
136 |
137 | Example
138 |
139 | ```js
140 | // Setup periodic sync with a fetch, or do this with Websocket
141 | setInterval(async () => {
142 | const entries = sync();
143 | await fetch("/patch", { method: "POST", payload: JSON.stringify(entries) });
144 | }, 1000);
145 | ```
146 |
147 | Example entries:
148 |
149 | ```json
150 | [
151 | {
152 | "transactionId": "6243062b469f516835327f65",
153 | "changes": [
154 | {
155 | "namespace": "root",
156 | "patches": [
157 | {
158 | "op": "replace",
159 | "path": ["children", 1],
160 | "value": {
161 | "component": "Box",
162 | "id": "6241f55791596f2467df9c2a",
163 | "style": {},
164 | "children": []
165 | }
166 | },
167 | {
168 | "op": "replace",
169 | "path": ["children", 2],
170 | "value": {
171 | "component": "Box",
172 | "id": "6241f55a91596f2467df9c36",
173 | "style": {},
174 | "children": []
175 | }
176 | },
177 | {
178 | "op": "replace",
179 | "path": ["children", "length"],
180 | "value": 3
181 | }
182 | ]
183 | }
184 | ]
185 | }
186 | ]
187 | ```
188 |
189 | ## Create a new store
190 |
191 | If you want to have multiple separate undoable states, create a separate store for each. They add to the same sync queue in the end.
192 |
193 | ```js
194 | import { Store } from "immerhin";
195 |
196 | const store = new Store();
197 | ```
198 |
--------------------------------------------------------------------------------
/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | presets: ["@babel/preset-typescript"],
3 | };
4 |
--------------------------------------------------------------------------------
/examples/react/.gitignore:
--------------------------------------------------------------------------------
1 | .parcel-cache
--------------------------------------------------------------------------------
/examples/react/index.html:
--------------------------------------------------------------------------------
1 |
2 |
--------------------------------------------------------------------------------
/examples/react/index.js:
--------------------------------------------------------------------------------
1 | import React, { Fragment } from "react";
2 | import { createRoot } from "react-dom/client";
3 | import { atom } from 'nanostores';
4 | import { useStore } from '@nanostores/react'
5 | import store, { sync } from "immerhin";
6 |
7 | const itemsContainer = atom([]);
8 |
9 | store.register("items", itemsContainer);
10 |
11 | const List = () => {
12 | const items = useStore(itemsContainer);
13 | return (
14 |
15 | {items.map((item, index) => (
16 | - {item.value}
17 | ))}
18 |
19 | );
20 | };
21 |
22 | const App = () => {
23 | return (
24 |
25 |
68 |
69 |
70 |
71 |
72 |
73 |
74 | );
75 | };
76 |
77 | createRoot(document.body.appendChild(document.createElement("div"))).render(
78 |
79 | );
80 |
--------------------------------------------------------------------------------
/examples/react/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "immerhin-basic-example",
3 | "version": "0.1.0",
4 | "scripts": {
5 | "start": "yarn parcel index.html"
6 | },
7 | "dependencies": {
8 | "@nanostores/react": "^0.4.1",
9 | "immerhin": "link:../../",
10 | "nanostores": "^0.7.1",
11 | "react": ">=16.8",
12 | "react-dom": ">=16.8"
13 | },
14 | "main": "index.js",
15 | "alias": {
16 | "process": false
17 | },
18 | "devDependencies": {
19 | "parcel": "^2.4.1",
20 | "process": "^0.11.10"
21 | }
22 | }
23 |
--------------------------------------------------------------------------------
/examples/react/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@babel/code-frame@^7.0.0":
6 | version "7.16.7"
7 | resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.16.7.tgz#44416b6bd7624b998f5b1af5d470856c40138789"
8 | integrity sha512-iAXqUn8IIeBTNd72xsFlgaXHkMBMt6y4HJp1tIaK465CWLT/fG1aqB7ykr95gHHmlBdGbFeWWfyB4NJJ0nmeIg==
9 | dependencies:
10 | "@babel/highlight" "^7.16.7"
11 |
12 | "@babel/helper-validator-identifier@^7.16.7":
13 | version "7.16.7"
14 | resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.16.7.tgz#e8c602438c4a8195751243da9031d1607d247cad"
15 | integrity sha512-hsEnFemeiW4D08A5gUAZxLBTXpZ39P+a+DGDsHw1yxqyQ/jzFEnxf5uTEGp+3bzAbNOxU1paTgYS4ECU/IgfDw==
16 |
17 | "@babel/highlight@^7.16.7":
18 | version "7.16.10"
19 | resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.16.10.tgz#744f2eb81579d6eea753c227b0f570ad785aba88"
20 | integrity sha512-5FnTQLSLswEj6IkgVw5KusNUUFY9ZGqe/TRFnP/BKYHYgfh7tc+C7mwiy95/yNP7Dh9x580Vv8r7u7ZfTBFxdw==
21 | dependencies:
22 | "@babel/helper-validator-identifier" "^7.16.7"
23 | chalk "^2.0.0"
24 | js-tokens "^4.0.0"
25 |
26 | "@nanostores/react@^0.4.1":
27 | version "0.4.1"
28 | resolved "https://registry.yarnpkg.com/@nanostores/react/-/react-0.4.1.tgz#209c6726c0b42a1d21d9f7aa8f5276cdb0ad40d8"
29 | integrity sha512-lsv0CYrMxczbXtoV/mxFVEoL/uVjEjseoP89srO/5yNAOkJka+dSFS7LYyWEbuvCPO7EgbtkvRpO5V+OztKQOw==
30 | dependencies:
31 | use-sync-external-store "^1.2.0"
32 |
33 | "@parcel/bundler-default@2.4.1":
34 | version "2.4.1"
35 | resolved "https://registry.yarnpkg.com/@parcel/bundler-default/-/bundler-default-2.4.1.tgz#a158fe63d99e38865db8353132bd1b2ff62ab47a"
36 | integrity sha512-PTfBOuoiiYdfwyoPFeBTOinyl1RL4qaoyAQ0PCe01C1i4NcRWCY1w7zRvwJW/OhU3Ka+LtioGmfxu5/drdXzLg==
37 | dependencies:
38 | "@parcel/diagnostic" "2.4.1"
39 | "@parcel/hash" "2.4.1"
40 | "@parcel/plugin" "2.4.1"
41 | "@parcel/utils" "2.4.1"
42 | nullthrows "^1.1.1"
43 |
44 | "@parcel/cache@2.4.1":
45 | version "2.4.1"
46 | resolved "https://registry.yarnpkg.com/@parcel/cache/-/cache-2.4.1.tgz#94322d6de5b9ccb18d58585c267022f47a6315d3"
47 | integrity sha512-2N5ly++p/yefmPdK39X1QIoA2e6NtS1aYSsxrIC9EX92Kjd7SfSceqUJhlJWB49omJSheEJLd1qM3EJG9EvICQ==
48 | dependencies:
49 | "@parcel/fs" "2.4.1"
50 | "@parcel/logger" "2.4.1"
51 | "@parcel/utils" "2.4.1"
52 | lmdb "2.2.4"
53 |
54 | "@parcel/codeframe@2.4.1":
55 | version "2.4.1"
56 | resolved "https://registry.yarnpkg.com/@parcel/codeframe/-/codeframe-2.4.1.tgz#57dcedb0326ca120241d2f272b84019009350b20"
57 | integrity sha512-m3WDeEpWvgqekCqsHfPMJrSQquahdIgSR1x1RDCqQ1YelvW0fQiGgu42MXI5tjoBrHC1l1mF01UDb+xMSxz1DA==
58 | dependencies:
59 | chalk "^4.1.0"
60 |
61 | "@parcel/compressor-raw@2.4.1":
62 | version "2.4.1"
63 | resolved "https://registry.yarnpkg.com/@parcel/compressor-raw/-/compressor-raw-2.4.1.tgz#0bd2cb6fe02ae910e4e25f4db7b08ec1c1a52395"
64 | integrity sha512-cEOOOzIK7glxCqJX0OfBFBZE/iT7tmjEOXswRY3CnqY9FGoY3NYDAsOLm7A73RuIdNaZfYVxVUy3g7OLpbKL+g==
65 | dependencies:
66 | "@parcel/plugin" "2.4.1"
67 |
68 | "@parcel/config-default@2.4.1":
69 | version "2.4.1"
70 | resolved "https://registry.yarnpkg.com/@parcel/config-default/-/config-default-2.4.1.tgz#4b498b916dd9e47d49d4ad414a4139846a3e11bd"
71 | integrity sha512-yGA4Mx/KDzVOPm8IYb4Id+zlz1TaIM7s472pxA4tUV1qcEtBInY0aeO9R/GsLKC2+3QPHURZld9WI9EMXRUBBA==
72 | dependencies:
73 | "@parcel/bundler-default" "2.4.1"
74 | "@parcel/compressor-raw" "2.4.1"
75 | "@parcel/namer-default" "2.4.1"
76 | "@parcel/optimizer-css" "2.4.1"
77 | "@parcel/optimizer-htmlnano" "2.4.1"
78 | "@parcel/optimizer-image" "2.4.1"
79 | "@parcel/optimizer-svgo" "2.4.1"
80 | "@parcel/optimizer-terser" "2.4.1"
81 | "@parcel/packager-css" "2.4.1"
82 | "@parcel/packager-html" "2.4.1"
83 | "@parcel/packager-js" "2.4.1"
84 | "@parcel/packager-raw" "2.4.1"
85 | "@parcel/packager-svg" "2.4.1"
86 | "@parcel/reporter-dev-server" "2.4.1"
87 | "@parcel/resolver-default" "2.4.1"
88 | "@parcel/runtime-browser-hmr" "2.4.1"
89 | "@parcel/runtime-js" "2.4.1"
90 | "@parcel/runtime-react-refresh" "2.4.1"
91 | "@parcel/runtime-service-worker" "2.4.1"
92 | "@parcel/transformer-babel" "2.4.1"
93 | "@parcel/transformer-css" "2.4.1"
94 | "@parcel/transformer-html" "2.4.1"
95 | "@parcel/transformer-image" "2.4.1"
96 | "@parcel/transformer-js" "2.4.1"
97 | "@parcel/transformer-json" "2.4.1"
98 | "@parcel/transformer-postcss" "2.4.1"
99 | "@parcel/transformer-posthtml" "2.4.1"
100 | "@parcel/transformer-raw" "2.4.1"
101 | "@parcel/transformer-react-refresh-wrap" "2.4.1"
102 | "@parcel/transformer-svg" "2.4.1"
103 |
104 | "@parcel/core@2.4.1":
105 | version "2.4.1"
106 | resolved "https://registry.yarnpkg.com/@parcel/core/-/core-2.4.1.tgz#436b219769f273af299deb81f576be5b528c7e27"
107 | integrity sha512-h2FvqLA75ZQdIXX1y+ylGjIIi7YtbAUJyIapxaO081h3EsYG2jr9sRL4sym5ECgmvbyua/DEgtMLX3eGYn09FA==
108 | dependencies:
109 | "@parcel/cache" "2.4.1"
110 | "@parcel/diagnostic" "2.4.1"
111 | "@parcel/events" "2.4.1"
112 | "@parcel/fs" "2.4.1"
113 | "@parcel/graph" "2.4.1"
114 | "@parcel/hash" "2.4.1"
115 | "@parcel/logger" "2.4.1"
116 | "@parcel/package-manager" "2.4.1"
117 | "@parcel/plugin" "2.4.1"
118 | "@parcel/source-map" "^2.0.0"
119 | "@parcel/types" "2.4.1"
120 | "@parcel/utils" "2.4.1"
121 | "@parcel/workers" "2.4.1"
122 | abortcontroller-polyfill "^1.1.9"
123 | base-x "^3.0.8"
124 | browserslist "^4.6.6"
125 | clone "^2.1.1"
126 | dotenv "^7.0.0"
127 | dotenv-expand "^5.1.0"
128 | json-source-map "^0.6.1"
129 | json5 "^2.2.0"
130 | msgpackr "^1.5.4"
131 | nullthrows "^1.1.1"
132 | semver "^5.7.1"
133 |
134 | "@parcel/css-darwin-arm64@1.7.4":
135 | version "1.7.4"
136 | resolved "https://registry.yarnpkg.com/@parcel/css-darwin-arm64/-/css-darwin-arm64-1.7.4.tgz#9d173f8d9a3f6dec34e49999654ba091121f1f22"
137 | integrity sha512-fA+aBZAAgXSV7jUQFRYuKpJr5EEqNq++mFu4o/pU/lBFMJhL6Z11aqzrBecC1JziWT3t/BgryWdznf1QkNtM4w==
138 |
139 | "@parcel/css-darwin-x64@1.7.4":
140 | version "1.7.4"
141 | resolved "https://registry.yarnpkg.com/@parcel/css-darwin-x64/-/css-darwin-x64-1.7.4.tgz#e36f8a4c941c9059d6fc96e1f52c8022f04c32ef"
142 | integrity sha512-qx/+vEXSmed7eeBgVvV/1lrEjk8KnKUiAN+CCes8d6ddJJzK5evTKQsWkywe1jNdHC33d2mlLlhLFmC2+2IPOw==
143 |
144 | "@parcel/css-linux-arm-gnueabihf@1.7.4":
145 | version "1.7.4"
146 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm-gnueabihf/-/css-linux-arm-gnueabihf-1.7.4.tgz#783407f8179164e6555c9498436bc0e8d1c6c4e3"
147 | integrity sha512-+Qf+j8dqJ+t7V/w9LnyWBzNcMG/GnlzjlWNQhiUkt1aYFYPr5i/eRWuWLYxVlz8EGQOUbYlinDGLXTUJDt31gA==
148 |
149 | "@parcel/css-linux-arm64-gnu@1.7.4":
150 | version "1.7.4"
151 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-gnu/-/css-linux-arm64-gnu-1.7.4.tgz#34ed91540fe31001a835f7f5dfc86c90419fb2db"
152 | integrity sha512-ITP0HZT/Ay6JCgH3W7JpoRUYfciW+jBVBTjglZjYgyYPLLWk2J1kXB+qC3jHp5XCeH4feh7eFB1pyQcE7kqCjA==
153 |
154 | "@parcel/css-linux-arm64-musl@1.7.4":
155 | version "1.7.4"
156 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-arm64-musl/-/css-linux-arm64-musl-1.7.4.tgz#3937fdadb0581e96b9f76a37713241b35a3250fa"
157 | integrity sha512-or61QRhhpsDlHfrc73KP4bPwnnVZWni1jkuRv1mCi+0SzYzoaO190JEaj7VWh/boUvjGiIl//FsLoZleQIWKNA==
158 |
159 | "@parcel/css-linux-x64-gnu@1.7.4":
160 | version "1.7.4"
161 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-gnu/-/css-linux-x64-gnu-1.7.4.tgz#ee883af8a97b99519c581cb2971c414e962a6ae1"
162 | integrity sha512-GHGsM06F26FAkvPcnsGw7NHxPVD7TQvg7OC7cVAYmETccO8mqs9DyRzBTevk+1kl7EQXNnHDojn7VpVN6q+phg==
163 |
164 | "@parcel/css-linux-x64-musl@1.7.4":
165 | version "1.7.4"
166 | resolved "https://registry.yarnpkg.com/@parcel/css-linux-x64-musl/-/css-linux-x64-musl-1.7.4.tgz#fd14e88683026665543bc48dee138edc553fcf75"
167 | integrity sha512-H/9wvQ7LNqng9yIwulpfUUhs6zm9+vLCzri2qnC4vm8geyTjA0W0H5fphV8IlzNJ/DfHmoesJ+TXw5NG+QC9hg==
168 |
169 | "@parcel/css-win32-x64-msvc@1.7.4":
170 | version "1.7.4"
171 | resolved "https://registry.yarnpkg.com/@parcel/css-win32-x64-msvc/-/css-win32-x64-msvc-1.7.4.tgz#ed6dfb63600610ba555124262d84fa537ee7e6a4"
172 | integrity sha512-xmg18iISCn1f9IyYUif6yR8FuEmi93qzH55oUiri5vZWuCY8xfraHsRA6i8yLWnxgDmVeHyiN0IICl7rgZo10A==
173 |
174 | "@parcel/css@^1.7.4":
175 | version "1.7.4"
176 | resolved "https://registry.yarnpkg.com/@parcel/css/-/css-1.7.4.tgz#87b522681a5527ad38baec4193a26a94fde37a5e"
177 | integrity sha512-K1N9mxEkWQQmSINMNuGvlyPq7yCY+AtHskGxWav97lhu2i8GMMXRV9kc8/x/jkZh5KDBWO5vHhdQiujRBrgR8g==
178 | dependencies:
179 | detect-libc "^1.0.3"
180 | optionalDependencies:
181 | "@parcel/css-darwin-arm64" "1.7.4"
182 | "@parcel/css-darwin-x64" "1.7.4"
183 | "@parcel/css-linux-arm-gnueabihf" "1.7.4"
184 | "@parcel/css-linux-arm64-gnu" "1.7.4"
185 | "@parcel/css-linux-arm64-musl" "1.7.4"
186 | "@parcel/css-linux-x64-gnu" "1.7.4"
187 | "@parcel/css-linux-x64-musl" "1.7.4"
188 | "@parcel/css-win32-x64-msvc" "1.7.4"
189 |
190 | "@parcel/diagnostic@2.4.1":
191 | version "2.4.1"
192 | resolved "https://registry.yarnpkg.com/@parcel/diagnostic/-/diagnostic-2.4.1.tgz#edb275699b543f71cf933bea141a3165ad919a0d"
193 | integrity sha512-wmJIfn0PG2ABuraS+kMjl6UKaLjTDTtG+XkjJLWHzU/dd5RozqAZDKp65GWjvHzHLx7KICTAdUJsXh2s3TnTOQ==
194 | dependencies:
195 | json-source-map "^0.6.1"
196 | nullthrows "^1.1.1"
197 |
198 | "@parcel/events@2.4.1":
199 | version "2.4.1"
200 | resolved "https://registry.yarnpkg.com/@parcel/events/-/events-2.4.1.tgz#6e1ba26d55f7a2d6a7491e0901d287de3e471e99"
201 | integrity sha512-er2jwyzYt3Zimkrp7TR865GIeIMYNd7YSSxW39y/egm4LIPBsruUpHSnKRD5b65Jd+gckkxDsnrpADG6MH1zNw==
202 |
203 | "@parcel/fs-search@2.4.1":
204 | version "2.4.1"
205 | resolved "https://registry.yarnpkg.com/@parcel/fs-search/-/fs-search-2.4.1.tgz#ae195107895f366183ed0a3fa34bd4eeeaf3dfef"
206 | integrity sha512-xfoLvHjHkZm4VZf3UWU5v6gzz+x7IBVY7siHGn0YyGwvlv73FmiR4mCSizqerXOyXknF2fpg6tNHNQyyNLS32Q==
207 | dependencies:
208 | detect-libc "^1.0.3"
209 |
210 | "@parcel/fs@2.4.1":
211 | version "2.4.1"
212 | resolved "https://registry.yarnpkg.com/@parcel/fs/-/fs-2.4.1.tgz#49e22a8f8018916a4922682e8e608256752c9692"
213 | integrity sha512-kE9HzW6XjO/ZA5bQnAzp1YVmGlXeDqUaius2cH2K0wU7KQX/GBjyfEWJm/UsKPB6QIrGXgkPH6ashNzOgwDqpw==
214 | dependencies:
215 | "@parcel/fs-search" "2.4.1"
216 | "@parcel/types" "2.4.1"
217 | "@parcel/utils" "2.4.1"
218 | "@parcel/watcher" "^2.0.0"
219 | "@parcel/workers" "2.4.1"
220 |
221 | "@parcel/graph@2.4.1":
222 | version "2.4.1"
223 | resolved "https://registry.yarnpkg.com/@parcel/graph/-/graph-2.4.1.tgz#33c8d370603e898d1ef6e99b4936b90c45d6d76c"
224 | integrity sha512-3JCnPI9BJdKpGIk6NtVN7ML3C/J9Ey+WfUfk8WisDxFP7vjYkXwZbNSR/HnxH+Y03wmB6cv4HI8A4kndF0H0pw==
225 | dependencies:
226 | "@parcel/utils" "2.4.1"
227 | nullthrows "^1.1.1"
228 |
229 | "@parcel/hash@2.4.1":
230 | version "2.4.1"
231 | resolved "https://registry.yarnpkg.com/@parcel/hash/-/hash-2.4.1.tgz#475ecec62b08dbd21dddb62d6dc5b9148a6e5fe5"
232 | integrity sha512-Ch1kkFPedef3geapU+XYmAdZY29u3eQXn/twMjowAKkWCmj6wZ+muUgBmOO2uCfK3xys7GycI8jYZcAbF5DVLg==
233 | dependencies:
234 | detect-libc "^1.0.3"
235 | xxhash-wasm "^0.4.2"
236 |
237 | "@parcel/logger@2.4.1":
238 | version "2.4.1"
239 | resolved "https://registry.yarnpkg.com/@parcel/logger/-/logger-2.4.1.tgz#8f87097009d6847409da69ecbc248a136b2f36c2"
240 | integrity sha512-wm7FoKY+1dyo+Dd7Z4b0d6hmpgRBWfZwCoZSSyhgbG96Ty68/oo3m7oEMXPfry8IVGIhShmWKDp4py44PH3l7w==
241 | dependencies:
242 | "@parcel/diagnostic" "2.4.1"
243 | "@parcel/events" "2.4.1"
244 |
245 | "@parcel/markdown-ansi@2.4.1":
246 | version "2.4.1"
247 | resolved "https://registry.yarnpkg.com/@parcel/markdown-ansi/-/markdown-ansi-2.4.1.tgz#65f798234e5767d92c5f411de5aae11e611cd9b6"
248 | integrity sha512-BkWhzbKQhTQ9lS96ZMMG0KyXSJBFdNeBVobWrdrrwcFlNER0nt2m6fdF7Hfpf1TqFhM4tT+GNFtON7ybL53RiQ==
249 | dependencies:
250 | chalk "^4.1.0"
251 |
252 | "@parcel/namer-default@2.4.1":
253 | version "2.4.1"
254 | resolved "https://registry.yarnpkg.com/@parcel/namer-default/-/namer-default-2.4.1.tgz#63442b2bf06ec555f825924435f450c9768bcc5a"
255 | integrity sha512-a/Xulfia7JJP6Cw/D6Wq5xX6IAKVKMRPEYtU2wB8vKuwC/et6kXi+0bFVeCLnTjDzVtsjDdyOEwfRC4yiEy3BA==
256 | dependencies:
257 | "@parcel/diagnostic" "2.4.1"
258 | "@parcel/plugin" "2.4.1"
259 | nullthrows "^1.1.1"
260 |
261 | "@parcel/node-resolver-core@2.4.1":
262 | version "2.4.1"
263 | resolved "https://registry.yarnpkg.com/@parcel/node-resolver-core/-/node-resolver-core-2.4.1.tgz#640fd087f610f030db7411bb2f61ae0e896d7cd1"
264 | integrity sha512-CvCADj3l4o5USqz/ZCaqbK8gdAQK63q94oSa0KnP6hrcDI/gDyf5Bk4+3cD4kSI+ByuN6aFLAYBS2nHBh5O/MQ==
265 | dependencies:
266 | "@parcel/diagnostic" "2.4.1"
267 | "@parcel/utils" "2.4.1"
268 | nullthrows "^1.1.1"
269 |
270 | "@parcel/optimizer-css@2.4.1":
271 | version "2.4.1"
272 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-css/-/optimizer-css-2.4.1.tgz#67a6db736f3a2dce506cfefe40c12d25f23d530a"
273 | integrity sha512-+1CxZ43aoAUF8Hj2wLPK4d+TzdJlgYidXJ19Qwlh6XdQs8OeFGBAzIsUBFSr8+XCugXmnTkjYK94nX04Z2FhtQ==
274 | dependencies:
275 | "@parcel/css" "^1.7.4"
276 | "@parcel/diagnostic" "2.4.1"
277 | "@parcel/plugin" "2.4.1"
278 | "@parcel/source-map" "^2.0.0"
279 | "@parcel/utils" "2.4.1"
280 | browserslist "^4.6.6"
281 | nullthrows "^1.1.1"
282 |
283 | "@parcel/optimizer-htmlnano@2.4.1":
284 | version "2.4.1"
285 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-htmlnano/-/optimizer-htmlnano-2.4.1.tgz#18995b850fb1835a60c84378abff01b337f50cc7"
286 | integrity sha512-JkykHZcBS92iggT7GHuJJd+MDIc7BMAG0xxTJIY9KzzcxGNYsY8P3LedGVTL0/X8tkdlYQSGNLkTCntP0/62cw==
287 | dependencies:
288 | "@parcel/plugin" "2.4.1"
289 | htmlnano "^2.0.0"
290 | nullthrows "^1.1.1"
291 | posthtml "^0.16.5"
292 | svgo "^2.4.0"
293 |
294 | "@parcel/optimizer-image@2.4.1":
295 | version "2.4.1"
296 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-image/-/optimizer-image-2.4.1.tgz#f3fd069290268c84e9a12bdda7dc5ded781c874e"
297 | integrity sha512-cv03Ta1FWuF75o9DJLuk1eYk1ULSdSbSkriQUAzc4InKW1bJH6gJasMZSTBsAg2Oz1TWqiDyiy5D/6i/UPoBJg==
298 | dependencies:
299 | "@parcel/diagnostic" "2.4.1"
300 | "@parcel/plugin" "2.4.1"
301 | "@parcel/utils" "2.4.1"
302 | "@parcel/workers" "2.4.1"
303 | detect-libc "^1.0.3"
304 |
305 | "@parcel/optimizer-svgo@2.4.1":
306 | version "2.4.1"
307 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-svgo/-/optimizer-svgo-2.4.1.tgz#ff925aa40ca84a5dd816716662d22fb217b52288"
308 | integrity sha512-sOiofvHXjwJDu0NnTO8gGKDv0BztykVczfJdcedYmj207uU71JG1uODZvhyY4uiw1eRqmZnIXELZIftvYnZnDA==
309 | dependencies:
310 | "@parcel/diagnostic" "2.4.1"
311 | "@parcel/plugin" "2.4.1"
312 | "@parcel/utils" "2.4.1"
313 | svgo "^2.4.0"
314 |
315 | "@parcel/optimizer-terser@2.4.1":
316 | version "2.4.1"
317 | resolved "https://registry.yarnpkg.com/@parcel/optimizer-terser/-/optimizer-terser-2.4.1.tgz#999ae4551448540494f79861d4f68eb0cd0bfa48"
318 | integrity sha512-naRdp6gApWHUI1FCBZEJs9NzNngjZx8hRhIHeQtTxWpc2Mu8cVzxbVHNAwUj10nW3iOYmxyj4wleOArl8xpVCQ==
319 | dependencies:
320 | "@parcel/diagnostic" "2.4.1"
321 | "@parcel/plugin" "2.4.1"
322 | "@parcel/source-map" "^2.0.0"
323 | "@parcel/utils" "2.4.1"
324 | nullthrows "^1.1.1"
325 | terser "^5.2.0"
326 |
327 | "@parcel/package-manager@2.4.1":
328 | version "2.4.1"
329 | resolved "https://registry.yarnpkg.com/@parcel/package-manager/-/package-manager-2.4.1.tgz#fcd05b0d1999bef52496599043e0d5432abf57da"
330 | integrity sha512-JUUinm4U3hy4epHl9A389xb+BGiFR8n9+qw3Z4UDfS1te43sh8+0virBGcnai/G7mlr5/vHW+l9xulc7WQaY6w==
331 | dependencies:
332 | "@parcel/diagnostic" "2.4.1"
333 | "@parcel/fs" "2.4.1"
334 | "@parcel/logger" "2.4.1"
335 | "@parcel/types" "2.4.1"
336 | "@parcel/utils" "2.4.1"
337 | "@parcel/workers" "2.4.1"
338 | semver "^5.7.1"
339 |
340 | "@parcel/packager-css@2.4.1":
341 | version "2.4.1"
342 | resolved "https://registry.yarnpkg.com/@parcel/packager-css/-/packager-css-2.4.1.tgz#644d1b50426f08f08dd13beea6cd5b5a75d2d11b"
343 | integrity sha512-COx6RvHbpZ3DzuAgB/XvLLR/luxn9kYhqdFrnmIlYBh4B9atfXyr4rKDlWj1W/r2R72R6LHM35KhkwUATmrC/w==
344 | dependencies:
345 | "@parcel/plugin" "2.4.1"
346 | "@parcel/source-map" "^2.0.0"
347 | "@parcel/utils" "2.4.1"
348 | nullthrows "^1.1.1"
349 |
350 | "@parcel/packager-html@2.4.1":
351 | version "2.4.1"
352 | resolved "https://registry.yarnpkg.com/@parcel/packager-html/-/packager-html-2.4.1.tgz#6aa04c2650e4586fae0a5aa09913ee165d968cb9"
353 | integrity sha512-F5/PmWKoz8JhToufnp3u+NQ4LUoVkabzIJYHyQrM858XVmNbMInRfiTYxtgCBa2ARm2BTPhToh7N01OEyFCOhA==
354 | dependencies:
355 | "@parcel/plugin" "2.4.1"
356 | "@parcel/types" "2.4.1"
357 | "@parcel/utils" "2.4.1"
358 | nullthrows "^1.1.1"
359 | posthtml "^0.16.5"
360 |
361 | "@parcel/packager-js@2.4.1":
362 | version "2.4.1"
363 | resolved "https://registry.yarnpkg.com/@parcel/packager-js/-/packager-js-2.4.1.tgz#f544f9e48718a1187be7856a5e638dc231e1867e"
364 | integrity sha512-broWBUQisJLF5ThFtnl/asypuLMlMBwFPBTr8Ho9FYlL6W4wUzIymu7eOcuDljstmbD6luNVGMdCBYqt3IhHmw==
365 | dependencies:
366 | "@parcel/diagnostic" "2.4.1"
367 | "@parcel/hash" "2.4.1"
368 | "@parcel/plugin" "2.4.1"
369 | "@parcel/source-map" "^2.0.0"
370 | "@parcel/utils" "2.4.1"
371 | globals "^13.2.0"
372 | nullthrows "^1.1.1"
373 |
374 | "@parcel/packager-raw@2.4.1":
375 | version "2.4.1"
376 | resolved "https://registry.yarnpkg.com/@parcel/packager-raw/-/packager-raw-2.4.1.tgz#2566bd6187cf4e2393e5aad2b567d803248fdacb"
377 | integrity sha512-4lCY3TjiYaZyRIqshNF21i6XkQ5PJyr+ahhK4O2IymuYuD8/wGH2amTZqKPpGLuiF3j1HskRRUNv1ekpvExJ8w==
378 | dependencies:
379 | "@parcel/plugin" "2.4.1"
380 |
381 | "@parcel/packager-svg@2.4.1":
382 | version "2.4.1"
383 | resolved "https://registry.yarnpkg.com/@parcel/packager-svg/-/packager-svg-2.4.1.tgz#218c2b1e2efee648b4113ca72ed314a83ad38522"
384 | integrity sha512-V7GW/dgJPqXHReTzwpLcNEdyT5WWveYOW1MfxvKgOOK1ENk6oPgXL0FUdm5IHzqlK1bbwF5hzSQs2vaJMv7rPg==
385 | dependencies:
386 | "@parcel/plugin" "2.4.1"
387 | "@parcel/types" "2.4.1"
388 | "@parcel/utils" "2.4.1"
389 | posthtml "^0.16.4"
390 |
391 | "@parcel/plugin@2.4.1":
392 | version "2.4.1"
393 | resolved "https://registry.yarnpkg.com/@parcel/plugin/-/plugin-2.4.1.tgz#15294d796be2703b16fa4e617967cfaa8e5631d4"
394 | integrity sha512-EJzNhwNWYuSpIPRlG1U2hKcovq/RsVie4Os1z51/e2dcCto/uAoJOMoWYYsCxtjkJ7BjFYyQ7fcZRKM9DEr6gQ==
395 | dependencies:
396 | "@parcel/types" "2.4.1"
397 |
398 | "@parcel/reporter-cli@2.4.1":
399 | version "2.4.1"
400 | resolved "https://registry.yarnpkg.com/@parcel/reporter-cli/-/reporter-cli-2.4.1.tgz#011a84e4da9fdc5f65c7c44c31f7b24c8841ea8a"
401 | integrity sha512-99v/dSQ6wYmfpjmBxbsuBoxPWu9bm7PRxDDJxiVapbbym50bWYwVmMEHj6mYnK151YbMssV0garrSs1yYQEvqw==
402 | dependencies:
403 | "@parcel/plugin" "2.4.1"
404 | "@parcel/types" "2.4.1"
405 | "@parcel/utils" "2.4.1"
406 | chalk "^4.1.0"
407 | term-size "^2.2.1"
408 |
409 | "@parcel/reporter-dev-server@2.4.1":
410 | version "2.4.1"
411 | resolved "https://registry.yarnpkg.com/@parcel/reporter-dev-server/-/reporter-dev-server-2.4.1.tgz#dc29b399f0402ad6327fa1697ddc8bee74e7ff7d"
412 | integrity sha512-tRz1LHiudDhujBC3kJ3Qm0Wnbo3p3SpE6fjyCFRhdv2PJnEufNTTwzEUoa7lYZACwFVQUtrh6F7nMXFw6ynrsQ==
413 | dependencies:
414 | "@parcel/plugin" "2.4.1"
415 | "@parcel/utils" "2.4.1"
416 |
417 | "@parcel/resolver-default@2.4.1":
418 | version "2.4.1"
419 | resolved "https://registry.yarnpkg.com/@parcel/resolver-default/-/resolver-default-2.4.1.tgz#0ac851a42c9fb7521936339341f69730e6052495"
420 | integrity sha512-iJRt1+7lk0n7+wb+S/tVyiObbaiYP1YQGKRsTE8y4Kgp4/OPukdUHGFJwzbojWa0HnyoXm3zEgelVz7cHl47fQ==
421 | dependencies:
422 | "@parcel/node-resolver-core" "2.4.1"
423 | "@parcel/plugin" "2.4.1"
424 |
425 | "@parcel/runtime-browser-hmr@2.4.1":
426 | version "2.4.1"
427 | resolved "https://registry.yarnpkg.com/@parcel/runtime-browser-hmr/-/runtime-browser-hmr-2.4.1.tgz#dcc0d5b41e5662aa694dc5ad937c00d088c80dca"
428 | integrity sha512-INsr78Kn0OuwMdXHCzw7v6l3Gf/UBTYtX7N7JNDOIBEFFkuZQiFWyAOI2P/DvMm8qeqcsrKliBO5Xty/a2Ivaw==
429 | dependencies:
430 | "@parcel/plugin" "2.4.1"
431 | "@parcel/utils" "2.4.1"
432 |
433 | "@parcel/runtime-js@2.4.1":
434 | version "2.4.1"
435 | resolved "https://registry.yarnpkg.com/@parcel/runtime-js/-/runtime-js-2.4.1.tgz#7322a434a49ce78a14dccfb945dfc24f009397df"
436 | integrity sha512-/EXwRpo+GPvWgN5yD0hjjt84Gm6QWp757dqOOzTG5R2rm1WU+g1a+zJJB1zXkxhu9lleQs44D1jEffzhh2Voyw==
437 | dependencies:
438 | "@parcel/plugin" "2.4.1"
439 | "@parcel/utils" "2.4.1"
440 | nullthrows "^1.1.1"
441 |
442 | "@parcel/runtime-react-refresh@2.4.1":
443 | version "2.4.1"
444 | resolved "https://registry.yarnpkg.com/@parcel/runtime-react-refresh/-/runtime-react-refresh-2.4.1.tgz#86c9e2bbf4ce7a4bfed493da07716f8c3a24948d"
445 | integrity sha512-a4GBQ/fO7Mklh1M1G2JVpJBPbZD7YXUPAzh9Y4vpCf0ouTHBRMc8ew4CyKPJIrrTly5P42tFWnD3P4FVNKwHOQ==
446 | dependencies:
447 | "@parcel/plugin" "2.4.1"
448 | "@parcel/utils" "2.4.1"
449 | react-refresh "^0.9.0"
450 |
451 | "@parcel/runtime-service-worker@2.4.1":
452 | version "2.4.1"
453 | resolved "https://registry.yarnpkg.com/@parcel/runtime-service-worker/-/runtime-service-worker-2.4.1.tgz#928fb063273766ea52d8839758c212bbc657f1cb"
454 | integrity sha512-WtMKSiyQ0kF78rBw0XIx7n65mMb+6GBx+5m49r1aVZzeZEOSynpjJzJvqo7rxVmA7qTDkD2bko7BH41iScsEaw==
455 | dependencies:
456 | "@parcel/plugin" "2.4.1"
457 | "@parcel/utils" "2.4.1"
458 | nullthrows "^1.1.1"
459 |
460 | "@parcel/source-map@^2.0.0":
461 | version "2.0.2"
462 | resolved "https://registry.yarnpkg.com/@parcel/source-map/-/source-map-2.0.2.tgz#9aa0b00518cee31d5634de6e9c924a5539b142c1"
463 | integrity sha512-NnUrPYLpYB6qyx2v6bcRPn/gVigmGG6M6xL8wIg/i0dP1GLkuY1nf+Hqdf63FzPTqqT7K3k6eE5yHPQVMO5jcA==
464 | dependencies:
465 | detect-libc "^1.0.3"
466 |
467 | "@parcel/transformer-babel@2.4.1":
468 | version "2.4.1"
469 | resolved "https://registry.yarnpkg.com/@parcel/transformer-babel/-/transformer-babel-2.4.1.tgz#55e1a9587dd90adb4b3a16e600f625972a3a7a0f"
470 | integrity sha512-S+L14Fdr+S/+hqOi2nqnhuJvBbEJW24KyQeLmdaoMkt7DQLy5zENjGb9U2WYgB0Q96au0vX8NgB6jOnONecnpg==
471 | dependencies:
472 | "@parcel/diagnostic" "2.4.1"
473 | "@parcel/plugin" "2.4.1"
474 | "@parcel/source-map" "^2.0.0"
475 | "@parcel/utils" "2.4.1"
476 | browserslist "^4.6.6"
477 | json5 "^2.2.0"
478 | nullthrows "^1.1.1"
479 | semver "^5.7.0"
480 |
481 | "@parcel/transformer-css@2.4.1":
482 | version "2.4.1"
483 | resolved "https://registry.yarnpkg.com/@parcel/transformer-css/-/transformer-css-2.4.1.tgz#974cdf17ddf6a0a0a87c9f709d1c631b344e1820"
484 | integrity sha512-+6wCc0eEg4ez96Mucp/RjYKyRVN+7HPWPH7axalsQdp88t7wawWoqI2nd2mEw2PxpyuejIsk0ixLzYZ5opZivw==
485 | dependencies:
486 | "@parcel/css" "^1.7.4"
487 | "@parcel/diagnostic" "2.4.1"
488 | "@parcel/plugin" "2.4.1"
489 | "@parcel/source-map" "^2.0.0"
490 | "@parcel/utils" "2.4.1"
491 | browserslist "^4.6.6"
492 | nullthrows "^1.1.1"
493 |
494 | "@parcel/transformer-html@2.4.1":
495 | version "2.4.1"
496 | resolved "https://registry.yarnpkg.com/@parcel/transformer-html/-/transformer-html-2.4.1.tgz#f24ba5bc1d34c369e1d361e20e32fd194fc4aae0"
497 | integrity sha512-jyteTWuBA+f5wXn1RmAq3gOnB3yy41c748vARU9uNEXkLB4a7R106w4e5dlTG1DJfk+Tw1okSe1p2BeHoZntAw==
498 | dependencies:
499 | "@parcel/diagnostic" "2.4.1"
500 | "@parcel/hash" "2.4.1"
501 | "@parcel/plugin" "2.4.1"
502 | nullthrows "^1.1.1"
503 | posthtml "^0.16.5"
504 | posthtml-parser "^0.10.1"
505 | posthtml-render "^3.0.0"
506 | semver "^5.7.1"
507 |
508 | "@parcel/transformer-image@2.4.1":
509 | version "2.4.1"
510 | resolved "https://registry.yarnpkg.com/@parcel/transformer-image/-/transformer-image-2.4.1.tgz#5b3f97d8d41b08b29c47a0ca7cef6600520098ea"
511 | integrity sha512-pOfgPVe13lMTKdzydjXXNl4bojVMmuQmwm44OZ9cmpwOD3phkZzCtrxgySoV1eRBCOipdQg1O6GGI3za1KNdvw==
512 | dependencies:
513 | "@parcel/plugin" "2.4.1"
514 | "@parcel/workers" "2.4.1"
515 | nullthrows "^1.1.1"
516 |
517 | "@parcel/transformer-js@2.4.1":
518 | version "2.4.1"
519 | resolved "https://registry.yarnpkg.com/@parcel/transformer-js/-/transformer-js-2.4.1.tgz#824fc0cf86225a18eb3ac330a5096795ffb65374"
520 | integrity sha512-39Y9RUuDk5dc09Z3Pgj8snQd5E8926IqOowdTLKNJr7EcmkwHdinbpI4EqgKnisOwX4NSzxUti1I2DHsP1QZHw==
521 | dependencies:
522 | "@parcel/diagnostic" "2.4.1"
523 | "@parcel/plugin" "2.4.1"
524 | "@parcel/source-map" "^2.0.0"
525 | "@parcel/utils" "2.4.1"
526 | "@parcel/workers" "2.4.1"
527 | "@swc/helpers" "^0.3.6"
528 | browserslist "^4.6.6"
529 | detect-libc "^1.0.3"
530 | nullthrows "^1.1.1"
531 | regenerator-runtime "^0.13.7"
532 | semver "^5.7.1"
533 |
534 | "@parcel/transformer-json@2.4.1":
535 | version "2.4.1"
536 | resolved "https://registry.yarnpkg.com/@parcel/transformer-json/-/transformer-json-2.4.1.tgz#0585e539db5a81899a0409cfee63f509b81d6962"
537 | integrity sha512-bAwKyWb2/Wm6GS7OpQg1lWgcq+VDBXTKy5oFGX3edbpZFsrb59Ln1v+1jI888zRq4ehDBybhx8WTxPKTJnU+jA==
538 | dependencies:
539 | "@parcel/plugin" "2.4.1"
540 | json5 "^2.2.0"
541 |
542 | "@parcel/transformer-postcss@2.4.1":
543 | version "2.4.1"
544 | resolved "https://registry.yarnpkg.com/@parcel/transformer-postcss/-/transformer-postcss-2.4.1.tgz#5082c9733d4b8433c69466b1b532e23deaa36529"
545 | integrity sha512-I+jauarY5RlDUcd0zb9CC4GlpA7/+FqNSqCaGrM73aoszh6FNs4GiwD5tgy0pKOEASBZ0fBPmHEG1OBiVBXRGg==
546 | dependencies:
547 | "@parcel/diagnostic" "2.4.1"
548 | "@parcel/hash" "2.4.1"
549 | "@parcel/plugin" "2.4.1"
550 | "@parcel/utils" "2.4.1"
551 | clone "^2.1.1"
552 | nullthrows "^1.1.1"
553 | postcss-value-parser "^4.2.0"
554 | semver "^5.7.1"
555 |
556 | "@parcel/transformer-posthtml@2.4.1":
557 | version "2.4.1"
558 | resolved "https://registry.yarnpkg.com/@parcel/transformer-posthtml/-/transformer-posthtml-2.4.1.tgz#c5187fd92f38de1e8d05d17a6c849818eeaa2d7c"
559 | integrity sha512-DNtS41Sew940vnnqlFS0QK3ZbjQqCGT8JXkvwFojIrdH+3BW/n/9Hrtxj+X/bxrlwZlsRiqiRJ7crXp7TVhx2g==
560 | dependencies:
561 | "@parcel/plugin" "2.4.1"
562 | "@parcel/utils" "2.4.1"
563 | nullthrows "^1.1.1"
564 | posthtml "^0.16.5"
565 | posthtml-parser "^0.10.1"
566 | posthtml-render "^3.0.0"
567 | semver "^5.7.1"
568 |
569 | "@parcel/transformer-raw@2.4.1":
570 | version "2.4.1"
571 | resolved "https://registry.yarnpkg.com/@parcel/transformer-raw/-/transformer-raw-2.4.1.tgz#5e1842fbd661b6058294a7ba984a34b6896c3e65"
572 | integrity sha512-0PzdWJSGSTQ522aohymHEnq4GABy0mHSs+LkPZyMfNmX9ZAIyy6XuFJ9dz8nUmP4Nhn8qDvbRjoAYXR3XsGDGQ==
573 | dependencies:
574 | "@parcel/plugin" "2.4.1"
575 |
576 | "@parcel/transformer-react-refresh-wrap@2.4.1":
577 | version "2.4.1"
578 | resolved "https://registry.yarnpkg.com/@parcel/transformer-react-refresh-wrap/-/transformer-react-refresh-wrap-2.4.1.tgz#14f9194f30e417b46fc325f78ee4035254670f64"
579 | integrity sha512-zF6pzj/BwSiD1jA/BHDCEJnKSIDekjblU+OWp1WpSjA1uYkJORuZ5knLcq6mXOQ8M2NCbOXosc1ru8071i8sYA==
580 | dependencies:
581 | "@parcel/plugin" "2.4.1"
582 | "@parcel/utils" "2.4.1"
583 | react-refresh "^0.9.0"
584 |
585 | "@parcel/transformer-svg@2.4.1":
586 | version "2.4.1"
587 | resolved "https://registry.yarnpkg.com/@parcel/transformer-svg/-/transformer-svg-2.4.1.tgz#30381670312f4a512e714b47abd4c501e1d2401f"
588 | integrity sha512-E0XdXsZOnP7g9zvJskfvXeIHx9pKjPHtLKo/txmpjW1eXOmsFcRMVy6l4pFh+kBciAgiZOI6o1pVHt+Uf7ia/g==
589 | dependencies:
590 | "@parcel/diagnostic" "2.4.1"
591 | "@parcel/hash" "2.4.1"
592 | "@parcel/plugin" "2.4.1"
593 | nullthrows "^1.1.1"
594 | posthtml "^0.16.5"
595 | posthtml-parser "^0.10.1"
596 | posthtml-render "^3.0.0"
597 | semver "^5.7.1"
598 |
599 | "@parcel/types@2.4.1":
600 | version "2.4.1"
601 | resolved "https://registry.yarnpkg.com/@parcel/types/-/types-2.4.1.tgz#4cd7b99db403ec36a1fe9f31a6320b2f6148f580"
602 | integrity sha512-YqkiyGS8oiD89Z2lJP7sbjn0F0wlSJMAuqgqf7obeKj0zmZJS7n2xK0uUEuIlUO+Cbqgl0kCGsUSjuT8xcEqjg==
603 | dependencies:
604 | "@parcel/cache" "2.4.1"
605 | "@parcel/diagnostic" "2.4.1"
606 | "@parcel/fs" "2.4.1"
607 | "@parcel/package-manager" "2.4.1"
608 | "@parcel/source-map" "^2.0.0"
609 | "@parcel/workers" "2.4.1"
610 | utility-types "^3.10.0"
611 |
612 | "@parcel/utils@2.4.1":
613 | version "2.4.1"
614 | resolved "https://registry.yarnpkg.com/@parcel/utils/-/utils-2.4.1.tgz#1d8e30fc0fb61a52c3445235f0ed2e0130a29797"
615 | integrity sha512-hmbrnPtFAfMT6s9FMMIVlIzCwEFX/+byB67GoJmSCAMRmj6RMu4a6xKlv2FdzkTKJV2ucg8vxAcua0MQ/q8rkQ==
616 | dependencies:
617 | "@parcel/codeframe" "2.4.1"
618 | "@parcel/diagnostic" "2.4.1"
619 | "@parcel/hash" "2.4.1"
620 | "@parcel/logger" "2.4.1"
621 | "@parcel/markdown-ansi" "2.4.1"
622 | "@parcel/source-map" "^2.0.0"
623 | chalk "^4.1.0"
624 |
625 | "@parcel/watcher@^2.0.0":
626 | version "2.0.5"
627 | resolved "https://registry.yarnpkg.com/@parcel/watcher/-/watcher-2.0.5.tgz#f913a54e1601b0aac972803829b0eece48de215b"
628 | integrity sha512-x0hUbjv891omnkcHD7ZOhiyyUqUUR6MNjq89JhEI3BxppeKWAm6NPQsqqRrAkCJBogdT/o/My21sXtTI9rJIsw==
629 | dependencies:
630 | node-addon-api "^3.2.1"
631 | node-gyp-build "^4.3.0"
632 |
633 | "@parcel/workers@2.4.1":
634 | version "2.4.1"
635 | resolved "https://registry.yarnpkg.com/@parcel/workers/-/workers-2.4.1.tgz#27bc3ac703625bc1694873fee07fdbeaf555d987"
636 | integrity sha512-EYujbJOblFqIt2NGQ+baIYTuavJqbhy84IfZ3j0jmACeKO5Ew1EHXZyl9LJgWHKaIPZsnvnbxw2mDOF05K65xQ==
637 | dependencies:
638 | "@parcel/diagnostic" "2.4.1"
639 | "@parcel/logger" "2.4.1"
640 | "@parcel/types" "2.4.1"
641 | "@parcel/utils" "2.4.1"
642 | chrome-trace-event "^1.0.2"
643 | nullthrows "^1.1.1"
644 |
645 | "@swc/helpers@^0.3.6":
646 | version "0.3.8"
647 | resolved "https://registry.yarnpkg.com/@swc/helpers/-/helpers-0.3.8.tgz#5b9ecf4ee480ca00f1ffbc2d1a5d4eed0d1afe81"
648 | integrity sha512-aWItSZvJj4+GI6FWkjZR13xPNPctq2RRakzo+O6vN7bC2yjwdg5EFpgaSAUn95b7BGSgcflvzVDPoKmJv24IOg==
649 |
650 | "@trysound/sax@0.2.0":
651 | version "0.2.0"
652 | resolved "https://registry.yarnpkg.com/@trysound/sax/-/sax-0.2.0.tgz#cccaab758af56761eb7bf37af6f03f326dd798ad"
653 | integrity sha512-L7z9BgrNEcYyUYtF+HaEfiS5ebkh9jXqbszz7pC0hRBPaatV0XjSD3+eHrpqFemQfgwiFF0QPIarnIihIDn7OA==
654 |
655 | "@types/parse-json@^4.0.0":
656 | version "4.0.0"
657 | resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0"
658 | integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA==
659 |
660 | abortcontroller-polyfill@^1.1.9:
661 | version "1.7.3"
662 | resolved "https://registry.yarnpkg.com/abortcontroller-polyfill/-/abortcontroller-polyfill-1.7.3.tgz#1b5b487bd6436b5b764fd52a612509702c3144b5"
663 | integrity sha512-zetDJxd89y3X99Kvo4qFx8GKlt6GsvN3UcRZHwU6iFA/0KiOmhkTVhe8oRoTBiTVPZu09x3vCra47+w8Yz1+2Q==
664 |
665 | acorn@^8.5.0:
666 | version "8.7.0"
667 | resolved "https://registry.yarnpkg.com/acorn/-/acorn-8.7.0.tgz#90951fde0f8f09df93549481e5fc141445b791cf"
668 | integrity sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==
669 |
670 | ansi-styles@^3.2.1:
671 | version "3.2.1"
672 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-3.2.1.tgz#41fbb20243e50b12be0f04b8dedbf07520ce841d"
673 | integrity sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==
674 | dependencies:
675 | color-convert "^1.9.0"
676 |
677 | ansi-styles@^4.1.0:
678 | version "4.3.0"
679 | resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.3.0.tgz#edd803628ae71c04c85ae7a0906edad34b648937"
680 | integrity sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==
681 | dependencies:
682 | color-convert "^2.0.1"
683 |
684 | base-x@^3.0.8:
685 | version "3.0.9"
686 | resolved "https://registry.yarnpkg.com/base-x/-/base-x-3.0.9.tgz#6349aaabb58526332de9f60995e548a53fe21320"
687 | integrity sha512-H7JU6iBHTal1gp56aKoaa//YUxEaAOUiydvrV/pILqIHXTtqxSkATOnDA2u+jZ/61sD+L/412+7kzXRtWukhpQ==
688 | dependencies:
689 | safe-buffer "^5.0.1"
690 |
691 | boolbase@^1.0.0:
692 | version "1.0.0"
693 | resolved "https://registry.yarnpkg.com/boolbase/-/boolbase-1.0.0.tgz#68dff5fbe60c51eb37725ea9e3ed310dcc1e776e"
694 | integrity sha1-aN/1++YMUes3cl6p4+0xDcwed24=
695 |
696 | browserslist@^4.6.6:
697 | version "4.20.2"
698 | resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.20.2.tgz#567b41508757ecd904dab4d1c646c612cd3d4f88"
699 | integrity sha512-CQOBCqp/9pDvDbx3xfMi+86pr4KXIf2FDkTTdeuYw8OxS9t898LA1Khq57gtufFILXpfgsSx5woNgsBgvGjpsA==
700 | dependencies:
701 | caniuse-lite "^1.0.30001317"
702 | electron-to-chromium "^1.4.84"
703 | escalade "^3.1.1"
704 | node-releases "^2.0.2"
705 | picocolors "^1.0.0"
706 |
707 | bson-objectid@^2.0.3:
708 | version "2.0.3"
709 | resolved "https://registry.yarnpkg.com/bson-objectid/-/bson-objectid-2.0.3.tgz#d840185172846b2f10c42ce2bcdb4a50956a9db5"
710 | integrity sha512-WYwVtY9yqk179EPMNuF3vcxufdrGLEo2XwqdRVbfLVe9X6jLt7WKZQgP+ObOcprakBGbHxzl76tgTaieqsH29g==
711 |
712 | buffer-from@^1.0.0:
713 | version "1.1.2"
714 | resolved "https://registry.yarnpkg.com/buffer-from/-/buffer-from-1.1.2.tgz#2b146a6fd72e80b4f55d255f35ed59a3a9a41bd5"
715 | integrity sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==
716 |
717 | callsites@^3.0.0:
718 | version "3.1.0"
719 | resolved "https://registry.yarnpkg.com/callsites/-/callsites-3.1.0.tgz#b3630abd8943432f54b3f0519238e33cd7df2f73"
720 | integrity sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==
721 |
722 | caniuse-lite@^1.0.30001317:
723 | version "1.0.30001325"
724 | resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001325.tgz#2b4ad19b77aa36f61f2eaf72e636d7481d55e606"
725 | integrity sha512-sB1bZHjseSjDtijV1Hb7PB2Zd58Kyx+n/9EotvZ4Qcz2K3d0lWB8dB4nb8wN/TsOGFq3UuAm0zQZNQ4SoR7TrQ==
726 |
727 | chalk@^2.0.0:
728 | version "2.4.2"
729 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-2.4.2.tgz#cd42541677a54333cf541a49108c1432b44c9424"
730 | integrity sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==
731 | dependencies:
732 | ansi-styles "^3.2.1"
733 | escape-string-regexp "^1.0.5"
734 | supports-color "^5.3.0"
735 |
736 | chalk@^4.1.0:
737 | version "4.1.2"
738 | resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01"
739 | integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==
740 | dependencies:
741 | ansi-styles "^4.1.0"
742 | supports-color "^7.1.0"
743 |
744 | chrome-trace-event@^1.0.2:
745 | version "1.0.3"
746 | resolved "https://registry.yarnpkg.com/chrome-trace-event/-/chrome-trace-event-1.0.3.tgz#1015eced4741e15d06664a957dbbf50d041e26ac"
747 | integrity sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==
748 |
749 | clone@^2.1.1:
750 | version "2.1.2"
751 | resolved "https://registry.yarnpkg.com/clone/-/clone-2.1.2.tgz#1b7f4b9f591f1e8f83670401600345a02887435f"
752 | integrity sha1-G39Ln1kfHo+DZwQBYANFoCiHQ18=
753 |
754 | color-convert@^1.9.0:
755 | version "1.9.3"
756 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-1.9.3.tgz#bb71850690e1f136567de629d2d5471deda4c1e8"
757 | integrity sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==
758 | dependencies:
759 | color-name "1.1.3"
760 |
761 | color-convert@^2.0.1:
762 | version "2.0.1"
763 | resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3"
764 | integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==
765 | dependencies:
766 | color-name "~1.1.4"
767 |
768 | color-name@1.1.3:
769 | version "1.1.3"
770 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25"
771 | integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=
772 |
773 | color-name@~1.1.4:
774 | version "1.1.4"
775 | resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2"
776 | integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==
777 |
778 | commander@^2.20.0:
779 | version "2.20.3"
780 | resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33"
781 | integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==
782 |
783 | commander@^7.0.0, commander@^7.2.0:
784 | version "7.2.0"
785 | resolved "https://registry.yarnpkg.com/commander/-/commander-7.2.0.tgz#a36cb57d0b501ce108e4d20559a150a391d97ab7"
786 | integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==
787 |
788 | cosmiconfig@^7.0.1:
789 | version "7.0.1"
790 | resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-7.0.1.tgz#714d756522cace867867ccb4474c5d01bbae5d6d"
791 | integrity sha512-a1YWNUV2HwGimB7dU2s1wUMurNKjpx60HxBB6xUM8Re+2s1g1IIfJvFR0/iCF+XHdE0GMTKTuLR32UQff4TEyQ==
792 | dependencies:
793 | "@types/parse-json" "^4.0.0"
794 | import-fresh "^3.2.1"
795 | parse-json "^5.0.0"
796 | path-type "^4.0.0"
797 | yaml "^1.10.0"
798 |
799 | css-select@^4.1.3:
800 | version "4.3.0"
801 | resolved "https://registry.yarnpkg.com/css-select/-/css-select-4.3.0.tgz#db7129b2846662fd8628cfc496abb2b59e41529b"
802 | integrity sha512-wPpOYtnsVontu2mODhA19JrqWxNsfdatRKd64kmpRbQgh1KtItko5sTnEpPdpSaJszTOhEMlF/RPz28qj4HqhQ==
803 | dependencies:
804 | boolbase "^1.0.0"
805 | css-what "^6.0.1"
806 | domhandler "^4.3.1"
807 | domutils "^2.8.0"
808 | nth-check "^2.0.1"
809 |
810 | css-tree@^1.1.2, css-tree@^1.1.3:
811 | version "1.1.3"
812 | resolved "https://registry.yarnpkg.com/css-tree/-/css-tree-1.1.3.tgz#eb4870fb6fd7707327ec95c2ff2ab09b5e8db91d"
813 | integrity sha512-tRpdppF7TRazZrjJ6v3stzv93qxRcSsFmW6cX0Zm2NVKpxE1WV1HblnghVv9TreireHkqI/VDEsfolRF1p6y7Q==
814 | dependencies:
815 | mdn-data "2.0.14"
816 | source-map "^0.6.1"
817 |
818 | css-what@^6.0.1:
819 | version "6.1.0"
820 | resolved "https://registry.yarnpkg.com/css-what/-/css-what-6.1.0.tgz#fb5effcf76f1ddea2c81bdfaa4de44e79bac70f4"
821 | integrity sha512-HTUrgRJ7r4dsZKU6GjmpfRK1O76h97Z8MfS1G0FozR+oF2kG6Vfe8JE6zwrkbxigziPHinCJ+gCPjA9EaBDtRw==
822 |
823 | csso@^4.2.0:
824 | version "4.2.0"
825 | resolved "https://registry.yarnpkg.com/csso/-/csso-4.2.0.tgz#ea3a561346e8dc9f546d6febedd50187cf389529"
826 | integrity sha512-wvlcdIbf6pwKEk7vHj8/Bkc0B4ylXZruLvOgs9doS5eOsOpuodOV2zJChSpkp+pRpYQLQMeF04nr3Z68Sta9jA==
827 | dependencies:
828 | css-tree "^1.1.2"
829 |
830 | detect-libc@^1.0.3:
831 | version "1.0.3"
832 | resolved "https://registry.yarnpkg.com/detect-libc/-/detect-libc-1.0.3.tgz#fa137c4bd698edf55cd5cd02ac559f91a4c4ba9b"
833 | integrity sha1-+hN8S9aY7fVc1c0CrFWfkaTEups=
834 |
835 | dom-serializer@^1.0.1:
836 | version "1.3.2"
837 | resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-1.3.2.tgz#6206437d32ceefaec7161803230c7a20bc1b4d91"
838 | integrity sha512-5c54Bk5Dw4qAxNOI1pFEizPSjVsx5+bpJKmL2kPn8JhBUq2q09tTCa3mjijun2NfK78NMouDYNMBkOrPZiS+ig==
839 | dependencies:
840 | domelementtype "^2.0.1"
841 | domhandler "^4.2.0"
842 | entities "^2.0.0"
843 |
844 | domelementtype@^2.0.1, domelementtype@^2.2.0:
845 | version "2.2.0"
846 | resolved "https://registry.yarnpkg.com/domelementtype/-/domelementtype-2.2.0.tgz#9a0b6c2782ed6a1c7323d42267183df9bd8b1d57"
847 | integrity sha512-DtBMo82pv1dFtUmHyr48beiuq792Sxohr+8Hm9zoxklYPfa6n0Z3Byjj2IV7bmr2IyqClnqEQhfgHJJ5QF0R5A==
848 |
849 | domhandler@^4.2.0, domhandler@^4.2.2, domhandler@^4.3.1:
850 | version "4.3.1"
851 | resolved "https://registry.yarnpkg.com/domhandler/-/domhandler-4.3.1.tgz#8d792033416f59d68bc03a5aa7b018c1ca89279c"
852 | integrity sha512-GrwoxYN+uWlzO8uhUXRl0P+kHE4GtVPfYzVLcUxPL7KNdHKj66vvlhiweIHqYYXWlw+T8iLMp42Lm67ghw4WMQ==
853 | dependencies:
854 | domelementtype "^2.2.0"
855 |
856 | domutils@^2.8.0:
857 | version "2.8.0"
858 | resolved "https://registry.yarnpkg.com/domutils/-/domutils-2.8.0.tgz#4437def5db6e2d1f5d6ee859bd95ca7d02048135"
859 | integrity sha512-w96Cjofp72M5IIhpjgobBimYEfoPjx1Vx0BSX9P30WBdZW2WIKU0T1Bd0kz2eNZ9ikjKgHbEyKx8BB6H1L3h3A==
860 | dependencies:
861 | dom-serializer "^1.0.1"
862 | domelementtype "^2.2.0"
863 | domhandler "^4.2.0"
864 |
865 | dotenv-expand@^5.1.0:
866 | version "5.1.0"
867 | resolved "https://registry.yarnpkg.com/dotenv-expand/-/dotenv-expand-5.1.0.tgz#3fbaf020bfd794884072ea26b1e9791d45a629f0"
868 | integrity sha512-YXQl1DSa4/PQyRfgrv6aoNjhasp/p4qs9FjJ4q4cQk+8m4r6k4ZSiEyytKG8f8W9gi8WsQtIObNmKd+tMzNTmA==
869 |
870 | dotenv@^7.0.0:
871 | version "7.0.0"
872 | resolved "https://registry.yarnpkg.com/dotenv/-/dotenv-7.0.0.tgz#a2be3cd52736673206e8a85fb5210eea29628e7c"
873 | integrity sha512-M3NhsLbV1i6HuGzBUH8vXrtxOk+tWmzWKDMbAVSUp3Zsjm7ywFeuwrUXhmhQyRK1q5B5GGy7hcXPbj3bnfZg2g==
874 |
875 | electron-to-chromium@^1.4.84:
876 | version "1.4.103"
877 | resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.4.103.tgz#abfe376a4d70fa1e1b4b353b95df5d6dfd05da3a"
878 | integrity sha512-c/uKWR1Z/W30Wy/sx3dkZoj4BijbXX85QKWu9jJfjho3LBAXNEGAEW3oWiGb+dotA6C6BzCTxL2/aLes7jlUeg==
879 |
880 | entities@^2.0.0:
881 | version "2.2.0"
882 | resolved "https://registry.yarnpkg.com/entities/-/entities-2.2.0.tgz#098dc90ebb83d8dffa089d55256b351d34c4da55"
883 | integrity sha512-p92if5Nz619I0w+akJrLZH0MX0Pb5DX39XOwQTtXSdQQOaYH03S1uIQp4mhOZtAXrxq4ViO67YTiLBo2638o9A==
884 |
885 | entities@^3.0.1:
886 | version "3.0.1"
887 | resolved "https://registry.yarnpkg.com/entities/-/entities-3.0.1.tgz#2b887ca62585e96db3903482d336c1006c3001d4"
888 | integrity sha512-WiyBqoomrwMdFG1e0kqvASYfnlb0lp8M5o5Fw2OFq1hNZxxcNk8Ik0Xm7LxzBhuidnZB/UtBqVCgUz3kBOP51Q==
889 |
890 | error-ex@^1.3.1:
891 | version "1.3.2"
892 | resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.2.tgz#b4ac40648107fdcdcfae242f428bea8a14d4f1bf"
893 | integrity sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==
894 | dependencies:
895 | is-arrayish "^0.2.1"
896 |
897 | escalade@^3.1.1:
898 | version "3.1.1"
899 | resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.1.tgz#d8cfdc7000965c5a0174b4a82eaa5c0552742e40"
900 | integrity sha512-k0er2gUkLf8O0zKJiAhmkTnJlTvINGv7ygDNPbeIsX/TJjGJZHuh9B2UxbsaEkmlEo9MfhrSzmhIlhRlI2GXnw==
901 |
902 | escape-string-regexp@^1.0.5:
903 | version "1.0.5"
904 | resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
905 | integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
906 |
907 | get-port@^4.2.0:
908 | version "4.2.0"
909 | resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119"
910 | integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw==
911 |
912 | globals@^13.2.0:
913 | version "13.13.0"
914 | resolved "https://registry.yarnpkg.com/globals/-/globals-13.13.0.tgz#ac32261060d8070e2719dd6998406e27d2b5727b"
915 | integrity sha512-EQ7Q18AJlPwp3vUDL4mKA0KXrXyNIQyWon6T6XQiBQF0XHvRsiCSrWmmeATpUzdJN2HhWZU6Pdl0a9zdep5p6A==
916 | dependencies:
917 | type-fest "^0.20.2"
918 |
919 | has-flag@^3.0.0:
920 | version "3.0.0"
921 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-3.0.0.tgz#b5d454dc2199ae225699f3467e5a07f3b955bafd"
922 | integrity sha1-tdRU3CGZriJWmfNGfloH87lVuv0=
923 |
924 | has-flag@^4.0.0:
925 | version "4.0.0"
926 | resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-4.0.0.tgz#944771fd9c81c81265c4d6941860da06bb59479b"
927 | integrity sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==
928 |
929 | htmlnano@^2.0.0:
930 | version "2.0.0"
931 | resolved "https://registry.yarnpkg.com/htmlnano/-/htmlnano-2.0.0.tgz#07376faa064f7e1e832dfd91e1a9f606b0bc9b78"
932 | integrity sha512-thKQfhcp2xgtsWNE27A2bliEeqVL5xjAgGn0wajyttvFFsvFWWah1ntV9aEX61gz0T6MBQ5xK/1lXuEumhJTcg==
933 | dependencies:
934 | cosmiconfig "^7.0.1"
935 | posthtml "^0.16.5"
936 | timsort "^0.3.0"
937 |
938 | htmlparser2@^7.1.1:
939 | version "7.2.0"
940 | resolved "https://registry.yarnpkg.com/htmlparser2/-/htmlparser2-7.2.0.tgz#8817cdea38bbc324392a90b1990908e81a65f5a5"
941 | integrity sha512-H7MImA4MS6cw7nbyURtLPO1Tms7C5H602LRETv95z1MxO/7CP7rDVROehUYeYBUYEON94NXXDEPmZuq+hX4sog==
942 | dependencies:
943 | domelementtype "^2.0.1"
944 | domhandler "^4.2.2"
945 | domutils "^2.8.0"
946 | entities "^3.0.1"
947 |
948 | immer@^9.0.12:
949 | version "9.0.12"
950 | resolved "https://registry.yarnpkg.com/immer/-/immer-9.0.12.tgz#2d33ddf3ee1d247deab9d707ca472c8c942a0f20"
951 | integrity sha512-lk7UNmSbAukB5B6dh9fnh5D0bJTOFKxVg2cyJWTYrWRfhLrLMBquONcUs3aFq507hNoIZEDDh8lb8UtOizSMhA==
952 |
953 | "immerhin@link:../..":
954 | version "0.0.0"
955 | uid ""
956 |
957 | import-fresh@^3.2.1:
958 | version "3.3.0"
959 | resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.3.0.tgz#37162c25fcb9ebaa2e6e53d5b4d88ce17d9e0c2b"
960 | integrity sha512-veYYhQa+D1QBKznvhUHxb8faxlrwUnxseDAbAp457E0wLNio2bOSKnjYDhMj+YiAq61xrMGhQk9iXVk5FzgQMw==
961 | dependencies:
962 | parent-module "^1.0.0"
963 | resolve-from "^4.0.0"
964 |
965 | is-arrayish@^0.2.1:
966 | version "0.2.1"
967 | resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
968 | integrity sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=
969 |
970 | is-json@^2.0.1:
971 | version "2.0.1"
972 | resolved "https://registry.yarnpkg.com/is-json/-/is-json-2.0.1.tgz#6be166d144828a131d686891b983df62c39491ff"
973 | integrity sha1-a+Fm0USCihMdaGiRuYPfYsOUkf8=
974 |
975 | "js-tokens@^3.0.0 || ^4.0.0", js-tokens@^4.0.0:
976 | version "4.0.0"
977 | resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-4.0.0.tgz#19203fb59991df98e3a287050d4647cdeaf32499"
978 | integrity sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==
979 |
980 | json-parse-even-better-errors@^2.3.0:
981 | version "2.3.1"
982 | resolved "https://registry.yarnpkg.com/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz#7c47805a94319928e05777405dc12e1f7a4ee02d"
983 | integrity sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==
984 |
985 | json-source-map@^0.6.1:
986 | version "0.6.1"
987 | resolved "https://registry.yarnpkg.com/json-source-map/-/json-source-map-0.6.1.tgz#e0b1f6f4ce13a9ad57e2ae165a24d06e62c79a0f"
988 | integrity sha512-1QoztHPsMQqhDq0hlXY5ZqcEdUzxQEIxgFkKl4WUp2pgShObl+9ovi4kRh2TfvAfxAoHOJ9vIMEqk3k4iex7tg==
989 |
990 | json5@^2.2.0:
991 | version "2.2.1"
992 | resolved "https://registry.yarnpkg.com/json5/-/json5-2.2.1.tgz#655d50ed1e6f95ad1a3caababd2b0efda10b395c"
993 | integrity sha512-1hqLFMSrGHRHxav9q9gNjJ5EXznIxGVO09xQRrwplcS8qs28pZ8s8hupZAmqDwZUmVZ2Qb2jnyPOWcDH8m8dlA==
994 |
995 | lines-and-columns@^1.1.6:
996 | version "1.2.4"
997 | resolved "https://registry.yarnpkg.com/lines-and-columns/-/lines-and-columns-1.2.4.tgz#eca284f75d2965079309dc0ad9255abb2ebc1632"
998 | integrity sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==
999 |
1000 | lmdb@2.2.4:
1001 | version "2.2.4"
1002 | resolved "https://registry.yarnpkg.com/lmdb/-/lmdb-2.2.4.tgz#6494d5a1d1db152e0be759edcfa06893e4cbdb53"
1003 | integrity sha512-gto+BB2uEob8qRiTlOq+R3uX0YNHsX9mjxj9Sbdue/LIKqu6IlZjrsjKeGyOMquc/474GEqFyX2pdytpydp0rQ==
1004 | dependencies:
1005 | msgpackr "^1.5.4"
1006 | nan "^2.14.2"
1007 | node-gyp-build "^4.2.3"
1008 | ordered-binary "^1.2.4"
1009 | weak-lru-cache "^1.2.2"
1010 |
1011 | loose-envify@^1.1.0:
1012 | version "1.4.0"
1013 | resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.4.0.tgz#71ee51fa7be4caec1a63839f7e682d8132d30caf"
1014 | integrity sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==
1015 | dependencies:
1016 | js-tokens "^3.0.0 || ^4.0.0"
1017 |
1018 | mdn-data@2.0.14:
1019 | version "2.0.14"
1020 | resolved "https://registry.yarnpkg.com/mdn-data/-/mdn-data-2.0.14.tgz#7113fc4281917d63ce29b43446f701e68c25ba50"
1021 | integrity sha512-dn6wd0uw5GsdswPFfsgMp5NSB0/aDe6fK94YJV/AJDYXL6HVLWBsxeq7js7Ad+mU2K9LAlwpk6kN2D5mwCPVow==
1022 |
1023 | msgpackr-extract@^1.0.14:
1024 | version "1.0.16"
1025 | resolved "https://registry.yarnpkg.com/msgpackr-extract/-/msgpackr-extract-1.0.16.tgz#701c4f6e6f25c100ae84557092274e8fffeefe45"
1026 | integrity sha512-fxdRfQUxPrL/TizyfYfMn09dK58e+d65bRD/fcaVH4052vj30QOzzqxcQIS7B0NsqlypEQ/6Du3QmP2DhWFfCA==
1027 | dependencies:
1028 | nan "^2.14.2"
1029 | node-gyp-build "^4.2.3"
1030 |
1031 | msgpackr@^1.5.4:
1032 | version "1.5.5"
1033 | resolved "https://registry.yarnpkg.com/msgpackr/-/msgpackr-1.5.5.tgz#c0562abc2951d7e29f75d77a8656b01f103a042c"
1034 | integrity sha512-JG0V47xRIQ9pyUnx6Hb4+3TrQoia2nA3UIdmyTldhxaxtKFkekkKpUW/N6fwHwod9o4BGuJGtouxOk+yCP5PEA==
1035 | optionalDependencies:
1036 | msgpackr-extract "^1.0.14"
1037 |
1038 | nan@^2.14.2:
1039 | version "2.15.0"
1040 | resolved "https://registry.yarnpkg.com/nan/-/nan-2.15.0.tgz#3f34a473ff18e15c1b5626b62903b5ad6e665fee"
1041 | integrity sha512-8ZtvEnA2c5aYCZYd1cvgdnU6cqwixRoYg70xPLWUws5ORTa/lnw+u4amixRS/Ac5U5mQVgp9pnlSUnbNWFaWZQ==
1042 |
1043 | nanostores@^0.7.1:
1044 | version "0.7.1"
1045 | resolved "https://registry.yarnpkg.com/nanostores/-/nanostores-0.7.1.tgz#ed27fa3f9b1c2ab9b28f14373811e28b9d3fc5eb"
1046 | integrity sha512-7HenoVpZOjRudHCmAVWKloBTk3+Ozw49KuRWq/pNlEIIVS3x9dID+I5z3Rhjxl1muhHwv4dFhpT+0FebT9jvaA==
1047 |
1048 | node-addon-api@^3.2.1:
1049 | version "3.2.1"
1050 | resolved "https://registry.yarnpkg.com/node-addon-api/-/node-addon-api-3.2.1.tgz#81325e0a2117789c0128dab65e7e38f07ceba161"
1051 | integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==
1052 |
1053 | node-gyp-build@^4.2.3, node-gyp-build@^4.3.0:
1054 | version "4.4.0"
1055 | resolved "https://registry.yarnpkg.com/node-gyp-build/-/node-gyp-build-4.4.0.tgz#42e99687ce87ddeaf3a10b99dc06abc11021f3f4"
1056 | integrity sha512-amJnQCcgtRVw9SvoebO3BKGESClrfXGCUTX9hSn1OuGQTQBOZmVd0Z0OlecpuRksKvbsUqALE8jls/ErClAPuQ==
1057 |
1058 | node-releases@^2.0.2:
1059 | version "2.0.2"
1060 | resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-2.0.2.tgz#7139fe71e2f4f11b47d4d2986aaf8c48699e0c01"
1061 | integrity sha512-XxYDdcQ6eKqp/YjI+tb2C5WM2LgjnZrfYg4vgQt49EK268b6gYCHsBLrK2qvJo4FmCtqmKezb0WZFK4fkrZNsg==
1062 |
1063 | nth-check@^2.0.1:
1064 | version "2.0.1"
1065 | resolved "https://registry.yarnpkg.com/nth-check/-/nth-check-2.0.1.tgz#2efe162f5c3da06a28959fbd3db75dbeea9f0fc2"
1066 | integrity sha512-it1vE95zF6dTT9lBsYbxvqh0Soy4SPowchj0UBGj/V6cTPnXXtQOPUbhZ6CmGzAD/rW22LQK6E96pcdJXk4A4w==
1067 | dependencies:
1068 | boolbase "^1.0.0"
1069 |
1070 | nullthrows@^1.1.1:
1071 | version "1.1.1"
1072 | resolved "https://registry.yarnpkg.com/nullthrows/-/nullthrows-1.1.1.tgz#7818258843856ae971eae4208ad7d7eb19a431b1"
1073 | integrity sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==
1074 |
1075 | ordered-binary@^1.2.4:
1076 | version "1.2.4"
1077 | resolved "https://registry.yarnpkg.com/ordered-binary/-/ordered-binary-1.2.4.tgz#51d3a03af078a0bdba6c7bc8f4fedd1f5d45d83e"
1078 | integrity sha512-A/csN0d3n+igxBPfUrjbV5GC69LWj2pjZzAAeeHXLukQ4+fytfP4T1Lg0ju7MSPSwq7KtHkGaiwO8URZN5IpLg==
1079 |
1080 | parcel@^2.4.1:
1081 | version "2.4.1"
1082 | resolved "https://registry.yarnpkg.com/parcel/-/parcel-2.4.1.tgz#e369d0c1a3f383df244eb546d0613d1df51f6b35"
1083 | integrity sha512-H8n7cJ0rOt0AZZLuPuG6hvujUWiWz8kxx4pkqEDm31dijrbKb0pNgccXOllQ34em6r7elv6yH7lxox8jDCp0hw==
1084 | dependencies:
1085 | "@parcel/config-default" "2.4.1"
1086 | "@parcel/core" "2.4.1"
1087 | "@parcel/diagnostic" "2.4.1"
1088 | "@parcel/events" "2.4.1"
1089 | "@parcel/fs" "2.4.1"
1090 | "@parcel/logger" "2.4.1"
1091 | "@parcel/package-manager" "2.4.1"
1092 | "@parcel/reporter-cli" "2.4.1"
1093 | "@parcel/reporter-dev-server" "2.4.1"
1094 | "@parcel/utils" "2.4.1"
1095 | chalk "^4.1.0"
1096 | commander "^7.0.0"
1097 | get-port "^4.2.0"
1098 | v8-compile-cache "^2.0.0"
1099 |
1100 | parent-module@^1.0.0:
1101 | version "1.0.1"
1102 | resolved "https://registry.yarnpkg.com/parent-module/-/parent-module-1.0.1.tgz#691d2709e78c79fae3a156622452d00762caaaa2"
1103 | integrity sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==
1104 | dependencies:
1105 | callsites "^3.0.0"
1106 |
1107 | parse-json@^5.0.0:
1108 | version "5.2.0"
1109 | resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-5.2.0.tgz#c76fc66dee54231c962b22bcc8a72cf2f99753cd"
1110 | integrity sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==
1111 | dependencies:
1112 | "@babel/code-frame" "^7.0.0"
1113 | error-ex "^1.3.1"
1114 | json-parse-even-better-errors "^2.3.0"
1115 | lines-and-columns "^1.1.6"
1116 |
1117 | path-type@^4.0.0:
1118 | version "4.0.0"
1119 | resolved "https://registry.yarnpkg.com/path-type/-/path-type-4.0.0.tgz#84ed01c0a7ba380afe09d90a8c180dcd9d03043b"
1120 | integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==
1121 |
1122 | picocolors@^1.0.0:
1123 | version "1.0.0"
1124 | resolved "https://registry.yarnpkg.com/picocolors/-/picocolors-1.0.0.tgz#cb5bdc74ff3f51892236eaf79d68bc44564ab81c"
1125 | integrity sha512-1fygroTLlHu66zi26VoTDv8yRgm0Fccecssto+MhsZ0D/DGW2sm8E8AjW7NU5VVTRt5GxbeZ5qBuJr+HyLYkjQ==
1126 |
1127 | postcss-value-parser@^4.2.0:
1128 | version "4.2.0"
1129 | resolved "https://registry.yarnpkg.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz#723c09920836ba6d3e5af019f92bc0971c02e514"
1130 | integrity sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==
1131 |
1132 | posthtml-parser@^0.10.1:
1133 | version "0.10.2"
1134 | resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.10.2.tgz#df364d7b179f2a6bf0466b56be7b98fd4e97c573"
1135 | integrity sha512-PId6zZ/2lyJi9LiKfe+i2xv57oEjJgWbsHGGANwos5AvdQp98i6AtamAl8gzSVFGfQ43Glb5D614cvZf012VKg==
1136 | dependencies:
1137 | htmlparser2 "^7.1.1"
1138 |
1139 | posthtml-parser@^0.11.0:
1140 | version "0.11.0"
1141 | resolved "https://registry.yarnpkg.com/posthtml-parser/-/posthtml-parser-0.11.0.tgz#25d1c7bf811ea83559bc4c21c189a29747a24b7a"
1142 | integrity sha512-QecJtfLekJbWVo/dMAA+OSwY79wpRmbqS5TeXvXSX+f0c6pW4/SE6inzZ2qkU7oAMCPqIDkZDvd/bQsSFUnKyw==
1143 | dependencies:
1144 | htmlparser2 "^7.1.1"
1145 |
1146 | posthtml-render@^3.0.0:
1147 | version "3.0.0"
1148 | resolved "https://registry.yarnpkg.com/posthtml-render/-/posthtml-render-3.0.0.tgz#97be44931496f495b4f07b99e903cc70ad6a3205"
1149 | integrity sha512-z+16RoxK3fUPgwaIgH9NGnK1HKY9XIDpydky5eQGgAFVXTCSezalv9U2jQuNV+Z9qV1fDWNzldcw4eK0SSbqKA==
1150 | dependencies:
1151 | is-json "^2.0.1"
1152 |
1153 | posthtml@^0.16.4, posthtml@^0.16.5:
1154 | version "0.16.6"
1155 | resolved "https://registry.yarnpkg.com/posthtml/-/posthtml-0.16.6.tgz#e2fc407f67a64d2fa3567afe770409ffdadafe59"
1156 | integrity sha512-JcEmHlyLK/o0uGAlj65vgg+7LIms0xKXe60lcDOTU7oVX/3LuEuLwrQpW3VJ7de5TaFKiW4kWkaIpJL42FEgxQ==
1157 | dependencies:
1158 | posthtml-parser "^0.11.0"
1159 | posthtml-render "^3.0.0"
1160 |
1161 | process@^0.11.10:
1162 | version "0.11.10"
1163 | resolved "https://registry.yarnpkg.com/process/-/process-0.11.10.tgz#7332300e840161bda3e69a1d1d91a7d4bc16f182"
1164 | integrity sha1-czIwDoQBYb2j5podHZGn1LwW8YI=
1165 |
1166 | react-dom@>=16.8:
1167 | version "18.0.0"
1168 | resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-18.0.0.tgz#26b88534f8f1dbb80853e1eabe752f24100d8023"
1169 | integrity sha512-XqX7uzmFo0pUceWFCt7Gff6IyIMzFUn7QMZrbrQfGxtaxXZIcGQzoNpRLE3fQLnS4XzLLPMZX2T9TRcSrasicw==
1170 | dependencies:
1171 | loose-envify "^1.1.0"
1172 | scheduler "^0.21.0"
1173 |
1174 | react-refresh@^0.9.0:
1175 | version "0.9.0"
1176 | resolved "https://registry.yarnpkg.com/react-refresh/-/react-refresh-0.9.0.tgz#71863337adc3e5c2f8a6bfddd12ae3bfe32aafbf"
1177 | integrity sha512-Gvzk7OZpiqKSkxsQvO/mbTN1poglhmAV7gR/DdIrRrSMXraRQQlfikRJOr3Nb9GTMPC5kof948Zy6jJZIFtDvQ==
1178 |
1179 | react@>=16.8:
1180 | version "18.0.0"
1181 | resolved "https://registry.yarnpkg.com/react/-/react-18.0.0.tgz#b468736d1f4a5891f38585ba8e8fb29f91c3cb96"
1182 | integrity sha512-x+VL6wbT4JRVPm7EGxXhZ8w8LTROaxPXOqhlGyVSrv0sB1jkyFGgXxJ8LVoPRLvPR6/CIZGFmfzqUa2NYeMr2A==
1183 | dependencies:
1184 | loose-envify "^1.1.0"
1185 |
1186 | regenerator-runtime@^0.13.7:
1187 | version "0.13.9"
1188 | resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz#8925742a98ffd90814988d7566ad30ca3b263b52"
1189 | integrity sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==
1190 |
1191 | resolve-from@^4.0.0:
1192 | version "4.0.0"
1193 | resolved "https://registry.yarnpkg.com/resolve-from/-/resolve-from-4.0.0.tgz#4abcd852ad32dd7baabfe9b40e00a36db5f392e6"
1194 | integrity sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==
1195 |
1196 | safe-buffer@^5.0.1:
1197 | version "5.2.1"
1198 | resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.2.1.tgz#1eaf9fa9bdb1fdd4ec75f58f9cdb4e6b7827eec6"
1199 | integrity sha512-rp3So07KcdmmKbGvgaNxQSJr7bGVSVk5S9Eq1F+ppbRo70+YeaDxkw5Dd8NPN+GD6bjnYm2VuPuCXmpuYvmCXQ==
1200 |
1201 | scheduler@^0.21.0:
1202 | version "0.21.0"
1203 | resolved "https://registry.yarnpkg.com/scheduler/-/scheduler-0.21.0.tgz#6fd2532ff5a6d877b6edb12f00d8ab7e8f308820"
1204 | integrity sha512-1r87x5fz9MXqswA2ERLo0EbOAU74DpIUO090gIasYTqlVoJeMcl+Z1Rg7WHz+qtPujhS/hGIt9kxZOYBV3faRQ==
1205 | dependencies:
1206 | loose-envify "^1.1.0"
1207 |
1208 | semver@^5.7.0, semver@^5.7.1:
1209 | version "5.7.1"
1210 | resolved "https://registry.yarnpkg.com/semver/-/semver-5.7.1.tgz#a954f931aeba508d307bbf069eff0c01c96116f7"
1211 | integrity sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==
1212 |
1213 | source-map-support@~0.5.20:
1214 | version "0.5.21"
1215 | resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.5.21.tgz#04fe7c7f9e1ed2d662233c28cb2b35b9f63f6e4f"
1216 | integrity sha512-uBHU3L3czsIyYXKX88fdrGovxdSCoTGDRZ6SYXtSRxLZUzHg5P/66Ht6uoUlHu9EZod+inXhKo3qQgwXUT/y1w==
1217 | dependencies:
1218 | buffer-from "^1.0.0"
1219 | source-map "^0.6.0"
1220 |
1221 | source-map@^0.6.0, source-map@^0.6.1:
1222 | version "0.6.1"
1223 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.6.1.tgz#74722af32e9614e9c287a8d0bbde48b5e2f1a263"
1224 | integrity sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==
1225 |
1226 | source-map@~0.7.2:
1227 | version "0.7.3"
1228 | resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.7.3.tgz#5302f8169031735226544092e64981f751750383"
1229 | integrity sha512-CkCj6giN3S+n9qrYiBTX5gystlENnRW5jZeNLHpe6aue+SrHcG5VYwujhW9s4dY31mEGsxBDrHR6oI69fTXsaQ==
1230 |
1231 | stable@^0.1.8:
1232 | version "0.1.8"
1233 | resolved "https://registry.yarnpkg.com/stable/-/stable-0.1.8.tgz#836eb3c8382fe2936feaf544631017ce7d47a3cf"
1234 | integrity sha512-ji9qxRnOVfcuLDySj9qzhGSEFVobyt1kIOSkj1qZzYLzq7Tos/oUUWvotUPQLlrsidqsK6tBH89Bc9kL5zHA6w==
1235 |
1236 | supports-color@^5.3.0:
1237 | version "5.5.0"
1238 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f"
1239 | integrity sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==
1240 | dependencies:
1241 | has-flag "^3.0.0"
1242 |
1243 | supports-color@^7.1.0:
1244 | version "7.2.0"
1245 | resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-7.2.0.tgz#1b7dcdcb32b8138801b3e478ba6a51caa89648da"
1246 | integrity sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==
1247 | dependencies:
1248 | has-flag "^4.0.0"
1249 |
1250 | svgo@^2.4.0:
1251 | version "2.8.0"
1252 | resolved "https://registry.yarnpkg.com/svgo/-/svgo-2.8.0.tgz#4ff80cce6710dc2795f0c7c74101e6764cfccd24"
1253 | integrity sha512-+N/Q9kV1+F+UeWYoSiULYo4xYSDQlTgb+ayMobAXPwMnLvop7oxKMo9OzIrX5x3eS4L4f2UHhc9axXwY8DpChg==
1254 | dependencies:
1255 | "@trysound/sax" "0.2.0"
1256 | commander "^7.2.0"
1257 | css-select "^4.1.3"
1258 | css-tree "^1.1.3"
1259 | csso "^4.2.0"
1260 | picocolors "^1.0.0"
1261 | stable "^0.1.8"
1262 |
1263 | term-size@^2.2.1:
1264 | version "2.2.1"
1265 | resolved "https://registry.yarnpkg.com/term-size/-/term-size-2.2.1.tgz#2a6a54840432c2fb6320fea0f415531e90189f54"
1266 | integrity sha512-wK0Ri4fOGjv/XPy8SBHZChl8CM7uMc5VML7SqiQ0zG7+J5Vr+RMQDoHa2CNT6KHUnTGIXH34UDMkPzAUyapBZg==
1267 |
1268 | terser@^5.2.0:
1269 | version "5.12.1"
1270 | resolved "https://registry.yarnpkg.com/terser/-/terser-5.12.1.tgz#4cf2ebed1f5bceef5c83b9f60104ac4a78b49e9c"
1271 | integrity sha512-NXbs+7nisos5E+yXwAD+y7zrcTkMqb0dEJxIGtSKPdCBzopf7ni4odPul2aechpV7EXNvOudYOX2bb5tln1jbQ==
1272 | dependencies:
1273 | acorn "^8.5.0"
1274 | commander "^2.20.0"
1275 | source-map "~0.7.2"
1276 | source-map-support "~0.5.20"
1277 |
1278 | timsort@^0.3.0:
1279 | version "0.3.0"
1280 | resolved "https://registry.yarnpkg.com/timsort/-/timsort-0.3.0.tgz#405411a8e7e6339fe64db9a234de11dc31e02bd4"
1281 | integrity sha1-QFQRqOfmM5/mTbmiNN4R3DHgK9Q=
1282 |
1283 | type-fest@^0.20.2:
1284 | version "0.20.2"
1285 | resolved "https://registry.yarnpkg.com/type-fest/-/type-fest-0.20.2.tgz#1bf207f4b28f91583666cb5fbd327887301cd5f4"
1286 | integrity sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==
1287 |
1288 | use-sync-external-store@^1.2.0:
1289 | version "1.2.0"
1290 | resolved "https://registry.yarnpkg.com/use-sync-external-store/-/use-sync-external-store-1.2.0.tgz#7dbefd6ef3fe4e767a0cf5d7287aacfb5846928a"
1291 | integrity sha512-eEgnFxGQ1Ife9bzYs6VLi8/4X6CObHMw9Qr9tPY43iKwsPw8xE8+EFsf/2cFZ5S3esXgpWgtSCtLNS41F+sKPA==
1292 |
1293 | utility-types@^3.10.0:
1294 | version "3.10.0"
1295 | resolved "https://registry.yarnpkg.com/utility-types/-/utility-types-3.10.0.tgz#ea4148f9a741015f05ed74fd615e1d20e6bed82b"
1296 | integrity sha512-O11mqxmi7wMKCo6HKFt5AhO4BwY3VV68YU07tgxfz8zJTIxr4BpsezN49Ffwy9j3ZpwwJp4fkRwjRzq3uWE6Rg==
1297 |
1298 | v8-compile-cache@^2.0.0:
1299 | version "2.3.0"
1300 | resolved "https://registry.yarnpkg.com/v8-compile-cache/-/v8-compile-cache-2.3.0.tgz#2de19618c66dc247dcfb6f99338035d8245a2cee"
1301 | integrity sha512-l8lCEmLcLYZh4nbunNZvQCJc5pv7+RCwa8q/LdUx8u7lsWvPDKmpodJAJNwkAhJC//dFY48KuIEmjtd4RViDrA==
1302 |
1303 | weak-lru-cache@^1.2.2:
1304 | version "1.2.2"
1305 | resolved "https://registry.yarnpkg.com/weak-lru-cache/-/weak-lru-cache-1.2.2.tgz#fdbb6741f36bae9540d12f480ce8254060dccd19"
1306 | integrity sha512-DEAoo25RfSYMuTGc9vPJzZcZullwIqRDSI9LOy+fkCJPi6hykCnfKaXTuPBDuXAUcqHXyOgFtHNp/kB2FjYHbw==
1307 |
1308 | xxhash-wasm@^0.4.2:
1309 | version "0.4.2"
1310 | resolved "https://registry.yarnpkg.com/xxhash-wasm/-/xxhash-wasm-0.4.2.tgz#752398c131a4dd407b5132ba62ad372029be6f79"
1311 | integrity sha512-/eyHVRJQCirEkSZ1agRSCwriMhwlyUcFkXD5TPVSLP+IPzjsqMVzZwdoczLp1SoQU0R3dxz1RpIK+4YNQbCVOA==
1312 |
1313 | yaml@^1.10.0:
1314 | version "1.10.2"
1315 | resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.10.2.tgz#2301c5ffbf12b467de8da2333a459e29e7920e4b"
1316 | integrity sha512-r3vXyErRCYJ7wg28yvBY5VSoAF8ZvlcW9/BwUzEtUsjvX/DKs24dIkuwjtuprwJJHsbyUbLApepYTR1BN4uHrg==
1317 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageManager": "yarn@1.22.19",
3 | "name": "immerhin",
4 | "version": "0.10.0",
5 | "description": "Send patches around to keep the system in sync.",
6 | "type": "module",
7 | "exports": {
8 | "import": "./dist/immerhin.js",
9 | "types": "./dist/index.d.ts"
10 | },
11 | "scripts": {
12 | "build:types": "tsc --declaration --emitDeclarationOnly --outDir dist",
13 | "build:js": "esbuild src/index.ts --bundle --format=esm --external:immer --external:nanoid --outfile=dist/immerhin.js",
14 | "build": "rm -rf dist && yarn build:js && yarn build:types",
15 | "typecheck": "tsc --noEmit",
16 | "prepublishOnly": "yarn build"
17 | },
18 | "repository": {
19 | "type": "git",
20 | "url": "git+ssh://git@github.com/webstudio-is/immerhin.git"
21 | },
22 | "keywords": [
23 | "Immer",
24 | "JSON",
25 | "Patch",
26 | "State",
27 | "management",
28 | "undo-redo"
29 | ],
30 | "author": "Oleg Isonen",
31 | "license": "MIT",
32 | "bugs": {
33 | "url": "https://github.com/webstudio-is/immerhin/issues"
34 | },
35 | "homepage": "https://github.com/webstudio-is/immerhin#readme",
36 | "devDependencies": {
37 | "esbuild": "^0.18.15",
38 | "prettier": "^3.3.3",
39 | "typescript": "^5.1.6"
40 | },
41 | "dependencies": {
42 | "immer": "^10.0.2",
43 | "nanoid": "^5.0.1"
44 | },
45 | "files": [
46 | "dist",
47 | "README.md"
48 | ]
49 | }
50 |
--------------------------------------------------------------------------------
/src/index.ts:
--------------------------------------------------------------------------------
1 | export { Store } from "./store";
2 | export type { Change } from "./transaction";
3 | export type { SyncItem } from "./sync-queue";
4 |
--------------------------------------------------------------------------------
/src/store.ts:
--------------------------------------------------------------------------------
1 | import { createDraft, finishDraft, enablePatches, type Patch } from "immer";
2 | import { type ValueContainer } from "./types";
3 | import { type Change, Transaction } from "./transaction";
4 | import {
5 | type TransactionCallback,
6 | TransactionsManager,
7 | } from "./transactions-manager";
8 | import { type Queue, enqueue, popAll } from "./sync-queue";
9 |
10 | enablePatches();
11 |
12 | // eslint-disable-next-line @typescript-eslint/no-explicit-any
13 | type Any = any;
14 |
15 | type UnwrapContainers>> = {
16 | [Index in keyof Containers]: Containers[Index] extends ValueContainer<
17 | infer Value
18 | >
19 | ? Value
20 | : never;
21 | };
22 |
23 | export class Store {
24 | namespaces = new Map, string>();
25 | containers = new Map>();
26 |
27 | transactionManager: TransactionsManager;
28 |
29 | private callbacks: TransactionCallback[] = [];
30 |
31 | private transactionQueue: Parameters[] = [];
32 | private syncQueue: Queue = [];
33 |
34 | constructor() {
35 | this.transactionManager = new TransactionsManager(
36 | (transactionId, changes, source) => {
37 | // store transactions until at least one subscription is added
38 | if (this.callbacks.length === 0) {
39 | this.transactionQueue.push([transactionId, changes, source]);
40 | }
41 | enqueue(this.syncQueue, transactionId, changes);
42 | for (const callback of this.callbacks) {
43 | callback(transactionId, changes, source);
44 | }
45 | },
46 | );
47 | }
48 |
49 | register(namespace: string, container: ValueContainer) {
50 | this.namespaces.set(container, namespace);
51 | this.containers.set(namespace, container);
52 | }
53 |
54 | createTransaction>>(
55 | containers: [...Containers],
56 | recipe: (...values: UnwrapContainers) => void,
57 | source?: string,
58 | ): UnwrapContainers {
59 | type Values = UnwrapContainers;
60 | const drafts = [] as unknown as Values;
61 | for (const container of containers) {
62 | drafts.push(createDraft(container.get()));
63 | }
64 | recipe(...drafts);
65 | const transaction = new Transaction();
66 | const values = [] as unknown as Values;
67 | drafts.forEach((draft, index) => {
68 | const namespace = this.namespaces.get(containers[index]);
69 | if (namespace === undefined) {
70 | throw new Error(
71 | "Container used for transaction is not registered in sync engine",
72 | );
73 | }
74 | const value = finishDraft(
75 | draft,
76 | (patches: Array, revisePatches: Array) => {
77 | // ignore empty changes
78 | if (patches.length === 0) {
79 | return;
80 | }
81 | transaction.add({
82 | namespace,
83 | patches,
84 | revisePatches,
85 | container: containers[index],
86 | });
87 | },
88 | );
89 | values.push(value);
90 | });
91 | this.transactionManager.add(transaction, source);
92 | return values;
93 | }
94 |
95 | createTransactionFromChanges(changes: Array, source?: string) {
96 | const transaction = new Transaction();
97 | for (const change of changes) {
98 | const container = this.containers.get(change.namespace);
99 | if (container) {
100 | transaction.add({
101 | ...change,
102 | container,
103 | });
104 | }
105 | }
106 | this.transactionManager.add(transaction, source);
107 | }
108 |
109 | addTransaction(
110 | transactionId: string,
111 | changes: Array,
112 | source?: string,
113 | ) {
114 | const transaction = new Transaction(transactionId);
115 | for (const change of changes) {
116 | const container = this.containers.get(change.namespace);
117 | if (container) {
118 | transaction.add({
119 | ...change,
120 | container,
121 | });
122 | }
123 | }
124 | this.transactionManager.add(transaction, source);
125 | }
126 |
127 | revertTransaction(transactionId: string) {
128 | this.transactionManager.revert(transactionId);
129 | }
130 |
131 | subscribe(callback: TransactionCallback) {
132 | // flush transactions from queue
133 | if (this.callbacks.length === 0) {
134 | for (const [transactionId, changes, source] of this.transactionQueue) {
135 | callback(transactionId, changes, source);
136 | }
137 | this.transactionQueue = [];
138 | }
139 | this.callbacks.push(callback);
140 | return () => {
141 | this.callbacks = this.callbacks.filter((item) => callback !== item);
142 | };
143 | }
144 |
145 | undo() {
146 | this.transactionManager.undo();
147 | }
148 |
149 | redo() {
150 | this.transactionManager.redo();
151 | }
152 |
153 | popAll() {
154 | return popAll(this.syncQueue);
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/src/sync-queue.ts:
--------------------------------------------------------------------------------
1 | import type { Change } from "./transaction";
2 |
3 | export type SyncItem = {
4 | transactionId: string;
5 | changes: Array;
6 | };
7 |
8 | export type Queue = SyncItem[]
9 |
10 |
11 | const dequeue = (queue: Queue, transactionId: string) => {
12 | const index = queue.findIndex(
13 | (entry) => entry.transactionId === transactionId
14 | );
15 | if (index === -1) return false;
16 | queue.splice(index, 1);
17 | return true;
18 | };
19 |
20 | export const enqueue = (queue: Queue, transactionId: string, changes: Array) => {
21 | // We are trying to delete that transaction from the queue,
22 | // if it was not found - we are adding the patches, because they are new
23 | // if it was found - we don't add it because it is technically an undo operation.
24 | // This can happen if user runs undo before sync happened, so we we are avoiding
25 | // sending it to the server unnecessarily.
26 | if (dequeue(queue, transactionId) === false) {
27 | queue.push({ transactionId, changes });
28 | }
29 | };
30 |
31 | export const popAll = (queue: Queue) => {
32 | if (queue.length === 0) return [];
33 | const queueCopy = [...queue];
34 | queue.splice(0);
35 | return queueCopy;
36 | };
37 |
--------------------------------------------------------------------------------
/src/transaction.ts:
--------------------------------------------------------------------------------
1 | import { nanoid } from "nanoid";
2 | import { applyPatches, type Patch } from "immer";
3 | import { type ValueContainer } from "./types";
4 |
5 | export type Change = {
6 | namespace: string;
7 | patches: Array;
8 | revisePatches: Array;
9 | };
10 |
11 | type TransactionSpec = {
12 | namespace: string;
13 | patches: Array;
14 | revisePatches: Array;
15 | container: ValueContainer>;
16 | };
17 |
18 | export class Transaction {
19 | id: string;
20 | specs: Array = [];
21 | constructor(id = nanoid()) {
22 | this.id = id;
23 | }
24 | applyPatches() {
25 | for (const change of this.specs) {
26 | const value = applyPatches(change.container.get(), change.patches);
27 | change.container.set(value);
28 | }
29 | }
30 | applyRevisePatches() {
31 | for (const change of this.specs) {
32 | const value = applyPatches(change.container.get(), change.revisePatches);
33 | change.container.set(value);
34 | }
35 | }
36 | add(change: TransactionSpec) {
37 | this.specs.push(change);
38 | }
39 | getChanges(): Array {
40 | return this.specs.map(({ namespace, patches, revisePatches }) => ({
41 | namespace,
42 | patches,
43 | revisePatches,
44 | }));
45 | }
46 | getReviseChanges(): Array {
47 | return this.specs.map(({ namespace, patches, revisePatches }) => ({
48 | namespace,
49 | patches: revisePatches,
50 | revisePatches: patches,
51 | }));
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/src/transactions-manager.ts:
--------------------------------------------------------------------------------
1 | import type { Change, Transaction } from "./transaction";
2 |
3 | export type TransactionCallback = (
4 | transactionId: string,
5 | changes: Array,
6 | source?: string,
7 | ) => void;
8 |
9 | export class TransactionsManager {
10 | max = 100;
11 | currentStack: Array = [];
12 | undoneStack: Array = [];
13 |
14 | constructor(private callback: TransactionCallback) { }
15 |
16 | undo() {
17 | const transaction = this.currentStack.pop();
18 | if (transaction === undefined) return;
19 | transaction.applyRevisePatches();
20 | this.callback(transaction.id, transaction.getReviseChanges());
21 | this.undoneStack.push(transaction);
22 | }
23 |
24 | redo() {
25 | const transaction = this.undoneStack.pop();
26 | if (transaction === undefined) return;
27 | transaction.applyPatches();
28 | this.currentStack.push(transaction);
29 | this.callback(transaction.id, transaction.getChanges());
30 | }
31 |
32 | add(transaction: Transaction, source?: string) {
33 | // ignore empty transactions
34 | if (transaction.specs.length === 0) {
35 | return;
36 | }
37 | transaction.applyPatches();
38 | this.currentStack.push(transaction);
39 | this.callback(transaction.id, transaction.getChanges(), source);
40 | if (this.currentStack.length > this.max) {
41 | this.currentStack.shift();
42 | }
43 | // After we add a change, we can't redo something we have undone before.
44 | // It would make undo unpredictable, because there are new changes.
45 | this.undoneStack.splice(0);
46 | }
47 |
48 | revert(transactionId: string) {
49 | const transactionIndex = this.currentStack.findIndex(
50 | (transaction) => transaction.id === transactionId,
51 | );
52 | const transaction = this.currentStack[transactionIndex];
53 | transaction.applyRevisePatches();
54 | this.currentStack.splice(transactionIndex, 1);
55 | }
56 | }
57 |
--------------------------------------------------------------------------------
/src/types.ts:
--------------------------------------------------------------------------------
1 | export type ValueContainer = {
2 | get(): ValueType;
3 | set(value: ValueType): void;
4 | };
5 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "ES2020",
4 | "moduleResolution": "bundler",
5 | "isolatedModules": true
6 | }
7 | }
8 |
--------------------------------------------------------------------------------
/yarn.lock:
--------------------------------------------------------------------------------
1 | # THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
2 | # yarn lockfile v1
3 |
4 |
5 | "@esbuild/android-arm64@0.18.15":
6 | version "0.18.15"
7 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm64/-/android-arm64-0.18.15.tgz#abbe87b815d2f95ec749ffb4eba65d7d5343411f"
8 | integrity sha512-NI/gnWcMl2kXt1HJKOn2H69SYn4YNheKo6NZt1hyfKWdMbaGadxjZIkcj4Gjk/WPxnbFXs9/3HjGHaknCqjrww==
9 |
10 | "@esbuild/android-arm@0.18.15":
11 | version "0.18.15"
12 | resolved "https://registry.yarnpkg.com/@esbuild/android-arm/-/android-arm-0.18.15.tgz#6afedd79c68d5d4d1e434e20a9ab620bb5849372"
13 | integrity sha512-wlkQBWb79/jeEEoRmrxt/yhn5T1lU236OCNpnfRzaCJHZ/5gf82uYx1qmADTBWE0AR/v7FiozE1auk2riyQd3w==
14 |
15 | "@esbuild/android-x64@0.18.15":
16 | version "0.18.15"
17 | resolved "https://registry.yarnpkg.com/@esbuild/android-x64/-/android-x64-0.18.15.tgz#cdd886a58748b1584ad72d960c446fa958c11ab3"
18 | integrity sha512-FM9NQamSaEm/IZIhegF76aiLnng1kEsZl2eve/emxDeReVfRuRNmvT28l6hoFD9TsCxpK+i4v8LPpEj74T7yjA==
19 |
20 | "@esbuild/darwin-arm64@0.18.15":
21 | version "0.18.15"
22 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-arm64/-/darwin-arm64-0.18.15.tgz#648b124a6a63022adb5b0cf441e264e8f5ba4af2"
23 | integrity sha512-XmrFwEOYauKte9QjS6hz60FpOCnw4zaPAb7XV7O4lx1r39XjJhTN7ZpXqJh4sN6q60zbP6QwAVVA8N/wUyBH/w==
24 |
25 | "@esbuild/darwin-x64@0.18.15":
26 | version "0.18.15"
27 | resolved "https://registry.yarnpkg.com/@esbuild/darwin-x64/-/darwin-x64-0.18.15.tgz#91cd2601c1604d123454d325e6b24fb6438350cf"
28 | integrity sha512-bMqBmpw1e//7Fh5GLetSZaeo9zSC4/CMtrVFdj+bqKPGJuKyfNJ5Nf2m3LknKZTS+Q4oyPiON+v3eaJ59sLB5A==
29 |
30 | "@esbuild/freebsd-arm64@0.18.15":
31 | version "0.18.15"
32 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-arm64/-/freebsd-arm64-0.18.15.tgz#575940b0fc2f52833de4f6360445586742a8ff8b"
33 | integrity sha512-LoTK5N3bOmNI9zVLCeTgnk5Rk0WdUTrr9dyDAQGVMrNTh9EAPuNwSTCgaKOKiDpverOa0htPcO9NwslSE5xuLA==
34 |
35 | "@esbuild/freebsd-x64@0.18.15":
36 | version "0.18.15"
37 | resolved "https://registry.yarnpkg.com/@esbuild/freebsd-x64/-/freebsd-x64-0.18.15.tgz#09694fc601dd8d3263a1075977ee7d3488514ef8"
38 | integrity sha512-62jX5n30VzgrjAjOk5orYeHFq6sqjvsIj1QesXvn5OZtdt5Gdj0vUNJy9NIpjfdNdqr76jjtzBJKf+h2uzYuTQ==
39 |
40 | "@esbuild/linux-arm64@0.18.15":
41 | version "0.18.15"
42 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm64/-/linux-arm64-0.18.15.tgz#2f5d226b024964f2b5b6bce7c874a8ad31785fa2"
43 | integrity sha512-BWncQeuWDgYv0jTNzJjaNgleduV4tMbQjmk/zpPh/lUdMcNEAxy+jvneDJ6RJkrqloG7tB9S9rCrtfk/kuplsQ==
44 |
45 | "@esbuild/linux-arm@0.18.15":
46 | version "0.18.15"
47 | resolved "https://registry.yarnpkg.com/@esbuild/linux-arm/-/linux-arm-0.18.15.tgz#172331fc66bbe89ba96e5e2ad583b2faa132d85c"
48 | integrity sha512-dT4URUv6ir45ZkBqhwZwyFV6cH61k8MttIwhThp2BGiVtagYvCToF+Bggyx2VI57RG4Fbt21f9TmXaYx0DeUJg==
49 |
50 | "@esbuild/linux-ia32@0.18.15":
51 | version "0.18.15"
52 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ia32/-/linux-ia32-0.18.15.tgz#fa797051131ee5f46d70c65a7edd14b6230cfc2f"
53 | integrity sha512-JPXORvgHRHITqfms1dWT/GbEY89u848dC08o0yK3fNskhp0t2TuNUnsrrSgOdH28ceb1hJuwyr8R/1RnyPwocw==
54 |
55 | "@esbuild/linux-loong64@0.18.15":
56 | version "0.18.15"
57 | resolved "https://registry.yarnpkg.com/@esbuild/linux-loong64/-/linux-loong64-0.18.15.tgz#aeae1fa3d92b1486a91c0cb1cfd9c0ebe9168de4"
58 | integrity sha512-kArPI0DopjJCEplsVj/H+2Qgzz7vdFSacHNsgoAKpPS6W/Ndh8Oe24HRDQ5QCu4jHgN6XOtfFfLpRx3TXv/mEg==
59 |
60 | "@esbuild/linux-mips64el@0.18.15":
61 | version "0.18.15"
62 | resolved "https://registry.yarnpkg.com/@esbuild/linux-mips64el/-/linux-mips64el-0.18.15.tgz#b63cfe356c33807c4d8ee5a75452922e98502073"
63 | integrity sha512-b/tmngUfO02E00c1XnNTw/0DmloKjb6XQeqxaYuzGwHe0fHVgx5/D6CWi+XH1DvkszjBUkK9BX7n1ARTOst59w==
64 |
65 | "@esbuild/linux-ppc64@0.18.15":
66 | version "0.18.15"
67 | resolved "https://registry.yarnpkg.com/@esbuild/linux-ppc64/-/linux-ppc64-0.18.15.tgz#7dcb394e69cb47e4dc8a5960dd58b1a273d07f5d"
68 | integrity sha512-KXPY69MWw79QJkyvUYb2ex/OgnN/8N/Aw5UDPlgoRtoEfcBqfeLodPr42UojV3NdkoO4u10NXQdamWm1YEzSKw==
69 |
70 | "@esbuild/linux-riscv64@0.18.15":
71 | version "0.18.15"
72 | resolved "https://registry.yarnpkg.com/@esbuild/linux-riscv64/-/linux-riscv64-0.18.15.tgz#fdfb9cf23b50d33112315e3194b9e16f7abf6c30"
73 | integrity sha512-komK3NEAeeGRnvFEjX1SfVg6EmkfIi5aKzevdvJqMydYr9N+pRQK0PGJXk+bhoPZwOUgLO4l99FZmLGk/L1jWg==
74 |
75 | "@esbuild/linux-s390x@0.18.15":
76 | version "0.18.15"
77 | resolved "https://registry.yarnpkg.com/@esbuild/linux-s390x/-/linux-s390x-0.18.15.tgz#ce608d95989a502878d7cb1167df791e45268011"
78 | integrity sha512-632T5Ts6gQ2WiMLWRRyeflPAm44u2E/s/TJvn+BP6M5mnHSk93cieaypj3VSMYO2ePTCRqAFXtuYi1yv8uZJNA==
79 |
80 | "@esbuild/linux-x64@0.18.15":
81 | version "0.18.15"
82 | resolved "https://registry.yarnpkg.com/@esbuild/linux-x64/-/linux-x64-0.18.15.tgz#49bbba5607702709f63b41906b4f1bcc44cf2f8e"
83 | integrity sha512-MsHtX0NgvRHsoOtYkuxyk4Vkmvk3PLRWfA4okK7c+6dT0Fu4SUqXAr9y4Q3d8vUf1VWWb6YutpL4XNe400iQ1g==
84 |
85 | "@esbuild/netbsd-x64@0.18.15":
86 | version "0.18.15"
87 | resolved "https://registry.yarnpkg.com/@esbuild/netbsd-x64/-/netbsd-x64-0.18.15.tgz#08b5ccaf027c7e2174b9a19c29bebfe59dce1cfb"
88 | integrity sha512-djST6s+jQiwxMIVQ5rlt24JFIAr4uwUnzceuFL7BQT4CbrRtqBPueS4GjXSiIpmwVri1Icj/9pFRJ7/aScvT+A==
89 |
90 | "@esbuild/openbsd-x64@0.18.15":
91 | version "0.18.15"
92 | resolved "https://registry.yarnpkg.com/@esbuild/openbsd-x64/-/openbsd-x64-0.18.15.tgz#38ec4223ebab562f0a89ffe20a40f05d500f89f0"
93 | integrity sha512-naeRhUIvhsgeounjkF5mvrNAVMGAm6EJWiabskeE5yOeBbLp7T89tAEw0j5Jm/CZAwyLe3c67zyCWH6fsBLCpw==
94 |
95 | "@esbuild/sunos-x64@0.18.15":
96 | version "0.18.15"
97 | resolved "https://registry.yarnpkg.com/@esbuild/sunos-x64/-/sunos-x64-0.18.15.tgz#dbbebf641957a54b77f39ca9b10b0b38586799ba"
98 | integrity sha512-qkT2+WxyKbNIKV1AEhI8QiSIgTHMcRctzSaa/I3kVgMS5dl3fOeoqkb7pW76KwxHoriImhx7Mg3TwN/auMDsyQ==
99 |
100 | "@esbuild/win32-arm64@0.18.15":
101 | version "0.18.15"
102 | resolved "https://registry.yarnpkg.com/@esbuild/win32-arm64/-/win32-arm64-0.18.15.tgz#7f15fe5d14b9b24eb18ca211ad92e0f5df92a18b"
103 | integrity sha512-HC4/feP+pB2Vb+cMPUjAnFyERs+HJN7E6KaeBlFdBv799MhD+aPJlfi/yk36SED58J9TPwI8MAcVpJgej4ud0A==
104 |
105 | "@esbuild/win32-ia32@0.18.15":
106 | version "0.18.15"
107 | resolved "https://registry.yarnpkg.com/@esbuild/win32-ia32/-/win32-ia32-0.18.15.tgz#a6609735a4a5e8fbdeb045720bc8be46825566fa"
108 | integrity sha512-ovjwoRXI+gf52EVF60u9sSDj7myPixPxqzD5CmkEUmvs+W9Xd0iqISVBQn8xcx4ciIaIVlWCuTbYDOXOnOL44Q==
109 |
110 | "@esbuild/win32-x64@0.18.15":
111 | version "0.18.15"
112 | resolved "https://registry.yarnpkg.com/@esbuild/win32-x64/-/win32-x64-0.18.15.tgz#41ee66253566124cc44bce1b4c760a87d9f5bf1d"
113 | integrity sha512-imUxH9a3WJARyAvrG7srLyiK73XdX83NXQkjKvQ+7vPh3ZxoLrzvPkQKKw2DwZ+RV2ZB6vBfNHP8XScAmQC3aA==
114 |
115 | esbuild@^0.18.15:
116 | version "0.18.15"
117 | resolved "https://registry.yarnpkg.com/esbuild/-/esbuild-0.18.15.tgz#5b5c1a22e608afd5675f82ad466c4d2cfd723f85"
118 | integrity sha512-3WOOLhrvuTGPRzQPU6waSDWrDTnQriia72McWcn6UCi43GhCHrXH4S59hKMeez+IITmdUuUyvbU9JIp+t3xlPQ==
119 | optionalDependencies:
120 | "@esbuild/android-arm" "0.18.15"
121 | "@esbuild/android-arm64" "0.18.15"
122 | "@esbuild/android-x64" "0.18.15"
123 | "@esbuild/darwin-arm64" "0.18.15"
124 | "@esbuild/darwin-x64" "0.18.15"
125 | "@esbuild/freebsd-arm64" "0.18.15"
126 | "@esbuild/freebsd-x64" "0.18.15"
127 | "@esbuild/linux-arm" "0.18.15"
128 | "@esbuild/linux-arm64" "0.18.15"
129 | "@esbuild/linux-ia32" "0.18.15"
130 | "@esbuild/linux-loong64" "0.18.15"
131 | "@esbuild/linux-mips64el" "0.18.15"
132 | "@esbuild/linux-ppc64" "0.18.15"
133 | "@esbuild/linux-riscv64" "0.18.15"
134 | "@esbuild/linux-s390x" "0.18.15"
135 | "@esbuild/linux-x64" "0.18.15"
136 | "@esbuild/netbsd-x64" "0.18.15"
137 | "@esbuild/openbsd-x64" "0.18.15"
138 | "@esbuild/sunos-x64" "0.18.15"
139 | "@esbuild/win32-arm64" "0.18.15"
140 | "@esbuild/win32-ia32" "0.18.15"
141 | "@esbuild/win32-x64" "0.18.15"
142 |
143 | immer@^10.0.2:
144 | version "10.0.2"
145 | resolved "https://registry.yarnpkg.com/immer/-/immer-10.0.2.tgz#11636c5b77acf529e059582d76faf338beb56141"
146 | integrity sha512-Rx3CqeqQ19sxUtYV9CU911Vhy8/721wRFnJv3REVGWUmoAcIwzifTsdmJte/MV+0/XpM35LZdQMBGkRIoLPwQA==
147 |
148 | nanoid@^5.0.1:
149 | version "5.0.1"
150 | resolved "https://registry.yarnpkg.com/nanoid/-/nanoid-5.0.1.tgz#3e95d775a8bc8a98afbf0a237e2bbc6a71b0662e"
151 | integrity sha512-vWeVtV5Cw68aML/QaZvqN/3QQXc6fBfIieAlu05m7FZW2Dgb+3f0xc0TTxuJW+7u30t7iSDTV/j3kVI0oJqIfQ==
152 |
153 | prettier@^3.3.3:
154 | version "3.3.3"
155 | resolved "https://registry.yarnpkg.com/prettier/-/prettier-3.3.3.tgz#30c54fe0be0d8d12e6ae61dbb10109ea00d53105"
156 | integrity sha512-i2tDNA0O5IrMO757lfrdQZCc2jPNDVntV0m/+4whiDfWaTKfMNgR7Qz0NAeGz/nRqF4m5/6CLzbP4/liHt12Ew==
157 |
158 | typescript@^5.1.6:
159 | version "5.1.6"
160 | resolved "https://registry.yarnpkg.com/typescript/-/typescript-5.1.6.tgz#02f8ac202b6dad2c0dd5e0913745b47a37998274"
161 | integrity sha512-zaWCozRZ6DLEWAWFrVDz1H6FVXzUSfTy5FUMWsQlU8Ym5JP9eO4xkTIROFCQvhQf61z6O/G6ugw3SgAnvvm+HA==
162 |
--------------------------------------------------------------------------------