@yaasl/core 0.9.1 → 0.10.0-alpha.0
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/dist/@types/base/Stateful.d.ts +1 -0
- package/dist/@types/base/config.d.ts +3 -0
- package/dist/@types/base/createActions.d.ts +1 -1
- package/dist/@types/base/createAtom.d.ts +6 -15
- package/dist/@types/base/createDerived.d.ts +1 -1
- package/dist/@types/base/createSelector.d.ts +13 -12
- package/dist/@types/base/createSlice.d.ts +35 -0
- package/dist/@types/base/index.d.ts +2 -0
- package/dist/@types/effects/createEffect.d.ts +1 -1
- package/dist/@types/effects/index.d.ts +1 -1
- package/dist/cjs/base/Stateful.js +1 -0
- package/dist/cjs/base/config.js +1 -0
- package/dist/cjs/base/createActions.js +1 -1
- package/dist/cjs/base/createAtom.js +4 -11
- package/dist/cjs/base/createSlice.js +38 -0
- package/dist/cjs/base/index.js +2 -0
- package/dist/mjs/base/Stateful.js +4 -2
- package/dist/mjs/base/config.js +1 -0
- package/dist/mjs/base/createActions.js +1 -1
- package/dist/mjs/base/createAtom.js +8 -11
- package/dist/mjs/base/createDerived.js +6 -4
- package/dist/mjs/base/createSlice.js +34 -0
- package/dist/mjs/base/index.js +2 -0
- package/dist/mjs/effects/EffectDispatcher.js +3 -3
- package/dist/mjs/utils/Expiration.js +9 -7
- package/dist/mjs/utils/LocalStorage.js +2 -0
- package/dist/mjs/utils/Scheduler.js +1 -3
- package/dist/mjs/utils/Store.js +2 -0
- package/package.json +3 -3
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
type Callback<Value> = (value: Value, previous: Value) => void;
|
|
2
2
|
export declare class Stateful<Value = unknown> {
|
|
3
3
|
protected value: Value;
|
|
4
|
+
/** Promise that resolves when the states initialization was finished. */
|
|
4
5
|
didInit: PromiseLike<void> | boolean;
|
|
5
6
|
private listeners;
|
|
6
7
|
constructor(value: Value);
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { EffectAtomCallback } from "../effects/createEffect";
|
|
1
2
|
interface Config {
|
|
2
3
|
/** Global name to make internal keys unique
|
|
3
4
|
* among UIs on the same domain.
|
|
@@ -6,6 +7,8 @@ interface Config {
|
|
|
6
7
|
* "{config-name}/{atom-name}")
|
|
7
8
|
**/
|
|
8
9
|
name?: string;
|
|
10
|
+
/** Global effects to apply on all atoms. (e.g. reduxDevtools) */
|
|
11
|
+
globalEffects: EffectAtomCallback<any>[];
|
|
9
12
|
}
|
|
10
13
|
/** Global configuration object to change internal behavior of yaasl.
|
|
11
14
|
*
|
|
@@ -12,7 +12,7 @@ export type Actions<State, R extends Reducers<State>> = {
|
|
|
12
12
|
/** Create actions to change the state of an atom.
|
|
13
13
|
*
|
|
14
14
|
* @param atom Atom to be used.
|
|
15
|
-
* @param reducers Reducers for custom actions to set the
|
|
15
|
+
* @param reducers Reducers for custom actions to set the atom's value.
|
|
16
16
|
*
|
|
17
17
|
* @returns Actions to change the state of the atom.
|
|
18
18
|
*
|
|
@@ -1,22 +1,20 @@
|
|
|
1
1
|
import { SetStateAction } from "@yaasl/utils";
|
|
2
|
-
import { Actions, Reducers } from "./createActions";
|
|
3
2
|
import { Stateful } from "./Stateful";
|
|
4
3
|
import { EffectAtomCallback } from "../effects/createEffect";
|
|
5
|
-
export interface AtomConfig<Value
|
|
4
|
+
export interface AtomConfig<Value> {
|
|
6
5
|
/** Value that will be used initially. */
|
|
7
6
|
defaultValue: Value;
|
|
8
7
|
/** Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}". */
|
|
9
8
|
name?: string;
|
|
10
9
|
/** Effects that will be applied on the atom. */
|
|
11
10
|
effects?: EffectAtomCallback<any>[];
|
|
12
|
-
/** Reducers for custom actions to set the atom's value. */
|
|
13
|
-
reducers?: R;
|
|
14
11
|
}
|
|
15
|
-
export declare class Atom<Value = unknown
|
|
12
|
+
export declare class Atom<Value = unknown> extends Stateful<Value> {
|
|
13
|
+
/** Default value of the atom. */
|
|
16
14
|
readonly defaultValue: Value;
|
|
15
|
+
/** Identifier of the atom. */
|
|
17
16
|
readonly name: string;
|
|
18
|
-
|
|
19
|
-
constructor({ defaultValue, name, effects, reducers, }: AtomConfig<Value, R>);
|
|
17
|
+
constructor({ defaultValue, name, effects: localEffects, }: AtomConfig<Value>);
|
|
20
18
|
/** Set the value of the atom.
|
|
21
19
|
*
|
|
22
20
|
* @param next New value or function to create the
|
|
@@ -29,14 +27,7 @@ export declare class Atom<Value = unknown, R extends Reducers<Value> = Reducers<
|
|
|
29
27
|
* @param config.defaultValue Value that will be used initially.
|
|
30
28
|
* @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
|
|
31
29
|
* @param config.effects Effects that will be applied on the atom.
|
|
32
|
-
* @param config.reducers Reducers for custom actions to set the atom's value.
|
|
33
30
|
*
|
|
34
31
|
* @returns An atom instance.
|
|
35
|
-
* - `result.get`: Read the value of state.
|
|
36
|
-
* - `result.subscribe`: Subscribe to value changes.
|
|
37
|
-
* - `result.set`: Set the value of the atom.
|
|
38
|
-
* - `result.actions`: All actions that were created with reducers.
|
|
39
|
-
* - `result.didInit`: State of the atom's effects initialization process.
|
|
40
|
-
* Will be a promise if the initialization is pending and `true` if finished.
|
|
41
32
|
**/
|
|
42
|
-
export declare const createAtom: <Value
|
|
33
|
+
export declare const createAtom: <Value>(config: AtomConfig<Value>) => Atom<Value>;
|
|
@@ -17,7 +17,7 @@ export declare class Derive<Value> extends Stateful<Value> {
|
|
|
17
17
|
}
|
|
18
18
|
export declare class SettableDerive<Value = unknown> extends Derive<Value> {
|
|
19
19
|
private readonly setter;
|
|
20
|
-
protected readonly setterDependencies: Set<Atom<any
|
|
20
|
+
protected readonly setterDependencies: Set<Atom<any> | SettableDerive<any>>;
|
|
21
21
|
constructor(getter: GetterFn<Value>, setter: SetterFn<Value>);
|
|
22
22
|
/** Set the value of the derived atom.
|
|
23
23
|
*
|
|
@@ -1,15 +1,16 @@
|
|
|
1
|
+
import { Prettify } from "@yaasl/utils";
|
|
1
2
|
import { Stateful } from "./Stateful";
|
|
2
|
-
type
|
|
3
|
-
type
|
|
4
|
-
[K in keyof
|
|
5
|
-
}[keyof
|
|
6
|
-
type
|
|
7
|
-
export declare class PathSelector<
|
|
8
|
-
constructor(atom: Stateful<
|
|
3
|
+
type PathableValue = Record<string | number, unknown>;
|
|
4
|
+
export type ObjPath<Obj> = Prettify<Obj> extends PathableValue ? {
|
|
5
|
+
[K in keyof Obj]: `${Exclude<K, symbol>}${"" | `.${ObjPath<Obj[K]>}`}`;
|
|
6
|
+
}[keyof Obj] : never;
|
|
7
|
+
type ObjPathValue<State, Path> = State extends PathableValue ? Path extends `${infer Current}.${infer Next}` ? ObjPathValue<State[Current], Next> : State[Path & string] : never;
|
|
8
|
+
export declare class PathSelector<ParentValue, Path extends ObjPath<ParentValue>> extends Stateful<ObjPathValue<ParentValue, Path>> {
|
|
9
|
+
constructor(atom: Stateful<ParentValue>, path: Path);
|
|
9
10
|
}
|
|
10
|
-
type InferValuesFromAtoms<
|
|
11
|
-
export declare class CombinerSelector<
|
|
12
|
-
constructor(atoms:
|
|
11
|
+
type InferValuesFromAtoms<ParentAtoms extends readonly unknown[], ParentValues extends unknown[] = []> = ParentAtoms extends [Stateful<infer Value>, ...infer Rest] ? InferValuesFromAtoms<Rest, [...ParentValues, Value]> : ParentValues;
|
|
12
|
+
export declare class CombinerSelector<ParentAtoms extends [Stateful<any>, ...Stateful<any>[]], CombinedValue> extends Stateful<CombinedValue> {
|
|
13
|
+
constructor(atoms: ParentAtoms, combiner: (...res: InferValuesFromAtoms<ParentAtoms>) => CombinedValue);
|
|
13
14
|
}
|
|
14
15
|
interface CreateSelectorOverloads {
|
|
15
16
|
/** Creates a value, selected from one atom with an object value by using a key path.
|
|
@@ -19,7 +20,7 @@ interface CreateSelectorOverloads {
|
|
|
19
20
|
*
|
|
20
21
|
* @returns A PathSelector instance.
|
|
21
22
|
**/
|
|
22
|
-
<
|
|
23
|
+
<ParentValue, Path extends ObjPath<ParentValue>>(atom: Stateful<ParentValue>, path: Path): PathSelector<ParentValue, Path>;
|
|
23
24
|
/** Creates a value, selected from one atom with an object value by using a key path.
|
|
24
25
|
*
|
|
25
26
|
* @param atoms Atoms you need to combine to receive the new value.
|
|
@@ -27,7 +28,7 @@ interface CreateSelectorOverloads {
|
|
|
27
28
|
*
|
|
28
29
|
* @returns A CombinerSelector instance.
|
|
29
30
|
**/
|
|
30
|
-
<
|
|
31
|
+
<ParentAtoms extends [Stateful<any>, ...Stateful<any>[]], CombinedValue>(states: ParentAtoms, combiner: (...res: InferValuesFromAtoms<ParentAtoms>) => CombinedValue): CombinerSelector<ParentAtoms, CombinedValue>;
|
|
31
32
|
}
|
|
32
33
|
export declare const createSelector: CreateSelectorOverloads;
|
|
33
34
|
export {};
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { Actions, Reducers } from "./createActions";
|
|
2
|
+
import { Atom, AtomConfig } from "./createAtom";
|
|
3
|
+
import { CombinerSelector, ObjPath, PathSelector } from "./createSelector";
|
|
4
|
+
interface ReducersProp<State, R extends Reducers<State> | undefined> {
|
|
5
|
+
/** Reducers for custom actions to set the atom's value. */
|
|
6
|
+
reducers?: R;
|
|
7
|
+
}
|
|
8
|
+
type Selectors<State> = Record<string, ObjPath<State> | ((state: State) => any)>;
|
|
9
|
+
type ConditionalActions<State, R> = keyof R extends never ? {} : R extends Reducers<State> ? {
|
|
10
|
+
/** Actions that can be used to set the atom's value. */
|
|
11
|
+
actions: Actions<State, R>;
|
|
12
|
+
} : {};
|
|
13
|
+
interface SelectorsProp<State, S extends Selectors<State> | undefined> {
|
|
14
|
+
/** Selectors to create values from the atom. */
|
|
15
|
+
selectors?: S;
|
|
16
|
+
}
|
|
17
|
+
type GetSelector<State, S extends ObjPath<State> | ((state: State) => any)> = S extends ObjPath<State> ? PathSelector<State, S> : S extends (state: State) => any ? CombinerSelector<[Atom<State>], ReturnType<S>> : never;
|
|
18
|
+
type ConditionalSelectors<State, S> = keyof S extends never ? {} : S extends Selectors<State> ? {
|
|
19
|
+
/** Selectors to create new values based on the atom's value. */
|
|
20
|
+
selectors: {
|
|
21
|
+
[K in keyof S]: GetSelector<State, S[K]>;
|
|
22
|
+
};
|
|
23
|
+
} : {};
|
|
24
|
+
/** Creates a slice with actions and selectors.
|
|
25
|
+
*
|
|
26
|
+
* @param config.defaultValue Value that will be used initially.
|
|
27
|
+
* @param config.name Name of the atom.
|
|
28
|
+
* @param config.effects Effects that will be applied on the atom.
|
|
29
|
+
* @param config.reducers Reducers for custom actions to set the atom's value.
|
|
30
|
+
* @param config.selectors Path or combiner selectors to use the atom's values to create new ones.
|
|
31
|
+
*
|
|
32
|
+
* @returns An atom instance with actions and selectors.
|
|
33
|
+
**/
|
|
34
|
+
export declare const createSlice: <State, R extends Reducers<State> | undefined, S extends Selectors<State> | undefined>(config: AtomConfig<State> & ReducersProp<State, R> & SelectorsProp<State, S>) => Atom<State> & ConditionalActions<State, R> & ConditionalSelectors<State, S>;
|
|
35
|
+
export {};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Atom } from "../base";
|
|
2
2
|
export type ActionType = "init" | "didInit" | "set";
|
|
3
|
-
interface EffectPayload<Options, AtomValue> {
|
|
3
|
+
export interface EffectPayload<Options = undefined, AtomValue = any> {
|
|
4
4
|
value: AtomValue;
|
|
5
5
|
atom: Atom<AtomValue>;
|
|
6
6
|
options: Options;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export { createEffect } from "./createEffect";
|
|
2
|
-
export type { Effect } from "./createEffect";
|
|
2
|
+
export type { Effect, EffectPayload } from "./createEffect";
|
|
3
3
|
export { localStorage } from "./localStorage";
|
|
4
4
|
export type { LocalStorageOptions, LocalStorageParser } from "./localStorage";
|
|
5
5
|
export { indexedDb } from "./indexedDb";
|
package/dist/cjs/base/config.js
CHANGED
|
@@ -4,7 +4,7 @@ exports.createActions = void 0;
|
|
|
4
4
|
/** Create actions to change the state of an atom.
|
|
5
5
|
*
|
|
6
6
|
* @param atom Atom to be used.
|
|
7
|
-
* @param reducers Reducers for custom actions to set the
|
|
7
|
+
* @param reducers Reducers for custom actions to set the atom's value.
|
|
8
8
|
*
|
|
9
9
|
* @returns Actions to change the state of the atom.
|
|
10
10
|
*
|
|
@@ -1,17 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
3
|
exports.createAtom = exports.Atom = void 0;
|
|
4
|
-
const
|
|
4
|
+
const config_1 = require("./config");
|
|
5
5
|
const Stateful_1 = require("./Stateful");
|
|
6
6
|
const EffectDispatcher_1 = require("../effects/EffectDispatcher");
|
|
7
7
|
let key = 0;
|
|
8
8
|
class Atom extends Stateful_1.Stateful {
|
|
9
|
-
constructor({ defaultValue, name = `atom-${++key}`, effects
|
|
9
|
+
constructor({ defaultValue, name = `atom-${++key}`, effects: localEffects = [], }) {
|
|
10
10
|
super(defaultValue);
|
|
11
11
|
this.name = name;
|
|
12
12
|
this.defaultValue = defaultValue;
|
|
13
|
-
|
|
14
|
-
if (
|
|
13
|
+
const effects = [...config_1.CONFIG.globalEffects, ...localEffects];
|
|
14
|
+
if (effects.length === 0) {
|
|
15
15
|
this.didInit = true;
|
|
16
16
|
return;
|
|
17
17
|
}
|
|
@@ -34,15 +34,8 @@ exports.Atom = Atom;
|
|
|
34
34
|
* @param config.defaultValue Value that will be used initially.
|
|
35
35
|
* @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
|
|
36
36
|
* @param config.effects Effects that will be applied on the atom.
|
|
37
|
-
* @param config.reducers Reducers for custom actions to set the atom's value.
|
|
38
37
|
*
|
|
39
38
|
* @returns An atom instance.
|
|
40
|
-
* - `result.get`: Read the value of state.
|
|
41
|
-
* - `result.subscribe`: Subscribe to value changes.
|
|
42
|
-
* - `result.set`: Set the value of the atom.
|
|
43
|
-
* - `result.actions`: All actions that were created with reducers.
|
|
44
|
-
* - `result.didInit`: State of the atom's effects initialization process.
|
|
45
|
-
* Will be a promise if the initialization is pending and `true` if finished.
|
|
46
39
|
**/
|
|
47
40
|
const createAtom = (config) => new Atom(config);
|
|
48
41
|
exports.createAtom = createAtom;
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.createSlice = void 0;
|
|
4
|
+
const createActions_1 = require("./createActions");
|
|
5
|
+
const createAtom_1 = require("./createAtom");
|
|
6
|
+
const createSelector_1 = require("./createSelector");
|
|
7
|
+
const isEmpty = (obj) => !obj || Object.keys(obj).length === 0;
|
|
8
|
+
const createSelectors = (atom, selectors) => Object.fromEntries(Object.entries(selectors).map(([key, selector]) => [
|
|
9
|
+
key,
|
|
10
|
+
typeof selector === "string"
|
|
11
|
+
? (0, createSelector_1.createSelector)(atom, selector)
|
|
12
|
+
: (0, createSelector_1.createSelector)([atom], selector),
|
|
13
|
+
]));
|
|
14
|
+
/** Creates a slice with actions and selectors.
|
|
15
|
+
*
|
|
16
|
+
* @param config.defaultValue Value that will be used initially.
|
|
17
|
+
* @param config.name Name of the atom.
|
|
18
|
+
* @param config.effects Effects that will be applied on the atom.
|
|
19
|
+
* @param config.reducers Reducers for custom actions to set the atom's value.
|
|
20
|
+
* @param config.selectors Path or combiner selectors to use the atom's values to create new ones.
|
|
21
|
+
*
|
|
22
|
+
* @returns An atom instance with actions and selectors.
|
|
23
|
+
**/
|
|
24
|
+
const createSlice = (config) => {
|
|
25
|
+
const atom = new createAtom_1.Atom(config);
|
|
26
|
+
const actionsProp = isEmpty(config.reducers)
|
|
27
|
+
? {}
|
|
28
|
+
: {
|
|
29
|
+
actions: (0, createActions_1.createActions)(atom, config.reducers),
|
|
30
|
+
};
|
|
31
|
+
const selectorsProp = isEmpty(config.selectors)
|
|
32
|
+
? {}
|
|
33
|
+
: {
|
|
34
|
+
selectors: createSelectors(atom, config.selectors),
|
|
35
|
+
};
|
|
36
|
+
return Object.assign(atom, actionsProp, selectorsProp);
|
|
37
|
+
};
|
|
38
|
+
exports.createSlice = createSlice;
|
package/dist/cjs/base/index.js
CHANGED
|
@@ -15,7 +15,9 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
|
15
15
|
};
|
|
16
16
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
17
|
__exportStar(require("./config"), exports);
|
|
18
|
+
__exportStar(require("./createActions"), exports);
|
|
18
19
|
__exportStar(require("./createAtom"), exports);
|
|
19
20
|
__exportStar(require("./createDerived"), exports);
|
|
20
21
|
__exportStar(require("./createSelector"), exports);
|
|
22
|
+
__exportStar(require("./createSlice"), exports);
|
|
21
23
|
__exportStar(require("./Stateful"), exports);
|
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
export class Stateful {
|
|
2
|
+
value;
|
|
3
|
+
/** Promise that resolves when the states initialization was finished. */
|
|
4
|
+
didInit = false;
|
|
5
|
+
listeners = new Set();
|
|
2
6
|
constructor(value) {
|
|
3
7
|
this.value = value;
|
|
4
|
-
this.didInit = false;
|
|
5
|
-
this.listeners = new Set();
|
|
6
8
|
}
|
|
7
9
|
/** Read the value of state.
|
|
8
10
|
*
|
package/dist/mjs/base/config.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/** Create actions to change the state of an atom.
|
|
2
2
|
*
|
|
3
3
|
* @param atom Atom to be used.
|
|
4
|
-
* @param reducers Reducers for custom actions to set the
|
|
4
|
+
* @param reducers Reducers for custom actions to set the atom's value.
|
|
5
5
|
*
|
|
6
6
|
* @returns Actions to change the state of the atom.
|
|
7
7
|
*
|
|
@@ -1,14 +1,18 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { CONFIG } from "./config";
|
|
2
2
|
import { Stateful } from "./Stateful";
|
|
3
3
|
import { EffectDispatcher } from "../effects/EffectDispatcher";
|
|
4
4
|
let key = 0;
|
|
5
5
|
export class Atom extends Stateful {
|
|
6
|
-
|
|
6
|
+
/** Default value of the atom. */
|
|
7
|
+
defaultValue;
|
|
8
|
+
/** Identifier of the atom. */
|
|
9
|
+
name;
|
|
10
|
+
constructor({ defaultValue, name = `atom-${++key}`, effects: localEffects = [], }) {
|
|
7
11
|
super(defaultValue);
|
|
8
12
|
this.name = name;
|
|
9
13
|
this.defaultValue = defaultValue;
|
|
10
|
-
|
|
11
|
-
if (
|
|
14
|
+
const effects = [...CONFIG.globalEffects, ...localEffects];
|
|
15
|
+
if (effects.length === 0) {
|
|
12
16
|
this.didInit = true;
|
|
13
17
|
return;
|
|
14
18
|
}
|
|
@@ -30,14 +34,7 @@ export class Atom extends Stateful {
|
|
|
30
34
|
* @param config.defaultValue Value that will be used initially.
|
|
31
35
|
* @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
|
|
32
36
|
* @param config.effects Effects that will be applied on the atom.
|
|
33
|
-
* @param config.reducers Reducers for custom actions to set the atom's value.
|
|
34
37
|
*
|
|
35
38
|
* @returns An atom instance.
|
|
36
|
-
* - `result.get`: Read the value of state.
|
|
37
|
-
* - `result.subscribe`: Subscribe to value changes.
|
|
38
|
-
* - `result.set`: Set the value of the atom.
|
|
39
|
-
* - `result.actions`: All actions that were created with reducers.
|
|
40
|
-
* - `result.didInit`: State of the atom's effects initialization process.
|
|
41
|
-
* Will be a promise if the initialization is pending and `true` if finished.
|
|
42
39
|
**/
|
|
43
40
|
export const createAtom = (config) => new Atom(config);
|
|
@@ -7,11 +7,12 @@ const allDidInit = (atoms) => {
|
|
|
7
7
|
return inits.length === 0 ? true : Promise.all(inits).then(toVoid);
|
|
8
8
|
};
|
|
9
9
|
export class Derive extends Stateful {
|
|
10
|
+
getter;
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
12
|
+
getterDependencies = new Set();
|
|
10
13
|
constructor(getter) {
|
|
11
14
|
super(undefined);
|
|
12
15
|
this.getter = getter;
|
|
13
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
14
|
-
this.getterDependencies = new Set();
|
|
15
16
|
this.value = getter({ get: dep => this.addGetDependency(dep) });
|
|
16
17
|
this.setDidInit(allDidInit(Array.from(this.getterDependencies)));
|
|
17
18
|
}
|
|
@@ -27,11 +28,12 @@ export class Derive extends Stateful {
|
|
|
27
28
|
}
|
|
28
29
|
}
|
|
29
30
|
export class SettableDerive extends Derive {
|
|
31
|
+
setter;
|
|
32
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
33
|
+
setterDependencies = new Set();
|
|
30
34
|
constructor(getter, setter) {
|
|
31
35
|
super(getter);
|
|
32
36
|
this.setter = setter;
|
|
33
|
-
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
34
|
-
this.setterDependencies = new Set();
|
|
35
37
|
setter({
|
|
36
38
|
value: this.get(),
|
|
37
39
|
set: dep => this.addSetDependency(dep),
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import { createActions } from "./createActions";
|
|
2
|
+
import { Atom } from "./createAtom";
|
|
3
|
+
import { createSelector, } from "./createSelector";
|
|
4
|
+
const isEmpty = (obj) => !obj || Object.keys(obj).length === 0;
|
|
5
|
+
const createSelectors = (atom, selectors) => Object.fromEntries(Object.entries(selectors).map(([key, selector]) => [
|
|
6
|
+
key,
|
|
7
|
+
typeof selector === "string"
|
|
8
|
+
? createSelector(atom, selector)
|
|
9
|
+
: createSelector([atom], selector),
|
|
10
|
+
]));
|
|
11
|
+
/** Creates a slice with actions and selectors.
|
|
12
|
+
*
|
|
13
|
+
* @param config.defaultValue Value that will be used initially.
|
|
14
|
+
* @param config.name Name of the atom.
|
|
15
|
+
* @param config.effects Effects that will be applied on the atom.
|
|
16
|
+
* @param config.reducers Reducers for custom actions to set the atom's value.
|
|
17
|
+
* @param config.selectors Path or combiner selectors to use the atom's values to create new ones.
|
|
18
|
+
*
|
|
19
|
+
* @returns An atom instance with actions and selectors.
|
|
20
|
+
**/
|
|
21
|
+
export const createSlice = (config) => {
|
|
22
|
+
const atom = new Atom(config);
|
|
23
|
+
const actionsProp = isEmpty(config.reducers)
|
|
24
|
+
? {}
|
|
25
|
+
: {
|
|
26
|
+
actions: createActions(atom, config.reducers),
|
|
27
|
+
};
|
|
28
|
+
const selectorsProp = isEmpty(config.selectors)
|
|
29
|
+
? {}
|
|
30
|
+
: {
|
|
31
|
+
selectors: createSelectors(atom, config.selectors),
|
|
32
|
+
};
|
|
33
|
+
return Object.assign(atom, actionsProp, selectorsProp);
|
|
34
|
+
};
|
package/dist/mjs/base/index.js
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
1
|
import { isPromiseLike } from "@yaasl/utils";
|
|
2
2
|
import { Scheduler } from "../utils/Scheduler";
|
|
3
3
|
export class EffectDispatcher {
|
|
4
|
+
didInit = false;
|
|
5
|
+
effects = [];
|
|
6
|
+
scheduler = new Scheduler();
|
|
4
7
|
constructor({ atom, effects }) {
|
|
5
|
-
this.didInit = false;
|
|
6
|
-
this.effects = [];
|
|
7
|
-
this.scheduler = new Scheduler();
|
|
8
8
|
this.effects = effects.map(create => create(atom));
|
|
9
9
|
this.callEffectAction("init", atom);
|
|
10
10
|
this.subscribeSetters(atom);
|
|
@@ -1,13 +1,9 @@
|
|
|
1
1
|
const STORAGE = window.localStorage;
|
|
2
2
|
export class Expiration {
|
|
3
|
+
key;
|
|
4
|
+
getExpiration;
|
|
5
|
+
timeout = null;
|
|
3
6
|
constructor({ key, expiresAt, expiresIn }) {
|
|
4
|
-
this.timeout = null;
|
|
5
|
-
this.dispatchExpiration = (expiresIn, onExpire) => {
|
|
6
|
-
this.timeout = setTimeout(() => {
|
|
7
|
-
onExpire();
|
|
8
|
-
this.remove();
|
|
9
|
-
}, expiresIn);
|
|
10
|
-
};
|
|
11
7
|
this.timeout = null;
|
|
12
8
|
this.key = key;
|
|
13
9
|
if (expiresAt) {
|
|
@@ -30,6 +26,12 @@ export class Expiration {
|
|
|
30
26
|
this.timeout = null;
|
|
31
27
|
}
|
|
32
28
|
}
|
|
29
|
+
dispatchExpiration = (expiresIn, onExpire) => {
|
|
30
|
+
this.timeout = setTimeout(() => {
|
|
31
|
+
onExpire();
|
|
32
|
+
this.remove();
|
|
33
|
+
}, expiresIn);
|
|
34
|
+
};
|
|
33
35
|
init(onExpire) {
|
|
34
36
|
if (!this.getExpiration)
|
|
35
37
|
return;
|
|
@@ -10,6 +10,8 @@ const syncOverBrowserTabs = (observingKey, onTabSync) => window.addEventListener
|
|
|
10
10
|
onTabSync(newValue);
|
|
11
11
|
});
|
|
12
12
|
export class LocalStorage {
|
|
13
|
+
key;
|
|
14
|
+
parser;
|
|
13
15
|
constructor(key, options = {}) {
|
|
14
16
|
this.key = key;
|
|
15
17
|
this.parser = options.parser ?? defaultParser;
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { toVoid, isPromiseLike, Thenable } from "@yaasl/utils";
|
|
2
2
|
export class Scheduler {
|
|
3
|
-
|
|
4
|
-
this.queue = null;
|
|
5
|
-
}
|
|
3
|
+
queue = null;
|
|
6
4
|
run(...tasks) {
|
|
7
5
|
const run = () => this.execute(tasks.flat()).then(toVoid);
|
|
8
6
|
const promise = this.queue ? this.queue.then(run) : run();
|
package/dist/mjs/utils/Store.js
CHANGED
|
@@ -3,6 +3,8 @@ const promisifyRequest = (request) => new Promise((resolve, reject) => {
|
|
|
3
3
|
request.onerror = () => reject(request.error);
|
|
4
4
|
});
|
|
5
5
|
export class Store {
|
|
6
|
+
name;
|
|
7
|
+
database;
|
|
6
8
|
constructor(name) {
|
|
7
9
|
this.name = name;
|
|
8
10
|
const openRequest = indexedDB.open(`${name}-database`);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yaasl/core",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.10.0-alpha.0",
|
|
4
4
|
"description": "yet another atomic store library (vanilla-js)",
|
|
5
5
|
"author": "PrettyCoffee",
|
|
6
6
|
"license": "MIT",
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"build": "run-s clean compile",
|
|
29
29
|
"clean": "rimraf ./dist",
|
|
30
30
|
"compile": "run-p compile:mjs compile:cjs compile:types",
|
|
31
|
-
"compile:mjs": "tsc -p ./tsconfig.node.json --outDir ./dist/mjs -m
|
|
31
|
+
"compile:mjs": "tsc -p ./tsconfig.node.json --outDir ./dist/mjs -m esnext -t esnext",
|
|
32
32
|
"compile:cjs": "tsc -p ./tsconfig.node.json --outDir ./dist/cjs -m commonjs -t es2015",
|
|
33
33
|
"compile:types": "tsc -p ./tsconfig.node.json --outDir ./dist/@types --declaration --emitDeclarationOnly",
|
|
34
34
|
"test": "vitest run",
|
|
@@ -38,7 +38,7 @@
|
|
|
38
38
|
"validate": "run-s lint test build"
|
|
39
39
|
},
|
|
40
40
|
"dependencies": {
|
|
41
|
-
"@yaasl/utils": "0.
|
|
41
|
+
"@yaasl/utils": "0.10.0-alpha.0"
|
|
42
42
|
},
|
|
43
43
|
"eslintConfig": {
|
|
44
44
|
"extends": [
|