@yaasl/core 0.11.0 → 0.12.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.
Files changed (66) hide show
  1. package/dist/@types/base/config.d.ts +1 -1
  2. package/dist/@types/base/{createActions.d.ts → create-actions.d.ts} +2 -2
  3. package/dist/@types/base/{createAtom.d.ts → create-atom.d.ts} +2 -2
  4. package/dist/@types/base/{createDerived.d.ts → create-derived.d.ts} +2 -2
  5. package/dist/@types/base/{createSelector.d.ts → create-selector.d.ts} +1 -1
  6. package/dist/@types/base/{createSlice.d.ts → create-slice.d.ts} +3 -3
  7. package/dist/@types/base/{Destroyable.d.ts → destroyable.d.ts} +1 -1
  8. package/dist/@types/base/index.d.ts +6 -6
  9. package/dist/@types/base/{Stateful.d.ts → stateful.d.ts} +1 -1
  10. package/dist/@types/effects/{EffectDispatcher.d.ts → effect-dispatcher.d.ts} +2 -2
  11. package/dist/@types/effects/expiration.d.ts +1 -1
  12. package/dist/@types/effects/index.d.ts +8 -6
  13. package/dist/@types/effects/{indexedDb.d.ts → indexed-db.d.ts} +1 -1
  14. package/dist/@types/effects/{localStorage.d.ts → local-storage.d.ts} +3 -6
  15. package/dist/@types/effects/migration.d.ts +1 -1
  16. package/dist/@types/effects/session-storage.d.ts +23 -0
  17. package/dist/@types/index.d.ts +1 -0
  18. package/dist/@types/utils/{Store.d.ts → idb-store.d.ts} +1 -1
  19. package/dist/@types/utils/string-storage.d.ts +24 -0
  20. package/dist/cjs/base/{createAtom.js → create-atom.js} +5 -4
  21. package/dist/cjs/base/{createDerived.js → create-derived.js} +4 -4
  22. package/dist/cjs/base/{createSelector.js → create-selector.js} +4 -4
  23. package/dist/cjs/base/{createSlice.js → create-slice.js} +7 -7
  24. package/dist/cjs/base/{Destroyable.js → destroyable.js} +1 -0
  25. package/dist/cjs/base/index.js +6 -6
  26. package/dist/cjs/base/{Stateful.js → stateful.js} +2 -2
  27. package/dist/cjs/effects/{EffectDispatcher.js → effect-dispatcher.js} +2 -2
  28. package/dist/cjs/effects/expiration.js +4 -4
  29. package/dist/cjs/effects/index.js +9 -7
  30. package/dist/cjs/effects/{indexedDb.js → indexed-db.js} +4 -4
  31. package/dist/cjs/effects/local-storage.js +55 -0
  32. package/dist/cjs/effects/migration.js +2 -2
  33. package/dist/cjs/effects/{localStorage.js → session-storage.js} +13 -10
  34. package/dist/cjs/utils/{Store.js → idb-store.js} +3 -3
  35. package/dist/cjs/utils/string-storage.js +45 -0
  36. package/dist/esm/base/{createAtom.js → create-atom.js} +3 -2
  37. package/dist/esm/base/{createDerived.js → create-derived.js} +3 -3
  38. package/dist/esm/base/{createSelector.js → create-selector.js} +1 -1
  39. package/dist/esm/base/{createSlice.js → create-slice.js} +3 -3
  40. package/dist/esm/base/{Destroyable.js → destroyable.js} +1 -0
  41. package/dist/esm/base/index.js +6 -6
  42. package/dist/esm/base/{Stateful.js → stateful.js} +1 -1
  43. package/dist/esm/effects/{EffectDispatcher.js → effect-dispatcher.js} +1 -1
  44. package/dist/esm/effects/expiration.js +2 -2
  45. package/dist/esm/effects/index.js +4 -3
  46. package/dist/esm/effects/{indexedDb.js → indexed-db.js} +3 -3
  47. package/dist/esm/effects/{localStorage.js → local-storage.js} +14 -4
  48. package/dist/esm/effects/migration.js +1 -1
  49. package/dist/esm/effects/session-storage.js +40 -0
  50. package/dist/esm/utils/{Store.js → idb-store.js} +1 -1
  51. package/dist/esm/utils/string-storage.js +44 -0
  52. package/package.json +1 -1
  53. package/dist/@types/utils/LocalStorage.d.ts +0 -17
  54. package/dist/cjs/utils/LocalStorage.js +0 -68
  55. package/dist/esm/utils/LocalStorage.js +0 -60
  56. /package/dist/@types/effects/{createEffect.d.ts → create-effect.d.ts} +0 -0
  57. /package/dist/@types/utils/{Expiration.d.ts → expiration.d.ts} +0 -0
  58. /package/dist/@types/utils/{Queue.d.ts → queue.d.ts} +0 -0
  59. /package/dist/cjs/base/{createActions.js → create-actions.js} +0 -0
  60. /package/dist/cjs/effects/{createEffect.js → create-effect.js} +0 -0
  61. /package/dist/cjs/utils/{Expiration.js → expiration.js} +0 -0
  62. /package/dist/cjs/utils/{Queue.js → queue.js} +0 -0
  63. /package/dist/esm/base/{createActions.js → create-actions.js} +0 -0
  64. /package/dist/esm/effects/{createEffect.js → create-effect.js} +0 -0
  65. /package/dist/esm/utils/{Expiration.js → expiration.js} +0 -0
  66. /package/dist/esm/utils/{Queue.js → queue.js} +0 -0
