cross-state 1.9.9 → 1.9.11
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/duration-B07HkB7T.cjs +142 -0
- package/dist/duration-B07HkB7T.cjs.map +1 -0
- package/dist/duration-ByqeeOs7.js +124 -0
- package/dist/duration-ByqeeOs7.js.map +1 -0
- package/dist/index.cjs +6 -4
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +5 -3
- package/dist/index.js.map +1 -1
- package/dist/mutative/register.cjs +1 -1
- package/dist/mutative/register.cjs.map +1 -1
- package/dist/mutative/register.d.cts +1 -1
- package/dist/mutative/register.d.ts +1 -1
- package/dist/mutative/register.js +1 -1
- package/dist/mutative/register.js.map +1 -1
- package/dist/patchMethods-BBQDDqwe.cjs.map +1 -1
- package/dist/{patchMethods-R3f7HxTy.d.cts → patchMethods-Bfu4UYG7.d.cts} +2 -2
- package/dist/{patchMethods--ekCkYUF.d.ts → patchMethods-CEUdeSb_.d.ts} +2 -2
- package/dist/patchMethods-D3cdG80W.js.map +1 -1
- package/dist/patches/index.d.cts +1 -1
- package/dist/patches/index.d.ts +1 -1
- package/dist/patches/register.cjs +1 -1
- package/dist/patches/register.cjs.map +1 -1
- package/dist/patches/register.d.cts +2 -2
- package/dist/patches/register.d.ts +2 -2
- package/dist/patches/register.js +1 -1
- package/dist/patches/register.js.map +1 -1
- package/dist/persist/index.cjs +4 -0
- package/dist/persist/index.d.cts +2 -0
- package/dist/persist/index.d.ts +2 -0
- package/dist/persist/index.js +3 -0
- package/dist/persist/register.cjs +2 -2
- package/dist/persist/register.cjs.map +1 -1
- package/dist/persist/register.d.cts +1 -1
- package/dist/persist/register.d.ts +1 -1
- package/dist/persist/register.js +2 -2
- package/dist/persist/register.js.map +1 -1
- package/dist/{persist-xv73m7UR.js → persist-BRvAr-ZK.js} +2 -2
- package/dist/{persist-xv73m7UR.js.map → persist-BRvAr-ZK.js.map} +1 -1
- package/dist/{persist-B341lrOA.cjs → persist-IJeNYfT6.cjs} +11 -11
- package/dist/{persist-B341lrOA.cjs.map → persist-IJeNYfT6.cjs.map} +1 -1
- package/dist/react/index.cjs +8 -7
- package/dist/react/index.cjs.map +1 -1
- package/dist/react/index.d.cts +1 -1
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +3 -2
- package/dist/react/index.js.map +1 -1
- package/dist/react/register.cjs +3 -3
- package/dist/react/register.cjs.map +1 -1
- package/dist/react/register.d.cts +2 -2
- package/dist/react/register.d.ts +2 -2
- package/dist/react/register.js +3 -3
- package/dist/react/register.js.map +1 -1
- package/dist/{scope-BfaweXvz.js → scope-CtOcmKmO.js} +3 -2
- package/dist/{scope-BfaweXvz.js.map → scope-CtOcmKmO.js.map} +1 -1
- package/dist/{scope-8MUrzqlS.cjs → scope-DiDmyExm.cjs} +5 -4
- package/dist/{scope-8MUrzqlS.cjs.map → scope-DiDmyExm.cjs.map} +1 -1
- package/dist/{store-BmlnyYal.js → store-9XkJrxBs.js} +3 -124
- package/dist/store-9XkJrxBs.js.map +1 -0
- package/dist/{store-fmAYV5hy.cjs → store-B_ToOCrU.cjs} +10 -149
- package/dist/store-B_ToOCrU.cjs.map +1 -0
- package/dist/{storeMethods-pGlt0zfb.js → storeMethods-D54_9ZCG.js} +2 -2
- package/dist/{storeMethods-pGlt0zfb.js.map → storeMethods-D54_9ZCG.js.map} +1 -1
- package/dist/{storeMethods-DrMQ7hqX.d.cts → storeMethods-DlScpjKj.d.cts} +2 -2
- package/dist/{storeMethods-CYX3AAnA.d.ts → storeMethods-M7KjCOHg.d.ts} +2 -2
- package/dist/{storeMethods-DYgUGHSk.cjs → storeMethods-fBHg4hVK.cjs} +2 -2
- package/dist/{storeMethods-DYgUGHSk.cjs.map → storeMethods-fBHg4hVK.cjs.map} +1 -1
- package/package.json +5 -1
- package/dist/store-BmlnyYal.js.map +0 -1
- package/dist/store-fmAYV5hy.cjs.map +0 -1
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { r as patchMethods } from "../patchMethods-
|
|
1
|
+
import { r as patchMethods } from "../patchMethods-Bfu4UYG7.cjs";
|
|
2
2
|
|
|
3
3
|
//#region src/patches/register.d.ts
|
|
4
4
|
type PatchMethods = typeof patchMethods;
|
|
5
|
-
declare module "
|
|
5
|
+
declare module ".." {
|
|
6
6
|
interface Store<T> extends PatchMethods {}
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=register.d.cts.map
|
|
@@ -1,8 +1,8 @@
|
|
|
1
|
-
import { r as patchMethods } from "../patchMethods
|
|
1
|
+
import { r as patchMethods } from "../patchMethods-CEUdeSb_.js";
|
|
2
2
|
|
|
3
3
|
//#region src/patches/register.d.ts
|
|
4
4
|
type PatchMethods = typeof patchMethods;
|
|
5
|
-
declare module "
|
|
5
|
+
declare module ".." {
|
|
6
6
|
interface Store<T> extends PatchMethods {}
|
|
7
7
|
}
|
|
8
8
|
//# sourceMappingURL=register.d.ts.map
|
package/dist/patches/register.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","names":[],"sources":["../../src/patches/register.ts"],"sourcesContent":["import { patchMethods } from './patchMethods';\nimport { Store } from '@core';\nimport { autobind } from '@lib/autobind';\n\ntype PatchMethods = typeof patchMethods;\n\ndeclare module '
|
|
1
|
+
{"version":3,"file":"register.js","names":[],"sources":["../../src/patches/register.ts"],"sourcesContent":["import { patchMethods } from './patchMethods';\nimport { Store } from '@core';\nimport { autobind } from '@lib/autobind';\n\ntype PatchMethods = typeof patchMethods;\n\ndeclare module '..' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface Store<T> extends PatchMethods {}\n}\n\nObject.assign(Store.prototype, patchMethods);\nautobind(Store);\n"],"mappings":";;;;AAWA,OAAO,OAAO,MAAM,WAAW,YAAY;AAC3C,SAAS,KAAK"}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as PersistStorageBase, c as PersistStorageWithListItems, i as PersistStorage, n as PersistOptions, o as PersistStorageWithKeys, r as persist, s as PersistStorageWithLength, t as Persist } from "../persist-CoSWtRt0.cjs";
|
|
2
|
+
export { type Persist, type PersistOptions, type PersistStorage, type PersistStorageBase, type PersistStorageWithKeys, type PersistStorageWithLength, type PersistStorageWithListItems, persist };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import { a as PersistStorageBase, c as PersistStorageWithListItems, i as PersistStorage, n as PersistOptions, o as PersistStorageWithKeys, r as persist, s as PersistStorageWithLength, t as Persist } from "../persist-XVT4fROX.js";
|
|
2
|
+
export { type Persist, type PersistOptions, type PersistStorage, type PersistStorageBase, type PersistStorageWithKeys, type PersistStorageWithLength, type PersistStorageWithListItems, persist };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_store = require('../store-
|
|
2
|
-
const require_persist = require('../persist-
|
|
1
|
+
const require_store = require('../store-B_ToOCrU.cjs');
|
|
2
|
+
const require_persist = require('../persist-IJeNYfT6.cjs');
|
|
3
3
|
|
|
4
4
|
//#region src/persist/register.ts
|
|
5
5
|
require_store.Store.addHook((store) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.cjs","names":["Store","persist"],"sources":["../../src/persist/register.ts"],"sourcesContent":["import { Store } from '@core';\nimport { persist, type Persist, type PersistOptions } from '@persist/persist';\n\ndeclare module '
|
|
1
|
+
{"version":3,"file":"register.cjs","names":["Store","persist"],"sources":["../../src/persist/register.ts"],"sourcesContent":["import { Store } from '@core';\nimport { persist, type Persist, type PersistOptions } from '@persist/persist';\n\ndeclare module '..' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface StoreOptions<T> {\n persist?: PersistOptions<T>;\n }\n\n interface Store<T> {\n persistance?: Persist<T>;\n }\n}\n\nStore.addHook((store) => {\n if (store.options.persist) {\n store.persistance = persist(store, store.options.persist);\n }\n});\n"],"mappings":";;;;AAcAA,oBAAM,SAAS,UAAU;CACvB,IAAI,MAAM,QAAQ,SAChB,MAAM,cAAcC,wBAAQ,OAAO,MAAM,QAAQ,OAAO;AAE5D,CAAC"}
|
package/dist/persist/register.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { t as Store } from "../store-
|
|
2
|
-
import { t as persist } from "../persist-
|
|
1
|
+
import { t as Store } from "../store-9XkJrxBs.js";
|
|
2
|
+
import { t as persist } from "../persist-BRvAr-ZK.js";
|
|
3
3
|
|
|
4
4
|
//#region src/persist/register.ts
|
|
5
5
|
Store.addHook((store) => {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"register.js","names":[],"sources":["../../src/persist/register.ts"],"sourcesContent":["import { Store } from '@core';\nimport { persist, type Persist, type PersistOptions } from '@persist/persist';\n\ndeclare module '
|
|
1
|
+
{"version":3,"file":"register.js","names":[],"sources":["../../src/persist/register.ts"],"sourcesContent":["import { Store } from '@core';\nimport { persist, type Persist, type PersistOptions } from '@persist/persist';\n\ndeclare module '..' {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n interface StoreOptions<T> {\n persist?: PersistOptions<T>;\n }\n\n interface Store<T> {\n persistance?: Persist<T>;\n }\n}\n\nStore.addHook((store) => {\n if (store.options.persist) {\n store.persistance = persist(store, store.options.persist);\n }\n});\n"],"mappings":";;;;AAcA,MAAM,SAAS,UAAU;CACvB,IAAI,MAAM,QAAQ,SAChB,MAAM,cAAc,QAAQ,OAAO,MAAM,QAAQ,OAAO;AAE5D,CAAC"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { f as queue, m as isPromise, u as calcDuration } from "./store-BmlnyYal.js";
|
|
2
1
|
import { a as set, i as remove, l as shallowEqual, n as get, t as castArrayPath } from "./propAccess-CsUaG5V_.js";
|
|
2
|
+
import { n as queue, r as isPromise, t as calcDuration } from "./duration-ByqeeOs7.js";
|
|
3
3
|
import { n as subscribePatches } from "./patchMethods-D3cdG80W.js";
|
|
4
4
|
import { i as toExtendedJsonString, n as fromExtendedJsonString } from "./extendedJson-BOmrkRrD.js";
|
|
5
5
|
|
|
@@ -250,4 +250,4 @@ function isPlainPath(p) {
|
|
|
250
250
|
|
|
251
251
|
//#endregion
|
|
252
252
|
export { persist as t };
|
|
253
|
-
//# sourceMappingURL=persist-
|
|
253
|
+
//# sourceMappingURL=persist-BRvAr-ZK.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist-xv73m7UR.js","names":[],"sources":["../src/lib/promiseChain.ts","../src/persist/persistStorage.ts","../src/persist/persistPathHelpers.ts","../src/persist/persist.ts"],"sourcesContent":["import isPromise from '@lib/isPromise';\n\nexport interface Chain<T> {\n value: T;\n next<S>(fn: (value: Awaited<T>) => S): T extends Promise<any> ? Chain<Promise<S>> : Chain<S>;\n}\n\nexport default function promiseChain<T>(value: T | (() => T)): Chain<T> {\n if (value instanceof Function) {\n value = value();\n }\n\n return {\n value,\n next(fn) {\n const next = isPromise(value)\n ? value.then((value) => fn(value as Awaited<T>))\n : fn(value as Awaited<T>);\n\n return promiseChain(next) as any;\n },\n };\n}\n","import isPromise from '@lib/isPromise';\nimport promiseChain from '@lib/promiseChain';\n\nexport interface PersistStorageBase {\n getItem: (key: string) => string | null | Promise<string | null>;\n setItem: (key: string, value: string) => void | Promise<unknown>;\n removeItem: (key: string) => void | Promise<unknown>;\n}\n\nexport interface PersistStorageWithKeys extends PersistStorageBase {\n keys: () => string[] | Promise<string[]>;\n}\n\nexport interface PersistStorageWithLength extends PersistStorageBase {\n length: number | (() => number | Promise<number>);\n key: (keyIndex: number) => string | null | Promise<string | null>;\n}\n\nexport interface PersistStorageWithListItems extends PersistStorageBase {\n listItems: () => Map<string, string> | Promise<Map<string, string>>;\n}\n\nexport type PersistStorage =\n | PersistStorageWithKeys\n | PersistStorageWithLength\n | PersistStorageWithListItems;\n\nexport function normalizeStorage(storage: PersistStorage): PersistStorageWithListItems {\n return {\n getItem: storage.getItem.bind(storage),\n setItem: storage.setItem.bind(storage),\n removeItem: storage.removeItem.bind(storage),\n\n listItems() {\n if ('listItems' in storage) {\n return storage.listItems();\n }\n\n return promiseChain(() => {\n if ('keys' in storage) {\n return storage.keys();\n } else {\n return promiseChain(\n storage.length instanceof Function ? storage.length() : storage.length,\n )\n .next((length) => {\n const keys = Array.from({ length }, (_, index) => storage.key(index));\n return keys.some(isPromise) ? Promise.all(keys) : (keys as (string | null)[]);\n })\n .next((keys) => {\n return keys.filter((key): key is string => typeof key === 'string');\n }).value;\n }\n })\n .next((keys) => {\n const results = keys.map(\n (key) =>\n promiseChain(storage.getItem(key)).next((value) => [key, value] as const).value,\n );\n\n return results.some(isPromise)\n ? Promise.all(results)\n : (results as [string, string | null][]);\n })\n .next((results) => {\n return new Map(results.filter(([, value]) => value !== null) as [string, string][]);\n }).value;\n },\n };\n}\n","import type { KeyType } from '@lib/path';\n\nexport const isAncestor = (ancestor: KeyType[], path: KeyType[]): boolean => {\n return (\n ancestor.length <= path.length &&\n ancestor.every((v, i) => v === '*' || path[i] === '*' || v === path[i])\n );\n};\n\nexport const split = (value: any, path: KeyType[]): { path: KeyType[]; value: unknown }[] => {\n const [first, ...rest] = path;\n if (first === undefined) return [{ path: [], value }];\n\n let entries: Map<KeyType, unknown>;\n if (value instanceof Map) {\n entries = value;\n } else if (value instanceof Set) {\n entries = new Map([...value].map((v, i) => [i, v]));\n } else if (Array.isArray(value)) {\n entries = new Map(value.map((v, i) => [i, v]));\n } else if (typeof value === 'object' && value !== null) {\n entries = new Map(Object.entries(value));\n } else {\n return [{ path: [], value }];\n }\n\n if (first === '*') {\n return [...entries].flatMap(([k, v]) =>\n split(v, rest).map(({ path, value }) => ({ path: [k, ...path], value })),\n );\n }\n\n const subValue = entries.get(first);\n if (subValue === undefined) return [{ path: [], value }];\n\n return split(subValue, rest).map(({ path, value }) => ({ path: [first, ...path], value }));\n};\n","import {\n normalizeStorage,\n type PersistStorage,\n type PersistStorageWithListItems,\n} from './persistStorage';\nimport { type Cancel, type Duration, type Store } from '@core';\nimport { calcDuration } from '@lib/duration';\nimport { shallowEqual } from '@lib/equals';\nimport { fromExtendedJsonString, toExtendedJsonString } from '@lib/extendedJson';\nimport isPromise from '@lib/isPromise';\nimport type { KeyType, WildcardPath } from '@lib/path';\nimport promiseChain from '@lib/promiseChain';\nimport { castArrayPath, get, remove, set } from '@lib/propAccess';\nimport { queue } from '@lib/queue';\nimport { subscribePatches } from '@patches/patchMethods';\nimport { isAncestor, split } from '@persist/persistPathHelpers';\n\ntype PathOption<T> =\n | WildcardPath<T>\n | {\n path: WildcardPath<T>;\n // throttle?: Duration;\n };\n\ntype Key = { type: 'internal'; path: string } | { type: 'data'; path: KeyType[] };\n\nexport interface PersistOptions<T> {\n id: string;\n storage: PersistStorage;\n paths?: PathOption<T>[];\n throttle?: Duration;\n persistInitialState?: boolean;\n}\n\nexport class Persist<T> {\n readonly storage: PersistStorageWithListItems;\n readonly [Symbol.dispose]!: Cancel;\n\n readonly paths: {\n path: KeyType[];\n throttle?: number;\n }[];\n\n readonly initialized: Promise<void>;\n\n private resolveInitialized?: () => void;\n\n private channel: BroadcastChannel;\n\n private queue = queue();\n\n private handles = new Set<Cancel>();\n\n private stopped = false;\n\n private updateInProgress = new Map<string, unknown>();\n\n private prefix;\n\n constructor(\n public readonly store: Store<T>,\n public readonly options: PersistOptions<T>,\n ) {\n this.storage = normalizeStorage(options.storage);\n this.channel = new BroadcastChannel(`cross-state-persist_${options.id}`);\n this.prefix = `${options.id}:`;\n\n if (Symbol.dispose) {\n this[Symbol.dispose] = () => this.stop();\n }\n\n this.paths = (options.paths ?? [])\n .map<{\n path: KeyType[];\n throttle?: number;\n }>((p) => {\n if (isPlainPath(p)) {\n return {\n path: castArrayPath(p),\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n };\n }\n\n const _p = p as { path: KeyType[]; throttle?: Duration };\n\n return {\n path: castArrayPath(_p.path),\n throttle:\n (_p.throttle ? calcDuration(_p.throttle) : undefined) ??\n (options.throttle ? calcDuration(options.throttle) : undefined),\n };\n })\n .sort((a, b) => b.path.length - a.path.length);\n\n if (this.paths.length === 0) {\n this.paths.push({\n path: ['*'],\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n });\n }\n\n this.initialized = new Promise((resolve) => {\n this.resolveInitialized = resolve;\n });\n\n this.watchStore();\n void this.watchStorage();\n }\n\n private watchStore() {\n const throttle = Math.min(...this.paths.map((p) => p.throttle ?? 0)) || undefined;\n\n const cancel = subscribePatches.apply(this.store as Store<unknown>, [\n (patches, reversePatches) => {\n let i = 0;\n for (const patch of patches) {\n const reversePatch = reversePatches[i++];\n\n const stringPath = JSON.stringify(patch.path);\n if (\n this.updateInProgress.has(stringPath) &&\n this.updateInProgress.get(stringPath) ===\n (patch.op === 'remove' ? undefined : patch.value)\n ) {\n continue;\n }\n\n const matchingPaths = this.paths.filter(\n (p) => isAncestor(p.path, patch.path) || isAncestor(patch.path, p.path),\n );\n\n for (const { path } of matchingPaths) {\n if (path.length <= patch.path.length) {\n const pathToSave = patch.path.slice(0, path.length);\n void this.queue(() => this.save(pathToSave), pathToSave);\n } else if (patch.op === 'remove') {\n const subValues = split(\n reversePatch?.op === 'add' ? reversePatch.value : {},\n path.slice(patch.path.length),\n );\n\n for (const { path } of subValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n } else {\n const updatedValues = split(patch.value, path.slice(patch.path.length));\n const removedValues = split(\n reversePatch?.op !== 'remove' ? (reversePatch?.value ?? {}) : {},\n path.slice(patch.path.length),\n ).filter((v) => !updatedValues.some((u) => shallowEqual(u.path, v.path)));\n\n for (const { path } of updatedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n for (const { path } of removedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n }\n }\n }\n },\n { runNow: this.options.persistInitialState ?? false, passive: true, throttle },\n ]);\n\n this.handles.add(cancel);\n }\n\n private async watchStorage() {\n if (!this.options.persistInitialState) {\n let items = this.storage.listItems();\n if (isPromise(items)) {\n items = await items;\n }\n\n if (this.stopped) {\n return;\n }\n\n const toLoad = new Map(\n [...items.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .map(([key, value]) => [this.parseKey(key), value])\n .filter(([key]) => key) as [Key, string][],\n );\n\n void this.queue(() => this.load(toLoad));\n }\n\n void this.queue(() => this.resolveInitialized?.());\n\n const listener = (event: MessageEvent) => {\n void this.queue(() => this.load([{ type: 'data', path: event.data }]));\n };\n\n this.channel.addEventListener('message', listener);\n this.handles.add(() => this.channel.removeEventListener('message', listener));\n }\n\n private buildKey({ type, path }: Key) {\n return `${this.prefix}${type === 'internal' ? path : JSON.stringify(path)}`;\n }\n\n private parseKey(key: string): Key | undefined {\n if (!key.startsWith(this.prefix)) {\n return;\n }\n\n key = key.slice(this.prefix.length);\n\n if (!key.startsWith('[')) {\n return { type: 'internal', path: key };\n }\n\n return { type: 'data', path: JSON.parse(key) as KeyType[] };\n }\n\n private load(items: Key[] | Map<Key, string>): void | Promise<void> {\n return promiseChain(() => {\n if (Array.isArray(items)) {\n return promiseChain(() => {\n const entries = items.map(\n (key) =>\n promiseChain(() => {\n return this.storage.getItem(this.buildKey(key));\n }).next((value) => [key, value] as const).value,\n );\n\n return entries.some(isPromise)\n ? Promise.all(entries)\n : (entries as [Key, string | null][]);\n }).next((entries) => {\n return entries.filter((entry) => entry !== null) as [Key, string][];\n }).value;\n } else {\n return [...items.entries()];\n }\n }).next((entries) => {\n if (this.stopped) {\n return;\n }\n\n const toWrite = entries\n .filter(([key, value]) => {\n if (key.type !== 'data' || !value) {\n return;\n }\n\n if (\n !this.paths.find(\n (p) =>\n (p.path.length === 1 && p.path[0] === '*' && key.path.length === 0) ||\n (p.path.length === key.path.length && isAncestor(p.path, key.path)),\n )\n ) {\n return null;\n }\n\n const inSaveQueue = this.queue\n .getRefs()\n .find((ref) => isAncestor(ref, key.path) || isAncestor(key.path, ref));\n return !inSaveQueue;\n })\n .map(([key, value]) => {\n try {\n return {\n path: key.path,\n value: !value || value === 'undefined' ? undefined : fromExtendedJsonString(value),\n };\n } catch {\n return undefined;\n }\n })\n .filter(Boolean) as { path: KeyType[]; value: unknown }[];\n\n if (toWrite.length > 0) {\n for (const { path, value } of toWrite) {\n this.updateInProgress.set(JSON.stringify(path), value);\n }\n\n this.store.set((state) => {\n for (const { path, value } of toWrite) {\n if (value === undefined) {\n state = remove(state, path as any);\n } else {\n state = set(state, path as any, value);\n }\n }\n\n return state;\n });\n\n this.updateInProgress.clear();\n }\n\n const versionEntry = entries.find(\n ([key]) => key.type === 'internal' && key.path === 'version',\n );\n if (versionEntry) {\n this.store.version = versionEntry[1];\n }\n }).value;\n }\n\n private save(path: KeyType[]): void | Promise<unknown> {\n const key = this.buildKey({ type: 'data', path });\n const value = get(this.store.get() as any, path);\n\n return promiseChain(value)\n .next((value) => {\n if (value === undefined) {\n return this.storage.removeItem(key);\n } else {\n return this.storage.setItem(key, toExtendedJsonString(value));\n }\n })\n .next(() => {\n this.channel.postMessage(path);\n\n if (this.store.version) {\n return this.storage.setItem(\n this.buildKey({ type: 'internal', path: 'version' }),\n this.store.version,\n );\n } else {\n return this.storage.removeItem(this.buildKey({ type: 'internal', path: 'version' }));\n }\n }).value;\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n\n for (const handle of this.handles) {\n handle();\n }\n\n await this.queue.whenDone();\n this.channel.close();\n }\n}\n\nexport function persist<T>(store: Store<T>, options: PersistOptions<T>): Persist<T> {\n return new Persist<T>(store, options);\n}\n\nfunction isPlainPath<T>(p: PathOption<T>): p is WildcardPath<T> & (KeyType[] | string) {\n return typeof p === 'string' || Array.isArray(p);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"persist-BRvAr-ZK.js","names":[],"sources":["../src/lib/promiseChain.ts","../src/persist/persistStorage.ts","../src/persist/persistPathHelpers.ts","../src/persist/persist.ts"],"sourcesContent":["import isPromise from '@lib/isPromise';\n\nexport interface Chain<T> {\n value: T;\n next<S>(fn: (value: Awaited<T>) => S): T extends Promise<any> ? Chain<Promise<S>> : Chain<S>;\n}\n\nexport default function promiseChain<T>(value: T | (() => T)): Chain<T> {\n if (value instanceof Function) {\n value = value();\n }\n\n return {\n value,\n next(fn) {\n const next = isPromise(value)\n ? value.then((value) => fn(value as Awaited<T>))\n : fn(value as Awaited<T>);\n\n return promiseChain(next) as any;\n },\n };\n}\n","import isPromise from '@lib/isPromise';\nimport promiseChain from '@lib/promiseChain';\n\nexport interface PersistStorageBase {\n getItem: (key: string) => string | null | Promise<string | null>;\n setItem: (key: string, value: string) => void | Promise<unknown>;\n removeItem: (key: string) => void | Promise<unknown>;\n}\n\nexport interface PersistStorageWithKeys extends PersistStorageBase {\n keys: () => string[] | Promise<string[]>;\n}\n\nexport interface PersistStorageWithLength extends PersistStorageBase {\n length: number | (() => number | Promise<number>);\n key: (keyIndex: number) => string | null | Promise<string | null>;\n}\n\nexport interface PersistStorageWithListItems extends PersistStorageBase {\n listItems: () => Map<string, string> | Promise<Map<string, string>>;\n}\n\nexport type PersistStorage =\n | PersistStorageWithKeys\n | PersistStorageWithLength\n | PersistStorageWithListItems;\n\nexport function normalizeStorage(storage: PersistStorage): PersistStorageWithListItems {\n return {\n getItem: storage.getItem.bind(storage),\n setItem: storage.setItem.bind(storage),\n removeItem: storage.removeItem.bind(storage),\n\n listItems() {\n if ('listItems' in storage) {\n return storage.listItems();\n }\n\n return promiseChain(() => {\n if ('keys' in storage) {\n return storage.keys();\n } else {\n return promiseChain(\n storage.length instanceof Function ? storage.length() : storage.length,\n )\n .next((length) => {\n const keys = Array.from({ length }, (_, index) => storage.key(index));\n return keys.some(isPromise) ? Promise.all(keys) : (keys as (string | null)[]);\n })\n .next((keys) => {\n return keys.filter((key): key is string => typeof key === 'string');\n }).value;\n }\n })\n .next((keys) => {\n const results = keys.map(\n (key) =>\n promiseChain(storage.getItem(key)).next((value) => [key, value] as const).value,\n );\n\n return results.some(isPromise)\n ? Promise.all(results)\n : (results as [string, string | null][]);\n })\n .next((results) => {\n return new Map(results.filter(([, value]) => value !== null) as [string, string][]);\n }).value;\n },\n };\n}\n","import type { KeyType } from '@lib/path';\n\nexport const isAncestor = (ancestor: KeyType[], path: KeyType[]): boolean => {\n return (\n ancestor.length <= path.length &&\n ancestor.every((v, i) => v === '*' || path[i] === '*' || v === path[i])\n );\n};\n\nexport const split = (value: any, path: KeyType[]): { path: KeyType[]; value: unknown }[] => {\n const [first, ...rest] = path;\n if (first === undefined) return [{ path: [], value }];\n\n let entries: Map<KeyType, unknown>;\n if (value instanceof Map) {\n entries = value;\n } else if (value instanceof Set) {\n entries = new Map([...value].map((v, i) => [i, v]));\n } else if (Array.isArray(value)) {\n entries = new Map(value.map((v, i) => [i, v]));\n } else if (typeof value === 'object' && value !== null) {\n entries = new Map(Object.entries(value));\n } else {\n return [{ path: [], value }];\n }\n\n if (first === '*') {\n return [...entries].flatMap(([k, v]) =>\n split(v, rest).map(({ path, value }) => ({ path: [k, ...path], value })),\n );\n }\n\n const subValue = entries.get(first);\n if (subValue === undefined) return [{ path: [], value }];\n\n return split(subValue, rest).map(({ path, value }) => ({ path: [first, ...path], value }));\n};\n","import {\n normalizeStorage,\n type PersistStorage,\n type PersistStorageWithListItems,\n} from './persistStorage';\nimport { type Cancel, type Duration, type Store } from '@core';\nimport { calcDuration } from '@lib/duration';\nimport { shallowEqual } from '@lib/equals';\nimport { fromExtendedJsonString, toExtendedJsonString } from '@lib/extendedJson';\nimport isPromise from '@lib/isPromise';\nimport type { KeyType, WildcardPath } from '@lib/path';\nimport promiseChain from '@lib/promiseChain';\nimport { castArrayPath, get, remove, set } from '@lib/propAccess';\nimport { queue } from '@lib/queue';\nimport { subscribePatches } from '@patches/patchMethods';\nimport { isAncestor, split } from '@persist/persistPathHelpers';\n\ntype PathOption<T> =\n | WildcardPath<T>\n | {\n path: WildcardPath<T>;\n // throttle?: Duration;\n };\n\ntype Key = { type: 'internal'; path: string } | { type: 'data'; path: KeyType[] };\n\nexport interface PersistOptions<T> {\n id: string;\n storage: PersistStorage;\n paths?: PathOption<T>[];\n throttle?: Duration;\n persistInitialState?: boolean;\n}\n\nexport class Persist<T> {\n readonly storage: PersistStorageWithListItems;\n readonly [Symbol.dispose]!: Cancel;\n\n readonly paths: {\n path: KeyType[];\n throttle?: number;\n }[];\n\n readonly initialized: Promise<void>;\n\n private resolveInitialized?: () => void;\n\n private channel: BroadcastChannel;\n\n private queue = queue();\n\n private handles = new Set<Cancel>();\n\n private stopped = false;\n\n private updateInProgress = new Map<string, unknown>();\n\n private prefix;\n\n constructor(\n public readonly store: Store<T>,\n public readonly options: PersistOptions<T>,\n ) {\n this.storage = normalizeStorage(options.storage);\n this.channel = new BroadcastChannel(`cross-state-persist_${options.id}`);\n this.prefix = `${options.id}:`;\n\n if (Symbol.dispose) {\n this[Symbol.dispose] = () => this.stop();\n }\n\n this.paths = (options.paths ?? [])\n .map<{\n path: KeyType[];\n throttle?: number;\n }>((p) => {\n if (isPlainPath(p)) {\n return {\n path: castArrayPath(p),\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n };\n }\n\n const _p = p as { path: KeyType[]; throttle?: Duration };\n\n return {\n path: castArrayPath(_p.path),\n throttle:\n (_p.throttle ? calcDuration(_p.throttle) : undefined) ??\n (options.throttle ? calcDuration(options.throttle) : undefined),\n };\n })\n .sort((a, b) => b.path.length - a.path.length);\n\n if (this.paths.length === 0) {\n this.paths.push({\n path: ['*'],\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n });\n }\n\n this.initialized = new Promise((resolve) => {\n this.resolveInitialized = resolve;\n });\n\n this.watchStore();\n void this.watchStorage();\n }\n\n private watchStore() {\n const throttle = Math.min(...this.paths.map((p) => p.throttle ?? 0)) || undefined;\n\n const cancel = subscribePatches.apply(this.store as Store<unknown>, [\n (patches, reversePatches) => {\n let i = 0;\n for (const patch of patches) {\n const reversePatch = reversePatches[i++];\n\n const stringPath = JSON.stringify(patch.path);\n if (\n this.updateInProgress.has(stringPath) &&\n this.updateInProgress.get(stringPath) ===\n (patch.op === 'remove' ? undefined : patch.value)\n ) {\n continue;\n }\n\n const matchingPaths = this.paths.filter(\n (p) => isAncestor(p.path, patch.path) || isAncestor(patch.path, p.path),\n );\n\n for (const { path } of matchingPaths) {\n if (path.length <= patch.path.length) {\n const pathToSave = patch.path.slice(0, path.length);\n void this.queue(() => this.save(pathToSave), pathToSave);\n } else if (patch.op === 'remove') {\n const subValues = split(\n reversePatch?.op === 'add' ? reversePatch.value : {},\n path.slice(patch.path.length),\n );\n\n for (const { path } of subValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n } else {\n const updatedValues = split(patch.value, path.slice(patch.path.length));\n const removedValues = split(\n reversePatch?.op !== 'remove' ? (reversePatch?.value ?? {}) : {},\n path.slice(patch.path.length),\n ).filter((v) => !updatedValues.some((u) => shallowEqual(u.path, v.path)));\n\n for (const { path } of updatedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n for (const { path } of removedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n }\n }\n }\n },\n { runNow: this.options.persistInitialState ?? false, passive: true, throttle },\n ]);\n\n this.handles.add(cancel);\n }\n\n private async watchStorage() {\n if (!this.options.persistInitialState) {\n let items = this.storage.listItems();\n if (isPromise(items)) {\n items = await items;\n }\n\n if (this.stopped) {\n return;\n }\n\n const toLoad = new Map(\n [...items.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .map(([key, value]) => [this.parseKey(key), value])\n .filter(([key]) => key) as [Key, string][],\n );\n\n void this.queue(() => this.load(toLoad));\n }\n\n void this.queue(() => this.resolveInitialized?.());\n\n const listener = (event: MessageEvent) => {\n void this.queue(() => this.load([{ type: 'data', path: event.data }]));\n };\n\n this.channel.addEventListener('message', listener);\n this.handles.add(() => this.channel.removeEventListener('message', listener));\n }\n\n private buildKey({ type, path }: Key) {\n return `${this.prefix}${type === 'internal' ? path : JSON.stringify(path)}`;\n }\n\n private parseKey(key: string): Key | undefined {\n if (!key.startsWith(this.prefix)) {\n return;\n }\n\n key = key.slice(this.prefix.length);\n\n if (!key.startsWith('[')) {\n return { type: 'internal', path: key };\n }\n\n return { type: 'data', path: JSON.parse(key) as KeyType[] };\n }\n\n private load(items: Key[] | Map<Key, string>): void | Promise<void> {\n return promiseChain(() => {\n if (Array.isArray(items)) {\n return promiseChain(() => {\n const entries = items.map(\n (key) =>\n promiseChain(() => {\n return this.storage.getItem(this.buildKey(key));\n }).next((value) => [key, value] as const).value,\n );\n\n return entries.some(isPromise)\n ? Promise.all(entries)\n : (entries as [Key, string | null][]);\n }).next((entries) => {\n return entries.filter((entry) => entry !== null) as [Key, string][];\n }).value;\n } else {\n return [...items.entries()];\n }\n }).next((entries) => {\n if (this.stopped) {\n return;\n }\n\n const toWrite = entries\n .filter(([key, value]) => {\n if (key.type !== 'data' || !value) {\n return;\n }\n\n if (\n !this.paths.find(\n (p) =>\n (p.path.length === 1 && p.path[0] === '*' && key.path.length === 0) ||\n (p.path.length === key.path.length && isAncestor(p.path, key.path)),\n )\n ) {\n return null;\n }\n\n const inSaveQueue = this.queue\n .getRefs()\n .find((ref) => isAncestor(ref, key.path) || isAncestor(key.path, ref));\n return !inSaveQueue;\n })\n .map(([key, value]) => {\n try {\n return {\n path: key.path,\n value: !value || value === 'undefined' ? undefined : fromExtendedJsonString(value),\n };\n } catch {\n return undefined;\n }\n })\n .filter(Boolean) as { path: KeyType[]; value: unknown }[];\n\n if (toWrite.length > 0) {\n for (const { path, value } of toWrite) {\n this.updateInProgress.set(JSON.stringify(path), value);\n }\n\n this.store.set((state) => {\n for (const { path, value } of toWrite) {\n if (value === undefined) {\n state = remove(state, path as any);\n } else {\n state = set(state, path as any, value);\n }\n }\n\n return state;\n });\n\n this.updateInProgress.clear();\n }\n\n const versionEntry = entries.find(\n ([key]) => key.type === 'internal' && key.path === 'version',\n );\n if (versionEntry) {\n this.store.version = versionEntry[1];\n }\n }).value;\n }\n\n private save(path: KeyType[]): void | Promise<unknown> {\n const key = this.buildKey({ type: 'data', path });\n const value = get(this.store.get() as any, path);\n\n return promiseChain(value)\n .next((value) => {\n if (value === undefined) {\n return this.storage.removeItem(key);\n } else {\n return this.storage.setItem(key, toExtendedJsonString(value));\n }\n })\n .next(() => {\n this.channel.postMessage(path);\n\n if (this.store.version) {\n return this.storage.setItem(\n this.buildKey({ type: 'internal', path: 'version' }),\n this.store.version,\n );\n } else {\n return this.storage.removeItem(this.buildKey({ type: 'internal', path: 'version' }));\n }\n }).value;\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n\n for (const handle of this.handles) {\n handle();\n }\n\n await this.queue.whenDone();\n this.channel.close();\n }\n}\n\nexport function persist<T>(store: Store<T>, options: PersistOptions<T>): Persist<T> {\n return new Persist<T>(store, options);\n}\n\nfunction isPlainPath<T>(p: PathOption<T>): p is WildcardPath<T> & (KeyType[] | string) {\n return typeof p === 'string' || Array.isArray(p);\n}\n"],"mappings":"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"}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
const require_store = require('./store-fmAYV5hy.cjs');
|
|
2
1
|
const require_propAccess = require('./propAccess-DdLF12Jq.cjs');
|
|
2
|
+
const require_duration = require('./duration-B07HkB7T.cjs');
|
|
3
3
|
const require_patchMethods = require('./patchMethods-BBQDDqwe.cjs');
|
|
4
4
|
const require_extendedJson = require('./extendedJson-pbOLcymB.cjs');
|
|
5
5
|
|
|
@@ -9,7 +9,7 @@ function promiseChain(value) {
|
|
|
9
9
|
return {
|
|
10
10
|
value,
|
|
11
11
|
next(fn) {
|
|
12
|
-
return promiseChain(
|
|
12
|
+
return promiseChain(require_duration.isPromise(value) ? value.then((value) => fn(value)) : fn(value));
|
|
13
13
|
}
|
|
14
14
|
};
|
|
15
15
|
}
|
|
@@ -27,13 +27,13 @@ function normalizeStorage(storage) {
|
|
|
27
27
|
if ("keys" in storage) return storage.keys();
|
|
28
28
|
else return promiseChain(storage.length instanceof Function ? storage.length() : storage.length).next((length) => {
|
|
29
29
|
const keys = Array.from({ length }, (_, index) => storage.key(index));
|
|
30
|
-
return keys.some(
|
|
30
|
+
return keys.some(require_duration.isPromise) ? Promise.all(keys) : keys;
|
|
31
31
|
}).next((keys) => {
|
|
32
32
|
return keys.filter((key) => typeof key === "string");
|
|
33
33
|
}).value;
|
|
34
34
|
}).next((keys) => {
|
|
35
35
|
const results = keys.map((key) => promiseChain(storage.getItem(key)).next((value) => [key, value]).value);
|
|
36
|
-
return results.some(
|
|
36
|
+
return results.some(require_duration.isPromise) ? Promise.all(results) : results;
|
|
37
37
|
}).next((results) => {
|
|
38
38
|
return new Map(results.filter(([, value]) => value !== null));
|
|
39
39
|
}).value;
|
|
@@ -83,7 +83,7 @@ var Persist = class {
|
|
|
83
83
|
constructor(store, options) {
|
|
84
84
|
this.store = store;
|
|
85
85
|
this.options = options;
|
|
86
|
-
this.queue =
|
|
86
|
+
this.queue = require_duration.queue();
|
|
87
87
|
this.handles = /* @__PURE__ */ new Set();
|
|
88
88
|
this.stopped = false;
|
|
89
89
|
this.updateInProgress = /* @__PURE__ */ new Map();
|
|
@@ -94,17 +94,17 @@ var Persist = class {
|
|
|
94
94
|
this.paths = (options.paths ?? []).map((p) => {
|
|
95
95
|
if (isPlainPath(p)) return {
|
|
96
96
|
path: require_propAccess.castArrayPath(p),
|
|
97
|
-
throttle: options.throttle ?
|
|
97
|
+
throttle: options.throttle ? require_duration.calcDuration(options.throttle) : void 0
|
|
98
98
|
};
|
|
99
99
|
const _p = p;
|
|
100
100
|
return {
|
|
101
101
|
path: require_propAccess.castArrayPath(_p.path),
|
|
102
|
-
throttle: (_p.throttle ?
|
|
102
|
+
throttle: (_p.throttle ? require_duration.calcDuration(_p.throttle) : void 0) ?? (options.throttle ? require_duration.calcDuration(options.throttle) : void 0)
|
|
103
103
|
};
|
|
104
104
|
}).sort((a, b) => b.path.length - a.path.length);
|
|
105
105
|
if (this.paths.length === 0) this.paths.push({
|
|
106
106
|
path: ["*"],
|
|
107
|
-
throttle: options.throttle ?
|
|
107
|
+
throttle: options.throttle ? require_duration.calcDuration(options.throttle) : void 0
|
|
108
108
|
});
|
|
109
109
|
this.initialized = new Promise((resolve) => {
|
|
110
110
|
this.resolveInitialized = resolve;
|
|
@@ -144,7 +144,7 @@ var Persist = class {
|
|
|
144
144
|
async watchStorage() {
|
|
145
145
|
if (!this.options.persistInitialState) {
|
|
146
146
|
let items = this.storage.listItems();
|
|
147
|
-
if (
|
|
147
|
+
if (require_duration.isPromise(items)) items = await items;
|
|
148
148
|
if (this.stopped) return;
|
|
149
149
|
const toLoad = new Map([...items.entries()].sort((a, b) => b[1].length - a[1].length).map(([key, value]) => [this.parseKey(key), value]).filter(([key]) => key));
|
|
150
150
|
this.queue(() => this.load(toLoad));
|
|
@@ -180,7 +180,7 @@ var Persist = class {
|
|
|
180
180
|
const entries = items.map((key) => promiseChain(() => {
|
|
181
181
|
return this.storage.getItem(this.buildKey(key));
|
|
182
182
|
}).next((value) => [key, value]).value);
|
|
183
|
-
return entries.some(
|
|
183
|
+
return entries.some(require_duration.isPromise) ? Promise.all(entries) : entries;
|
|
184
184
|
}).next((entries) => {
|
|
185
185
|
return entries.filter((entry) => entry !== null);
|
|
186
186
|
}).value;
|
|
@@ -255,4 +255,4 @@ Object.defineProperty(exports, 'persist', {
|
|
|
255
255
|
return persist;
|
|
256
256
|
}
|
|
257
257
|
});
|
|
258
|
-
//# sourceMappingURL=persist-
|
|
258
|
+
//# sourceMappingURL=persist-IJeNYfT6.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"persist-B341lrOA.cjs","names":["isPromise","isPromise","queue","castArrayPath","calcDuration","subscribePatches","shallowEqual","isPromise","fromExtendedJsonString","remove","set","get","toExtendedJsonString"],"sources":["../src/lib/promiseChain.ts","../src/persist/persistStorage.ts","../src/persist/persistPathHelpers.ts","../src/persist/persist.ts"],"sourcesContent":["import isPromise from '@lib/isPromise';\n\nexport interface Chain<T> {\n value: T;\n next<S>(fn: (value: Awaited<T>) => S): T extends Promise<any> ? Chain<Promise<S>> : Chain<S>;\n}\n\nexport default function promiseChain<T>(value: T | (() => T)): Chain<T> {\n if (value instanceof Function) {\n value = value();\n }\n\n return {\n value,\n next(fn) {\n const next = isPromise(value)\n ? value.then((value) => fn(value as Awaited<T>))\n : fn(value as Awaited<T>);\n\n return promiseChain(next) as any;\n },\n };\n}\n","import isPromise from '@lib/isPromise';\nimport promiseChain from '@lib/promiseChain';\n\nexport interface PersistStorageBase {\n getItem: (key: string) => string | null | Promise<string | null>;\n setItem: (key: string, value: string) => void | Promise<unknown>;\n removeItem: (key: string) => void | Promise<unknown>;\n}\n\nexport interface PersistStorageWithKeys extends PersistStorageBase {\n keys: () => string[] | Promise<string[]>;\n}\n\nexport interface PersistStorageWithLength extends PersistStorageBase {\n length: number | (() => number | Promise<number>);\n key: (keyIndex: number) => string | null | Promise<string | null>;\n}\n\nexport interface PersistStorageWithListItems extends PersistStorageBase {\n listItems: () => Map<string, string> | Promise<Map<string, string>>;\n}\n\nexport type PersistStorage =\n | PersistStorageWithKeys\n | PersistStorageWithLength\n | PersistStorageWithListItems;\n\nexport function normalizeStorage(storage: PersistStorage): PersistStorageWithListItems {\n return {\n getItem: storage.getItem.bind(storage),\n setItem: storage.setItem.bind(storage),\n removeItem: storage.removeItem.bind(storage),\n\n listItems() {\n if ('listItems' in storage) {\n return storage.listItems();\n }\n\n return promiseChain(() => {\n if ('keys' in storage) {\n return storage.keys();\n } else {\n return promiseChain(\n storage.length instanceof Function ? storage.length() : storage.length,\n )\n .next((length) => {\n const keys = Array.from({ length }, (_, index) => storage.key(index));\n return keys.some(isPromise) ? Promise.all(keys) : (keys as (string | null)[]);\n })\n .next((keys) => {\n return keys.filter((key): key is string => typeof key === 'string');\n }).value;\n }\n })\n .next((keys) => {\n const results = keys.map(\n (key) =>\n promiseChain(storage.getItem(key)).next((value) => [key, value] as const).value,\n );\n\n return results.some(isPromise)\n ? Promise.all(results)\n : (results as [string, string | null][]);\n })\n .next((results) => {\n return new Map(results.filter(([, value]) => value !== null) as [string, string][]);\n }).value;\n },\n };\n}\n","import type { KeyType } from '@lib/path';\n\nexport const isAncestor = (ancestor: KeyType[], path: KeyType[]): boolean => {\n return (\n ancestor.length <= path.length &&\n ancestor.every((v, i) => v === '*' || path[i] === '*' || v === path[i])\n );\n};\n\nexport const split = (value: any, path: KeyType[]): { path: KeyType[]; value: unknown }[] => {\n const [first, ...rest] = path;\n if (first === undefined) return [{ path: [], value }];\n\n let entries: Map<KeyType, unknown>;\n if (value instanceof Map) {\n entries = value;\n } else if (value instanceof Set) {\n entries = new Map([...value].map((v, i) => [i, v]));\n } else if (Array.isArray(value)) {\n entries = new Map(value.map((v, i) => [i, v]));\n } else if (typeof value === 'object' && value !== null) {\n entries = new Map(Object.entries(value));\n } else {\n return [{ path: [], value }];\n }\n\n if (first === '*') {\n return [...entries].flatMap(([k, v]) =>\n split(v, rest).map(({ path, value }) => ({ path: [k, ...path], value })),\n );\n }\n\n const subValue = entries.get(first);\n if (subValue === undefined) return [{ path: [], value }];\n\n return split(subValue, rest).map(({ path, value }) => ({ path: [first, ...path], value }));\n};\n","import {\n normalizeStorage,\n type PersistStorage,\n type PersistStorageWithListItems,\n} from './persistStorage';\nimport { type Cancel, type Duration, type Store } from '@core';\nimport { calcDuration } from '@lib/duration';\nimport { shallowEqual } from '@lib/equals';\nimport { fromExtendedJsonString, toExtendedJsonString } from '@lib/extendedJson';\nimport isPromise from '@lib/isPromise';\nimport type { KeyType, WildcardPath } from '@lib/path';\nimport promiseChain from '@lib/promiseChain';\nimport { castArrayPath, get, remove, set } from '@lib/propAccess';\nimport { queue } from '@lib/queue';\nimport { subscribePatches } from '@patches/patchMethods';\nimport { isAncestor, split } from '@persist/persistPathHelpers';\n\ntype PathOption<T> =\n | WildcardPath<T>\n | {\n path: WildcardPath<T>;\n // throttle?: Duration;\n };\n\ntype Key = { type: 'internal'; path: string } | { type: 'data'; path: KeyType[] };\n\nexport interface PersistOptions<T> {\n id: string;\n storage: PersistStorage;\n paths?: PathOption<T>[];\n throttle?: Duration;\n persistInitialState?: boolean;\n}\n\nexport class Persist<T> {\n readonly storage: PersistStorageWithListItems;\n readonly [Symbol.dispose]!: Cancel;\n\n readonly paths: {\n path: KeyType[];\n throttle?: number;\n }[];\n\n readonly initialized: Promise<void>;\n\n private resolveInitialized?: () => void;\n\n private channel: BroadcastChannel;\n\n private queue = queue();\n\n private handles = new Set<Cancel>();\n\n private stopped = false;\n\n private updateInProgress = new Map<string, unknown>();\n\n private prefix;\n\n constructor(\n public readonly store: Store<T>,\n public readonly options: PersistOptions<T>,\n ) {\n this.storage = normalizeStorage(options.storage);\n this.channel = new BroadcastChannel(`cross-state-persist_${options.id}`);\n this.prefix = `${options.id}:`;\n\n if (Symbol.dispose) {\n this[Symbol.dispose] = () => this.stop();\n }\n\n this.paths = (options.paths ?? [])\n .map<{\n path: KeyType[];\n throttle?: number;\n }>((p) => {\n if (isPlainPath(p)) {\n return {\n path: castArrayPath(p),\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n };\n }\n\n const _p = p as { path: KeyType[]; throttle?: Duration };\n\n return {\n path: castArrayPath(_p.path),\n throttle:\n (_p.throttle ? calcDuration(_p.throttle) : undefined) ??\n (options.throttle ? calcDuration(options.throttle) : undefined),\n };\n })\n .sort((a, b) => b.path.length - a.path.length);\n\n if (this.paths.length === 0) {\n this.paths.push({\n path: ['*'],\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n });\n }\n\n this.initialized = new Promise((resolve) => {\n this.resolveInitialized = resolve;\n });\n\n this.watchStore();\n void this.watchStorage();\n }\n\n private watchStore() {\n const throttle = Math.min(...this.paths.map((p) => p.throttle ?? 0)) || undefined;\n\n const cancel = subscribePatches.apply(this.store as Store<unknown>, [\n (patches, reversePatches) => {\n let i = 0;\n for (const patch of patches) {\n const reversePatch = reversePatches[i++];\n\n const stringPath = JSON.stringify(patch.path);\n if (\n this.updateInProgress.has(stringPath) &&\n this.updateInProgress.get(stringPath) ===\n (patch.op === 'remove' ? undefined : patch.value)\n ) {\n continue;\n }\n\n const matchingPaths = this.paths.filter(\n (p) => isAncestor(p.path, patch.path) || isAncestor(patch.path, p.path),\n );\n\n for (const { path } of matchingPaths) {\n if (path.length <= patch.path.length) {\n const pathToSave = patch.path.slice(0, path.length);\n void this.queue(() => this.save(pathToSave), pathToSave);\n } else if (patch.op === 'remove') {\n const subValues = split(\n reversePatch?.op === 'add' ? reversePatch.value : {},\n path.slice(patch.path.length),\n );\n\n for (const { path } of subValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n } else {\n const updatedValues = split(patch.value, path.slice(patch.path.length));\n const removedValues = split(\n reversePatch?.op !== 'remove' ? (reversePatch?.value ?? {}) : {},\n path.slice(patch.path.length),\n ).filter((v) => !updatedValues.some((u) => shallowEqual(u.path, v.path)));\n\n for (const { path } of updatedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n for (const { path } of removedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n }\n }\n }\n },\n { runNow: this.options.persistInitialState ?? false, passive: true, throttle },\n ]);\n\n this.handles.add(cancel);\n }\n\n private async watchStorage() {\n if (!this.options.persistInitialState) {\n let items = this.storage.listItems();\n if (isPromise(items)) {\n items = await items;\n }\n\n if (this.stopped) {\n return;\n }\n\n const toLoad = new Map(\n [...items.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .map(([key, value]) => [this.parseKey(key), value])\n .filter(([key]) => key) as [Key, string][],\n );\n\n void this.queue(() => this.load(toLoad));\n }\n\n void this.queue(() => this.resolveInitialized?.());\n\n const listener = (event: MessageEvent) => {\n void this.queue(() => this.load([{ type: 'data', path: event.data }]));\n };\n\n this.channel.addEventListener('message', listener);\n this.handles.add(() => this.channel.removeEventListener('message', listener));\n }\n\n private buildKey({ type, path }: Key) {\n return `${this.prefix}${type === 'internal' ? path : JSON.stringify(path)}`;\n }\n\n private parseKey(key: string): Key | undefined {\n if (!key.startsWith(this.prefix)) {\n return;\n }\n\n key = key.slice(this.prefix.length);\n\n if (!key.startsWith('[')) {\n return { type: 'internal', path: key };\n }\n\n return { type: 'data', path: JSON.parse(key) as KeyType[] };\n }\n\n private load(items: Key[] | Map<Key, string>): void | Promise<void> {\n return promiseChain(() => {\n if (Array.isArray(items)) {\n return promiseChain(() => {\n const entries = items.map(\n (key) =>\n promiseChain(() => {\n return this.storage.getItem(this.buildKey(key));\n }).next((value) => [key, value] as const).value,\n );\n\n return entries.some(isPromise)\n ? Promise.all(entries)\n : (entries as [Key, string | null][]);\n }).next((entries) => {\n return entries.filter((entry) => entry !== null) as [Key, string][];\n }).value;\n } else {\n return [...items.entries()];\n }\n }).next((entries) => {\n if (this.stopped) {\n return;\n }\n\n const toWrite = entries\n .filter(([key, value]) => {\n if (key.type !== 'data' || !value) {\n return;\n }\n\n if (\n !this.paths.find(\n (p) =>\n (p.path.length === 1 && p.path[0] === '*' && key.path.length === 0) ||\n (p.path.length === key.path.length && isAncestor(p.path, key.path)),\n )\n ) {\n return null;\n }\n\n const inSaveQueue = this.queue\n .getRefs()\n .find((ref) => isAncestor(ref, key.path) || isAncestor(key.path, ref));\n return !inSaveQueue;\n })\n .map(([key, value]) => {\n try {\n return {\n path: key.path,\n value: !value || value === 'undefined' ? undefined : fromExtendedJsonString(value),\n };\n } catch {\n return undefined;\n }\n })\n .filter(Boolean) as { path: KeyType[]; value: unknown }[];\n\n if (toWrite.length > 0) {\n for (const { path, value } of toWrite) {\n this.updateInProgress.set(JSON.stringify(path), value);\n }\n\n this.store.set((state) => {\n for (const { path, value } of toWrite) {\n if (value === undefined) {\n state = remove(state, path as any);\n } else {\n state = set(state, path as any, value);\n }\n }\n\n return state;\n });\n\n this.updateInProgress.clear();\n }\n\n const versionEntry = entries.find(\n ([key]) => key.type === 'internal' && key.path === 'version',\n );\n if (versionEntry) {\n this.store.version = versionEntry[1];\n }\n }).value;\n }\n\n private save(path: KeyType[]): void | Promise<unknown> {\n const key = this.buildKey({ type: 'data', path });\n const value = get(this.store.get() as any, path);\n\n return promiseChain(value)\n .next((value) => {\n if (value === undefined) {\n return this.storage.removeItem(key);\n } else {\n return this.storage.setItem(key, toExtendedJsonString(value));\n }\n })\n .next(() => {\n this.channel.postMessage(path);\n\n if (this.store.version) {\n return this.storage.setItem(\n this.buildKey({ type: 'internal', path: 'version' }),\n this.store.version,\n );\n } else {\n return this.storage.removeItem(this.buildKey({ type: 'internal', path: 'version' }));\n }\n }).value;\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n\n for (const handle of this.handles) {\n handle();\n }\n\n await this.queue.whenDone();\n this.channel.close();\n }\n}\n\nexport function persist<T>(store: Store<T>, options: PersistOptions<T>): Persist<T> {\n return new Persist<T>(store, options);\n}\n\nfunction isPlainPath<T>(p: PathOption<T>): p is WildcardPath<T> & (KeyType[] | string) {\n return typeof p === 'string' || Array.isArray(p);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"persist-IJeNYfT6.cjs","names":["isPromise","isPromise","queue","castArrayPath","calcDuration","subscribePatches","shallowEqual","isPromise","fromExtendedJsonString","remove","set","get","toExtendedJsonString"],"sources":["../src/lib/promiseChain.ts","../src/persist/persistStorage.ts","../src/persist/persistPathHelpers.ts","../src/persist/persist.ts"],"sourcesContent":["import isPromise from '@lib/isPromise';\n\nexport interface Chain<T> {\n value: T;\n next<S>(fn: (value: Awaited<T>) => S): T extends Promise<any> ? Chain<Promise<S>> : Chain<S>;\n}\n\nexport default function promiseChain<T>(value: T | (() => T)): Chain<T> {\n if (value instanceof Function) {\n value = value();\n }\n\n return {\n value,\n next(fn) {\n const next = isPromise(value)\n ? value.then((value) => fn(value as Awaited<T>))\n : fn(value as Awaited<T>);\n\n return promiseChain(next) as any;\n },\n };\n}\n","import isPromise from '@lib/isPromise';\nimport promiseChain from '@lib/promiseChain';\n\nexport interface PersistStorageBase {\n getItem: (key: string) => string | null | Promise<string | null>;\n setItem: (key: string, value: string) => void | Promise<unknown>;\n removeItem: (key: string) => void | Promise<unknown>;\n}\n\nexport interface PersistStorageWithKeys extends PersistStorageBase {\n keys: () => string[] | Promise<string[]>;\n}\n\nexport interface PersistStorageWithLength extends PersistStorageBase {\n length: number | (() => number | Promise<number>);\n key: (keyIndex: number) => string | null | Promise<string | null>;\n}\n\nexport interface PersistStorageWithListItems extends PersistStorageBase {\n listItems: () => Map<string, string> | Promise<Map<string, string>>;\n}\n\nexport type PersistStorage =\n | PersistStorageWithKeys\n | PersistStorageWithLength\n | PersistStorageWithListItems;\n\nexport function normalizeStorage(storage: PersistStorage): PersistStorageWithListItems {\n return {\n getItem: storage.getItem.bind(storage),\n setItem: storage.setItem.bind(storage),\n removeItem: storage.removeItem.bind(storage),\n\n listItems() {\n if ('listItems' in storage) {\n return storage.listItems();\n }\n\n return promiseChain(() => {\n if ('keys' in storage) {\n return storage.keys();\n } else {\n return promiseChain(\n storage.length instanceof Function ? storage.length() : storage.length,\n )\n .next((length) => {\n const keys = Array.from({ length }, (_, index) => storage.key(index));\n return keys.some(isPromise) ? Promise.all(keys) : (keys as (string | null)[]);\n })\n .next((keys) => {\n return keys.filter((key): key is string => typeof key === 'string');\n }).value;\n }\n })\n .next((keys) => {\n const results = keys.map(\n (key) =>\n promiseChain(storage.getItem(key)).next((value) => [key, value] as const).value,\n );\n\n return results.some(isPromise)\n ? Promise.all(results)\n : (results as [string, string | null][]);\n })\n .next((results) => {\n return new Map(results.filter(([, value]) => value !== null) as [string, string][]);\n }).value;\n },\n };\n}\n","import type { KeyType } from '@lib/path';\n\nexport const isAncestor = (ancestor: KeyType[], path: KeyType[]): boolean => {\n return (\n ancestor.length <= path.length &&\n ancestor.every((v, i) => v === '*' || path[i] === '*' || v === path[i])\n );\n};\n\nexport const split = (value: any, path: KeyType[]): { path: KeyType[]; value: unknown }[] => {\n const [first, ...rest] = path;\n if (first === undefined) return [{ path: [], value }];\n\n let entries: Map<KeyType, unknown>;\n if (value instanceof Map) {\n entries = value;\n } else if (value instanceof Set) {\n entries = new Map([...value].map((v, i) => [i, v]));\n } else if (Array.isArray(value)) {\n entries = new Map(value.map((v, i) => [i, v]));\n } else if (typeof value === 'object' && value !== null) {\n entries = new Map(Object.entries(value));\n } else {\n return [{ path: [], value }];\n }\n\n if (first === '*') {\n return [...entries].flatMap(([k, v]) =>\n split(v, rest).map(({ path, value }) => ({ path: [k, ...path], value })),\n );\n }\n\n const subValue = entries.get(first);\n if (subValue === undefined) return [{ path: [], value }];\n\n return split(subValue, rest).map(({ path, value }) => ({ path: [first, ...path], value }));\n};\n","import {\n normalizeStorage,\n type PersistStorage,\n type PersistStorageWithListItems,\n} from './persistStorage';\nimport { type Cancel, type Duration, type Store } from '@core';\nimport { calcDuration } from '@lib/duration';\nimport { shallowEqual } from '@lib/equals';\nimport { fromExtendedJsonString, toExtendedJsonString } from '@lib/extendedJson';\nimport isPromise from '@lib/isPromise';\nimport type { KeyType, WildcardPath } from '@lib/path';\nimport promiseChain from '@lib/promiseChain';\nimport { castArrayPath, get, remove, set } from '@lib/propAccess';\nimport { queue } from '@lib/queue';\nimport { subscribePatches } from '@patches/patchMethods';\nimport { isAncestor, split } from '@persist/persistPathHelpers';\n\ntype PathOption<T> =\n | WildcardPath<T>\n | {\n path: WildcardPath<T>;\n // throttle?: Duration;\n };\n\ntype Key = { type: 'internal'; path: string } | { type: 'data'; path: KeyType[] };\n\nexport interface PersistOptions<T> {\n id: string;\n storage: PersistStorage;\n paths?: PathOption<T>[];\n throttle?: Duration;\n persistInitialState?: boolean;\n}\n\nexport class Persist<T> {\n readonly storage: PersistStorageWithListItems;\n readonly [Symbol.dispose]!: Cancel;\n\n readonly paths: {\n path: KeyType[];\n throttle?: number;\n }[];\n\n readonly initialized: Promise<void>;\n\n private resolveInitialized?: () => void;\n\n private channel: BroadcastChannel;\n\n private queue = queue();\n\n private handles = new Set<Cancel>();\n\n private stopped = false;\n\n private updateInProgress = new Map<string, unknown>();\n\n private prefix;\n\n constructor(\n public readonly store: Store<T>,\n public readonly options: PersistOptions<T>,\n ) {\n this.storage = normalizeStorage(options.storage);\n this.channel = new BroadcastChannel(`cross-state-persist_${options.id}`);\n this.prefix = `${options.id}:`;\n\n if (Symbol.dispose) {\n this[Symbol.dispose] = () => this.stop();\n }\n\n this.paths = (options.paths ?? [])\n .map<{\n path: KeyType[];\n throttle?: number;\n }>((p) => {\n if (isPlainPath(p)) {\n return {\n path: castArrayPath(p),\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n };\n }\n\n const _p = p as { path: KeyType[]; throttle?: Duration };\n\n return {\n path: castArrayPath(_p.path),\n throttle:\n (_p.throttle ? calcDuration(_p.throttle) : undefined) ??\n (options.throttle ? calcDuration(options.throttle) : undefined),\n };\n })\n .sort((a, b) => b.path.length - a.path.length);\n\n if (this.paths.length === 0) {\n this.paths.push({\n path: ['*'],\n throttle: options.throttle ? calcDuration(options.throttle) : undefined,\n });\n }\n\n this.initialized = new Promise((resolve) => {\n this.resolveInitialized = resolve;\n });\n\n this.watchStore();\n void this.watchStorage();\n }\n\n private watchStore() {\n const throttle = Math.min(...this.paths.map((p) => p.throttle ?? 0)) || undefined;\n\n const cancel = subscribePatches.apply(this.store as Store<unknown>, [\n (patches, reversePatches) => {\n let i = 0;\n for (const patch of patches) {\n const reversePatch = reversePatches[i++];\n\n const stringPath = JSON.stringify(patch.path);\n if (\n this.updateInProgress.has(stringPath) &&\n this.updateInProgress.get(stringPath) ===\n (patch.op === 'remove' ? undefined : patch.value)\n ) {\n continue;\n }\n\n const matchingPaths = this.paths.filter(\n (p) => isAncestor(p.path, patch.path) || isAncestor(patch.path, p.path),\n );\n\n for (const { path } of matchingPaths) {\n if (path.length <= patch.path.length) {\n const pathToSave = patch.path.slice(0, path.length);\n void this.queue(() => this.save(pathToSave), pathToSave);\n } else if (patch.op === 'remove') {\n const subValues = split(\n reversePatch?.op === 'add' ? reversePatch.value : {},\n path.slice(patch.path.length),\n );\n\n for (const { path } of subValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n } else {\n const updatedValues = split(patch.value, path.slice(patch.path.length));\n const removedValues = split(\n reversePatch?.op !== 'remove' ? (reversePatch?.value ?? {}) : {},\n path.slice(patch.path.length),\n ).filter((v) => !updatedValues.some((u) => shallowEqual(u.path, v.path)));\n\n for (const { path } of updatedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n for (const { path } of removedValues) {\n void this.queue(\n () => this.save([...patch.path, ...path]),\n [...patch.path, ...path],\n );\n }\n }\n }\n }\n },\n { runNow: this.options.persistInitialState ?? false, passive: true, throttle },\n ]);\n\n this.handles.add(cancel);\n }\n\n private async watchStorage() {\n if (!this.options.persistInitialState) {\n let items = this.storage.listItems();\n if (isPromise(items)) {\n items = await items;\n }\n\n if (this.stopped) {\n return;\n }\n\n const toLoad = new Map(\n [...items.entries()]\n .sort((a, b) => b[1].length - a[1].length)\n .map(([key, value]) => [this.parseKey(key), value])\n .filter(([key]) => key) as [Key, string][],\n );\n\n void this.queue(() => this.load(toLoad));\n }\n\n void this.queue(() => this.resolveInitialized?.());\n\n const listener = (event: MessageEvent) => {\n void this.queue(() => this.load([{ type: 'data', path: event.data }]));\n };\n\n this.channel.addEventListener('message', listener);\n this.handles.add(() => this.channel.removeEventListener('message', listener));\n }\n\n private buildKey({ type, path }: Key) {\n return `${this.prefix}${type === 'internal' ? path : JSON.stringify(path)}`;\n }\n\n private parseKey(key: string): Key | undefined {\n if (!key.startsWith(this.prefix)) {\n return;\n }\n\n key = key.slice(this.prefix.length);\n\n if (!key.startsWith('[')) {\n return { type: 'internal', path: key };\n }\n\n return { type: 'data', path: JSON.parse(key) as KeyType[] };\n }\n\n private load(items: Key[] | Map<Key, string>): void | Promise<void> {\n return promiseChain(() => {\n if (Array.isArray(items)) {\n return promiseChain(() => {\n const entries = items.map(\n (key) =>\n promiseChain(() => {\n return this.storage.getItem(this.buildKey(key));\n }).next((value) => [key, value] as const).value,\n );\n\n return entries.some(isPromise)\n ? Promise.all(entries)\n : (entries as [Key, string | null][]);\n }).next((entries) => {\n return entries.filter((entry) => entry !== null) as [Key, string][];\n }).value;\n } else {\n return [...items.entries()];\n }\n }).next((entries) => {\n if (this.stopped) {\n return;\n }\n\n const toWrite = entries\n .filter(([key, value]) => {\n if (key.type !== 'data' || !value) {\n return;\n }\n\n if (\n !this.paths.find(\n (p) =>\n (p.path.length === 1 && p.path[0] === '*' && key.path.length === 0) ||\n (p.path.length === key.path.length && isAncestor(p.path, key.path)),\n )\n ) {\n return null;\n }\n\n const inSaveQueue = this.queue\n .getRefs()\n .find((ref) => isAncestor(ref, key.path) || isAncestor(key.path, ref));\n return !inSaveQueue;\n })\n .map(([key, value]) => {\n try {\n return {\n path: key.path,\n value: !value || value === 'undefined' ? undefined : fromExtendedJsonString(value),\n };\n } catch {\n return undefined;\n }\n })\n .filter(Boolean) as { path: KeyType[]; value: unknown }[];\n\n if (toWrite.length > 0) {\n for (const { path, value } of toWrite) {\n this.updateInProgress.set(JSON.stringify(path), value);\n }\n\n this.store.set((state) => {\n for (const { path, value } of toWrite) {\n if (value === undefined) {\n state = remove(state, path as any);\n } else {\n state = set(state, path as any, value);\n }\n }\n\n return state;\n });\n\n this.updateInProgress.clear();\n }\n\n const versionEntry = entries.find(\n ([key]) => key.type === 'internal' && key.path === 'version',\n );\n if (versionEntry) {\n this.store.version = versionEntry[1];\n }\n }).value;\n }\n\n private save(path: KeyType[]): void | Promise<unknown> {\n const key = this.buildKey({ type: 'data', path });\n const value = get(this.store.get() as any, path);\n\n return promiseChain(value)\n .next((value) => {\n if (value === undefined) {\n return this.storage.removeItem(key);\n } else {\n return this.storage.setItem(key, toExtendedJsonString(value));\n }\n })\n .next(() => {\n this.channel.postMessage(path);\n\n if (this.store.version) {\n return this.storage.setItem(\n this.buildKey({ type: 'internal', path: 'version' }),\n this.store.version,\n );\n } else {\n return this.storage.removeItem(this.buildKey({ type: 'internal', path: 'version' }));\n }\n }).value;\n }\n\n async stop(): Promise<void> {\n this.stopped = true;\n\n for (const handle of this.handles) {\n handle();\n }\n\n await this.queue.whenDone();\n this.channel.close();\n }\n}\n\nexport function persist<T>(store: Store<T>, options: PersistOptions<T>): Persist<T> {\n return new Persist<T>(store, options);\n}\n\nfunction isPlainPath<T>(p: PathOption<T>): p is WildcardPath<T> & (KeyType[] | string) {\n return typeof p === 'string' || Array.isArray(p);\n}\n"],"mappings":"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"}
|
package/dist/react/index.cjs
CHANGED
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
|
|
2
|
-
const require_store = require('../store-
|
|
2
|
+
const require_store = require('../store-B_ToOCrU.cjs');
|
|
3
3
|
const require_propAccess = require('../propAccess-DdLF12Jq.cjs');
|
|
4
|
+
const require_duration = require('../duration-B07HkB7T.cjs');
|
|
4
5
|
const require_extendedJson = require('../extendedJson-pbOLcymB.cjs');
|
|
5
|
-
const require_storeMethods = require('../storeMethods-
|
|
6
|
+
const require_storeMethods = require('../storeMethods-fBHg4hVK.cjs');
|
|
6
7
|
let react = require("react");
|
|
7
8
|
let react_jsx_runtime = require("react/jsx-runtime");
|
|
8
9
|
let mutative = require("mutative");
|
|
@@ -53,7 +54,7 @@ function useFormFieldProps({ name, commitOnBlur, commitDebounce, includeNestedEr
|
|
|
53
54
|
const field = this.useField(name, { includeNestedErrors });
|
|
54
55
|
const hasTriggeredValidations = this.useFormState((form) => form.hasTriggeredValidations);
|
|
55
56
|
const [localValue, setLocalValue] = (0, react.useState)();
|
|
56
|
-
const commitDebounceMs = commitDebounce !== void 0 ?
|
|
57
|
+
const commitDebounceMs = commitDebounce !== void 0 ? require_duration.calcDuration(commitDebounce) : void 0;
|
|
57
58
|
const commitLocalValue = require_storeMethods.useLatestFunction(() => {
|
|
58
59
|
if (localValue) {
|
|
59
60
|
field.setValue(localValue.v);
|
|
@@ -166,9 +167,9 @@ function resolveOnOriginalChange(onOriginalChange) {
|
|
|
166
167
|
function useFormAutosave(form) {
|
|
167
168
|
const { enabled = true, validateBeforeSave = true } = form.options.autoSave ?? {};
|
|
168
169
|
const isActive = enabled && !!form.options.autoSave?.save;
|
|
169
|
-
const debounceTime =
|
|
170
|
+
const debounceTime = require_duration.calcDuration(form.options.autoSave?.debounce ?? 2e3);
|
|
170
171
|
const prev = (0, react.useRef)(form.getDraft());
|
|
171
|
-
const q = (0, react.useMemo)(() =>
|
|
172
|
+
const q = (0, react.useMemo)(() => require_duration.queue(), []);
|
|
172
173
|
const latestSave = require_storeMethods.useLatestFunction(async () => {
|
|
173
174
|
if (validateBeforeSave && !form.validate()) return;
|
|
174
175
|
const draft = form.getDraft();
|
|
@@ -263,7 +264,7 @@ function LegacyFormField({ name, component, commitOnBlur, commitDebounce, inputF
|
|
|
263
264
|
});
|
|
264
265
|
const setValue = require_storeMethods.useLatestFunction((x) => form.getField(name).setValue(deserialize(x, getFormState())));
|
|
265
266
|
const hasTriggeredValidations = this.useFormState((form) => form.hasTriggeredValidations);
|
|
266
|
-
const commitDebounceMs = commitDebounce !== void 0 ?
|
|
267
|
+
const commitDebounceMs = commitDebounce !== void 0 ? require_duration.calcDuration(commitDebounce) : void 0;
|
|
267
268
|
(0, react.useEffect)(() => {
|
|
268
269
|
if (localValue === void 0 || commitDebounceMs === void 0 || commitDebounceMs <= 0) return;
|
|
269
270
|
const timeout = setTimeout(() => {
|
|
@@ -813,7 +814,7 @@ function useDecoupledState(value, onChange, options = {}) {
|
|
|
813
814
|
const update = (0, react.useMemo)(() => {
|
|
814
815
|
const update = async (value) => {
|
|
815
816
|
const result = latestOnChange(value);
|
|
816
|
-
if (
|
|
817
|
+
if (require_duration.isPromise(result)) {
|
|
817
818
|
const ac = onChangeAC.current = new AbortController();
|
|
818
819
|
await result;
|
|
819
820
|
if (ac.signal.aborted) return;
|