@yaasl/core 0.8.0 → 0.9.1

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.
Files changed (50) hide show
  1. package/dist/@types/base/createActions.d.ts +31 -0
  2. package/dist/@types/base/createAtom.d.ts +42 -0
  3. package/dist/@types/base/{derive.d.ts → createDerived.d.ts} +4 -4
  4. package/dist/@types/base/createSelector.d.ts +33 -0
  5. package/dist/@types/base/index.d.ts +3 -3
  6. package/dist/@types/effects/EffectDispatcher.d.ts +15 -0
  7. package/dist/@types/effects/createEffect.d.ts +39 -0
  8. package/dist/@types/{middleware → effects}/expiration.d.ts +3 -3
  9. package/dist/@types/{middleware → effects}/index.d.ts +2 -2
  10. package/dist/@types/{middleware → effects}/indexedDb.d.ts +2 -2
  11. package/dist/@types/{middleware → effects}/localStorage.d.ts +2 -2
  12. package/dist/@types/{middleware → effects}/migration.d.ts +19 -3
  13. package/dist/@types/index.d.ts +1 -1
  14. package/dist/cjs/base/createActions.js +28 -0
  15. package/dist/cjs/base/createAtom.js +48 -0
  16. package/dist/cjs/base/{derive.js → createDerived.js} +3 -3
  17. package/dist/cjs/base/createSelector.js +46 -0
  18. package/dist/cjs/base/index.js +3 -3
  19. package/dist/cjs/{middleware/MiddlewareDispatcher.js → effects/EffectDispatcher.js} +11 -11
  20. package/dist/cjs/effects/createEffect.js +27 -0
  21. package/dist/cjs/{middleware → effects}/expiration.js +4 -4
  22. package/dist/cjs/{middleware → effects}/index.js +3 -3
  23. package/dist/cjs/{middleware → effects}/indexedDb.js +3 -3
  24. package/dist/cjs/{middleware → effects}/localStorage.js +3 -3
  25. package/dist/cjs/{middleware → effects}/migration.js +18 -2
  26. package/dist/cjs/index.js +1 -1
  27. package/dist/mjs/base/createActions.js +24 -0
  28. package/dist/mjs/base/createAtom.js +43 -0
  29. package/dist/mjs/base/{derive.js → createDerived.js} +1 -1
  30. package/dist/mjs/base/createSelector.js +40 -0
  31. package/dist/mjs/base/index.js +3 -3
  32. package/dist/mjs/{middleware/MiddlewareDispatcher.js → effects/EffectDispatcher.js} +9 -9
  33. package/dist/mjs/effects/createEffect.js +23 -0
  34. package/dist/mjs/{middleware → effects}/expiration.js +4 -4
  35. package/dist/mjs/{middleware → effects}/index.js +1 -1
  36. package/dist/mjs/{middleware → effects}/indexedDb.js +3 -3
  37. package/dist/mjs/{middleware → effects}/localStorage.js +3 -3
  38. package/dist/mjs/{middleware → effects}/migration.js +18 -2
  39. package/dist/mjs/index.js +1 -1
  40. package/package.json +2 -2
  41. package/dist/@types/base/atom.d.ts +0 -33
  42. package/dist/@types/base/select.d.ts +0 -20
  43. package/dist/@types/middleware/MiddlewareDispatcher.d.ts +0 -15
  44. package/dist/@types/middleware/middleware.d.ts +0 -31
  45. package/dist/cjs/base/atom.js +0 -47
  46. package/dist/cjs/base/select.js +0 -26
  47. package/dist/cjs/middleware/middleware.js +0 -19
  48. package/dist/mjs/base/atom.js +0 -42
  49. package/dist/mjs/base/select.js +0 -21
  50. package/dist/mjs/middleware/middleware.js +0 -15
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createMigrationStep = exports.migration = void 0;
4
4
  const utils_1 = require("@yaasl/utils");
5
- const middleware_1 = require("./middleware");
5
+ const createEffect_1 = require("./createEffect");
6
6
  const base_1 = require("../base");
