@propero/easy-store
Version:
Simple, intuitive, functional reactive stores for typescript
1 lines • 8.96 kB
Source Map (JSON)
{"version":3,"sources":["../src/create-accessors.ts","../src/create-get-set.ts","../src/create-patch.ts","../src/create-store-subscribe.ts","../src/create-subscribable.ts","../src/create-store.ts","../src/derive-store.ts"],"sourcesContent":["import type { AccessibleStore, StoreGetter, StoreSetter } from \"src/types\";\n\nexport function createAccessors<T, Val>(\n obj: Val,\n get: StoreGetter<T>,\n set: StoreSetter<T>\n): Val & AccessibleStore<T> {\n Object.defineProperty(obj, \"value\", {\n get,\n set,\n configurable: true,\n enumerable: true,\n });\n return obj as any;\n}\n","import {\n NotifyFunction,\n StoreGetter,\n StoreSetter,\n UpdateFunction,\n} from \"src/types\";\n\nexport function createGetSet<T>(\n initial: T,\n notify: NotifyFunction<[newVal: T, oldVal?: T]>\n): [get: StoreGetter<T>, set: StoreSetter<T>] {\n let value: T = initial;\n let oldValue: T | undefined = undefined;\n\n return [\n () => value,\n function set(newValue: T | UpdateFunction<T>): void | Promise<void> {\n if (typeof newValue === \"function\")\n return Promise.resolve((newValue as UpdateFunction<T>)(value)).then(\n set\n );\n oldValue = value;\n value = newValue;\n notify(value, oldValue);\n } as any,\n ];\n}\n","import {\n PatchFunction,\n StoreGetter,\n StorePatcher,\n StoreSetter,\n} from \"src/types\";\n\nexport function createPatch<T>(\n get: StoreGetter<T>,\n set: StoreSetter<T>\n): StorePatcher<T> {\n return function patch(\n partial: Partial<T> | PatchFunction<T>\n ): void | Promise<void> {\n if (typeof partial === \"function\")\n return Promise.resolve((partial as PatchFunction<T>)(get())).then(patch);\n set({ ...get(), ...partial } as any);\n } as any;\n}\n","import { StoreGetter, SubscribeFunction } from \"src/types\";\n\nexport function createStoreSubscribe<T>(\n sub: SubscribeFunction<[newValue: T, oldValue?: T]>,\n get: StoreGetter<T>,\n immediatelyNotify?: boolean\n): SubscribeFunction<[newValue: T, oldValue?: T]> {\n if (!immediatelyNotify) return sub;\n return function subscribe(listeners) {\n const fns = Array.isArray(listeners) ? [...listeners] : [listeners];\n for (const fn of fns) fn(get());\n return sub(fns);\n };\n}\n","import type {\n ArrayOr,\n Notifiable,\n Subscribable,\n SubscribableOptions,\n} from \"src/types\";\n\nconst tooManyListeners = (count: number) =>\n `Too many listeners registered for subscribable! maximum allowed is ${count}.\nMaybe check if you attached listeners inside of a render function, event handler or loop?\nIn case you need more listeners, try setting the maxListeners option to a higher value.`;\nexport function createSubscribable<T extends unknown[]>({\n maxListeners = 50,\n}: SubscribableOptions = {}): Subscribable<T> & Notifiable<T> {\n const listeners: ((...params: T) => void)[] = [];\n\n function subscribe(listener: ArrayOr<(...params: T) => void>) {\n const wrapped = Array.isArray(listener) ? [...listener] : [listener];\n if (listeners.length + wrapped.length > maxListeners)\n throw Object.assign(new Error(tooManyListeners(maxListeners)), {\n code: \"TOO_MANY_LISTENERS\",\n });\n listeners.push(...wrapped);\n return () => {\n for (const listener of wrapped) {\n const index = listeners.lastIndexOf(listener);\n if (index !== -1) listeners.splice(index, 1);\n }\n };\n }\n\n function notify(...params: T) {\n for (const listener of listeners) listener(...params);\n }\n\n return { subscribe, notify };\n}\n","import { createAccessors } from \"src/create-accessors\";\nimport { createGetSet } from \"src/create-get-set\";\nimport { createPatch } from \"src/create-patch\";\nimport { createStoreSubscribe } from \"src/create-store-subscribe\";\nimport { createSubscribable } from \"src/create-subscribable\";\nimport type {\n AccessibleStore,\n PatchableStore,\n ReadonlyStore,\n StoreOptions,\n WritableStore,\n} from \"src/types\";\n\nexport function createStore<T>(\n initialValue: T,\n { maxListeners, immediatelyNotify }: StoreOptions = {}\n): ReadonlyStore<T> &\n PatchableStore<T> &\n WritableStore<T> &\n AccessibleStore<T> {\n const { subscribe: sub, notify } = createSubscribable<\n [newVal: T, oldVal?: T]\n >({ maxListeners });\n const [get, set] = createGetSet(initialValue, notify);\n const patch = createPatch(get, set);\n const subscribe = createStoreSubscribe(sub, get, immediatelyNotify);\n return createAccessors({ subscribe, set, get, patch }, get, set);\n}\n","import { createStore } from \"src/create-store\";\nimport {\n Destroyable,\n PromiseOr,\n ReadonlyStore,\n StoreOptions,\n StoreValues,\n} from \"src/types\";\n\nexport function deriveStore<\n T extends ReadonlyStore<any>[] | ReadonlyArray<ReadonlyStore<any>>,\n R\n>(\n stores: T,\n handler: (...values: StoreValues<T>) => R,\n initial?: R,\n options?: StoreOptions\n): ReadonlyStore<R> & Destroyable;\nexport function deriveStore<\n T extends ReadonlyStore<any>[] | ReadonlyArray<ReadonlyStore<any>>,\n R\n>(\n stores: T,\n handler: (...values: StoreValues<T>) => Promise<R>,\n initial: R,\n options?: StoreOptions\n): ReadonlyStore<R> & Destroyable;\nexport function deriveStore<\n T extends ReadonlyStore<any>[] | ReadonlyArray<ReadonlyStore<any>>,\n R\n>(\n stores: T,\n handler: (...values: StoreValues<T>) => PromiseOr<R>,\n initial?: R,\n options?: StoreOptions\n): ReadonlyStore<R> & Destroyable {\n const { get, set, subscribe } = createStore<R>(initial as R, options);\n const listener = () => {\n const result = handler(...(stores.map((it) => it.get()) as any));\n if (\n result &&\n typeof result === \"object\" &&\n \"then\" in result &&\n typeof result[\"then\"] === \"function\"\n )\n result.then(set);\n else set(result as any);\n };\n\n listener();\n const handles = stores.map((it) => it.subscribe(listener));\n const destroy = () => handles.forEach((it) => it());\n\n return { get, subscribe, destroy };\n}\n"],"mappings":"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","names":["createAccessors","obj","get","set","createGetSet","initial","notify","value","oldValue","set","newValue","createPatch","get","set","patch","partial","createStoreSubscribe","sub","get","immediatelyNotify","listeners","fns","fn","tooManyListeners","count","createSubscribable","maxListeners","listeners","subscribe","listener","wrapped","index","notify","params","createStore","initialValue","maxListeners","immediatelyNotify","sub","notify","createSubscribable","get","set","createGetSet","patch","createPatch","subscribe","createStoreSubscribe","createAccessors","deriveStore","stores","handler","initial","options","get","set","subscribe","createStore","listener","result","it","handles"]}