vast 2.0.0 → 2.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +1 -25
- package/README.md +32 -33
- package/dist/vast.cjs +55 -0
- package/dist/vast.cjs.map +1 -0
- package/dist/vast.mjs +55 -0
- package/dist/vast.mjs.map +1 -0
- package/package.json +22 -24
- package/src/__tests__/vast.test.ts +209 -0
- package/src/vast.ts +103 -0
- package/types/vast.d.cts +16 -0
- package/types/vast.d.cts.map +1 -0
- package/types/vast.d.mts +16 -0
- package/types/vast.d.mts.map +1 -0
- package/types/vast.d.ts +15 -12
- package/vitest.config.ts +21 -0
- package/dist/cjs/package.json +0 -1
- package/dist/cjs/vast.development.js +0 -81
- package/dist/cjs/vast.js +0 -7
- package/dist/cjs/vast.production.js +0 -1
- package/dist/es/package.json +0 -1
- package/dist/es/vast.development.js +0 -77
- package/dist/es/vast.production.js +0 -1
- package/dist/umd/vast.development.js +0 -87
- package/dist/umd/vast.production.js +0 -1
- package/tsconfig.json +0 -8
package/CHANGELOG.md
CHANGED
|
@@ -5,32 +5,8 @@ All notable changes to this project will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/) and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
|
|
6
6
|
|
|
7
7
|
## 2.0.0 - 2021-12-24
|
|
8
|
-
### Changed or removed
|
|
9
|
-
- e8652bc breaking(vest, enforce): prepare next major (ealush)
|
|
10
8
|
|
|
11
|
-
|
|
12
|
-
- 825e74b types(n4s): fix proxy type (ealush)
|
|
13
|
-
- 9f9b970 vx: improve package.json generation (ealush)
|
|
14
|
-
- 7baedf2 n4s: use named export in entry (ealush)
|
|
15
|
-
- e60e9a6 vx: make exports of a module use its main entry as an external (ealush)
|
|
16
|
-
- 94e00a8 patch(vest): Add isolate module for containing re-orders (ealush)
|
|
17
|
-
- bed7040 vx: add back to workspace (ealush)
|
|
18
|
-
- a87824b vx: add types to exports (ealush)
|
|
19
|
-
- f2d458d update build artifacts (ealush)
|
|
20
|
-
- package.json
|
|
21
|
-
- packages/anyone/package.json
|
|
22
|
-
- .eslintrc.js
|
|
23
|
-
- packages/anyone/package.json
|
|
24
|
-
- eeac20e chore: remove duplicate types (undefined)
|
|
25
|
-
- packages/anyone/package.json
|
|
26
|
-
- 4d88c04 patch: add nodejs exports (undefined)
|
|
27
|
-
- packages/anyone/package.json
|
|
28
|
-
- 26af06b chore: reduce complexity, remove all lint errors (undefined)
|
|
29
|
-
- packages/anyone/.npmignore
|
|
30
|
-
- .github/PULL_REQUEST_TEMPLATE.md
|
|
31
|
-
- ba68539 lint: handling lint of all packages (ealush)
|
|
32
|
-
- .gitignore
|
|
33
|
-
- 73b28a1 chore: some lint fixes (ealush)
|
|
9
|
+
- Use named exports
|
|
34
10
|
|
|
35
11
|
## 1.0.11 - 2021-07-02
|
|
36
12
|
|
package/README.md
CHANGED
|
@@ -1,12 +1,14 @@
|
|
|
1
1
|
# Vast - Simple State Utility for Libraries
|
|
2
2
|
|
|
3
|
-
Vast is a
|
|
3
|
+
Vast is a tiny state container inspired by React's `useState`, designed for libraries that need predictable, reusable state without a UI framework.
|
|
4
4
|
|
|
5
|
-
|
|
5
|
+
- Register any number of state keys, each with its own getter/setter pair.
|
|
6
|
+
- Provide global `onStateChange` and per-key `onUpdate` callbacks to react to changes.
|
|
7
|
+
- Reset state back to initial values at any time.
|
|
6
8
|
|
|
7
9
|
## Installation
|
|
8
10
|
|
|
9
|
-
```
|
|
11
|
+
```bash
|
|
10
12
|
npm i vast
|
|
11
13
|
```
|
|
12
14
|
|
|
@@ -15,51 +17,48 @@ npm i vast
|
|
|
15
17
|
```js
|
|
16
18
|
import { createState } from 'vast';
|
|
17
19
|
|
|
18
|
-
|
|
20
|
+
// Optional callback runs on every state change
|
|
21
|
+
const state = createState(() => console.log('state changed'));
|
|
19
22
|
|
|
20
|
-
|
|
21
|
-
|
|
23
|
+
// Create a key with an initial value
|
|
24
|
+
const useColor = state.registerStateKey('blue');
|
|
22
25
|
|
|
23
|
-
const [color, setColor] = useColor();
|
|
24
|
-
setColor('red');
|
|
25
|
-
```
|
|
26
|
+
const [color, setColor] = useColor();
|
|
27
|
+
setColor('red');
|
|
26
28
|
|
|
27
|
-
|
|
29
|
+
// Next call returns the updated value
|
|
30
|
+
const [current] = useColor();
|
|
31
|
+
// current === 'red'
|
|
32
|
+
```
|
|
28
33
|
|
|
29
|
-
|
|
34
|
+
The setter accepts either a value or an updater function that receives the current state value:
|
|
30
35
|
|
|
31
36
|
```js
|
|
32
|
-
const [
|
|
33
|
-
|
|
37
|
+
const [count, setCount] = state.registerStateKey(0)();
|
|
38
|
+
setCount(prev => prev + 1);
|
|
34
39
|
```
|
|
35
40
|
|
|
36
|
-
##
|
|
37
|
-
|
|
38
|
-
### Getting notified for every change in the state
|
|
41
|
+
## Subscriptions
|
|
39
42
|
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
Simply add an onChange callback to your createState:
|
|
43
|
+
- `onStateChange` (passed to `createState`) fires after every update to any key.
|
|
44
|
+
- `onUpdate` (passed to `registerStateKey`) fires for that key when it initializes and whenever it changes, receiving `(current, previous)`.
|
|
43
45
|
|
|
44
46
|
```js
|
|
45
|
-
const
|
|
46
|
-
|
|
47
|
+
const logColorChange = (next, prev) => console.log(`color: ${prev} -> ${next}`);
|
|
48
|
+
const useColor = state.registerStateKey('blue', logColorChange);
|
|
47
49
|
|
|
48
|
-
|
|
50
|
+
useColor()[1]('green');
|
|
51
|
+
// logs: color: blue -> green
|
|
52
|
+
```
|
|
49
53
|
|
|
50
|
-
|
|
54
|
+
`onUpdate` is invoked before the global `onStateChange`, matching the library's execution order.
|
|
51
55
|
|
|
52
|
-
|
|
56
|
+
## Resetting state
|
|
53
57
|
|
|
54
|
-
|
|
58
|
+
Call `state.reset()` to restore every registered key to its initial value. Setters still work after a reset:
|
|
55
59
|
|
|
56
60
|
```js
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
console.log(`the color changed from ${previousState} to ${currentState}!`);
|
|
61
|
-
}
|
|
62
|
-
);
|
|
61
|
+
state.reset();
|
|
62
|
+
const [color, setColor] = useColor();
|
|
63
|
+
setColor('purple');
|
|
63
64
|
```
|
|
64
|
-
|
|
65
|
-
Now, whenever a state update happens in that key, your callback will run, providing the previous and changed value as well.
|
package/dist/vast.cjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
let vest_utils = require("vest-utils");
|
|
2
|
+
|
|
3
|
+
//#region src/vast.ts
|
|
4
|
+
function createState(onStateChange) {
|
|
5
|
+
const state = { references: [] };
|
|
6
|
+
const registrations = [];
|
|
7
|
+
return {
|
|
8
|
+
registerStateKey,
|
|
9
|
+
reset
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
*
|
|
16
|
+
* const useColor = state.registerStateKey("blue");
|
|
17
|
+
*
|
|
18
|
+
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
19
|
+
*
|
|
20
|
+
* setColor("green");
|
|
21
|
+
*
|
|
22
|
+
* useColor()[0]; -> "green"
|
|
23
|
+
*/
|
|
24
|
+
function registerStateKey(initialState, onUpdate) {
|
|
25
|
+
const key = registrations.length;
|
|
26
|
+
registrations.push([initialState, onUpdate]);
|
|
27
|
+
return initKey(key, initialState);
|
|
28
|
+
}
|
|
29
|
+
function reset() {
|
|
30
|
+
const prev = current();
|
|
31
|
+
state.references = [];
|
|
32
|
+
registrations.forEach(([initialValue], index) => initKey(index, initialValue, prev[index]));
|
|
33
|
+
}
|
|
34
|
+
function initKey(key, initialState, prevState) {
|
|
35
|
+
current().push();
|
|
36
|
+
set(key, (0, vest_utils.dynamicValue)(initialState, prevState));
|
|
37
|
+
return function useStateKey() {
|
|
38
|
+
return [current()[key], (nextState) => set(key, (0, vest_utils.dynamicValue)(nextState, current()[key]))];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function current() {
|
|
42
|
+
return state.references;
|
|
43
|
+
}
|
|
44
|
+
function set(index, value) {
|
|
45
|
+
const prevValue = state.references[index];
|
|
46
|
+
state.references[index] = value;
|
|
47
|
+
const [, onUpdate] = registrations[index];
|
|
48
|
+
if ((0, vest_utils.isFunction)(onUpdate)) onUpdate(value, prevValue);
|
|
49
|
+
if ((0, vest_utils.isFunction)(onStateChange)) onStateChange();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
exports.createState = createState;
|
|
55
|
+
//# sourceMappingURL=vast.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vast.cjs","names":["state: {\n references: unknown[];\n }","registrations: [\n unknown,\n (<S>(currentState: S, prevState: S) => void)?,\n ][]"],"sources":["../src/vast.ts"],"sourcesContent":["import { CB, DynamicValue, Maybe, isFunction, dynamicValue } from 'vest-utils';\n\n// eslint-disable-next-line max-lines-per-function\nexport function createState(\n onStateChange?: (...args: unknown[]) => unknown,\n): CreateStateReturn {\n const state: {\n references: unknown[];\n } = {\n references: [],\n };\n\n const registrations: [\n unknown,\n (<S>(currentState: S, prevState: S) => void)?,\n ][] = [];\n\n return {\n registerStateKey,\n reset,\n };\n\n /**\n * Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.\n *\n * @example\n *\n * const useColor = state.registerStateKey(\"blue\");\n *\n * let [color, setColor] = useColor(); // -> [\"blue\", Function]\n *\n * setColor(\"green\");\n *\n * useColor()[0]; -> \"green\"\n */\n function registerStateKey<S>(\n initialState?: Maybe<StateInput<S>>,\n onUpdate?: () => void,\n ): CB<StateHandlerReturn<S>> {\n const key = registrations.length;\n registrations.push([initialState, onUpdate]);\n return initKey(key, initialState);\n }\n\n function reset(): void {\n const prev = current();\n state.references = [];\n registrations.forEach(([initialValue], index) =>\n initKey(index, initialValue, prev[index]),\n );\n }\n\n function initKey<S>(\n key: number,\n initialState?: Maybe<StateInput<S>>,\n prevState?: Maybe<S>,\n ) {\n current().push();\n set(key, dynamicValue(initialState, prevState));\n\n return function useStateKey(): StateHandlerReturn<S> {\n return [\n current()[key],\n (nextState: SetStateInput<S>) =>\n set(key, dynamicValue(nextState, current()[key])),\n ];\n };\n }\n\n function current(): any[] {\n return state.references;\n }\n\n function set(index: number, value: unknown): void {\n const prevValue = state.references[index];\n state.references[index] = value;\n\n const [, onUpdate] = registrations[index];\n\n if (isFunction(onUpdate)) {\n onUpdate(value, prevValue);\n }\n\n if (isFunction(onStateChange)) {\n onStateChange();\n }\n }\n}\n\ntype StateInput<S> = DynamicValue<S, [prevState?: S]>;\ntype SetStateInput<S> = DynamicValue<S, [prevState: S]>;\n\nexport type State = CreateStateReturn;\nexport type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];\nexport type UseState<S> = CB<StateHandlerReturn<S>>;\n\ntype CreateStateReturn = {\n reset: () => void;\n registerStateKey: <S>(\n initialState?: Maybe<StateInput<S>>,\n onUpdate?: () => void,\n ) => CB<StateHandlerReturn<S>>;\n};\n"],"mappings":";;;AAGA,SAAgB,YACd,eACmB;CACnB,MAAMA,QAEF,EACF,YAAY,EAAE,EACf;CAED,MAAMC,gBAGA,EAAE;AAER,QAAO;EACL;EACA;EACD;;;;;;;;;;;;;;CAeD,SAAS,iBACP,cACA,UAC2B;EAC3B,MAAM,MAAM,cAAc;AAC1B,gBAAc,KAAK,CAAC,cAAc,SAAS,CAAC;AAC5C,SAAO,QAAQ,KAAK,aAAa;;CAGnC,SAAS,QAAc;EACrB,MAAM,OAAO,SAAS;AACtB,QAAM,aAAa,EAAE;AACrB,gBAAc,SAAS,CAAC,eAAe,UACrC,QAAQ,OAAO,cAAc,KAAK,OAAO,CAC1C;;CAGH,SAAS,QACP,KACA,cACA,WACA;AACA,WAAS,CAAC,MAAM;AAChB,MAAI,kCAAkB,cAAc,UAAU,CAAC;AAE/C,SAAO,SAAS,cAAqC;AACnD,UAAO,CACL,SAAS,CAAC,OACT,cACC,IAAI,kCAAkB,WAAW,SAAS,CAAC,KAAK,CAAC,CACpD;;;CAIL,SAAS,UAAiB;AACxB,SAAO,MAAM;;CAGf,SAAS,IAAI,OAAe,OAAsB;EAChD,MAAM,YAAY,MAAM,WAAW;AACnC,QAAM,WAAW,SAAS;EAE1B,MAAM,GAAG,YAAY,cAAc;AAEnC,iCAAe,SAAS,CACtB,UAAS,OAAO,UAAU;AAG5B,iCAAe,cAAc,CAC3B,gBAAe"}
|
package/dist/vast.mjs
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { dynamicValue, isFunction } from "vest-utils";
|
|
2
|
+
|
|
3
|
+
//#region src/vast.ts
|
|
4
|
+
function createState(onStateChange) {
|
|
5
|
+
const state = { references: [] };
|
|
6
|
+
const registrations = [];
|
|
7
|
+
return {
|
|
8
|
+
registerStateKey,
|
|
9
|
+
reset
|
|
10
|
+
};
|
|
11
|
+
/**
|
|
12
|
+
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
*
|
|
16
|
+
* const useColor = state.registerStateKey("blue");
|
|
17
|
+
*
|
|
18
|
+
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
19
|
+
*
|
|
20
|
+
* setColor("green");
|
|
21
|
+
*
|
|
22
|
+
* useColor()[0]; -> "green"
|
|
23
|
+
*/
|
|
24
|
+
function registerStateKey(initialState, onUpdate) {
|
|
25
|
+
const key = registrations.length;
|
|
26
|
+
registrations.push([initialState, onUpdate]);
|
|
27
|
+
return initKey(key, initialState);
|
|
28
|
+
}
|
|
29
|
+
function reset() {
|
|
30
|
+
const prev = current();
|
|
31
|
+
state.references = [];
|
|
32
|
+
registrations.forEach(([initialValue], index) => initKey(index, initialValue, prev[index]));
|
|
33
|
+
}
|
|
34
|
+
function initKey(key, initialState, prevState) {
|
|
35
|
+
current().push();
|
|
36
|
+
set(key, dynamicValue(initialState, prevState));
|
|
37
|
+
return function useStateKey() {
|
|
38
|
+
return [current()[key], (nextState) => set(key, dynamicValue(nextState, current()[key]))];
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function current() {
|
|
42
|
+
return state.references;
|
|
43
|
+
}
|
|
44
|
+
function set(index, value) {
|
|
45
|
+
const prevValue = state.references[index];
|
|
46
|
+
state.references[index] = value;
|
|
47
|
+
const [, onUpdate] = registrations[index];
|
|
48
|
+
if (isFunction(onUpdate)) onUpdate(value, prevValue);
|
|
49
|
+
if (isFunction(onStateChange)) onStateChange();
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
//#endregion
|
|
54
|
+
export { createState };
|
|
55
|
+
//# sourceMappingURL=vast.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vast.mjs","names":["state: {\n references: unknown[];\n }","registrations: [\n unknown,\n (<S>(currentState: S, prevState: S) => void)?,\n ][]"],"sources":["../src/vast.ts"],"sourcesContent":["import { CB, DynamicValue, Maybe, isFunction, dynamicValue } from 'vest-utils';\n\n// eslint-disable-next-line max-lines-per-function\nexport function createState(\n onStateChange?: (...args: unknown[]) => unknown,\n): CreateStateReturn {\n const state: {\n references: unknown[];\n } = {\n references: [],\n };\n\n const registrations: [\n unknown,\n (<S>(currentState: S, prevState: S) => void)?,\n ][] = [];\n\n return {\n registerStateKey,\n reset,\n };\n\n /**\n * Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.\n *\n * @example\n *\n * const useColor = state.registerStateKey(\"blue\");\n *\n * let [color, setColor] = useColor(); // -> [\"blue\", Function]\n *\n * setColor(\"green\");\n *\n * useColor()[0]; -> \"green\"\n */\n function registerStateKey<S>(\n initialState?: Maybe<StateInput<S>>,\n onUpdate?: () => void,\n ): CB<StateHandlerReturn<S>> {\n const key = registrations.length;\n registrations.push([initialState, onUpdate]);\n return initKey(key, initialState);\n }\n\n function reset(): void {\n const prev = current();\n state.references = [];\n registrations.forEach(([initialValue], index) =>\n initKey(index, initialValue, prev[index]),\n );\n }\n\n function initKey<S>(\n key: number,\n initialState?: Maybe<StateInput<S>>,\n prevState?: Maybe<S>,\n ) {\n current().push();\n set(key, dynamicValue(initialState, prevState));\n\n return function useStateKey(): StateHandlerReturn<S> {\n return [\n current()[key],\n (nextState: SetStateInput<S>) =>\n set(key, dynamicValue(nextState, current()[key])),\n ];\n };\n }\n\n function current(): any[] {\n return state.references;\n }\n\n function set(index: number, value: unknown): void {\n const prevValue = state.references[index];\n state.references[index] = value;\n\n const [, onUpdate] = registrations[index];\n\n if (isFunction(onUpdate)) {\n onUpdate(value, prevValue);\n }\n\n if (isFunction(onStateChange)) {\n onStateChange();\n }\n }\n}\n\ntype StateInput<S> = DynamicValue<S, [prevState?: S]>;\ntype SetStateInput<S> = DynamicValue<S, [prevState: S]>;\n\nexport type State = CreateStateReturn;\nexport type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];\nexport type UseState<S> = CB<StateHandlerReturn<S>>;\n\ntype CreateStateReturn = {\n reset: () => void;\n registerStateKey: <S>(\n initialState?: Maybe<StateInput<S>>,\n onUpdate?: () => void,\n ) => CB<StateHandlerReturn<S>>;\n};\n"],"mappings":";;;AAGA,SAAgB,YACd,eACmB;CACnB,MAAMA,QAEF,EACF,YAAY,EAAE,EACf;CAED,MAAMC,gBAGA,EAAE;AAER,QAAO;EACL;EACA;EACD;;;;;;;;;;;;;;CAeD,SAAS,iBACP,cACA,UAC2B;EAC3B,MAAM,MAAM,cAAc;AAC1B,gBAAc,KAAK,CAAC,cAAc,SAAS,CAAC;AAC5C,SAAO,QAAQ,KAAK,aAAa;;CAGnC,SAAS,QAAc;EACrB,MAAM,OAAO,SAAS;AACtB,QAAM,aAAa,EAAE;AACrB,gBAAc,SAAS,CAAC,eAAe,UACrC,QAAQ,OAAO,cAAc,KAAK,OAAO,CAC1C;;CAGH,SAAS,QACP,KACA,cACA,WACA;AACA,WAAS,CAAC,MAAM;AAChB,MAAI,KAAK,aAAa,cAAc,UAAU,CAAC;AAE/C,SAAO,SAAS,cAAqC;AACnD,UAAO,CACL,SAAS,CAAC,OACT,cACC,IAAI,KAAK,aAAa,WAAW,SAAS,CAAC,KAAK,CAAC,CACpD;;;CAIL,SAAS,UAAiB;AACxB,SAAO,MAAM;;CAGf,SAAS,IAAI,OAAe,OAAsB;EAChD,MAAM,YAAY,MAAM,WAAW;AACnC,QAAM,WAAW,SAAS;EAE1B,MAAM,GAAG,YAAY,cAAc;AAEnC,MAAI,WAAW,SAAS,CACtB,UAAS,OAAO,UAAU;AAG5B,MAAI,WAAW,cAAc,CAC3B,gBAAe"}
|
package/package.json
CHANGED
|
@@ -1,45 +1,43 @@
|
|
|
1
1
|
{
|
|
2
|
-
"version": "2.0.
|
|
2
|
+
"version": "2.0.2",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"main": "./dist/
|
|
5
|
-
"types": "./types/vast.d.
|
|
4
|
+
"main": "./dist/vast.cjs",
|
|
5
|
+
"types": "./types/vast.d.cts",
|
|
6
6
|
"name": "vast",
|
|
7
7
|
"author": "ealush",
|
|
8
8
|
"scripts": {
|
|
9
9
|
"test": "vx test",
|
|
10
10
|
"release": "vx release"
|
|
11
11
|
},
|
|
12
|
-
"module": "./dist/
|
|
12
|
+
"module": "./dist/vast.mjs",
|
|
13
13
|
"repository": {
|
|
14
14
|
"type": "git",
|
|
15
|
-
"url": "https://github.com/ealush/vest.git",
|
|
15
|
+
"url": "git+https://github.com/ealush/vest.git",
|
|
16
16
|
"directory": "packages/vast"
|
|
17
17
|
},
|
|
18
18
|
"bugs": {
|
|
19
19
|
"url": "https://github.com/ealush/vest.git/issues"
|
|
20
20
|
},
|
|
21
|
+
"dependencies": {
|
|
22
|
+
"vest-utils": "^2.0.2"
|
|
23
|
+
},
|
|
24
|
+
"unpkg": "./dist/vast.mjs",
|
|
25
|
+
"jsdelivr": "./dist/vast.mjs",
|
|
26
|
+
"vxAllowResolve": [],
|
|
21
27
|
"exports": {
|
|
22
28
|
".": {
|
|
23
|
-
"
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
"module": "./dist/es/vast.development.js",
|
|
31
|
-
"default": "./dist/cjs/vast.development.js"
|
|
32
|
-
},
|
|
33
|
-
"types": "./types/vast.d.ts",
|
|
34
|
-
"browser": "./dist/es/vast.production.js",
|
|
35
|
-
"umd": "./dist/umd/vast.production.js",
|
|
36
|
-
"import": "./dist/es/vast.production.js",
|
|
37
|
-
"require": "./dist/cjs/vast.production.js",
|
|
38
|
-
"node": "./dist/cjs/vast.production.js",
|
|
39
|
-
"module": "./dist/es/vast.production.js",
|
|
40
|
-
"default": "./dist/cjs/vast.production.js"
|
|
29
|
+
"types": "./types/vast.d.cts",
|
|
30
|
+
"require": "./dist/vast.cjs",
|
|
31
|
+
"import": "./dist/vast.mjs"
|
|
32
|
+
},
|
|
33
|
+
"./*": {
|
|
34
|
+
"types": "./types/vast.d.cts",
|
|
35
|
+
"default": "./*"
|
|
41
36
|
},
|
|
42
37
|
"./package.json": "./package.json",
|
|
43
|
-
"./": "./"
|
|
38
|
+
"./vast": "./types/vast.d.cts",
|
|
39
|
+
"./vast.d.ts": "./types/vast.d.ts",
|
|
40
|
+
"./types/*": "./types/*",
|
|
41
|
+
"./dist/*": "./dist/*"
|
|
44
42
|
}
|
|
45
43
|
}
|
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
import { describe, it, expect, beforeEach, vi } from 'vitest';
|
|
2
|
+
|
|
3
|
+
import { createState } from '../vast';
|
|
4
|
+
|
|
5
|
+
let state = createState();
|
|
6
|
+
|
|
7
|
+
describe('vast state', () => {
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
state = createState();
|
|
10
|
+
});
|
|
11
|
+
|
|
12
|
+
describe('createState', () => {
|
|
13
|
+
it('Should return all stateRef methods', () => {
|
|
14
|
+
expect(state).toMatchInlineSnapshot(`
|
|
15
|
+
{
|
|
16
|
+
"registerStateKey": [Function],
|
|
17
|
+
"reset": [Function],
|
|
18
|
+
}
|
|
19
|
+
`);
|
|
20
|
+
});
|
|
21
|
+
});
|
|
22
|
+
|
|
23
|
+
describe('state.registerStateKey', () => {
|
|
24
|
+
it('Should return a function', () => {
|
|
25
|
+
expect(typeof state.registerStateKey()).toBe('function');
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
it('Should append another state key on each call', () => {
|
|
29
|
+
const stateValues = Array.from({ length: 100 }, () => Math.random());
|
|
30
|
+
const stateGetters = stateValues.map(value =>
|
|
31
|
+
state.registerStateKey(value),
|
|
32
|
+
);
|
|
33
|
+
expect(
|
|
34
|
+
stateGetters.every(
|
|
35
|
+
(stateGetter, i) => stateGetter()[0] === stateValues[i],
|
|
36
|
+
),
|
|
37
|
+
).toBe(true);
|
|
38
|
+
expect(stateGetters).toHaveLength(100);
|
|
39
|
+
});
|
|
40
|
+
|
|
41
|
+
describe('When initial value is a function', () => {
|
|
42
|
+
it('Should generate initial state from key', () => {
|
|
43
|
+
const initialStateKey = { key: 'value' };
|
|
44
|
+
const stateGetter = state.registerStateKey(() => initialStateKey);
|
|
45
|
+
expect(stateGetter()[0]).toBe(initialStateKey);
|
|
46
|
+
});
|
|
47
|
+
});
|
|
48
|
+
|
|
49
|
+
describe('When initial value is not a function', () => {
|
|
50
|
+
it('Should use provided value as initial state', () => {
|
|
51
|
+
const stateValue = { key: 'value' };
|
|
52
|
+
const stateGetter = state.registerStateKey(stateValue);
|
|
53
|
+
expect(stateGetter()[0]).toBe(stateValue);
|
|
54
|
+
});
|
|
55
|
+
});
|
|
56
|
+
|
|
57
|
+
describe('When initial value is not provided', () => {
|
|
58
|
+
it('Should set initial state to undefined', () => {
|
|
59
|
+
const stateGetter = state.registerStateKey();
|
|
60
|
+
expect(stateGetter()[0]).toBeUndefined();
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('State key function', () => {
|
|
66
|
+
it('Should return an Array with two elements', () => {
|
|
67
|
+
expect(state.registerStateKey()()).toHaveLength(2);
|
|
68
|
+
expect(state.registerStateKey('some value')()).toMatchInlineSnapshot(`
|
|
69
|
+
[
|
|
70
|
+
"some value",
|
|
71
|
+
[Function],
|
|
72
|
+
]
|
|
73
|
+
`);
|
|
74
|
+
});
|
|
75
|
+
|
|
76
|
+
describe('getting current value', () => {
|
|
77
|
+
it('Should have current value in the first array element', () => {
|
|
78
|
+
const stateGetter = state.registerStateKey('Some Value');
|
|
79
|
+
expect(stateGetter()[0]).toBe('Some Value');
|
|
80
|
+
});
|
|
81
|
+
});
|
|
82
|
+
|
|
83
|
+
describe('updating the state', () => {
|
|
84
|
+
it('Should contain state updater in the second array element', () => {
|
|
85
|
+
const stateGetter = state.registerStateKey('Some Value');
|
|
86
|
+
expect(typeof stateGetter()[1]).toBe('function');
|
|
87
|
+
});
|
|
88
|
+
|
|
89
|
+
it('Should update the state with provided value', () => {
|
|
90
|
+
const stateGetter = state.registerStateKey({ key: 'first-value' });
|
|
91
|
+
const [, valueSetter] = stateGetter();
|
|
92
|
+
const nextValue = { key: 'second-value' };
|
|
93
|
+
valueSetter(nextValue);
|
|
94
|
+
expect(stateGetter()[0]).toBe(nextValue);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
describe('When passing a function', () => {
|
|
98
|
+
it('Should update the state with the result of the function', () => {
|
|
99
|
+
const stateGetter = state.registerStateKey({ key: 'first-value' });
|
|
100
|
+
const [, valueSetter] = stateGetter();
|
|
101
|
+
const nextValue = { key: 'second-value' };
|
|
102
|
+
valueSetter(() => nextValue);
|
|
103
|
+
expect(stateGetter()[0]).toBe(nextValue);
|
|
104
|
+
});
|
|
105
|
+
|
|
106
|
+
it('Should pass the function the current state value', () => {
|
|
107
|
+
return new Promise<void>(done => {
|
|
108
|
+
const stateGetter = state.registerStateKey('555');
|
|
109
|
+
const [currentState, valueSetter] = stateGetter();
|
|
110
|
+
expect(currentState).toBe('555');
|
|
111
|
+
|
|
112
|
+
valueSetter(prevState => {
|
|
113
|
+
expect(prevState).toBe('555');
|
|
114
|
+
done();
|
|
115
|
+
return prevState;
|
|
116
|
+
});
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
});
|
|
120
|
+
});
|
|
121
|
+
});
|
|
122
|
+
|
|
123
|
+
describe('onStateChange and onUpdate handlers', () => {
|
|
124
|
+
it('Should run onStateChange handler when updating the state', () => {
|
|
125
|
+
const onStateChange = vi.fn();
|
|
126
|
+
state = createState(onStateChange);
|
|
127
|
+
|
|
128
|
+
const useKey1 = state.registerStateKey('v1');
|
|
129
|
+
const useKey2 = state.registerStateKey('v2');
|
|
130
|
+
expect(onStateChange).toHaveBeenCalledTimes(2);
|
|
131
|
+
useKey1()[1]('v1_1');
|
|
132
|
+
expect(onStateChange).toHaveBeenCalledTimes(3);
|
|
133
|
+
useKey2()[1]('v2_1');
|
|
134
|
+
expect(onStateChange).toHaveBeenCalledTimes(4);
|
|
135
|
+
expect(onStateChange).toHaveBeenCalledWith();
|
|
136
|
+
});
|
|
137
|
+
|
|
138
|
+
it('Should run onUpdate handler when updating the key', () => {
|
|
139
|
+
const onUpdate1 = vi.fn();
|
|
140
|
+
const onUpdate2 = vi.fn();
|
|
141
|
+
state = createState();
|
|
142
|
+
|
|
143
|
+
const useKey1 = state.registerStateKey('v1', onUpdate1);
|
|
144
|
+
const useKey2 = state.registerStateKey('v2', onUpdate2);
|
|
145
|
+
expect(onUpdate1).toHaveBeenCalledTimes(1);
|
|
146
|
+
expect(onUpdate1).toHaveBeenCalledWith('v1', undefined);
|
|
147
|
+
expect(onUpdate2).toHaveBeenCalledTimes(1);
|
|
148
|
+
const [, setKey1] = useKey1();
|
|
149
|
+
const [, setKey2] = useKey2();
|
|
150
|
+
setKey1('v1_1');
|
|
151
|
+
expect(onUpdate1).toHaveBeenCalledTimes(2);
|
|
152
|
+
|
|
153
|
+
// pass current state + previous state
|
|
154
|
+
expect(onUpdate1).toHaveBeenCalledWith('v1_1', 'v1');
|
|
155
|
+
setKey1('v1_2');
|
|
156
|
+
expect(onUpdate1).toHaveBeenCalledWith('v1_2', 'v1_1');
|
|
157
|
+
expect(onUpdate2).toHaveBeenCalledTimes(1);
|
|
158
|
+
setKey2('v2_1');
|
|
159
|
+
expect(onUpdate2).toHaveBeenCalledTimes(2);
|
|
160
|
+
expect(onUpdate2).toHaveBeenCalledWith('v2_1', 'v2');
|
|
161
|
+
});
|
|
162
|
+
|
|
163
|
+
it('Should first run onUpdate and then onStateChange', () => {
|
|
164
|
+
const onUpdate = vi.fn();
|
|
165
|
+
const onChange = vi.fn();
|
|
166
|
+
state = createState(onChange);
|
|
167
|
+
|
|
168
|
+
state.registerStateKey('v1', onUpdate);
|
|
169
|
+
expect(onUpdate.mock.invocationCallOrder[0]).toBeLessThan(
|
|
170
|
+
onChange.mock.invocationCallOrder[0],
|
|
171
|
+
);
|
|
172
|
+
});
|
|
173
|
+
});
|
|
174
|
+
|
|
175
|
+
describe('state.reset', () => {
|
|
176
|
+
it('Should fill up the state with registered keys', () => {
|
|
177
|
+
const s1 = state.registerStateKey(111);
|
|
178
|
+
const s2 = state.registerStateKey(222);
|
|
179
|
+
const s3 = state.registerStateKey(333);
|
|
180
|
+
const s4 = state.registerStateKey(444);
|
|
181
|
+
s1()[1](555);
|
|
182
|
+
s2()[1](666);
|
|
183
|
+
s3()[1](777);
|
|
184
|
+
s4()[1](888);
|
|
185
|
+
|
|
186
|
+
// sanity
|
|
187
|
+
expect(s1()[0]).toBe(555);
|
|
188
|
+
expect(s2()[0]).toBe(666);
|
|
189
|
+
expect(s3()[0]).toBe(777);
|
|
190
|
+
expect(s4()[0]).toBe(888);
|
|
191
|
+
|
|
192
|
+
state.reset();
|
|
193
|
+
|
|
194
|
+
// testing now that everything is back to initial value
|
|
195
|
+
expect(s1()[0]).toBe(111);
|
|
196
|
+
expect(s2()[0]).toBe(222);
|
|
197
|
+
expect(s3()[0]).toBe(333);
|
|
198
|
+
expect(s4()[0]).toBe(444);
|
|
199
|
+
});
|
|
200
|
+
|
|
201
|
+
it('Should allow setting a value after a state reset', () => {
|
|
202
|
+
const stateGetter = state.registerStateKey(() => 'hello!');
|
|
203
|
+
const [, stateSetter] = stateGetter();
|
|
204
|
+
state.reset();
|
|
205
|
+
stateSetter('Good Bye!');
|
|
206
|
+
expect(stateGetter()[0]).toBe('Good Bye!');
|
|
207
|
+
});
|
|
208
|
+
});
|
|
209
|
+
});
|
package/src/vast.ts
ADDED
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
import { CB, DynamicValue, Maybe, isFunction, dynamicValue } from 'vest-utils';
|
|
2
|
+
|
|
3
|
+
// eslint-disable-next-line max-lines-per-function
|
|
4
|
+
export function createState(
|
|
5
|
+
onStateChange?: (...args: unknown[]) => unknown,
|
|
6
|
+
): CreateStateReturn {
|
|
7
|
+
const state: {
|
|
8
|
+
references: unknown[];
|
|
9
|
+
} = {
|
|
10
|
+
references: [],
|
|
11
|
+
};
|
|
12
|
+
|
|
13
|
+
const registrations: [
|
|
14
|
+
unknown,
|
|
15
|
+
(<S>(currentState: S, prevState: S) => void)?,
|
|
16
|
+
][] = [];
|
|
17
|
+
|
|
18
|
+
return {
|
|
19
|
+
registerStateKey,
|
|
20
|
+
reset,
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
25
|
+
*
|
|
26
|
+
* @example
|
|
27
|
+
*
|
|
28
|
+
* const useColor = state.registerStateKey("blue");
|
|
29
|
+
*
|
|
30
|
+
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
31
|
+
*
|
|
32
|
+
* setColor("green");
|
|
33
|
+
*
|
|
34
|
+
* useColor()[0]; -> "green"
|
|
35
|
+
*/
|
|
36
|
+
function registerStateKey<S>(
|
|
37
|
+
initialState?: Maybe<StateInput<S>>,
|
|
38
|
+
onUpdate?: () => void,
|
|
39
|
+
): CB<StateHandlerReturn<S>> {
|
|
40
|
+
const key = registrations.length;
|
|
41
|
+
registrations.push([initialState, onUpdate]);
|
|
42
|
+
return initKey(key, initialState);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function reset(): void {
|
|
46
|
+
const prev = current();
|
|
47
|
+
state.references = [];
|
|
48
|
+
registrations.forEach(([initialValue], index) =>
|
|
49
|
+
initKey(index, initialValue, prev[index]),
|
|
50
|
+
);
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
function initKey<S>(
|
|
54
|
+
key: number,
|
|
55
|
+
initialState?: Maybe<StateInput<S>>,
|
|
56
|
+
prevState?: Maybe<S>,
|
|
57
|
+
) {
|
|
58
|
+
current().push();
|
|
59
|
+
set(key, dynamicValue(initialState, prevState));
|
|
60
|
+
|
|
61
|
+
return function useStateKey(): StateHandlerReturn<S> {
|
|
62
|
+
return [
|
|
63
|
+
current()[key],
|
|
64
|
+
(nextState: SetStateInput<S>) =>
|
|
65
|
+
set(key, dynamicValue(nextState, current()[key])),
|
|
66
|
+
];
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
function current(): any[] {
|
|
71
|
+
return state.references;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
function set(index: number, value: unknown): void {
|
|
75
|
+
const prevValue = state.references[index];
|
|
76
|
+
state.references[index] = value;
|
|
77
|
+
|
|
78
|
+
const [, onUpdate] = registrations[index];
|
|
79
|
+
|
|
80
|
+
if (isFunction(onUpdate)) {
|
|
81
|
+
onUpdate(value, prevValue);
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
if (isFunction(onStateChange)) {
|
|
85
|
+
onStateChange();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
type StateInput<S> = DynamicValue<S, [prevState?: S]>;
|
|
91
|
+
type SetStateInput<S> = DynamicValue<S, [prevState: S]>;
|
|
92
|
+
|
|
93
|
+
export type State = CreateStateReturn;
|
|
94
|
+
export type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];
|
|
95
|
+
export type UseState<S> = CB<StateHandlerReturn<S>>;
|
|
96
|
+
|
|
97
|
+
type CreateStateReturn = {
|
|
98
|
+
reset: () => void;
|
|
99
|
+
registerStateKey: <S>(
|
|
100
|
+
initialState?: Maybe<StateInput<S>>,
|
|
101
|
+
onUpdate?: () => void,
|
|
102
|
+
) => CB<StateHandlerReturn<S>>;
|
|
103
|
+
};
|
package/types/vast.d.cts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CB, DynamicValue, Maybe } from "vest-utils";
|
|
2
|
+
|
|
3
|
+
//#region src/vast.d.ts
|
|
4
|
+
declare function createState(onStateChange?: (...args: unknown[]) => unknown): CreateStateReturn;
|
|
5
|
+
type StateInput<S> = DynamicValue<S, [prevState?: S]>;
|
|
6
|
+
type SetStateInput<S> = DynamicValue<S, [prevState: S]>;
|
|
7
|
+
type State = CreateStateReturn;
|
|
8
|
+
type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];
|
|
9
|
+
type UseState<S> = CB<StateHandlerReturn<S>>;
|
|
10
|
+
type CreateStateReturn = {
|
|
11
|
+
reset: () => void;
|
|
12
|
+
registerStateKey: <S>(initialState?: Maybe<StateInput<S>>, onUpdate?: () => void) => CB<StateHandlerReturn<S>>;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { State, StateHandlerReturn, UseState, createState };
|
|
16
|
+
//# sourceMappingURL=vast.d.cts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vast.d.cts","names":["CB","DynamicValue","Maybe","createState","CreateStateReturn","StateInput","S","SetStateInput","State","StateHandlerReturn","UseState"],"sources":["../src/vast.d.ts"],"sourcesContent":["import { CB, DynamicValue, Maybe } from 'vest-utils';\nexport declare function createState(onStateChange?: (...args: unknown[]) => unknown): CreateStateReturn;\ntype StateInput<S> = DynamicValue<S, [prevState?: S]>;\ntype SetStateInput<S> = DynamicValue<S, [prevState: S]>;\nexport type State = CreateStateReturn;\nexport type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];\nexport type UseState<S> = CB<StateHandlerReturn<S>>;\ntype CreateStateReturn = {\n reset: () => void;\n registerStateKey: <S>(initialState?: Maybe<StateInput<S>>, onUpdate?: () => void) => CB<StateHandlerReturn<S>>;\n};\nexport {};\n"],"mappings":";;;iBACwBG,WAAAA,mDAA8DC;KACjFC,gBAAgBJ,aAAaK,gBAAgBA;AADlD,KAEKC,aAF8B,CAAA,CAAA,CAAA,GAEXN,YAF8DG,CAEjDE,CAFiDF,EAAAA,CAAAA,SAAiB,EAEnDE,CAFmD,CAAA,CAAA;AAClGD,KAEOG,KAAAA,GAAQJ,iBAFL;AAAmBE,KAGtBG,kBAHsBH,CAAAA,CAAAA,CAAAA,GAAAA,CAGGA,CAHHA,EAAAA,CAAAA,SAAAA,EAGkBC,aAHlBD,CAGgCA,CAHhCA,CAAAA,EAAAA,GAAAA,IAAAA,CAAAA;AAAgBA,KAItCI,QAJsCJ,CAAAA,CAAAA,CAAAA,GAIxBN,EAJwBM,CAIrBG,kBAJqBH,CAIFA,CAJEA,CAAAA,CAAAA;KAK7CF,iBAAAA,GALgBH;EAAY,KAAA,EAAA,GAAA,GAAA,IAAA;EAC5BM,gBAAa,EAAA,CAAA,CAAA,CAAAD,CAAAA,YAAA,CAAA,EAMuBJ,KANvB,CAM6BG,UAN7B,CAMwCC,CANxC,CAAA,CAAA,EAAA,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA,EAAA,GAMuEN,EANvE,CAM0ES,kBAN1E,CAM6FH,CAN7F,CAAA,CAAA;CAAmBA"}
|
package/types/vast.d.mts
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import { CB, DynamicValue, Maybe } from "vest-utils";
|
|
2
|
+
|
|
3
|
+
//#region src/vast.d.ts
|
|
4
|
+
declare function createState(onStateChange?: (...args: unknown[]) => unknown): CreateStateReturn;
|
|
5
|
+
type StateInput<S> = DynamicValue<S, [prevState?: S]>;
|
|
6
|
+
type SetStateInput<S> = DynamicValue<S, [prevState: S]>;
|
|
7
|
+
type State = CreateStateReturn;
|
|
8
|
+
type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];
|
|
9
|
+
type UseState<S> = CB<StateHandlerReturn<S>>;
|
|
10
|
+
type CreateStateReturn = {
|
|
11
|
+
reset: () => void;
|
|
12
|
+
registerStateKey: <S>(initialState?: Maybe<StateInput<S>>, onUpdate?: () => void) => CB<StateHandlerReturn<S>>;
|
|
13
|
+
};
|
|
14
|
+
//#endregion
|
|
15
|
+
export { State, StateHandlerReturn, UseState, createState };
|
|
16
|
+
//# sourceMappingURL=vast.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"vast.d.mts","names":["CB","DynamicValue","Maybe","createState","CreateStateReturn","StateInput","S","SetStateInput","State","StateHandlerReturn","UseState"],"sources":["../src/vast.d.ts"],"sourcesContent":["import { CB, DynamicValue, Maybe } from 'vest-utils';\nexport declare function createState(onStateChange?: (...args: unknown[]) => unknown): CreateStateReturn;\ntype StateInput<S> = DynamicValue<S, [prevState?: S]>;\ntype SetStateInput<S> = DynamicValue<S, [prevState: S]>;\nexport type State = CreateStateReturn;\nexport type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];\nexport type UseState<S> = CB<StateHandlerReturn<S>>;\ntype CreateStateReturn = {\n reset: () => void;\n registerStateKey: <S>(initialState?: Maybe<StateInput<S>>, onUpdate?: () => void) => CB<StateHandlerReturn<S>>;\n};\nexport {};\n"],"mappings":";;;iBACwBG,WAAAA,mDAA8DC;KACjFC,gBAAgBJ,aAAaK,gBAAgBA;AADlD,KAEKC,aAF8B,CAAA,CAAA,CAAA,GAEXN,YAF8DG,CAEjDE,CAFiDF,EAAAA,CAAAA,SAAiB,EAEnDE,CAFmD,CAAA,CAAA;AAClGD,KAEOG,KAAAA,GAAQJ,iBAFL;AAAmBE,KAGtBG,kBAHsBH,CAAAA,CAAAA,CAAAA,GAAAA,CAGGA,CAHHA,EAAAA,CAAAA,SAAAA,EAGkBC,aAHlBD,CAGgCA,CAHhCA,CAAAA,EAAAA,GAAAA,IAAAA,CAAAA;AAAgBA,KAItCI,QAJsCJ,CAAAA,CAAAA,CAAAA,GAIxBN,EAJwBM,CAIrBG,kBAJqBH,CAIFA,CAJEA,CAAAA,CAAAA;KAK7CF,iBAAAA,GALgBH;EAAY,KAAA,EAAA,GAAA,GAAA,IAAA;EAC5BM,gBAAa,EAAA,CAAA,CAAA,CAAAD,CAAAA,YAAA,CAAA,EAMuBJ,KANvB,CAM6BG,UAN7B,CAMwCC,CANxC,CAAA,CAAA,EAAA,QAAA,CAAA,EAAA,GAAA,GAAA,IAAA,EAAA,GAMuEN,EANvE,CAM0ES,kBAN1E,CAM6FH,CAN7F,CAAA,CAAA;CAAmBA"}
|
package/types/vast.d.ts
CHANGED
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
type
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
];
|
|
9
|
-
type
|
|
10
|
-
|
|
11
|
-
|
|
1
|
+
import { CB, DynamicValue, Maybe } from "vest-utils";
|
|
2
|
+
|
|
3
|
+
//#region src/vast.d.ts
|
|
4
|
+
declare function createState(onStateChange?: (...args: unknown[]) => unknown): CreateStateReturn;
|
|
5
|
+
type StateInput<S> = DynamicValue<S, [prevState?: S]>;
|
|
6
|
+
type SetStateInput<S> = DynamicValue<S, [prevState: S]>;
|
|
7
|
+
type State = CreateStateReturn;
|
|
8
|
+
type StateHandlerReturn<S> = [S, (nextState: SetStateInput<S>) => void];
|
|
9
|
+
type UseState<S> = CB<StateHandlerReturn<S>>;
|
|
10
|
+
type CreateStateReturn = {
|
|
11
|
+
reset: () => void;
|
|
12
|
+
registerStateKey: <S>(initialState?: Maybe<StateInput<S>>, onUpdate?: () => void) => CB<StateHandlerReturn<S>>;
|
|
12
13
|
};
|
|
13
|
-
|
|
14
|
+
//#endregion
|
|
15
|
+
export { State, StateHandlerReturn, UseState, createState };
|
|
16
|
+
//# sourceMappingURL=vast.d.cts.map
|
package/vitest.config.ts
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import path, { resolve } from 'path';
|
|
2
|
+
import { fileURLToPath } from 'url';
|
|
3
|
+
|
|
4
|
+
import { defineConfig } from 'vitest/config';
|
|
5
|
+
|
|
6
|
+
const __filename = fileURLToPath(import.meta.url);
|
|
7
|
+
const __dirname = path.dirname(__filename);
|
|
8
|
+
|
|
9
|
+
export default defineConfig({
|
|
10
|
+
test: {
|
|
11
|
+
globals: true,
|
|
12
|
+
include: ['./**/__tests__/*.test.ts'],
|
|
13
|
+
setupFiles: [resolve(__dirname, '../../', 'vx/config/vitest')],
|
|
14
|
+
},
|
|
15
|
+
root: __dirname,
|
|
16
|
+
resolve: {
|
|
17
|
+
alias: {
|
|
18
|
+
vast: resolve(__dirname, 'src/vast.ts'),
|
|
19
|
+
},
|
|
20
|
+
},
|
|
21
|
+
});
|
package/dist/cjs/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"commonjs"}
|
|
@@ -1,81 +0,0 @@
|
|
|
1
|
-
'use strict';
|
|
2
|
-
|
|
3
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
4
|
-
|
|
5
|
-
function isFunction(value) {
|
|
6
|
-
return typeof value === 'function';
|
|
7
|
-
}
|
|
8
|
-
|
|
9
|
-
function optionalFunctionValue(value) {
|
|
10
|
-
var args = [];
|
|
11
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
12
|
-
args[_i - 1] = arguments[_i];
|
|
13
|
-
}
|
|
14
|
-
return isFunction(value) ? value.apply(void 0, args) : value;
|
|
15
|
-
}
|
|
16
|
-
|
|
17
|
-
// eslint-disable-next-line max-lines-per-function
|
|
18
|
-
function createState(onStateChange) {
|
|
19
|
-
var state = {
|
|
20
|
-
references: []
|
|
21
|
-
};
|
|
22
|
-
var registrations = [];
|
|
23
|
-
return {
|
|
24
|
-
registerStateKey: registerStateKey,
|
|
25
|
-
reset: reset
|
|
26
|
-
};
|
|
27
|
-
/**
|
|
28
|
-
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
29
|
-
*
|
|
30
|
-
* @example
|
|
31
|
-
*
|
|
32
|
-
* const useColor = state.registerStateKey("blue");
|
|
33
|
-
*
|
|
34
|
-
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
35
|
-
*
|
|
36
|
-
* setColor("green");
|
|
37
|
-
*
|
|
38
|
-
* useColor()[0]; -> "green"
|
|
39
|
-
*/
|
|
40
|
-
function registerStateKey(initialState, onUpdate) {
|
|
41
|
-
var key = registrations.length;
|
|
42
|
-
registrations.push([initialState, onUpdate]);
|
|
43
|
-
return initKey(key, initialState);
|
|
44
|
-
}
|
|
45
|
-
function reset() {
|
|
46
|
-
var prev = current();
|
|
47
|
-
state.references = [];
|
|
48
|
-
registrations.forEach(function (_a, index) {
|
|
49
|
-
var initialValue = _a[0];
|
|
50
|
-
return initKey(index, initialValue, prev[index]);
|
|
51
|
-
});
|
|
52
|
-
}
|
|
53
|
-
function initKey(key, initialState, prevState) {
|
|
54
|
-
current().push();
|
|
55
|
-
set(key, optionalFunctionValue(initialState, prevState));
|
|
56
|
-
return function useStateKey() {
|
|
57
|
-
return [
|
|
58
|
-
current()[key],
|
|
59
|
-
function (nextState) {
|
|
60
|
-
return set(key, optionalFunctionValue(nextState, current()[key]));
|
|
61
|
-
},
|
|
62
|
-
];
|
|
63
|
-
};
|
|
64
|
-
}
|
|
65
|
-
function current() {
|
|
66
|
-
return state.references;
|
|
67
|
-
}
|
|
68
|
-
function set(index, value) {
|
|
69
|
-
var prevValue = state.references[index];
|
|
70
|
-
state.references[index] = value;
|
|
71
|
-
var _a = registrations[index], onUpdate = _a[1];
|
|
72
|
-
if (isFunction(onUpdate)) {
|
|
73
|
-
onUpdate(value, prevValue);
|
|
74
|
-
}
|
|
75
|
-
if (isFunction(onStateChange)) {
|
|
76
|
-
onStateChange();
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
exports.createState = createState;
|
package/dist/cjs/vast.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";function e(e){return"function"==typeof e}function r(r){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return e(r)?r.apply(void 0,n):r}Object.defineProperty(exports,"__esModule",{value:!0}),exports.createState=function(n){function t(e,n,t){return c.references.push(),u(e,r(n,t)),function(){return[c.references[e],function(n){return u(e,r(n,c.references[e]))}]}}function u(r,t){var u=c.references[r];c.references[r]=t,e(r=f[r][1])&&r(t,u),e(n)&&n()}var c={references:[]},f=[];return{registerStateKey:function(e,r){var n=f.length;return f.push([e,r]),t(n,e)},reset:function(){var e=c.references;c.references=[],f.forEach((function(r,n){return t(n,r[0],e[n])}))}}};
|
package/dist/es/package.json
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"type":"module"}
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
function isFunction(value) {
|
|
2
|
-
return typeof value === 'function';
|
|
3
|
-
}
|
|
4
|
-
|
|
5
|
-
function optionalFunctionValue(value) {
|
|
6
|
-
var args = [];
|
|
7
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
8
|
-
args[_i - 1] = arguments[_i];
|
|
9
|
-
}
|
|
10
|
-
return isFunction(value) ? value.apply(void 0, args) : value;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
// eslint-disable-next-line max-lines-per-function
|
|
14
|
-
function createState(onStateChange) {
|
|
15
|
-
var state = {
|
|
16
|
-
references: []
|
|
17
|
-
};
|
|
18
|
-
var registrations = [];
|
|
19
|
-
return {
|
|
20
|
-
registerStateKey: registerStateKey,
|
|
21
|
-
reset: reset
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
25
|
-
*
|
|
26
|
-
* @example
|
|
27
|
-
*
|
|
28
|
-
* const useColor = state.registerStateKey("blue");
|
|
29
|
-
*
|
|
30
|
-
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
31
|
-
*
|
|
32
|
-
* setColor("green");
|
|
33
|
-
*
|
|
34
|
-
* useColor()[0]; -> "green"
|
|
35
|
-
*/
|
|
36
|
-
function registerStateKey(initialState, onUpdate) {
|
|
37
|
-
var key = registrations.length;
|
|
38
|
-
registrations.push([initialState, onUpdate]);
|
|
39
|
-
return initKey(key, initialState);
|
|
40
|
-
}
|
|
41
|
-
function reset() {
|
|
42
|
-
var prev = current();
|
|
43
|
-
state.references = [];
|
|
44
|
-
registrations.forEach(function (_a, index) {
|
|
45
|
-
var initialValue = _a[0];
|
|
46
|
-
return initKey(index, initialValue, prev[index]);
|
|
47
|
-
});
|
|
48
|
-
}
|
|
49
|
-
function initKey(key, initialState, prevState) {
|
|
50
|
-
current().push();
|
|
51
|
-
set(key, optionalFunctionValue(initialState, prevState));
|
|
52
|
-
return function useStateKey() {
|
|
53
|
-
return [
|
|
54
|
-
current()[key],
|
|
55
|
-
function (nextState) {
|
|
56
|
-
return set(key, optionalFunctionValue(nextState, current()[key]));
|
|
57
|
-
},
|
|
58
|
-
];
|
|
59
|
-
};
|
|
60
|
-
}
|
|
61
|
-
function current() {
|
|
62
|
-
return state.references;
|
|
63
|
-
}
|
|
64
|
-
function set(index, value) {
|
|
65
|
-
var prevValue = state.references[index];
|
|
66
|
-
state.references[index] = value;
|
|
67
|
-
var _a = registrations[index], onUpdate = _a[1];
|
|
68
|
-
if (isFunction(onUpdate)) {
|
|
69
|
-
onUpdate(value, prevValue);
|
|
70
|
-
}
|
|
71
|
-
if (isFunction(onStateChange)) {
|
|
72
|
-
onStateChange();
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
|
|
77
|
-
export { createState };
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
function e(e){return"function"==typeof e}function r(r){for(var n=[],t=1;t<arguments.length;t++)n[t-1]=arguments[t];return e(r)?r.apply(void 0,n):r}export function createState(n){function t(e,n,t){return c.references.push(),f(e,r(n,t)),function(){return[c.references[e],function(n){return f(e,r(n,c.references[e]))}]}}function f(r,t){var f=c.references[r];c.references[r]=t,e(r=u[r][1])&&r(t,f),e(n)&&n()}var c={references:[]},u=[];return{registerStateKey:function(e,r){var n=u.length;return u.push([e,r]),t(n,e)},reset:function(){var e=c.references;c.references=[],u.forEach((function(r,n){return t(n,r[0],e[n])}))}}}
|
|
@@ -1,87 +0,0 @@
|
|
|
1
|
-
(function (global, factory) {
|
|
2
|
-
typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :
|
|
3
|
-
typeof define === 'function' && define.amd ? define(['exports'], factory) :
|
|
4
|
-
(global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vast = {}));
|
|
5
|
-
}(this, (function (exports) { 'use strict';
|
|
6
|
-
|
|
7
|
-
function isFunction(value) {
|
|
8
|
-
return typeof value === 'function';
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
function optionalFunctionValue(value) {
|
|
12
|
-
var args = [];
|
|
13
|
-
for (var _i = 1; _i < arguments.length; _i++) {
|
|
14
|
-
args[_i - 1] = arguments[_i];
|
|
15
|
-
}
|
|
16
|
-
return isFunction(value) ? value.apply(void 0, args) : value;
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
// eslint-disable-next-line max-lines-per-function
|
|
20
|
-
function createState(onStateChange) {
|
|
21
|
-
var state = {
|
|
22
|
-
references: []
|
|
23
|
-
};
|
|
24
|
-
var registrations = [];
|
|
25
|
-
return {
|
|
26
|
-
registerStateKey: registerStateKey,
|
|
27
|
-
reset: reset
|
|
28
|
-
};
|
|
29
|
-
/**
|
|
30
|
-
* Registers a new key in the state, takes the initial value (may be a function that returns the initial value), returns a function.
|
|
31
|
-
*
|
|
32
|
-
* @example
|
|
33
|
-
*
|
|
34
|
-
* const useColor = state.registerStateKey("blue");
|
|
35
|
-
*
|
|
36
|
-
* let [color, setColor] = useColor(); // -> ["blue", Function]
|
|
37
|
-
*
|
|
38
|
-
* setColor("green");
|
|
39
|
-
*
|
|
40
|
-
* useColor()[0]; -> "green"
|
|
41
|
-
*/
|
|
42
|
-
function registerStateKey(initialState, onUpdate) {
|
|
43
|
-
var key = registrations.length;
|
|
44
|
-
registrations.push([initialState, onUpdate]);
|
|
45
|
-
return initKey(key, initialState);
|
|
46
|
-
}
|
|
47
|
-
function reset() {
|
|
48
|
-
var prev = current();
|
|
49
|
-
state.references = [];
|
|
50
|
-
registrations.forEach(function (_a, index) {
|
|
51
|
-
var initialValue = _a[0];
|
|
52
|
-
return initKey(index, initialValue, prev[index]);
|
|
53
|
-
});
|
|
54
|
-
}
|
|
55
|
-
function initKey(key, initialState, prevState) {
|
|
56
|
-
current().push();
|
|
57
|
-
set(key, optionalFunctionValue(initialState, prevState));
|
|
58
|
-
return function useStateKey() {
|
|
59
|
-
return [
|
|
60
|
-
current()[key],
|
|
61
|
-
function (nextState) {
|
|
62
|
-
return set(key, optionalFunctionValue(nextState, current()[key]));
|
|
63
|
-
},
|
|
64
|
-
];
|
|
65
|
-
};
|
|
66
|
-
}
|
|
67
|
-
function current() {
|
|
68
|
-
return state.references;
|
|
69
|
-
}
|
|
70
|
-
function set(index, value) {
|
|
71
|
-
var prevValue = state.references[index];
|
|
72
|
-
state.references[index] = value;
|
|
73
|
-
var _a = registrations[index], onUpdate = _a[1];
|
|
74
|
-
if (isFunction(onUpdate)) {
|
|
75
|
-
onUpdate(value, prevValue);
|
|
76
|
-
}
|
|
77
|
-
if (isFunction(onStateChange)) {
|
|
78
|
-
onStateChange();
|
|
79
|
-
}
|
|
80
|
-
}
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
exports.createState = createState;
|
|
84
|
-
|
|
85
|
-
Object.defineProperty(exports, '__esModule', { value: true });
|
|
86
|
-
|
|
87
|
-
})));
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";!function(e,n){"object"==typeof exports&&"undefined"!=typeof module?n(exports):"function"==typeof define&&define.amd?define(["exports"],n):n((e="undefined"!=typeof globalThis?globalThis:e||self).vast={})}(this,(function(e){function n(e){return"function"==typeof e}function r(e){for(var r=[],t=1;t<arguments.length;t++)r[t-1]=arguments[t];return n(e)?e.apply(void 0,r):e}e.createState=function(e){function t(e,n,t){return o.references.push(),f(e,r(n,t)),function(){return[o.references[e],function(n){return f(e,r(n,o.references[e]))}]}}function f(r,t){var f=o.references[r];o.references[r]=t,n(r=u[r][1])&&r(t,f),n(e)&&e()}var o={references:[]},u=[];return{registerStateKey:function(e,n){var r=u.length;return u.push([e,n]),t(r,e)},reset:function(){var e=o.references;o.references=[],u.forEach((function(n,r){return t(r,n[0],e[r])}))}}},Object.defineProperty(e,"__esModule",{value:!0})}));
|