7
7
  const sortMigrations = (migrations) => {
8
8
  const first = migrations.find(migration => migration.previous === null);
@@ -58,7 +58,17 @@ const performMigration = (atom, version, migrations) => {
58
58
  return migrateVersion(atom, data, migration);
59
59
  }, currentState);
60
60
  };
61
- exports.migration = (0, middleware_1.middleware)({
61
+ /** Effect to migrate the persisted value of an atom to a newer version.
62
+ * You can use the `createMigrationStep` helper to create migration steps.
63
+ *
64
+ * @param {MigrationOptions} options
65
+ * @param options.steps An array of migration steps to perform for outdated values.
66
+ *
67
+ * __Note:__ One step must have a `previous` version set to null as entry point.
68
+ *
69
+ * @returns The effect to be used on atoms.
70
+ **/
71
+ exports.migration = (0, createEffect_1.createEffect)({
62
72
  didInit: ({ atom, options }) => {
63
73
  var _a, _b;
64
74
  const steps = sortMigrations(options.steps);
@@ -87,5 +97,11 @@ exports.migration = (0, middleware_1.middleware)({
87
97
  atom.set(data);
88
98
  },
89
99
  });
100
+ /** Helper to create a step for the migration effect.
101
+ *
102
+ * @param migration Migration step to create.
103
+ *
104
+ * @returns The migration step.
105
+ **/
90
106
  const createMigrationStep = (migration) => migration;
91
107
  exports.createMigrationStep = createMigrationStep;
package/dist/cjs/index.js CHANGED
@@ -15,4 +15,4 @@ var __exportStar = (this && this.__exportStar) || function(m, exports) {
15
15
  };
16
16
  Object.defineProperty(exports, "__esModule", { value: true });
17
17
  __exportStar(require("./base"), exports);
18
- __exportStar(require("./middleware"), exports);
18
+ __exportStar(require("./effects"), exports);
@@ -0,0 +1,24 @@
1
+ /** Create actions to change the state of an atom.
2
+ *
3
+ * @param atom Atom to be used.
4
+ * @param reducers Reducers for custom actions to set the atoms value.
5
+ *
6
+ * @returns Actions to change the state of the atom.
7
+ *
8
+ * @example
9
+ * const counter = createAtom({ defaultValue: 0 })
10
+ * const actions = createActions(counter, {
11
+ * increment: (state) => state + 1,
12
+ * decrement: (state) => state - 1,
13
+ * add: (state, value: number) => state + value,
14
+ * subtract: (state, value: number) => state - value,
15
+ * })
16
+ * actions.increment()
17
+ * actions.add(5)
18
+ **/
19
+ export const createActions = (atom, reducers) => Object.entries(reducers).reduce((result, [key, reducerFn]) => {
20
+ result[key] = (...payloadArgs) => {
21
+ atom.set((state) => reducerFn(state, ...payloadArgs));
22
+ };
23
+ return result;
24
+ }, {});
@@ -0,0 +1,43 @@
1
+ import { createActions } from "./createActions";
2
+ import { Stateful } from "./Stateful";
3
+ import { EffectDispatcher } from "../effects/EffectDispatcher";
4
+ let key = 0;
5
+ export class Atom extends Stateful {
6
+ constructor({ defaultValue, name = `atom-${++key}`, effects, reducers = {}, }) {
7
+ super(defaultValue);
8
+ this.name = name;
9
+ this.defaultValue = defaultValue;
10
+ this.actions = createActions(this, reducers);
11
+ if (!effects || effects.length === 0) {
12
+ this.didInit = true;
13
+ return;
14
+ }
15
+ const { didInit } = new EffectDispatcher({ atom: this, effects });
16
+ this.setDidInit(didInit);
17
+ }
18
+ /** Set the value of the atom.
19
+ *
20
+ * @param next New value or function to create the
21
+ * new value based off the previous value.
22
+ */
23
+ set(next) {
24
+ const value = next instanceof Function ? next(this.get()) : next;
25
+ super.update(value);
26
+ }
27
+ }
28
+ /** Creates an atom store.
29
+ *
30
+ * @param config.defaultValue Value that will be used initially.
31
+ * @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
32
+ * @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
+ *
35
+ * @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
+ **/
43
+ export const createAtom = (config) => new Atom(config);
@@ -68,7 +68,7 @@ export class SettableDerive extends Derive {
68
68
  return Array.from(setterDependencies).every(dependency => getterDependencies.has(dependency));
69
69
  }
70
70
  }
71
- export function derive(getter, setter) {
71
+ export function createDerived(getter, setter) {
72
72
  if (setter) {
73
73
  return new SettableDerive(getter, setter);
74
74
  }
@@ -0,0 +1,40 @@
1
+ import { toVoid } from "@yaasl/utils";
2
+ import { Stateful } from "./Stateful";
3
+ const selectPath = (state, path) => path
4
+ .split(".")
5
+ .reduce((result, key) => result[key], state);
6
+ export class PathSelector extends Stateful {
7
+ constructor(atom, path) {
8
+ super(selectPath(atom.get(), path));
9
+ atom.subscribe(state => this.update(selectPath(state, path)));
10
+ this.setDidInit(atom.didInit);
11
+ }
12
+ }
13
+ // -- Combiner selector
14
+ const allDidInit = (atoms) => {
15
+ const inits = atoms
16
+ .map(atom => atom.didInit)
17
+ .filter((didInit) => typeof didInit !== "boolean");
18
+ return inits.length === 0 ? true : Promise.all(inits).then(toVoid);
19
+ };
20
+ export class CombinerSelector extends Stateful {
21
+ constructor(atoms, combiner) {
22
+ const selectState = () => {
23
+ const values = atoms.map(atom => atom.get());
24
+ return combiner(...values);
25
+ };
26
+ super(selectState());
27
+ atoms.forEach(atom => atom.subscribe(() => this.update(selectState())));
28
+ this.setDidInit(allDidInit(atoms));
29
+ }
30
+ }
31
+ export const createSelector = (atoms, selector) => {
32
+ if (atoms instanceof Stateful && typeof selector === "string") {
33
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
34
+ return new PathSelector(atoms, selector);
35
+ }
36
+ if (Array.isArray(atoms) && typeof selector === "function") {
37
+ return new CombinerSelector(atoms, selector);
38
+ }
39
+ throw new Error("Selector args do not match any overload");
40
+ };
@@ -1,5 +1,5 @@
1
- export * from "./atom";
2
- export * from "./derive";
3
1
  export * from "./config";
4
- export * from "./select";
2
+ export * from "./createAtom";
3
+ export * from "./createDerived";
4
+ export * from "./createSelector";
5
5
  export * from "./Stateful";
@@ -1,14 +1,14 @@
1
1
  import { isPromiseLike } from "@yaasl/utils";
2
2
  import { Scheduler } from "../utils/Scheduler";
3
- export class MiddlewareDispatcher {
4
- constructor({ atom, middleware }) {
3
+ export class EffectDispatcher {
4
+ constructor({ atom, effects }) {
5
5
  this.didInit = false;
6
- this.middleware = [];
6
+ this.effects = [];
7
7
  this.scheduler = new Scheduler();
8
- this.middleware = middleware.map(create => create(atom));
9
- this.callMiddlewareAction("init", atom);
8
+ this.effects = effects.map(create => create(atom));
9
+ this.callEffectAction("init", atom);
10
10
  this.subscribeSetters(atom);
11
- this.callMiddlewareAction("didInit", atom);
11
+ this.callEffectAction("didInit", atom);
12
12
  const { queue } = this.scheduler;
13
13
  if (!isPromiseLike(queue)) {
14
14
  this.didInit = true;
@@ -19,12 +19,12 @@ export class MiddlewareDispatcher {
19
19
  });
20
20
  }
21
21
  subscribeSetters(atom) {
22
- atom.subscribe(value => this.callMiddlewareAction("set", atom, () => value));
22
+ atom.subscribe(value => this.callEffectAction("set", atom, () => value));
23
23
  }
24
- callMiddlewareAction(action, atom,
24
+ callEffectAction(action, atom,
25
25
  /* Must be a function to make sure it is using the latest value when used in promise */
26
26
  getValue = () => atom.get()) {
27
- const tasks = this.middleware.map(({ actions, options }) => {
27
+ const tasks = this.effects.map(({ actions, options }) => {
28
28
  const actionFn = actions[action];
29
29
  return () => actionFn?.({ value: getValue(), atom, options });
30
30
  });
@@ -0,0 +1,23 @@
1
+ /** Create effects to be used in combination with atoms.
2
+ *
3
+ * Effects can be used to interact with an atom by using the following lifecycle actions:
4
+ *
5
+ * - `init`: Action to be called when the atom is created, but before subscribing to `set` events.
6
+ * May return a promise that can be awaited by using `atom.didInit`.
7
+ * - `didInit`: Action to be called when the atom is created, but after subscribing to `set` events.
8
+ * May return a promise that can be awaited by using `atom.didInit`.
9
+ * - `set`: Action to be called when the atom's `set` function is called.
10
+ *
11
+ * @param setup Effect actions or function to create effect actions.
12
+ * Effect actions are fired in the atom lifecycle, alongside to the subscriptions.
13
+ *
14
+ * @returns The effect to be used on atoms.
15
+ **/
16
+ export const createEffect = (setup) => (...[optionsArg]) => (atom) => {
17
+ const options = optionsArg;
18
+ const actions = setup instanceof Function ? setup({ options, atom }) : setup;
19
+ return {
20
+ options,
21
+ actions,
22
+ };
23
+ };
@@ -1,4 +1,4 @@
1
- import { middleware } from "./middleware";
1
+ import { createEffect } from "./createEffect";
2
2
  import { CONFIG } from "../base";
3
3
  import { Expiration } from "../utils/Expiration";
4
4
  const STORAGE = window.localStorage;
@@ -10,7 +10,7 @@ const syncOverBrowserTabs = (observingKey, onChange) => window.addEventListener(
10
10
  return;
11
11
  onChange(newValue);
12
12
  });
13
- /** Middleware to make an atom value expirable and reset to its defaulValue.
13
+ /** Effect to make an atom value expirable and reset to its defaulValue.
14
14
  *
15
15
  * __Note:__ When using `expiresAt`, a function returning the date should be prefered since using a static date might end in an infinite loop.
16
16
  *
@@ -18,9 +18,9 @@ const syncOverBrowserTabs = (observingKey, onChange) => window.addEventListener(
18
18
  * @param options.expiresAt Date at which the value expires
19
19
  * @param options.expiresIn Milliseconds in which the value expires. Will be ignored if expiresAt is set.
20
20
  *
21
- * @returns The middleware to be used on atoms.
21
+ * @returns The effect to be used on atoms.
22
22
  **/
23
- export const expiration = middleware(({ atom, options = {} }) => {
23
+ export const expiration = createEffect(({ atom, options = {} }) => {
24
24
  const hasExpiration = Boolean(options.expiresAt ?? options.expiresIn);
25
25
  if (!hasExpiration)
26
26
  return {};
@@ -1,4 +1,4 @@
1
- export { middleware } from "./middleware";
1
+ export { createEffect } from "./createEffect";
2
2
  export { localStorage } from "./localStorage";
3
3
  export { indexedDb } from "./indexedDb";
4
4
  export { expiration } from "./expiration";
@@ -1,4 +1,4 @@
1
- import { middleware } from "./middleware";
1
+ import { createEffect } from "./createEffect";
2
2
  import { CONFIG } from "../base";
3
3
  import { Store } from "../utils/Store";
4
4
  let atomDb = null;
@@ -10,9 +10,9 @@ let atomDb = null;
10
10
  * @param {IndexedDbOptions | undefined} options
11
11
  * @param options.key Use your own store key. Will be `atom.name` by default.
12
12
  *
13
- * @returns The middleware to be used on atoms.
13
+ * @returns The effect to be used on atoms.
14
14
  **/
15
- export const indexedDb = middleware(({ atom, options }) => {
15
+ export const indexedDb = createEffect(({ atom, options }) => {
16
16
  const key = options?.key ?? atom.name;
17
17
  return {
18
18
  init: ({ atom }) => {
@@ -1,4 +1,4 @@
1
- import { middleware } from "./middleware";
1
+ import { createEffect } from "./createEffect";
2
2
  import { CONFIG } from "../base";
3
3
  import { LocalStorage } from "../utils/LocalStorage";
4
4
  /** Middleware to save and load atom values to the local storage.
@@ -9,9 +9,9 @@ import { LocalStorage } from "../utils/LocalStorage";
9
9
  * @param options.noTabSync Disable the synchronization of values over browser tabs.
10
10
  * @param options.parser Custom functions to stringify and parse values. Defaults to JSON.stringify and JSON.parse. Use this when handling complex datatypes like Maps or Sets.
11
11
  *
12
- * @returns The middleware to be used on atoms.
12
+ * @returns The effect to be used on atoms.
13
13
  **/
14
- export const localStorage = middleware(({ atom, options = {} }) => {
14
+ export const localStorage = createEffect(({ atom, options = {} }) => {
15
15
  const internalKey = CONFIG.name ? `${CONFIG.name}/${atom.name}` : atom.name;
16
16
  const { key = internalKey, parser, noTabSync } = options;
17
17
  const storage = new LocalStorage(key, {
@@ -1,5 +1,5 @@
1
1
  import { log } from "@yaasl/utils";
2
- import { middleware } from "./middleware";
2
+ import { createEffect } from "./createEffect";
3
3
  import { CONFIG } from "../base";
4
4
  const sortMigrations = (migrations) => {
5
5
  const first = migrations.find(migration => migration.previous === null);
@@ -55,7 +55,17 @@ const performMigration = (atom, version, migrations) => {
55
55
  return migrateVersion(atom, data, migration);
56
56
  }, currentState);
57
57
  };
58
- export const migration = middleware({
58
+ /** Effect to migrate the persisted value of an atom to a newer version.
59
+ * You can use the `createMigrationStep` helper to create migration steps.
60
+ *
61
+ * @param {MigrationOptions} options
62
+ * @param options.steps An array of migration steps to perform for outdated values.
63
+ *
64
+ * __Note:__ One step must have a `previous` version set to null as entry point.
65
+ *
66
+ * @returns The effect to be used on atoms.
67
+ **/
68
+ export const migration = createEffect({
59
69
  didInit: ({ atom, options }) => {
60
70
  const steps = sortMigrations(options.steps);
61
71
  const currentVersion = getVersion(atom);
@@ -83,4 +93,10 @@ export const migration = middleware({
83
93
  atom.set(data);
84
94
  },
85
95
  });
96
+ /** Helper to create a step for the migration effect.
97
+ *
98
+ * @param migration Migration step to create.
99
+ *
100
+ * @returns The migration step.
101
+ **/
86
102
  export const createMigrationStep = (migration) => migration;
package/dist/mjs/index.js CHANGED
@@ -1,2 +1,2 @@
1
1
  export * from "./base";
2
- export * from "./middleware";
2
+ export * from "./effects";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaasl/core",
3
- "version": "0.8.0",
3
+ "version": "0.9.1",
4
4
  "description": "yet another atomic store library (vanilla-js)",
5
5
  "author": "PrettyCoffee",
6
6
  "license": "MIT",
@@ -38,7 +38,7 @@
38
38
  "validate": "run-s lint test build"
39
39
  },
40
40
  "dependencies": {
41
- "@yaasl/utils": "0.8.0"
41
+ "@yaasl/utils": "0.9.1"
42
42
  },
43
43
  "eslintConfig": {
44
44
  "extends": [
@@ -1,33 +0,0 @@
1
- import { SetStateAction } from "@yaasl/utils";
2
- import { Stateful } from "./Stateful";
3
- import { MiddlewareActions, MiddlewareAtomCallback } from "../middleware/middleware";
4
- export interface AtomConfig<Value> {
5
- /** Value that will be returned if the atom is not defined in the store */
6
- defaultValue: Value;
7
- /** Name of the atom. Must be unique among all atoms. */
8
- name?: string;
9
- /** Middleware that will be applied on the atom */
10
- middleware?: MiddlewareAtomCallback<any>[];
11
- /** Inline middleware to apply on the atom */
12
- actions?: MiddlewareActions<undefined, Value>;
13
- }
14
- export declare class Atom<Value = unknown> extends Stateful<Value> {
15
- readonly defaultValue: Value;
16
- readonly name: string;
17
- constructor({ defaultValue, name, middleware: externalMiddleware, actions, }: AtomConfig<Value>);
18
- /** Set the value of the atom.
19
- *
20
- * @param next New value or function to create the
21
- * new value based off the previous value.
22
- */
23
- set(next: SetStateAction<Value>): void;
24
- }
25
- /** Creates an atom store.
26
- *
27
- * @param config.defaultValue Value that will be used initially.
28
- * @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
29
- * @param config.middleware Middleware that will be applied on the atom.
30
- *
31
- * @returns An atom instance.
32
- **/
33
- export declare const atom: <Value>(config: AtomConfig<Value>) => Atom<Value>;
@@ -1,20 +0,0 @@
1
- import { Stateful } from "./Stateful";
2
- type Selectable = Record<string | number, unknown>;
3
- type DeepKeys<T> = T extends object ? {
4
- [K in keyof T]: `${Exclude<K, symbol>}${"" | `.${DeepKeys<T[K]>}`}`;
5
- }[keyof T] : never;
6
- type DeepValue<T, Path> = T extends Record<string | number, unknown> ? Path extends `${infer Current}.${infer Next}` ? DeepValue<T[Current], Next> : T[Path & string] : never;
7
- export declare class Select<Path extends DeepKeys<State>, State extends Selectable> extends Stateful<DeepValue<State, Path>> {
8
- protected readonly parent: Stateful<State>;
9
- protected readonly path: Path;
10
- constructor(parent: Stateful<State>, path: Path);
11
- }
12
- /** Creates a value, selected from any stateful value.
13
- *
14
- * @param parent The parent element to select a value from. The internal state must be an object.
15
- * @param path The path to the value you want to select.
16
- *
17
- * @returns A select instance.
18
- **/
19
- export declare const select: <Path extends DeepKeys<State>, State extends Selectable>(parent: Stateful<State>, path: Path) => Select<Path, State>;
20
- export {};
@@ -1,15 +0,0 @@
1
- import { MiddlewareAtomCallback } from "./middleware";
2
- import { Atom } from "../base/atom";
3
- interface MiddlewareDispatcherConstructor {
4
- atom: Atom<any>;
5
- middleware: MiddlewareAtomCallback<any>[];
6
- }
7
- export declare class MiddlewareDispatcher {
8
- didInit: PromiseLike<void> | boolean;
9
- private middleware;
10
- private scheduler;
11
- constructor({ atom, middleware }: MiddlewareDispatcherConstructor);
12
- private subscribeSetters;
13
- private callMiddlewareAction;
14
- }
15
- export {};
@@ -1,31 +0,0 @@
1
- import { Atom } from "../base";
2
- export type ActionType = "init" | "didInit" | "set";
3
- interface MiddlewarePayload<Options, AtomValue> {
4
- value: AtomValue;
5
- atom: Atom<AtomValue>;
6
- options: Options;
7
- }
8
- export interface MiddlewareActions<Options, AtomValue> {
9
- init?: (payload: MiddlewarePayload<Options, AtomValue>) => Promise<any> | void;
10
- didInit?: (payload: MiddlewarePayload<Options, AtomValue>) => Promise<any> | void;
11
- set?: (payload: MiddlewarePayload<Options, AtomValue>) => void;
12
- }
13
- interface MiddlewareSetupProps<Options, AtomValue> {
14
- atom: Atom<AtomValue>;
15
- options: Options;
16
- }
17
- export type MiddlewareAtomCallback<Options = unknown, AtomValue = unknown> = (atom: Atom<AtomValue>) => Middleware<Options, AtomValue>;
18
- type MiddlewareSetup<Options, AtomValue> = MiddlewareActions<Options, AtomValue> | ((props: MiddlewareSetupProps<Options, AtomValue>) => MiddlewareActions<Options, AtomValue>);
19
- export interface Middleware<Options = unknown, AtomValue = unknown> {
20
- options: Options;
21
- actions: MiddlewareActions<Options, AtomValue>;
22
- }
23
- /** Create middlewares to be used in combination with atoms.
24
- *
25
- * @param setup Middleware actions or function to create middleware actions.
26
- * Middleware actions are fired in the atom lifecycle, alongside to the subscriptions.
27
- *
28
- * @returns A middleware function to be used in atoms.
29
- **/
30
- export declare const middleware: <Options = undefined, AtomValue = any>(setup: MiddlewareSetup<Options, AtomValue>) => (...[optionsArg]: Options extends undefined ? [Options] | [] : [Options]) => MiddlewareAtomCallback<Options, AtomValue>;
31
- export {};
@@ -1,47 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.atom = exports.Atom = void 0;
4
- const Stateful_1 = require("./Stateful");
5
- const middleware_1 = require("../middleware/middleware");
6
- const MiddlewareDispatcher_1 = require("../middleware/MiddlewareDispatcher");
7
- let key = 0;
8
- class Atom extends Stateful_1.Stateful {
9
- constructor({ defaultValue, name = `atom-${++key}`, middleware: externalMiddleware, actions, }) {
10
- super(defaultValue);
11
- this.name = name;
12
- this.defaultValue = defaultValue;
13
- const items = [
14
- ...(actions ? [(0, middleware_1.middleware)(actions)()] : []),
15
- ...(externalMiddleware !== null && externalMiddleware !== void 0 ? externalMiddleware : []),
16
- ];
17
- if (items.length === 0) {
18
- this.didInit = true;
19
- return;
20
- }
21
- const { didInit } = new MiddlewareDispatcher_1.MiddlewareDispatcher({
22
- atom: this,
23
- middleware: items,
24
- });
25
- this.setDidInit(didInit);
26
- }
27
- /** Set the value of the atom.
28
- *
29
- * @param next New value or function to create the
30
- * new value based off the previous value.
31
- */
32
- set(next) {
33
- const value = next instanceof Function ? next(this.get()) : next;
34
- super.update(value);
35
- }
36
- }
37
- exports.Atom = Atom;
38
- /** Creates an atom store.
39
- *
40
- * @param config.defaultValue Value that will be used initially.
41
- * @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
42
- * @param config.middleware Middleware that will be applied on the atom.
43
- *
44
- * @returns An atom instance.
45
- **/
46
- const atom = (config) => new Atom(config);
47
- exports.atom = atom;
@@ -1,26 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.select = exports.Select = void 0;
4
- const Stateful_1 = require("./Stateful");
5
- const selectValue = (state, path) => path
6
- .split(".")
7
- .reduce((result, key) => result[key], state);
8
- class Select extends Stateful_1.Stateful {
9
- constructor(parent, path) {
10
- super(selectValue(parent.get(), path));
11
- this.parent = parent;
12
- this.path = path;
13
- parent.subscribe(state => this.update(selectValue(state, path)));
14
- this.setDidInit(parent.didInit);
15
- }
16
- }
17
- exports.Select = Select;
18
- /** Creates a value, selected from any stateful value.
19
- *
20
- * @param parent The parent element to select a value from. The internal state must be an object.
21
- * @param path The path to the value you want to select.
22
- *
23
- * @returns A select instance.
24
- **/
25
- const select = (parent, path) => new Select(parent, path);
26
- exports.select = select;
@@ -1,19 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.middleware = void 0;
4
- /** Create middlewares to be used in combination with atoms.
5
- *
6
- * @param setup Middleware actions or function to create middleware actions.
7
- * Middleware actions are fired in the atom lifecycle, alongside to the subscriptions.
8
- *
9
- * @returns A middleware function to be used in atoms.
10
- **/
11
- const middleware = (setup) => (...[optionsArg]) => (atom) => {
12
- const options = optionsArg;
13
- const actions = setup instanceof Function ? setup({ options, atom }) : setup;
14
- return {
15
- options,
16
- actions,
17
- };
18
- };
19
- exports.middleware = middleware;
@@ -1,42 +0,0 @@
1
- import { Stateful } from "./Stateful";
2
- import { middleware, } from "../middleware/middleware";
3
- import { MiddlewareDispatcher } from "../middleware/MiddlewareDispatcher";
4
- let key = 0;
5
- export class Atom extends Stateful {
6
- constructor({ defaultValue, name = `atom-${++key}`, middleware: externalMiddleware, actions, }) {
7
- super(defaultValue);
8
- this.name = name;
9
- this.defaultValue = defaultValue;
10
- const items = [
11
- ...(actions ? [middleware(actions)()] : []),
12
- ...(externalMiddleware ?? []),
13
- ];
14
- if (items.length === 0) {
15
- this.didInit = true;
16
- return;
17
- }
18
- const { didInit } = new MiddlewareDispatcher({
19
- atom: this,
20
- middleware: items,
21
- });
22
- this.setDidInit(didInit);
23
- }
24
- /** Set the value of the atom.
25
- *
26
- * @param next New value or function to create the
27
- * new value based off the previous value.
28
- */
29
- set(next) {
30
- const value = next instanceof Function ? next(this.get()) : next;
31
- super.update(value);
32
- }
33
- }
34
- /** Creates an atom store.
35
- *
36
- * @param config.defaultValue Value that will be used initially.
37
- * @param config.name Name of the atom. Must be unique among all atoms. Defaults to "atom-{number}".
38
- * @param config.middleware Middleware that will be applied on the atom.
39
- *
40
- * @returns An atom instance.
41
- **/
42
- export const atom = (config) => new Atom(config);
@@ -1,21 +0,0 @@
1
- import { Stateful } from "./Stateful";
2
- const selectValue = (state, path) => path
3
- .split(".")
4
- .reduce((result, key) => result[key], state);
5
- export class Select extends Stateful {
6
- constructor(parent, path) {
7
- super(selectValue(parent.get(), path));
8
- this.parent = parent;
9
- this.path = path;
10
- parent.subscribe(state => this.update(selectValue(state, path)));
11
- this.setDidInit(parent.didInit);
12
- }
13
- }
14
- /** Creates a value, selected from any stateful value.
15
- *
16
- * @param parent The parent element to select a value from. The internal state must be an object.
17
- * @param path The path to the value you want to select.
18
- *
19
- * @returns A select instance.
20
- **/
21
- export const select = (parent, path) => new Select(parent, path);
@@ -1,15 +0,0 @@
1
- /** Create middlewares to be used in combination with atoms.
2
- *
3
- * @param setup Middleware actions or function to create middleware actions.
4
- * Middleware actions are fired in the atom lifecycle, alongside to the subscriptions.
5
- *
6
- * @returns A middleware function to be used in atoms.
7
- **/
8
- export const middleware = (setup) => (...[optionsArg]) => (atom) => {
9
- const options = optionsArg;
10
- const actions = setup instanceof Function ? setup({ options, atom }) : setup;
11
- return {
12
- options,
13
- actions,
14
- };
15
- };