@@ -1,4 +1,4 @@
1
- import type { EffectAtomCallback } from "../effects/createEffect";
1
+ import type { EffectAtomCallback } from "../effects/create-effect";
2
2
  interface Config {
3
3
  /** Global name to make internal keys unique
4
4
  * among UIs on the same domain.
@@ -1,5 +1,5 @@
1
- import type { Atom } from "./createAtom";
2
- import type { SettableDerive } from "./createDerived";
1
+ import type { Atom } from "./create-atom";
2
+ import type { SettableDerive } from "./create-derived";
3
3
  type Reducer<State> = (state: State, ...payloadArgs: any[]) => State;
4
4
  export type Reducers<State> = Record<string, Reducer<State>>;
5
5
  type Payload<R extends Reducer<any>> = Parameters<R> extends [any, ...infer PayloadArgs] ? PayloadArgs : [];
@@ -1,6 +1,6 @@
1
1
  import { Updater } from "@yaasl/utils";
2
- import { Stateful } from "./Stateful";
3
- import type { EffectAtomCallback } from "../effects/createEffect";
2
+ import { Stateful } from "./stateful";
3
+ import type { EffectAtomCallback } from "../effects/create-effect";
4
4
  export interface AtomConfig<Value> {
5
5
  /** Value that will be used initially. */
6
6
  defaultValue: Value;
@@ -1,6 +1,6 @@
1
1
  import { Updater } from "@yaasl/utils";
2
- import type { Atom } from "./createAtom";
3
- import { Stateful } from "./Stateful";
2
+ import type { Atom } from "./create-atom";
3
+ import { Stateful } from "./stateful";
4
4
  type GetterFn<Value> = (context: {
5
5
  get: <V>(dep: Stateful<V>) => V;
6
6
  }) => Value;
@@ -1,5 +1,5 @@
1
1
  import { Prettify } from "@yaasl/utils";
2
- import { Stateful } from "./Stateful";
2
+ import { Stateful } from "./stateful";
3
3
  type PathableValue = Record<string | number, unknown>;
4
4
  export type ObjPath<Obj> = Prettify<Obj> extends PathableValue ? {
5
5
  [K in keyof Obj]: `${Exclude<K, symbol>}${"" | `.${ObjPath<Obj[K]>}`}`;
@@ -1,6 +1,6 @@
1
- import { Actions, Reducers } from "./createActions";
2
- import { Atom, AtomConfig } from "./createAtom";
3
- import { CombinerSelector, ObjPath, PathSelector } from "./createSelector";
1
+ import { Actions, Reducers } from "./create-actions";
2
+ import { Atom, AtomConfig } from "./create-atom";
3
+ import { CombinerSelector, ObjPath, PathSelector } from "./create-selector";
4
4
  interface ReducersProp<State, R extends Reducers<State> | undefined> {
5
5
  /** Reducers for custom actions to set the atom's value. */
6
6
  reducers?: R;
@@ -1,4 +1,4 @@
1
- import type { Callback, Stateful } from "./Stateful";
1
+ import type { Callback, Stateful } from "./stateful";
2
2
  export declare class Destroyable {
3
3
  isDestroyed: boolean;
4
4
  private dependents;
@@ -1,7 +1,7 @@
1
1
  export * from "./config";
2
- export * from "./createActions";
3
- export * from "./createAtom";
4
- export * from "./createDerived";
5
- export * from "./createSelector";
6
- export * from "./createSlice";
7
- export * from "./Stateful";
2
+ export * from "./create-actions";
3
+ export * from "./create-atom";
4
+ export * from "./create-derived";
5
+ export * from "./create-selector";
6
+ export * from "./create-slice";
7
+ export * from "./stateful";
@@ -1,4 +1,4 @@
1
- import { Destroyable } from "./Destroyable";
1
+ import { Destroyable } from "./destroyable";
2
2
  export type Callback<Value> = (value: Value, previous: Value) => void;
3
3
  export declare class Stateful<Value = unknown> extends Destroyable {
4
4
  protected value: Value;
@@ -1,5 +1,5 @@
1
- import type { ActionType, EffectAtomCallback, EffectMeta } from "./createEffect";
2
- import type { Atom } from "../base/createAtom";
1
+ import type { ActionType, EffectAtomCallback, EffectMeta } from "./create-effect";
2
+ import type { Atom } from "../base/create-atom";
3
3
  export declare class EffectActions<Value> {
4
4
  private readonly atom;
5
5
  readonly meta?: EffectMeta;
@@ -14,4 +14,4 @@ export interface ExpirationOptions {
14
14
  *
15
15
  * @returns The effect to be used on atoms.
16
16
  **/
17
- export declare const expiration: (optionsArg: ExpirationOptions) => import("./createEffect").EffectAtomCallback<ExpirationOptions, any>;
17
+ export declare const expiration: (optionsArg: ExpirationOptions) => import("./create-effect").EffectAtomCallback<ExpirationOptions, any>;
@@ -1,9 +1,11 @@
1
- export { createEffect } from "./createEffect";
2
- export type { Effect, EffectPayload, EffectAtomCallback } from "./createEffect";
3
- export { localStorage } from "./localStorage";
4
- export type { LocalStorageOptions, LocalStorageParser } from "./localStorage";
5
- export { indexedDb } from "./indexedDb";
6
- export type { IndexedDbOptions } from "./indexedDb";
1
+ export { createEffect } from "./create-effect";
2
+ export type { Effect, EffectPayload, EffectAtomCallback } from "./create-effect";
3
+ export { localStorage } from "./local-storage";
4
+ export type { LocalStorageOptions } from "./local-storage";
5
+ export { sessionStorage } from "./session-storage";
6
+ export type { SessionStorageOptions } from "./session-storage";
7
+ export { indexedDb } from "./indexed-db";
8
+ export type { IndexedDbOptions } from "./indexed-db";
7
9
  export { expiration } from "./expiration";
8
10
  export type { ExpirationOptions } from "./expiration";
9
11
  export { migration, createMigrationStep } from "./migration";
@@ -12,4 +12,4 @@ export interface IndexedDbOptions {
12
12
  *
13
13
  * @returns The effect to be used on atoms.
14
14
  **/
15
- export declare const indexedDb: (...[optionsArg]: [] | [undefined] | [IndexedDbOptions]) => import("./createEffect").EffectAtomCallback<IndexedDbOptions | undefined, unknown>;
15
+ export declare const indexedDb: (...[optionsArg]: [] | [undefined] | [IndexedDbOptions]) => import("./create-effect").EffectAtomCallback<IndexedDbOptions | undefined, unknown>;
@@ -1,7 +1,4 @@
1
- export interface LocalStorageParser<T = any> {
2
- parse: (value: string) => T;
3
- stringify: (value: T) => string;
4
- }
1
+ import { StringStorageParser } from "../utils/string-storage";
5
2
  export interface LocalStorageOptions {
6
3
  /** Use your own key for the local storage.
7
4
  * Will be "{config-name}/{atom-name}" by default.
@@ -13,7 +10,7 @@ export interface LocalStorageOptions {
13
10
  * Defaults to JSON.stringify and JSON.parse.
14
11
  * Use this when handling complex datatypes like Maps or Sets.
15
12
  */
16
- parser?: LocalStorageParser;
13
+ parser?: StringStorageParser;
17
14
  }
18
15
  /** Middleware to save and load atom values to the local storage.
19
16
  *
@@ -25,4 +22,4 @@ export interface LocalStorageOptions {
25
22
  *
26
23
  * @returns The effect to be used on atoms.
27
24
  **/
28
- export declare const localStorage: (...[optionsArg]: [] | [undefined] | [LocalStorageOptions]) => import("./createEffect").EffectAtomCallback<LocalStorageOptions | undefined, unknown>;
25
+ export declare const localStorage: (...[optionsArg]: [] | [undefined] | [LocalStorageOptions]) => import("./create-effect").EffectAtomCallback<LocalStorageOptions | undefined, unknown>;
@@ -25,7 +25,7 @@ export interface MigrationOptions {
25
25
  *
26
26
  * @returns The effect to be used on atoms.
27
27
  **/
28
- export declare const migration: (optionsArg: MigrationOptions) => import("./createEffect").EffectAtomCallback<MigrationOptions, unknown>;
28
+ export declare const migration: (optionsArg: MigrationOptions) => import("./create-effect").EffectAtomCallback<MigrationOptions, unknown>;
29
29
  /** Helper to create a step for the migration effect.
30
30
  *
31
31
  * @param migration Migration step to create.
@@ -0,0 +1,23 @@
1
+ import { StringStorageParser } from "../utils/string-storage";
2
+ export interface SessionStorageOptions {
3
+ /** Use your own key for the session storage.
4
+ * Will be "{config-name}/{atom-name}" by default.
5
+ */
6
+ key?: string;
7
+ /** Custom functions to stringify and parse values.
8
+ * Defaults to JSON.stringify and JSON.parse.
9
+ * Use this when handling complex datatypes like Maps or Sets.
10
+ */
11
+ parser?: StringStorageParser;
12
+ }
13
+ /** Middleware to save and load atom values to the session storage.
14
+ *
15
+ * @param {SessionStorageOptions | undefined} options
16
+ * @param options.key Use your own key for the session storage.
17
+ * Will be "{config-name}/{atom-name}" by default.
18
+ * @param options.noTabSync Disable the synchronization of values over browser tabs.
19
+ * @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.
20
+ *
21
+ * @returns The effect to be used on atoms.
22
+ **/
23
+ export declare const sessionStorage: (...[optionsArg]: [] | [undefined] | [SessionStorageOptions]) => import("./create-effect").EffectAtomCallback<SessionStorageOptions | undefined, unknown>;
@@ -1,2 +1,3 @@
1
1
  export * from "./base";
2
2
  export * from "./effects";
3
+ export type { StringStorageParser } from "./utils/string-storage";
@@ -1,4 +1,4 @@
1
- export declare class Store<T> {
1
+ export declare class IdbStore<T> {
2
2
  private name;
3
3
  private database?;
4
4
  constructor(name: string);
@@ -0,0 +1,24 @@
1
+ interface StringStore {
2
+ getItem: (key: string) => string | null;
3
+ setItem: (key: string, value: string) => void;
4
+ removeItem: (key: string) => void;
5
+ }
6
+ export interface StringStorageParser<T = any> {
7
+ parse: (value: string) => T;
8
+ stringify: (value: T) => string;
9
+ }
10
+ export interface StringStorageConstructorOptions<T> {
11
+ key: string;
12
+ store?: StringStore;
13
+ parser?: StringStorageParser<T>;
14
+ }
15
+ export declare class StringStorage<T = unknown> {
16
+ private readonly key;
17
+ private readonly store;
18
+ private readonly parser;
19
+ constructor({ key, store, parser, }: StringStorageConstructorOptions<T>);
20
+ get(): T | null;
21
+ set(value: T): void;
22
+ remove(): void;
23
+ }
24
+ export {};
@@ -3,10 +3,10 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createAtom = exports.Atom = void 0;
4
4
  const utils_1 = require("@yaasl/utils");
5
5
  const config_1 = require("./config");
6
- const Stateful_1 = require("./Stateful");
7
- const EffectDispatcher_1 = require("../effects/EffectDispatcher");
6
+ const stateful_1 = require("./stateful");
7
+ const effect_dispatcher_1 = require("../effects/effect-dispatcher");
8
8
  let key = 0;
9
- class Atom extends Stateful_1.Stateful {
9
+ class Atom extends stateful_1.Stateful {
10
10
  constructor({ defaultValue, name = `atom-${++key}`, effects: localEffects = [], }) {
11
11
  super(defaultValue);
12
12
  this.name = name;
@@ -15,7 +15,7 @@ class Atom extends Stateful_1.Stateful {
15
15
  ...config_1.CONFIG.globalEffects,
16
16
  ...localEffects,
17
17
  ];
18
- this.effects = new EffectDispatcher_1.EffectDispatcher(this, effects);
18
+ this.effects = new effect_dispatcher_1.EffectDispatcher(this, effects);
19
19
  if (effects.length === 0) {
20
20
  this.setDidInit(true);
21
21
  return;
@@ -29,6 +29,7 @@ class Atom extends Stateful_1.Stateful {
29
29
  }
30
30
  }
31
31
  initEffects() {
32
+ // eslint-disable-next-line unicorn/consistent-function-scoping
32
33
  const updateValue = (value) => {
33
34
  super.update(value);
34
35
  return value;
@@ -3,20 +3,20 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.SettableDerive = exports.Derive = void 0;
4
4
  exports.createDerived = createDerived;
5
5
  const utils_1 = require("@yaasl/utils");
6
- const Stateful_1 = require("./Stateful");
6
+ const stateful_1 = require("./stateful");
7
7
  const allDidInit = (atoms) => {
8
8
  const inits = atoms
9
9
  .map(atom => atom.didInit)
10
10
  .filter((didInit) => typeof didInit !== "boolean");
11
11
  return inits.length === 0 ? true : Promise.all(inits).then(utils_1.toVoid);
12
12
  };
13
- class Derive extends Stateful_1.Stateful {
13
+ class Derive extends stateful_1.Stateful {
14
14
  constructor(getter) {
15
15
  super(undefined);
16
16
  this.getter = getter;
17
17
  this.getterDependencies = new Set();
18
18
  this.value = getter({ get: dep => this.addGetDependency(dep) });
19
- this.setDidInit(allDidInit(Array.from(this.getterDependencies)));
19
+ this.setDidInit(allDidInit([...this.getterDependencies]));
20
20
  }
21
21
  addGetDependency(dependency) {
22
22
  if (!this.getterDependencies.has(dependency)) {
@@ -71,7 +71,7 @@ class SettableDerive extends Derive {
71
71
  if (getterDependencies.size !== setterDependencies.size) {
72
72
  return false;
73
73
  }
74
- return Array.from(setterDependencies).every(dependency => getterDependencies.has(dependency));
74
+ return [...setterDependencies].every(dependency => getterDependencies.has(dependency));
75
75
  }
76
76
  }
77
77
  exports.SettableDerive = SettableDerive;
@@ -2,11 +2,11 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createSelector = exports.CombinerSelector = exports.PathSelector = void 0;
4
4
  const utils_1 = require("@yaasl/utils");
5
- const Stateful_1 = require("./Stateful");
5
+ const stateful_1 = require("./stateful");
6
6
  const selectPath = (state, path) => path
7
7
  .split(".")
8
8
  .reduce((result, key) => result[key], state);
9
- class PathSelector extends Stateful_1.Stateful {
9
+ class PathSelector extends stateful_1.Stateful {
10
10
  constructor(atom, path) {
11
11
  super(selectPath(atom.get(), path));
12
12
  this.subscribeTo(atom, state => this.update(selectPath(state, path)));
@@ -21,7 +21,7 @@ const allDidInit = (atoms) => {
21
21
  .filter((didInit) => typeof didInit !== "boolean");
22
22
  return inits.length === 0 ? true : Promise.all(inits).then(utils_1.toVoid);
23
23
  };
24
- class CombinerSelector extends Stateful_1.Stateful {
24
+ class CombinerSelector extends stateful_1.Stateful {
25
25
  constructor(atoms, combiner) {
26
26
  const selectState = () => {
27
27
  const values = atoms.map(atom => atom.get());
@@ -34,7 +34,7 @@ class CombinerSelector extends Stateful_1.Stateful {
34
34
  }
35
35
  exports.CombinerSelector = CombinerSelector;
36
36
  const createSelector = (atoms, selector) => {
37
- if (atoms instanceof Stateful_1.Stateful && typeof selector === "string") {
37
+ if (atoms instanceof stateful_1.Stateful && typeof selector === "string") {
38
38
  // eslint-disable-next-line @typescript-eslint/no-unsafe-return
39
39
  return new PathSelector(atoms, selector);
40
40
  }
@@ -1,15 +1,15 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createSlice = void 0;
4
- const createActions_1 = require("./createActions");
5
- const createAtom_1 = require("./createAtom");
6
- const createSelector_1 = require("./createSelector");
4
+ const create_actions_1 = require("./create-actions");
5
+ const create_atom_1 = require("./create-atom");
6
+ const create_selector_1 = require("./create-selector");
7
7
  const isEmpty = (obj) => !obj || Object.keys(obj).length === 0;
8
8
  const createSelectors = (atom, selectors) => Object.fromEntries(Object.entries(selectors).map(([key, selector]) => [
9
9
  key,
10
10
  typeof selector === "string"
11
- ? (0, createSelector_1.createSelector)(atom, selector)
12
- : (0, createSelector_1.createSelector)([atom], selector),
11
+ ? (0, create_selector_1.createSelector)(atom, selector)
12
+ : (0, create_selector_1.createSelector)([atom], selector),
13
13
  ]));
14
14
  /** Creates a slice with actions and selectors.
15
15
  *
@@ -22,11 +22,11 @@ const createSelectors = (atom, selectors) => Object.fromEntries(Object.entries(s
22
22
  * @returns An atom instance with actions and selectors.
23
23
  **/
24
24
  const createSlice = (config) => {
25
- const atom = new createAtom_1.Atom(config);
25
+ const atom = new create_atom_1.Atom(config);
26
26
  const actionsProp = isEmpty(config.reducers)
27
27
  ? {}
28
28
  : {
29
- actions: (0, createActions_1.createActions)(atom, config.reducers),
29
+ actions: (0, create_actions_1.createActions)(atom, config.reducers),
30
30
  };
31
31
  const selectorsProp = isEmpty(config.selectors)
32
32
  ? {}
@@ -16,6 +16,7 @@ class Destroyable {
16
16
  this.dependents.clear();
17
17
  this.unsubscribers.clear();
18
18
  this.isDestroyed = true;
19
+ // eslint-disable-next-line unicorn/consistent-function-scoping
19
20
  const throwOnCall = () => {
20
21
  const name = "name" in this ? this.name : undefined;
21
22
  throw new Error((0, utils_1.consoleMessage)("The methods of a destroyed atom cannot be called.", {
@@ -15,9 +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);
19
- __exportStar(require("./createAtom"), exports);
20
- __exportStar(require("./createDerived"), exports);
21
- __exportStar(require("./createSelector"), exports);
22
- __exportStar(require("./createSlice"), exports);
23
- __exportStar(require("./Stateful"), exports);
18
+ __exportStar(require("./create-actions"), exports);
19
+ __exportStar(require("./create-atom"), exports);
20
+ __exportStar(require("./create-derived"), exports);
21
+ __exportStar(require("./create-selector"), exports);
22
+ __exportStar(require("./create-slice"), exports);
23
+ __exportStar(require("./stateful"), exports);
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.Stateful = void 0;
4
- const Destroyable_1 = require("./Destroyable");
5
- class Stateful extends Destroyable_1.Destroyable {
4
+ const destroyable_1 = require("./destroyable");
5
+ class Stateful extends destroyable_1.Destroyable {
6
6
  constructor(value) {
7
7
  super();
8
8
  this.value = value;
@@ -2,7 +2,7 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.EffectDispatcher = exports.EffectActions = void 0;
4
4
  const utils_1 = require("@yaasl/utils");
5
- const Queue_1 = require("../utils/Queue");
5
+ const queue_1 = require("../utils/queue");
6
6
  const isTruthy = (value) => !!value;
7
7
  class EffectActions {
8
8
  constructor(atom, effectCreator) {
@@ -35,7 +35,7 @@ exports.EffectActions = EffectActions;
35
35
  class EffectDispatcher {
36
36
  constructor(atom, effects) {
37
37
  this.effects = [];
38
- this.queue = new Queue_1.Queue();
38
+ this.queue = new queue_1.Queue();
39
39
  this.effects = effects
40
40
  .map(create => new EffectActions(atom, create))
41
41
  .sort((a, b) => {
@@ -3,9 +3,9 @@ var _a, _b;
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.expiration = void 0;
5
5
  const utils_1 = require("@yaasl/utils");
6
- const createEffect_1 = require("./createEffect");
6
+ const create_effect_1 = require("./create-effect");
7
7
  const base_1 = require("../base");
8
- const Expiration_1 = require("../utils/Expiration");
8
+ const expiration_1 = require("../utils/expiration");
9
9
  const STORAGE = (_b = (_a = (0, utils_1.getWindow)()) === null || _a === void 0 ? void 0 : _a.localStorage) !== null && _b !== void 0 ? _b : {
10
10
  getItem: () => null,
11
11
  setItem: utils_1.toVoid,
@@ -32,13 +32,13 @@ const syncOverBrowserTabs = (observingKey, onChange) => {
32
32
  *
33
33
  * @returns The effect to be used on atoms.
34
34
  **/
35
- exports.expiration = (0, createEffect_1.createEffect)(({ atom, options = {} }) => {
35
+ exports.expiration = (0, create_effect_1.createEffect)(({ atom, options = {} }) => {
36
36
  var _a;
37
37
  const hasExpiration = Boolean((_a = options.expiresAt) !== null && _a !== void 0 ? _a : options.expiresIn);
38
38
  if (!hasExpiration)
39
39
  return {};
40
40
  const key = base_1.CONFIG.name ? `${base_1.CONFIG.name}/${atom.name}` : atom.name;
41
- const expiration = new Expiration_1.Expiration(Object.assign(Object.assign({}, options), { key: `${key}-expires-at` }));
41
+ const expiration = new expiration_1.Expiration(Object.assign(Object.assign({}, options), { key: `${key}-expires-at` }));
42
42
  const reset = () => {
43
43
  expiration.remove();
44
44
  atom.set(atom.defaultValue);
@@ -1,12 +1,14 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.createMigrationStep = exports.migration = exports.expiration = exports.indexedDb = exports.localStorage = exports.createEffect = void 0;
4
- var createEffect_1 = require("./createEffect");
5
- Object.defineProperty(exports, "createEffect", { enumerable: true, get: function () { return createEffect_1.createEffect; } });
6
- var localStorage_1 = require("./localStorage");
7
- Object.defineProperty(exports, "localStorage", { enumerable: true, get: function () { return localStorage_1.localStorage; } });
8
- var indexedDb_1 = require("./indexedDb");
9
- Object.defineProperty(exports, "indexedDb", { enumerable: true, get: function () { return indexedDb_1.indexedDb; } });
3
+ exports.createMigrationStep = exports.migration = exports.expiration = exports.indexedDb = exports.sessionStorage = exports.localStorage = exports.createEffect = void 0;
4
+ var create_effect_1 = require("./create-effect");
5
+ Object.defineProperty(exports, "createEffect", { enumerable: true, get: function () { return create_effect_1.createEffect; } });
6
+ var local_storage_1 = require("./local-storage");
7
+ Object.defineProperty(exports, "localStorage", { enumerable: true, get: function () { return local_storage_1.localStorage; } });
8
+ var session_storage_1 = require("./session-storage");
9
+ Object.defineProperty(exports, "sessionStorage", { enumerable: true, get: function () { return session_storage_1.sessionStorage; } });
10
+ var indexed_db_1 = require("./indexed-db");
11
+ Object.defineProperty(exports, "indexedDb", { enumerable: true, get: function () { return indexed_db_1.indexedDb; } });
10
12
  var expiration_1 = require("./expiration");
11
13
  Object.defineProperty(exports, "expiration", { enumerable: true, get: function () { return expiration_1.expiration; } });
12
14
  var migration_1 = require("./migration");
@@ -10,9 +10,9 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.indexedDb = void 0;
13
- const createEffect_1 = require("./createEffect");
13
+ const create_effect_1 = require("./create-effect");
14
14
  const base_1 = require("../base");
15
- const Store_1 = require("../utils/Store");
15
+ const idb_store_1 = require("../utils/idb-store");
16
16
  let atomDb = null;
17
17
  /** Middleware to save and load atom values to an indexedDb.
18
18
  *
@@ -24,7 +24,7 @@ let atomDb = null;
24
24
  *
25
25
  * @returns The effect to be used on atoms.
26
26
  **/
27
- exports.indexedDb = (0, createEffect_1.createEffect)(({ atom, options }) => {
27
+ exports.indexedDb = (0, create_effect_1.createEffect)(({ atom, options }) => {
28
28
  var _a;
29
29
  const key = (_a = options === null || options === void 0 ? void 0 : options.key) !== null && _a !== void 0 ? _a : atom.name;
30
30
  return {
@@ -32,7 +32,7 @@ exports.indexedDb = (0, createEffect_1.createEffect)(({ atom, options }) => {
32
32
  init: (_a) => __awaiter(void 0, [_a], void 0, function* ({ atom, set }) {
33
33
  var _b;
34
34
  if (!atomDb) {
35
- atomDb = new Store_1.Store((_b = base_1.CONFIG.name) !== null && _b !== void 0 ? _b : "yaasl");
35
+ atomDb = new idb_store_1.IdbStore((_b = base_1.CONFIG.name) !== null && _b !== void 0 ? _b : "yaasl");
36
36
  }
37
37
  const existing = yield atomDb.get(key);
38
38
  if (existing != null) {
@@ -0,0 +1,55 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.localStorage = void 0;
4
+ const utils_1 = require("@yaasl/utils");
5
+ const create_effect_1 = require("./create-effect");
6
+ const base_1 = require("../base");
7
+ const string_storage_1 = require("../utils/string-storage");
8
+ const syncOverBrowserTabs = (observingKey, onTabSync) => {
9
+ var _a;
10
+ return (_a = (0, utils_1.getWindow)()) === null || _a === void 0 ? void 0 : _a.addEventListener("storage", ({ key, newValue }) => {
11
+ if (observingKey !== key)
12
+ return;
13
+ onTabSync(newValue);
14
+ });
15
+ };
16
+ /** Middleware to save and load atom values to the local storage.
17
+ *
18
+ * @param {LocalStorageOptions | undefined} options
19
+ * @param options.key Use your own key for the local storage.
20
+ * Will be "{config-name}/{atom-name}" by default.
21
+ * @param options.noTabSync Disable the synchronization of values over browser tabs.
22
+ * @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.
23
+ *
24
+ * @returns The effect to be used on atoms.
25
+ **/
26
+ exports.localStorage = (0, create_effect_1.createEffect)(({ atom, options = {} }) => {
27
+ var _a;
28
+ const internalKey = base_1.CONFIG.name ? `${base_1.CONFIG.name}/${atom.name}` : atom.name;
29
+ const { key = internalKey, parser, noTabSync } = options;
30
+ const storage = new string_storage_1.StringStorage({
31
+ key,
32
+ store: (_a = (0, utils_1.getWindow)()) === null || _a === void 0 ? void 0 : _a.localStorage,
33
+ parser,
34
+ });
35
+ if (!noTabSync) {
36
+ syncOverBrowserTabs(key, () => { var _a; return atom.set((_a = storage.get()) !== null && _a !== void 0 ? _a : atom.defaultValue); });
37
+ }
38
+ return {
39
+ sort: "pre",
40
+ init: ({ set }) => {
41
+ const existing = storage.get();
42
+ if (existing != null) {
43
+ set(existing);
44
+ }
45
+ },
46
+ set: ({ value, atom }) => {
47
+ if (value === atom.defaultValue) {
48
+ storage.remove();
49
+ }
50
+ else {
51
+ storage.set(value);
52
+ }
53
+ },
54
+ };
55
+ });
@@ -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 createEffect_1 = require("./createEffect");
5
+ const create_effect_1 = require("./create-effect");
6
6
  const base_1 = require("../base");
7
7
  const sortMigrations = (migrations) => {
8
8
  const first = migrations.find(migration => migration.previous === null);
@@ -70,7 +70,7 @@ const performMigration = (atom, version, migrations) => {
70
70
  *
71
71
  * @returns The effect to be used on atoms.
72
72
  **/
73
- exports.migration = (0, createEffect_1.createEffect)({
73
+ exports.migration = (0, create_effect_1.createEffect)({
74
74
  didInit: ({ atom, options, set }) => {
75
75
  var _a, _b;
76
76
  const steps = sortMigrations(options.steps);
@@ -1,25 +1,28 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.localStorage = void 0;
4
- const createEffect_1 = require("./createEffect");
3
+ exports.sessionStorage = void 0;
4
+ const utils_1 = require("@yaasl/utils");
5
+ const create_effect_1 = require("./create-effect");
5
6
  const base_1 = require("../base");
6
- const LocalStorage_1 = require("../utils/LocalStorage");
7
- /** Middleware to save and load atom values to the local storage.
7
+ const string_storage_1 = require("../utils/string-storage");
8
+ /** Middleware to save and load atom values to the session storage.
8
9
  *
9
- * @param {LocalStorageOptions | undefined} options
10
- * @param options.key Use your own key for the local storage.
10
+ * @param {SessionStorageOptions | undefined} options
11
+ * @param options.key Use your own key for the session storage.
11
12
  * Will be "{config-name}/{atom-name}" by default.
12
13
  * @param options.noTabSync Disable the synchronization of values over browser tabs.
13
14
  * @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.
14
15
  *
15
16
  * @returns The effect to be used on atoms.
16
17
  **/
17
- exports.localStorage = (0, createEffect_1.createEffect)(({ atom, options = {} }) => {
18
+ exports.sessionStorage = (0, create_effect_1.createEffect)(({ atom, options = {} }) => {
19
+ var _a;
18
20
  const internalKey = base_1.CONFIG.name ? `${base_1.CONFIG.name}/${atom.name}` : atom.name;
19
- const { key = internalKey, parser, noTabSync } = options;
20
- const storage = new LocalStorage_1.LocalStorage(key, {
21
+ const { key = internalKey, parser } = options;
22
+ const storage = new string_storage_1.StringStorage({
23
+ key,
24
+ store: (_a = (0, utils_1.getWindow)()) === null || _a === void 0 ? void 0 : _a.sessionStorage,
21
25
  parser,
22
- onTabSync: noTabSync ? undefined : value => atom.set(value),
23
26
  });
24
27
  return {
25
28
  sort: "pre",
@@ -9,13 +9,13 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
9
9
  });
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
- exports.Store = void 0;
12
+ exports.IdbStore = void 0;
13
13
  const utils_1 = require("@yaasl/utils");
14
14
  const promisifyRequest = (request) => new Promise((resolve, reject) => {
15
15
  request.onsuccess = () => resolve(request.result);
16
16
  request.onerror = () => reject(request.error);
17
17
  });
18
- class Store {
18
+ class IdbStore {
19
19
  constructor(name) {
20
20
  var _a;
21
21
  this.name = name;
@@ -49,4 +49,4 @@ class Store {
49
49
  return this.getStore("readwrite").then(store => !store ? undefined : promisifyRequest(store.delete(key)));
50
50
  }
51
51
  }
52
- exports.Store = Store;
52
+ exports.IdbStore = IdbStore;
@@ -0,0 +1,45 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.StringStorage = void 0;
4
+ const utils_1 = require("@yaasl/utils");
5
+ const createMemoryStore = () => {
6
+ const store = {};
7
+ return {
8
+ getItem: (key) => { var _a; return (_a = store[key]) !== null && _a !== void 0 ? _a : null; },
9
+ setItem: (key, value) => (store[key] = value),
10
+ removeItem: (key) => delete store[key],
11
+ };
12
+ };
13
+ class StringStorage {
14
+ constructor({ key, store = createMemoryStore(), parser = JSON, }) {
15
+ this.key = key;
16
+ this.store = store;
17
+ this.parser = parser;
18
+ }
19
+ get() {
20
+ const value = this.store.getItem(this.key);
21
+ try {
22
+ return typeof value !== "string" ? null : this.parser.parse(value);
23
+ }
24
+ catch (_a) {
25
+ throw new Error((0, utils_1.consoleMessage)(`Value of local storage key "${this.key}" could not be parsed.`));
26
+ }
27
+ }
28
+ set(value) {
29
+ try {
30
+ if (value === null) {
31
+ this.store.removeItem(this.key);
32
+ }
33
+ else {
34
+ this.store.setItem(this.key, this.parser.stringify(value));
35
+ }
36
+ }
37
+ catch (_a) {
38
+ utils_1.log.error(`Value of atom with local storage key "${this.key}" could not be set.`, { value });
39
+ }
40
+ }
41
+ remove() {
42
+ this.store.removeItem(this.key);
43
+ }
44
+ }
45
+ exports.StringStorage = StringStorage;
@@ -1,7 +1,7 @@
1
1
  import { updater, Thenable, toVoid } from "@yaasl/utils";
2
2
  import { CONFIG } from "./config";
3
- import { Stateful } from "./Stateful";
4
- import { EffectDispatcher } from "../effects/EffectDispatcher";
3
+ import { Stateful } from "./stateful";
4
+ import { EffectDispatcher } from "../effects/effect-dispatcher";
5
5
  let key = 0;
6
6
  export class Atom extends Stateful {
7
7
  /** Default value of the atom. */
@@ -31,6 +31,7 @@ export class Atom extends Stateful {
31
31
  }
32
32
  }
33
33
  initEffects() {
34
+ // eslint-disable-next-line unicorn/consistent-function-scoping
34
35
  const updateValue = (value) => {
35
36
  super.update(value);
36
37
  return value;
@@ -1,5 +1,5 @@
1
1
  import { consoleMessage, toVoid, updater } from "@yaasl/utils";
2
- import { Stateful } from "./Stateful";
2
+ import { Stateful } from "./stateful";
3
3
  const allDidInit = (atoms) => {
4
4
  const inits = atoms
5
5
  .map(atom => atom.didInit)
@@ -13,7 +13,7 @@ export class Derive extends Stateful {
13
13
  super(undefined);
14
14
  this.getter = getter;
15
15
  this.value = getter({ get: dep => this.addGetDependency(dep) });
16
- this.setDidInit(allDidInit(Array.from(this.getterDependencies)));
16
+ this.setDidInit(allDidInit([...this.getterDependencies]));
17
17
  }
18
18
  addGetDependency(dependency) {
19
19
  if (!this.getterDependencies.has(dependency)) {
@@ -68,7 +68,7 @@ export class SettableDerive extends Derive {
68
68
  if (getterDependencies.size !== setterDependencies.size) {
69
69
  return false;
70
70
  }
71
- return Array.from(setterDependencies).every(dependency => getterDependencies.has(dependency));
71
+ return [...setterDependencies].every(dependency => getterDependencies.has(dependency));
72
72
  }
73
73
  }
74
74
  export function createDerived(getter, setter) {
@@ -1,5 +1,5 @@
1
1
  import { toVoid } from "@yaasl/utils";
2
- import { Stateful } from "./Stateful";
2
+ import { Stateful } from "./stateful";
3
3
  const selectPath = (state, path) => path
4
4
  .split(".")
5
5
  .reduce((result, key) => result[key], state);
@@ -1,6 +1,6 @@
1
- import { createActions } from "./createActions";
2
- import { Atom } from "./createAtom";
3
- import { createSelector, } from "./createSelector";
1
+ import { createActions } from "./create-actions";
2
+ import { Atom } from "./create-atom";
3
+ import { createSelector, } from "./create-selector";
4
4
  const isEmpty = (obj) => !obj || Object.keys(obj).length === 0;
5
5
  const createSelectors = (atom, selectors) => Object.fromEntries(Object.entries(selectors).map(([key, selector]) => [
6
6
  key,
@@ -11,6 +11,7 @@ export class Destroyable {
11
11
  this.dependents.clear();
12
12
  this.unsubscribers.clear();
13
13
  this.isDestroyed = true;
14
+ // eslint-disable-next-line unicorn/consistent-function-scoping
14
15
  const throwOnCall = () => {
15
16
  const name = "name" in this ? this.name : undefined;
16
17
  throw new Error(consoleMessage("The methods of a destroyed atom cannot be called.", {
@@ -1,7 +1,7 @@
1
1
  export * from "./config";
2
- export * from "./createActions";
3
- export * from "./createAtom";
4
- export * from "./createDerived";
5
- export * from "./createSelector";
6
- export * from "./createSlice";
7
- export * from "./Stateful";
2
+ export * from "./create-actions";
3
+ export * from "./create-atom";
4
+ export * from "./create-derived";
5
+ export * from "./create-selector";
6
+ export * from "./create-slice";
7
+ export * from "./stateful";
@@ -1,4 +1,4 @@
1
- import { Destroyable } from "./Destroyable";
1
+ import { Destroyable } from "./destroyable";
2
2
  export class Stateful extends Destroyable {
3
3
  value;
4
4
  /** Promise that resolves when the states initialization was finished. */
@@ -1,5 +1,5 @@
1
1
  import { isPromiseLike, updater } from "@yaasl/utils";
2
- import { Queue } from "../utils/Queue";
2
+ import { Queue } from "../utils/queue";
3
3
  const isTruthy = (value) => !!value;
4
4
  export class EffectActions {
5
5
  atom;
@@ -1,7 +1,7 @@
1
1
  import { toVoid, getWindow } from "@yaasl/utils";
2
- import { createEffect } from "./createEffect";
2
+ import { createEffect } from "./create-effect";
3
3
  import { CONFIG } from "../base";
4
- import { Expiration } from "../utils/Expiration";
4
+ import { Expiration } from "../utils/expiration";
5
5
  const STORAGE = getWindow()?.localStorage ?? {
6
6
  getItem: () => null,
7
7
  setItem: toVoid,
@@ -1,5 +1,6 @@
1
- export { createEffect } from "./createEffect";
2
- export { localStorage } from "./localStorage";
3
- export { indexedDb } from "./indexedDb";
1
+ export { createEffect } from "./create-effect";
2
+ export { localStorage } from "./local-storage";
3
+ export { sessionStorage } from "./session-storage";
4
+ export { indexedDb } from "./indexed-db";
4
5
  export { expiration } from "./expiration";
5
6
  export { migration, createMigrationStep } from "./migration";
@@ -1,6 +1,6 @@
1
- import { createEffect } from "./createEffect";
1
+ import { createEffect } from "./create-effect";
2
2
  import { CONFIG } from "../base";
3
- import { Store } from "../utils/Store";
3
+ import { IdbStore } from "../utils/idb-store";
4
4
  let atomDb = null;
5
5
  /** Middleware to save and load atom values to an indexedDb.
6
6
  *
@@ -18,7 +18,7 @@ export const indexedDb = createEffect(({ atom, options }) => {
18
18
  sort: "pre",
19
19
  init: async ({ atom, set }) => {
20
20
  if (!atomDb) {
21
- atomDb = new Store(CONFIG.name ?? "yaasl");
21
+ atomDb = new IdbStore(CONFIG.name ?? "yaasl");
22
22
  }
23
23
  const existing = await atomDb.get(key);
24
24
  if (existing != null) {
@@ -1,6 +1,12 @@
1
- import { createEffect } from "./createEffect";
1
+ import { getWindow } from "@yaasl/utils";
2
+ import { createEffect } from "./create-effect";
2
3
  import { CONFIG } from "../base";
3
- import { LocalStorage } from "../utils/LocalStorage";
4
+ import { StringStorage } from "../utils/string-storage";
5
+ const syncOverBrowserTabs = (observingKey, onTabSync) => getWindow()?.addEventListener("storage", ({ key, newValue }) => {
6
+ if (observingKey !== key)
7
+ return;
8
+ onTabSync(newValue);
9
+ });
4
10
  /** Middleware to save and load atom values to the local storage.
5
11
  *
6
12
  * @param {LocalStorageOptions | undefined} options
@@ -14,10 +20,14 @@ import { LocalStorage } from "../utils/LocalStorage";
14
20
  export const localStorage = createEffect(({ atom, options = {} }) => {
15
21
  const internalKey = CONFIG.name ? `${CONFIG.name}/${atom.name}` : atom.name;
16
22
  const { key = internalKey, parser, noTabSync } = options;
17
- const storage = new LocalStorage(key, {
23
+ const storage = new StringStorage({
24
+ key,
25
+ store: getWindow()?.localStorage,
18
26
  parser,
19
- onTabSync: noTabSync ? undefined : value => atom.set(value),
20
27
  });
28
+ if (!noTabSync) {
29
+ syncOverBrowserTabs(key, () => atom.set(storage.get() ?? atom.defaultValue));
30
+ }
21
31
  return {
22
32
  sort: "pre",
23
33
  init: ({ set }) => {
@@ -1,5 +1,5 @@
1
1
  import { getWindow, log } from "@yaasl/utils";
2
- import { createEffect } from "./createEffect";
2
+ import { createEffect } from "./create-effect";
3
3
  import { CONFIG } from "../base";
4
4
  const sortMigrations = (migrations) => {
5
5
  const first = migrations.find(migration => migration.previous === null);
@@ -0,0 +1,40 @@
1
+ import { getWindow } from "@yaasl/utils";
2
+ import { createEffect } from "./create-effect";
3
+ import { CONFIG } from "../base";
4
+ import { StringStorage } from "../utils/string-storage";
5
+ /** Middleware to save and load atom values to the session storage.
6
+ *
7
+ * @param {SessionStorageOptions | undefined} options
8
+ * @param options.key Use your own key for the session storage.
9
+ * Will be "{config-name}/{atom-name}" by default.
10
+ * @param options.noTabSync Disable the synchronization of values over browser tabs.
11
+ * @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.
12
+ *
13
+ * @returns The effect to be used on atoms.
14
+ **/
15
+ export const sessionStorage = createEffect(({ atom, options = {} }) => {
16
+ const internalKey = CONFIG.name ? `${CONFIG.name}/${atom.name}` : atom.name;
17
+ const { key = internalKey, parser } = options;
18
+ const storage = new StringStorage({
19
+ key,
20
+ store: getWindow()?.sessionStorage,
21
+ parser,
22
+ });
23
+ return {
24
+ sort: "pre",
25
+ init: ({ set }) => {
26
+ const existing = storage.get();
27
+ if (existing != null) {
28
+ set(existing);
29
+ }
30
+ },
31
+ set: ({ value, atom }) => {
32
+ if (value === atom.defaultValue) {
33
+ storage.remove();
34
+ }
35
+ else {
36
+ storage.set(value);
37
+ }
38
+ },
39
+ };
40
+ });
@@ -3,7 +3,7 @@ const promisifyRequest = (request) => new Promise((resolve, reject) => {
3
3
  request.onsuccess = () => resolve(request.result);
4
4
  request.onerror = () => reject(request.error);
5
5
  });
6
- export class Store {
6
+ export class IdbStore {
7
7
  name;
8
8
  database;
9
9
  constructor(name) {
@@ -0,0 +1,44 @@
1
+ import { consoleMessage, log } from "@yaasl/utils";
2
+ const createMemoryStore = () => {
3
+ const store = {};
4
+ return {
5
+ getItem: (key) => store[key] ?? null,
6
+ setItem: (key, value) => (store[key] = value),
7
+ removeItem: (key) => delete store[key],
8
+ };
9
+ };
10
+ export class StringStorage {
11
+ key;
12
+ store;
13
+ parser;
14
+ constructor({ key, store = createMemoryStore(), parser = JSON, }) {
15
+ this.key = key;
16
+ this.store = store;
17
+ this.parser = parser;
18
+ }
19
+ get() {
20
+ const value = this.store.getItem(this.key);
21
+ try {
22
+ return typeof value !== "string" ? null : this.parser.parse(value);
23
+ }
24
+ catch {
25
+ throw new Error(consoleMessage(`Value of local storage key "${this.key}" could not be parsed.`));
26
+ }
27
+ }
28
+ set(value) {
29
+ try {
30
+ if (value === null) {
31
+ this.store.removeItem(this.key);
32
+ }
33
+ else {
34
+ this.store.setItem(this.key, this.parser.stringify(value));
35
+ }
36
+ }
37
+ catch {
38
+ log.error(`Value of atom with local storage key "${this.key}" could not be set.`, { value });
39
+ }
40
+ }
41
+ remove() {
42
+ this.store.removeItem(this.key);
43
+ }
44
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@yaasl/core",
3
- "version": "0.11.0",
3
+ "version": "0.12.0",
4
4
  "description": "yet another atomic store library (vanilla-js)",
5
5
  "author": "PrettyCoffee",
6
6
  "license": "MIT",
@@ -1,17 +0,0 @@
1
- import { Dispatch } from "@yaasl/utils";
2
- export interface LocalStorageParser<T = any> {
3
- parse: (value: string) => T;
4
- stringify: (value: T) => string;
5
- }
6
- export interface LocalStorageConstructorOptions<T> {
7
- parser?: LocalStorageParser<T>;
8
- onTabSync?: Dispatch<T | null>;
9
- }
10
- export declare class LocalStorage<T = unknown> {
11
- private readonly key;
12
- private parser;
13
- constructor(key: string, options?: LocalStorageConstructorOptions<T>);
14
- get(): T | null;
15
- set(value: T): void;
16
- remove(): void;
17
- }
@@ -1,68 +0,0 @@
1
- "use strict";
2
- var _a, _b;
3
- Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.LocalStorage = void 0;
5
- const utils_1 = require("@yaasl/utils");
6
- const STORAGE = (_b = (_a = (0, utils_1.getWindow)()) === null || _a === void 0 ? void 0 : _a.localStorage) !== null && _b !== void 0 ? _b : {
7
- getItem: () => null,
8
- setItem: utils_1.toVoid,
9
- removeItem: utils_1.toVoid,
10
- };
11
- const defaultParser = {
12
- parse: JSON.parse,
13
- stringify: JSON.stringify,
14
- };
15
- const syncOverBrowserTabs = (observingKey, onTabSync) => {
16
- var _a;
17
- return (_a = (0, utils_1.getWindow)()) === null || _a === void 0 ? void 0 : _a.addEventListener("storage", ({ key, newValue }) => {
18
- if (observingKey !== key)
19
- return;
20
- onTabSync(newValue);
21
- });
22
- };
23
- class LocalStorage {
24
- constructor(key, options = {}) {
25
- var _a;
26
- this.key = key;
27
- this.parser = (_a = options.parser) !== null && _a !== void 0 ? _a : defaultParser;
28
- if (!options.onTabSync)
29
- return;
30
- syncOverBrowserTabs(key, value => {
31
- var _a;
32
- const newValue = value === null ? null : this.parser.parse(value);
33
- if (newValue === null) {
34
- this.remove();
35
- }
36
- else {
37
- this.set(newValue);
38
- }
39
- (_a = options.onTabSync) === null || _a === void 0 ? void 0 : _a.call(options, newValue);
40
- });
41
- }
42
- get() {
43
- const value = STORAGE.getItem(this.key);
44
- try {
45
- return typeof value !== "string" ? null : this.parser.parse(value);
46
- }
47
- catch (_a) {
48
- throw new Error((0, utils_1.consoleMessage)(`Value of local storage key "${this.key}" could not be parsed.`));
49
- }
50
- }
51
- set(value) {
52
- try {
53
- if (value === null) {
54
- STORAGE.removeItem(this.key);
55
- }
56
- else {
57
- STORAGE.setItem(this.key, this.parser.stringify(value));
58
- }
59
- }
60
- catch (_a) {
61
- utils_1.log.error(`Value of atom with local storage key "${this.key}" could not be set.`, { value });
62
- }
63
- }
64
- remove() {
65
- STORAGE.removeItem(this.key);
66
- }
67
- }
68
- exports.LocalStorage = LocalStorage;
@@ -1,60 +0,0 @@
1
- import { consoleMessage, log, toVoid, getWindow } from "@yaasl/utils";
2
- const STORAGE = getWindow()?.localStorage ?? {
3
- getItem: () => null,
4
- setItem: toVoid,
5
- removeItem: toVoid,
6
- };
7
- const defaultParser = {
8
- parse: JSON.parse,
9
- stringify: JSON.stringify,
10
- };
11
- const syncOverBrowserTabs = (observingKey, onTabSync) => getWindow()?.addEventListener("storage", ({ key, newValue }) => {
12
- if (observingKey !== key)
13
- return;
14
- onTabSync(newValue);
15
- });
16
- export class LocalStorage {
17
- key;
18
- parser;
19
- constructor(key, options = {}) {
20
- this.key = key;
21
- this.parser = options.parser ?? defaultParser;
22
- if (!options.onTabSync)
23
- return;
24
- syncOverBrowserTabs(key, value => {
25
- const newValue = value === null ? null : this.parser.parse(value);
26
- if (newValue === null) {
27
- this.remove();
28
- }
29
- else {
30
- this.set(newValue);
31
- }
32
- options.onTabSync?.(newValue);
33
- });
34
- }
35
- get() {
36
- const value = STORAGE.getItem(this.key);
37
- try {
38
- return typeof value !== "string" ? null : this.parser.parse(value);
39
- }
40
- catch {
41
- throw new Error(consoleMessage(`Value of local storage key "${this.key}" could not be parsed.`));
42
- }
43
- }
44
- set(value) {
45
- try {
46
- if (value === null) {
47
- STORAGE.removeItem(this.key);
48
- }
49
- else {
50
- STORAGE.setItem(this.key, this.parser.stringify(value));
51
- }
52
- }
53
- catch {
54
- log.error(`Value of atom with local storage key "${this.key}" could not be set.`, { value });
55
- }
56
- }
57
- remove() {
58
- STORAGE.removeItem(this.key);
59
- }
60
- }
File without changes
File without changes
File without changes
File without changes
File without changes