@anfenn/zync 0.1.14 → 0.1.15
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/README.md +1 -0
- package/dist/index.cjs +18 -10
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +9 -5
- package/dist/index.d.ts +9 -5
- package/dist/index.js +17 -10
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -76,6 +76,7 @@ export const useStore = create<any>()(
|
|
|
76
76
|
|
|
77
77
|
name: 'store',
|
|
78
78
|
storage: createJSONStorage(() => localStorage),
|
|
79
|
+
// storage: createJSONStorage(() => createIndexedDBStorage({ dbName: 'my-app', storeName: 'store' })),
|
|
79
80
|
},
|
|
80
81
|
{
|
|
81
82
|
// State-to-API map to enable syncing. Must implement the full CRUD API:
|
package/dist/index.cjs
CHANGED
|
@@ -280,6 +280,7 @@ var init_build = __esm({
|
|
|
280
280
|
// src/index.ts
|
|
281
281
|
var index_exports = {};
|
|
282
282
|
__export(index_exports, {
|
|
283
|
+
MissingRemoteRecordStrategy: () => MissingRemoteRecordStrategy,
|
|
283
284
|
SyncAction: () => SyncAction,
|
|
284
285
|
createIndexedDBStorage: () => createIndexedDBStorage,
|
|
285
286
|
createWithSync: () => createWithSync,
|
|
@@ -315,7 +316,7 @@ function nextLocalId() {
|
|
|
315
316
|
}
|
|
316
317
|
function orderFor(a) {
|
|
317
318
|
switch (a) {
|
|
318
|
-
case "
|
|
319
|
+
case "create-or-update" /* CreateOrUpdate */:
|
|
319
320
|
return 1;
|
|
320
321
|
case "remove" /* Remove */:
|
|
321
322
|
return 2;
|
|
@@ -417,7 +418,7 @@ async function pushOne(set, get, change, api, logger, queueToSync, missingStrate
|
|
|
417
418
|
logger.debug(`[zync] push:remove:success ${stateKey} ${localId} ${id}`);
|
|
418
419
|
removeFromPendingChanges(set, localId, stateKey);
|
|
419
420
|
break;
|
|
420
|
-
case "
|
|
421
|
+
case "create-or-update" /* CreateOrUpdate */: {
|
|
421
422
|
const state = get();
|
|
422
423
|
const items = state[stateKey] || [];
|
|
423
424
|
const item = items.find((i) => i._localId === localId);
|
|
@@ -449,18 +450,18 @@ async function pushOne(set, get, change, api, logger, queueToSync, missingStrate
|
|
|
449
450
|
id: item.id
|
|
450
451
|
});
|
|
451
452
|
switch (missingStrategy) {
|
|
452
|
-
case "
|
|
453
|
+
case "delete-local-record" /* DeleteLocalRecord */:
|
|
453
454
|
set((s) => ({
|
|
454
455
|
[stateKey]: (s[stateKey] || []).filter((i) => i._localId !== localId)
|
|
455
456
|
}));
|
|
456
457
|
break;
|
|
457
|
-
case "
|
|
458
|
+
case "insert-remote-record" /* InsertRemoteRecord */: {
|
|
458
459
|
omittedItem._localId = crypto.randomUUID();
|
|
459
460
|
omittedItem.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
460
461
|
set((s) => ({
|
|
461
462
|
[stateKey]: (s[stateKey] || []).map((i) => i._localId === localId ? omittedItem : i)
|
|
462
463
|
}));
|
|
463
|
-
queueToSync("
|
|
464
|
+
queueToSync("create-or-update" /* CreateOrUpdate */, stateKey, omittedItem._localId);
|
|
464
465
|
break;
|
|
465
466
|
}
|
|
466
467
|
}
|
|
@@ -574,14 +575,20 @@ function createIndexedDBStorage(options) {
|
|
|
574
575
|
|
|
575
576
|
// src/index.ts
|
|
576
577
|
var SyncAction = /* @__PURE__ */ ((SyncAction2) => {
|
|
577
|
-
SyncAction2["CreateOrUpdate"] = "
|
|
578
|
+
SyncAction2["CreateOrUpdate"] = "create-or-update";
|
|
578
579
|
SyncAction2["Remove"] = "remove";
|
|
579
580
|
return SyncAction2;
|
|
580
581
|
})(SyncAction || {});
|
|
582
|
+
var MissingRemoteRecordStrategy = /* @__PURE__ */ ((MissingRemoteRecordStrategy2) => {
|
|
583
|
+
MissingRemoteRecordStrategy2["Ignore"] = "ignore";
|
|
584
|
+
MissingRemoteRecordStrategy2["DeleteLocalRecord"] = "delete-local-record";
|
|
585
|
+
MissingRemoteRecordStrategy2["InsertRemoteRecord"] = "insert-remote-record";
|
|
586
|
+
return MissingRemoteRecordStrategy2;
|
|
587
|
+
})(MissingRemoteRecordStrategy || {});
|
|
581
588
|
var DEFAULT_SYNC_INTERVAL_MILLIS = 5e3;
|
|
582
589
|
var DEFAULT_LOGGER = console;
|
|
583
590
|
var DEFAULT_MIN_LOG_LEVEL = "debug";
|
|
584
|
-
var
|
|
591
|
+
var DEFAULT_MISSING_REMOTE_RECORD_STRATEGY = "ignore" /* Ignore */;
|
|
585
592
|
function createWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}) {
|
|
586
593
|
const store = (0, import_zustand.create)(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions));
|
|
587
594
|
return new Promise((resolve) => {
|
|
@@ -592,7 +599,7 @@ function createWithSync(stateCreator, persistOptions, syncApi, syncOptions = {})
|
|
|
592
599
|
}
|
|
593
600
|
function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}) {
|
|
594
601
|
const syncInterval = syncOptions.syncInterval ?? DEFAULT_SYNC_INTERVAL_MILLIS;
|
|
595
|
-
const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ??
|
|
602
|
+
const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ?? DEFAULT_MISSING_REMOTE_RECORD_STRATEGY;
|
|
596
603
|
const logger = newLogger(syncOptions.logger ?? DEFAULT_LOGGER, syncOptions.minLogLevel ?? DEFAULT_MIN_LOG_LEVEL);
|
|
597
604
|
const baseOnRehydrate = persistOptions?.onRehydrateStorage;
|
|
598
605
|
const basePartialize = persistOptions?.partialize;
|
|
@@ -760,11 +767,11 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
760
767
|
const queueItem = pendingChanges.find((p) => p.localId === localId && p.stateKey === stateKey);
|
|
761
768
|
if (queueItem) {
|
|
762
769
|
queueItem.version += 1;
|
|
763
|
-
if (queueItem.action === "
|
|
770
|
+
if (queueItem.action === "create-or-update" /* CreateOrUpdate */ && action === "remove" /* Remove */ && item.id) {
|
|
764
771
|
queueItem.action = "remove" /* Remove */;
|
|
765
772
|
queueItem.id = item.id;
|
|
766
773
|
}
|
|
767
|
-
logger.debug(`[zync] queueToSync:adjusted
|
|
774
|
+
logger.debug(`[zync] queueToSync:adjusted action=${action} localId=${localId} v=${queueItem.version}`);
|
|
768
775
|
} else {
|
|
769
776
|
pendingChanges.push({ action, stateKey, localId, id: item.id, version: 1 });
|
|
770
777
|
logger.debug(`[zync] queueToSync:added action=${action} localId=${localId}`);
|
|
@@ -843,6 +850,7 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
843
850
|
}
|
|
844
851
|
// Annotate the CommonJS export names for ESM import in node:
|
|
845
852
|
0 && (module.exports = {
|
|
853
|
+
MissingRemoteRecordStrategy,
|
|
846
854
|
SyncAction,
|
|
847
855
|
createIndexedDBStorage,
|
|
848
856
|
createWithSync,
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../node_modules/.pnpm/idb@8.0.3/node_modules/idb/build/index.js","../src/index.ts","../src/logger.ts","../src/helpers.ts","../src/pull.ts","../src/push.ts","../src/indexedDBStorage.ts"],"sourcesContent":["const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst transactionDoneMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(this.request);\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);\n });\n }\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event.newVersion, event));\n }\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking) {\n db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));\n }\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event));\n }\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nconst advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];\nconst methodMap = {};\nconst advanceResults = new WeakMap();\nconst ittrProxiedCursorToOriginalProxy = new WeakMap();\nconst cursorIteratorTraps = {\n get(target, prop) {\n if (!advanceMethodProps.includes(prop))\n return target[prop];\n let cachedFunc = methodMap[prop];\n if (!cachedFunc) {\n cachedFunc = methodMap[prop] = function (...args) {\n advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));\n };\n }\n return cachedFunc;\n },\n};\nasync function* iterate(...args) {\n // tslint:disable-next-line:no-this-assignment\n let cursor = this;\n if (!(cursor instanceof IDBCursor)) {\n cursor = await cursor.openCursor(...args);\n }\n if (!cursor)\n return;\n cursor = cursor;\n const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);\n ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);\n // Map this double-proxy back to the original, so other cursor methods work.\n reverseTransformCache.set(proxiedCursor, unwrap(cursor));\n while (cursor) {\n yield proxiedCursor;\n // If one of the advancing methods was not called, call continue().\n cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());\n advanceResults.delete(proxiedCursor);\n }\n}\nfunction isIteratorProp(target, prop) {\n return ((prop === Symbol.asyncIterator &&\n instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor])) ||\n (prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore])));\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get(target, prop, receiver) {\n if (isIteratorProp(target, prop))\n return iterate;\n return oldTraps.get(target, prop, receiver);\n },\n has(target, prop) {\n return isIteratorProp(target, prop) || oldTraps.has(target, prop);\n },\n}));\n\nexport { deleteDB, openDB, unwrap, wrap };\n","import { create, type StateCreator } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { newLogger, type Logger, type LogLevel } from './logger';\nimport { orderFor, findApi, nextLocalId } from './helpers';\nimport type {\n ApiFunctions,\n MissingRemoteRecordDuringUpdateStrategy,\n SyncOptions,\n SyncState,\n SyncedStateCreator,\n PendingChange,\n UseStoreWithSync,\n} from './types';\nimport { pull } from './pull';\nimport { pushOne } from './push';\n\nexport { createIndexedDBStorage } from './indexedDBStorage';\nexport { nextLocalId } from './helpers';\nexport type { ApiFunctions, UseStoreWithSync, SyncState } from './types';\n\nexport enum SyncAction {\n CreateOrUpdate = 'createOrUpdate',\n Remove = 'remove',\n}\n\nconst DEFAULT_SYNC_INTERVAL_MILLIS = 5000;\nconst DEFAULT_LOGGER: Logger = console;\nconst DEFAULT_MIN_LOG_LEVEL: LogLevel = 'debug';\nconst DEFAULT_MISSING_REMOTE_RECORD_ON_UPDATE_STRATEGY: MissingRemoteRecordDuringUpdateStrategy = 'ignore';\n\nexport function createWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n): Promise<UseStoreWithSync<TStore>> {\n const store = create(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions)) as UseStoreWithSync<TStore>;\n\n return new Promise<UseStoreWithSync<TStore>>((resolve) => {\n store.persist.onFinishHydration((_state) => {\n resolve(store);\n });\n });\n}\n\nexport function persistWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n) {\n const syncInterval = syncOptions.syncInterval ?? DEFAULT_SYNC_INTERVAL_MILLIS;\n const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ?? DEFAULT_MISSING_REMOTE_RECORD_ON_UPDATE_STRATEGY;\n const logger = newLogger(syncOptions.logger ?? DEFAULT_LOGGER, syncOptions.minLogLevel ?? DEFAULT_MIN_LOG_LEVEL);\n\n const baseOnRehydrate = persistOptions?.onRehydrateStorage;\n const basePartialize = persistOptions?.partialize;\n\n const wrappedPersistOptions = {\n ...persistOptions,\n onRehydrateStorage: () => {\n logger.debug('[zync] rehydration:start');\n\n return (state: any, error: any) => {\n if (error) {\n logger.error('[zync] rehydration:failed', error);\n } else {\n baseOnRehydrate?.(state, error);\n logger.debug('[zync] rehydration:complete', state);\n }\n };\n },\n partialize: (s: any) => {\n // Select state to be persisted\n\n const base = basePartialize ? basePartialize(s) : s;\n const { syncState, ...rest } = base || {};\n return {\n ...rest,\n syncState: {\n firstLoadDone: syncState.firstLoadDone,\n pendingChanges: syncState.pendingChanges,\n lastPulled: syncState.lastPulled,\n },\n };\n },\n merge: (persisted: any, current: any) => {\n // Here after hydration.\n // `persisted` is state from storage that's just loaded (possibly ascynchronously e.g. IndexedDB)\n // `current` is what the user has defined (they may have added or removed state keys)\n // Zync is designed to not be used until hydration is complete, so we don't expect to have to\n // merge user mutated state (i.e. current) into persisted. So we do the Zustand recommended pattern of\n // shallow copy where persisted keys win:\n const state = { ...current, ...persisted };\n\n return {\n ...state,\n syncState: {\n ...state.syncState,\n status: 'idle', // this confirms 'hydrating' is done\n },\n };\n },\n };\n\n const creator: StateCreator<TStore & SyncState, [], []> = (set: any, get: any, storeApi: any) => {\n let syncIntervalId: any;\n\n async function syncOnce() {\n const state: SyncState = get();\n if (!state.syncState.enabled || state.syncState.status !== 'idle') return;\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'syncing',\n },\n }));\n\n let syncError: Error | undefined;\n\n // 1) PULL for each stateKey\n for (const stateKey of Object.keys(syncApi)) {\n try {\n const api = findApi(stateKey, syncApi);\n await pull(set, get, stateKey, api, logger);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] pull:error stateKey=${stateKey}`, err);\n }\n }\n\n // 2) PUSH queued changes\n const snapshot: PendingChange[] = [...(get().syncState.pendingChanges || [])];\n\n // Deterministic ordering: Create -> Update -> Remove so dependencies (e.g. id assignment) happen early\n snapshot.sort((a, b) => orderFor(a.action) - orderFor(b.action));\n\n for (const change of snapshot) {\n try {\n const api = findApi(change.stateKey, syncApi);\n await pushOne(\n set,\n get,\n change,\n api,\n logger,\n queueToSync,\n missingStrategy,\n syncOptions.onMissingRemoteRecordDuringUpdate,\n syncOptions.onAfterRemoteAdd,\n );\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] push:error change=${change}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'idle',\n error: syncError,\n },\n }));\n\n if (get().syncState.pendingChanges.length > 0 && !syncError) {\n // If there are pending changes and no sync error, we can sync again\n await syncOnce();\n }\n }\n\n async function startFirstLoad() {\n let syncError: Error | undefined;\n\n for (const stateKey of Object.keys(syncApi)) {\n try {\n logger.info(`[zync] firstLoad:start stateKey=${stateKey}`);\n\n const api = findApi(stateKey, syncApi);\n let lastId; // Start as undefined to allow the userland api code to set the initial value+type\n\n // Batch until empty\n while (true) {\n const batch = await api.firstLoad(lastId);\n if (!batch?.length) break;\n\n // Merge batch\n set((state: any) => {\n const local: any[] = state[stateKey] || [];\n const localById = new Map<any, any>(local.filter((l) => l.id).map((l) => [l.id, l]));\n\n let newest = new Date(state.syncState.lastPulled[stateKey] || 0);\n const next = [...local];\n for (const remote of batch) {\n const remoteUpdated = new Date(remote.updated_at || 0);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n if (remote.deleted) continue;\n\n const localItem = remote.id ? localById.get(remote.id) : undefined;\n if (localItem) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n const idx = next.findIndex((i) => i._localId === localItem._localId);\n if (idx >= 0) next[idx] = merged;\n } else {\n next.push({\n ...remote,\n _localId: nextLocalId(),\n });\n }\n }\n\n return {\n [stateKey]: next,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n\n lastId = batch[batch.length - 1].id;\n }\n\n logger.info(`[zync] firstLoad:done stateKey=${stateKey}`);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] firstLoad:error stateKey=${stateKey}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n firstLoadDone: true,\n error: syncError,\n },\n }));\n }\n\n function queueToSync(action: any, stateKey: string, ...localIds: string[]) {\n set((state: any) => {\n const pendingChanges: any[] = state.syncState.pendingChanges || [];\n\n for (const localId of localIds) {\n const item = state[stateKey].find((i: any) => i._localId === localId);\n if (!item) {\n logger.error(`[zync] queueToSync:no-local-item localId=${localId}`);\n continue;\n }\n\n const queueItem = pendingChanges.find((p) => p.localId === localId && p.stateKey === stateKey);\n if (queueItem) {\n queueItem.version += 1;\n\n if (queueItem.action === SyncAction.CreateOrUpdate && action === SyncAction.Remove && item.id) {\n queueItem.action = SyncAction.Remove;\n queueItem.id = item.id;\n }\n logger.debug(`[zync] queueToSync:adjusted v=${queueItem.version} action=${action} localId=${localId}`);\n } else {\n pendingChanges.push({ action, stateKey, localId, id: item.id, version: 1 });\n logger.debug(`[zync] queueToSync:added action=${action} localId=${localId}`);\n }\n }\n\n return {\n syncState: {\n ...(state.syncState || {}),\n pendingChanges,\n },\n };\n });\n syncOnce();\n }\n\n function setAndSync(partial: any) {\n if (typeof partial === 'function') {\n set((state: any) => ({ ...partial(state) }));\n } else {\n set(partial);\n }\n syncOnce();\n }\n\n function enable(enabled: boolean) {\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n enabled,\n },\n }));\n\n enableSyncTimer(enabled);\n addVisibilityChangeListener(enabled);\n }\n\n function enableSyncTimer(enabled: boolean) {\n clearInterval(syncIntervalId);\n syncIntervalId = undefined;\n if (enabled) {\n syncIntervalId = setInterval(syncOnce, syncInterval);\n syncOnce();\n }\n }\n\n function addVisibilityChangeListener(add: boolean) {\n if (add) {\n document.addEventListener('visibilitychange', onVisibilityChange);\n } else {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n }\n\n function onVisibilityChange() {\n if (document.visibilityState === 'visible') {\n logger.debug('[zync] sync:start-in-foreground');\n enableSyncTimer(true);\n } else {\n logger.debug('[zync] sync:pause-in-background');\n enableSyncTimer(false);\n }\n }\n\n // public useStore.sync api, similar in principle to useStore.persist\n storeApi.sync = {\n enable,\n startFirstLoad,\n };\n\n const userState = stateCreator(setAndSync, get, queueToSync) as TStore;\n\n return {\n ...userState,\n syncState: {\n // set defaults\n status: 'hydrating',\n error: undefined,\n enabled: false,\n firstLoadDone: false,\n pendingChanges: [],\n lastPulled: {},\n },\n } as TStore & SyncState;\n };\n\n return persist(creator, wrappedPersistOptions);\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';\n\nexport interface Logger {\n debug: (...args: any[]) => void;\n info: (...args: any[]) => void;\n warn: (...args: any[]) => void;\n error: (...args: any[]) => void;\n}\n\nexport function newLogger(base: Logger, min: LogLevel): Logger {\n const order: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n none: 100,\n };\n const threshold = order[min];\n const enabled = (lvl: LogLevel) => order[lvl] >= threshold;\n return {\n debug: (...a: any[]) => enabled('debug') && base.debug?.(...a),\n info: (...a: any[]) => enabled('info') && base.info?.(...a),\n warn: (...a: any[]) => enabled('warn') && base.warn?.(...a),\n error: (...a: any[]) => enabled('error') && base.error?.(...a),\n };\n}\n","import { SyncAction } from './index';\nimport type { ApiFunctions, PendingChange } from './types';\n\nexport function nextLocalId(): string {\n return crypto.randomUUID();\n}\n\nexport function orderFor(a: SyncAction): number {\n switch (a) {\n case SyncAction.CreateOrUpdate:\n return 1;\n case SyncAction.Remove:\n return 2;\n }\n}\n\nexport function omitSyncFields(item: any, fields: readonly string[]) {\n const result = { ...item };\n for (const k of fields) delete result[k];\n return result;\n}\n\nexport function samePendingVersion(get: any, stateKey: string, localId: string, version: number): boolean {\n const q: PendingChange[] = get().syncState.pendingChanges || [];\n const curChange = q.find((p) => p.localId === localId && p.stateKey === stateKey);\n return curChange?.version === version;\n}\n\nexport function removeFromPendingChanges(set: any, localId: string, stateKey: string) {\n set((s: any) => {\n const queue: PendingChange[] = (s.syncState.pendingChanges || []).filter((p: PendingChange) => !(p.localId === localId && p.stateKey === stateKey));\n return {\n syncState: {\n ...(s.syncState || {}),\n pendingChanges: queue,\n },\n };\n });\n}\n\nexport function findApi(stateKey: string, syncApi: Record<string, ApiFunctions>) {\n const api = syncApi[stateKey];\n if (!api || !api.add || !api.update || !api.remove || !api.list || !api.firstLoad) {\n throw new Error(`Missing API function(s) for state key: ${stateKey}.`);\n }\n return api;\n}\n","import type { ApiFunctions, PendingChange, SyncedRecord } from './types';\nimport { SyncAction } from './index';\nimport { nextLocalId } from './helpers';\n\nexport async function pull(set: any, get: any, stateKey: string, api: ApiFunctions, logger: any) {\n const lastPulled: Record<string, string> = get().syncState.lastPulled || {};\n const lastPulledAt = new Date(lastPulled[stateKey] || new Date(0));\n\n logger.debug(`[zync] pull:start stateKey=${stateKey} since=${lastPulledAt.toISOString()}`);\n\n const serverData = (await api.list(lastPulledAt)) as SyncedRecord[];\n if (!serverData?.length) return;\n\n let newest = lastPulledAt;\n set((state: any) => {\n const pendingChanges: PendingChange[] = state.syncState.pendingChanges || [];\n const localItems: any[] = state[stateKey] || [];\n let nextItems = [...localItems];\n const localById = new Map<any, any>(localItems.filter((l) => l.id).map((l) => [l.id, l]));\n // prevent resurrecting deleted items by pulling them again\n const pendingRemovalById = new Set(pendingChanges.filter((p) => p.stateKey === stateKey && p.action === SyncAction.Remove).map((p) => p.id));\n\n for (const remote of serverData) {\n const remoteUpdated = new Date(remote.updated_at);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n // If a Remove is pending for this localId, skip merging/adding to avoid flicker\n if (pendingRemovalById.has(remote.id)) {\n logger.debug(`[zync] pull:skip-pending-remove stateKey=${stateKey} id=${remote.id}`);\n continue;\n }\n\n const localItem = localById.get(remote.id);\n if (remote.deleted) {\n if (localItem) {\n nextItems = nextItems.filter((i: any) => i.id !== remote.id);\n logger.debug(`[zync] pull:remove stateKey=${stateKey} id=${remote.id}`);\n }\n continue;\n }\n\n const pending = localItem && pendingChanges.some((p: any) => p.stateKey === stateKey && p.localId === localItem._localId);\n if (localItem && !pending) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n nextItems = nextItems.map((i: any) => (i._localId === localItem._localId ? merged : i));\n logger.debug(`[zync] pull:merge stateKey=${stateKey} id=${remote.id}`);\n } else if (!localItem) {\n // Add remote item (no local or pending collisions)\n nextItems = [...nextItems, { ...remote, _localId: nextLocalId() }];\n logger.debug(`[zync] pull:add stateKey=${stateKey} id=${remote.id}`);\n }\n }\n\n return {\n [stateKey]: nextItems,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n}\n","import { removeFromPendingChanges, omitSyncFields, samePendingVersion } from './helpers';\nimport { SyncAction } from './index';\nimport type { ApiFunctions } from './types';\n\nconst SYNC_FIELDS = ['id', '_localId', 'updated_at', 'deleted'] as const;\n\nexport async function pushOne(\n set: any,\n get: any,\n change: any,\n api: ApiFunctions,\n logger: any,\n queueToSync: any,\n missingStrategy: string,\n onMissingRemoteRecordDuringUpdate?: any,\n onAfterRemoteAdd?: any,\n) {\n logger.debug(`[zync] push:attempt action=${change.action} stateKey=${change.stateKey} localId=${change.localId}`);\n\n const { action, stateKey, localId, id, version } = change;\n\n switch (action) {\n case SyncAction.Remove:\n await api.remove(id);\n logger.debug(`[zync] push:remove:success ${stateKey} ${localId} ${id}`);\n removeFromPendingChanges(set, localId, stateKey);\n break;\n\n case SyncAction.CreateOrUpdate: {\n const state = get();\n const items: any[] = state[stateKey] || [];\n const item = items.find((i) => i._localId === localId);\n if (!item) {\n logger.warn(`[zync] push:create-or-update:no-local-item`, {\n stateKey,\n localId,\n });\n removeFromPendingChanges(set, localId, stateKey);\n return;\n }\n\n const omittedItem = omitSyncFields(item, SYNC_FIELDS);\n if (item.id) {\n // Update\n const changed = await api.update(item.id, omittedItem);\n if (changed) {\n logger.debug('[zync] push:update:success', {\n stateKey,\n localId,\n id: item.id,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n return;\n } else {\n logger.warn('[zync] push:update:missing-remote', {\n stateKey,\n localId,\n id: item.id,\n });\n\n switch (missingStrategy) {\n case 'deleteLocalRecord':\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).filter((i: any) => i._localId !== localId),\n }));\n break;\n\n case 'insertNewRemoteRecord': {\n omittedItem._localId = crypto.randomUUID();\n omittedItem.updated_at = new Date().toISOString();\n\n // replace old with new copy without id so it becomes a Create\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? omittedItem : i)),\n }));\n\n queueToSync(SyncAction.CreateOrUpdate, stateKey, omittedItem._localId);\n break;\n }\n }\n removeFromPendingChanges(set, localId, stateKey);\n // Call hook so userland can alert the user etc.\n onMissingRemoteRecordDuringUpdate?.(missingStrategy, omittedItem, omittedItem._localId);\n }\n return;\n }\n\n // Create\n const result = await api.add(omittedItem);\n if (result) {\n logger.debug('[zync] push:create:success', {\n stateKey,\n localId,\n id: result.id,\n });\n\n // Merge server-assigned fields (id, updated_at, etc) directly into local entity\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? { ...i, ...result } : i)),\n }));\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n // Call hook so userland can perform any cascading adjustments\n onAfterRemoteAdd?.(set, get, queueToSync, stateKey, {\n ...item,\n ...result,\n });\n } else {\n logger.warn('[zync] push:create:no-result', {\n stateKey,\n localId,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n }\n break;\n }\n }\n}\n","import type { IDBPDatabase } from 'idb';\n\nexport function createIndexedDBStorage(options: { dbName: string; storeName: string }) {\n const dbName = options.dbName;\n const storeName = options.storeName;\n\n // dbPromise is created lazily by initDB() to avoid pulling `idb` into bundles\n let dbPromise: Promise<IDBPDatabase<any>> | null = null;\n\n async function initDB(): Promise<IDBPDatabase<any>> {\n if (dbPromise) return dbPromise;\n try {\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, 1, {\n upgrade(db: IDBPDatabase<any>) {\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName);\n }\n },\n });\n return dbPromise;\n } catch (_e) {\n throw new Error('Missing optional dependency \"idb\". Install it to use IndexedDB storage: npm install idb');\n }\n }\n\n async function ensureStore(): Promise<void> {\n const db = await initDB();\n if (db.objectStoreNames.contains(storeName)) return;\n const nextVersion = (db.version || 0) + 1;\n try {\n db.close();\n } catch (_e) {\n // ignore\n }\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, nextVersion, {\n upgrade(upg: IDBPDatabase<any>) {\n if (!upg.objectStoreNames.contains(storeName)) upg.createObjectStore(storeName);\n },\n });\n await dbPromise;\n }\n\n async function withRetry<T>(fn: (db: IDBPDatabase<any>) => Promise<T>): Promise<T> {\n try {\n const db = await initDB();\n return await fn(db);\n } catch (err: any) {\n const msg = String(err && err.message ? err.message : err);\n if (err && (err.name === 'NotFoundError' || /objectStore/i.test(msg))) {\n await ensureStore();\n const db2 = await initDB();\n return await fn(db2);\n }\n throw err;\n }\n }\n\n return {\n getItem: async (name: string): Promise<string | null> => {\n return withRetry(async (db) => {\n let v = await db.get(storeName, name);\n v = v ?? null; // Zustand expects null for missing keys\n return v;\n });\n },\n setItem: async (name: string, value: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.put(storeName, value, name);\n });\n },\n removeItem: async (name: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.delete(storeName, name);\n });\n },\n };\n}\n"],"mappings":"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","names":["target","SyncAction","state"]}
|
|
1
|
+
{"version":3,"sources":["../node_modules/.pnpm/idb@8.0.3/node_modules/idb/build/index.js","../src/index.ts","../src/logger.ts","../src/helpers.ts","../src/pull.ts","../src/push.ts","../src/indexedDBStorage.ts"],"sourcesContent":["const instanceOfAny = (object, constructors) => constructors.some((c) => object instanceof c);\n\nlet idbProxyableTypes;\nlet cursorAdvanceMethods;\n// This is a function to prevent it throwing up in node environments.\nfunction getIdbProxyableTypes() {\n return (idbProxyableTypes ||\n (idbProxyableTypes = [\n IDBDatabase,\n IDBObjectStore,\n IDBIndex,\n IDBCursor,\n IDBTransaction,\n ]));\n}\n// This is a function to prevent it throwing up in node environments.\nfunction getCursorAdvanceMethods() {\n return (cursorAdvanceMethods ||\n (cursorAdvanceMethods = [\n IDBCursor.prototype.advance,\n IDBCursor.prototype.continue,\n IDBCursor.prototype.continuePrimaryKey,\n ]));\n}\nconst transactionDoneMap = new WeakMap();\nconst transformCache = new WeakMap();\nconst reverseTransformCache = new WeakMap();\nfunction promisifyRequest(request) {\n const promise = new Promise((resolve, reject) => {\n const unlisten = () => {\n request.removeEventListener('success', success);\n request.removeEventListener('error', error);\n };\n const success = () => {\n resolve(wrap(request.result));\n unlisten();\n };\n const error = () => {\n reject(request.error);\n unlisten();\n };\n request.addEventListener('success', success);\n request.addEventListener('error', error);\n });\n // This mapping exists in reverseTransformCache but doesn't exist in transformCache. This\n // is because we create many promises from a single IDBRequest.\n reverseTransformCache.set(promise, request);\n return promise;\n}\nfunction cacheDonePromiseForTransaction(tx) {\n // Early bail if we've already created a done promise for this transaction.\n if (transactionDoneMap.has(tx))\n return;\n const done = new Promise((resolve, reject) => {\n const unlisten = () => {\n tx.removeEventListener('complete', complete);\n tx.removeEventListener('error', error);\n tx.removeEventListener('abort', error);\n };\n const complete = () => {\n resolve();\n unlisten();\n };\n const error = () => {\n reject(tx.error || new DOMException('AbortError', 'AbortError'));\n unlisten();\n };\n tx.addEventListener('complete', complete);\n tx.addEventListener('error', error);\n tx.addEventListener('abort', error);\n });\n // Cache it for later retrieval.\n transactionDoneMap.set(tx, done);\n}\nlet idbProxyTraps = {\n get(target, prop, receiver) {\n if (target instanceof IDBTransaction) {\n // Special handling for transaction.done.\n if (prop === 'done')\n return transactionDoneMap.get(target);\n // Make tx.store return the only store in the transaction, or undefined if there are many.\n if (prop === 'store') {\n return receiver.objectStoreNames[1]\n ? undefined\n : receiver.objectStore(receiver.objectStoreNames[0]);\n }\n }\n // Else transform whatever we get back.\n return wrap(target[prop]);\n },\n set(target, prop, value) {\n target[prop] = value;\n return true;\n },\n has(target, prop) {\n if (target instanceof IDBTransaction &&\n (prop === 'done' || prop === 'store')) {\n return true;\n }\n return prop in target;\n },\n};\nfunction replaceTraps(callback) {\n idbProxyTraps = callback(idbProxyTraps);\n}\nfunction wrapFunction(func) {\n // Due to expected object equality (which is enforced by the caching in `wrap`), we\n // only create one new func per func.\n // Cursor methods are special, as the behaviour is a little more different to standard IDB. In\n // IDB, you advance the cursor and wait for a new 'success' on the IDBRequest that gave you the\n // cursor. It's kinda like a promise that can resolve with many values. That doesn't make sense\n // with real promises, so each advance methods returns a new promise for the cursor object, or\n // undefined if the end of the cursor has been reached.\n if (getCursorAdvanceMethods().includes(func)) {\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n func.apply(unwrap(this), args);\n return wrap(this.request);\n };\n }\n return function (...args) {\n // Calling the original function with the proxy as 'this' causes ILLEGAL INVOCATION, so we use\n // the original object.\n return wrap(func.apply(unwrap(this), args));\n };\n}\nfunction transformCachableValue(value) {\n if (typeof value === 'function')\n return wrapFunction(value);\n // This doesn't return, it just creates a 'done' promise for the transaction,\n // which is later returned for transaction.done (see idbObjectHandler).\n if (value instanceof IDBTransaction)\n cacheDonePromiseForTransaction(value);\n if (instanceOfAny(value, getIdbProxyableTypes()))\n return new Proxy(value, idbProxyTraps);\n // Return the same value back if we're not going to transform it.\n return value;\n}\nfunction wrap(value) {\n // We sometimes generate multiple promises from a single IDBRequest (eg when cursoring), because\n // IDB is weird and a single IDBRequest can yield many responses, so these can't be cached.\n if (value instanceof IDBRequest)\n return promisifyRequest(value);\n // If we've already transformed this value before, reuse the transformed value.\n // This is faster, but it also provides object equality.\n if (transformCache.has(value))\n return transformCache.get(value);\n const newValue = transformCachableValue(value);\n // Not all types are transformed.\n // These may be primitive types, so they can't be WeakMap keys.\n if (newValue !== value) {\n transformCache.set(value, newValue);\n reverseTransformCache.set(newValue, value);\n }\n return newValue;\n}\nconst unwrap = (value) => reverseTransformCache.get(value);\n\n/**\n * Open a database.\n *\n * @param name Name of the database.\n * @param version Schema version.\n * @param callbacks Additional callbacks.\n */\nfunction openDB(name, version, { blocked, upgrade, blocking, terminated } = {}) {\n const request = indexedDB.open(name, version);\n const openPromise = wrap(request);\n if (upgrade) {\n request.addEventListener('upgradeneeded', (event) => {\n upgrade(wrap(request.result), event.oldVersion, event.newVersion, wrap(request.transaction), event);\n });\n }\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event.newVersion, event));\n }\n openPromise\n .then((db) => {\n if (terminated)\n db.addEventListener('close', () => terminated());\n if (blocking) {\n db.addEventListener('versionchange', (event) => blocking(event.oldVersion, event.newVersion, event));\n }\n })\n .catch(() => { });\n return openPromise;\n}\n/**\n * Delete a database.\n *\n * @param name Name of the database.\n */\nfunction deleteDB(name, { blocked } = {}) {\n const request = indexedDB.deleteDatabase(name);\n if (blocked) {\n request.addEventListener('blocked', (event) => blocked(\n // Casting due to https://github.com/microsoft/TypeScript-DOM-lib-generator/pull/1405\n event.oldVersion, event));\n }\n return wrap(request).then(() => undefined);\n}\n\nconst readMethods = ['get', 'getKey', 'getAll', 'getAllKeys', 'count'];\nconst writeMethods = ['put', 'add', 'delete', 'clear'];\nconst cachedMethods = new Map();\nfunction getMethod(target, prop) {\n if (!(target instanceof IDBDatabase &&\n !(prop in target) &&\n typeof prop === 'string')) {\n return;\n }\n if (cachedMethods.get(prop))\n return cachedMethods.get(prop);\n const targetFuncName = prop.replace(/FromIndex$/, '');\n const useIndex = prop !== targetFuncName;\n const isWrite = writeMethods.includes(targetFuncName);\n if (\n // Bail if the target doesn't exist on the target. Eg, getAll isn't in Edge.\n !(targetFuncName in (useIndex ? IDBIndex : IDBObjectStore).prototype) ||\n !(isWrite || readMethods.includes(targetFuncName))) {\n return;\n }\n const method = async function (storeName, ...args) {\n // isWrite ? 'readwrite' : undefined gzipps better, but fails in Edge :(\n const tx = this.transaction(storeName, isWrite ? 'readwrite' : 'readonly');\n let target = tx.store;\n if (useIndex)\n target = target.index(args.shift());\n // Must reject if op rejects.\n // If it's a write operation, must reject if tx.done rejects.\n // Must reject with op rejection first.\n // Must resolve with op value.\n // Must handle both promises (no unhandled rejections)\n return (await Promise.all([\n target[targetFuncName](...args),\n isWrite && tx.done,\n ]))[0];\n };\n cachedMethods.set(prop, method);\n return method;\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get: (target, prop, receiver) => getMethod(target, prop) || oldTraps.get(target, prop, receiver),\n has: (target, prop) => !!getMethod(target, prop) || oldTraps.has(target, prop),\n}));\n\nconst advanceMethodProps = ['continue', 'continuePrimaryKey', 'advance'];\nconst methodMap = {};\nconst advanceResults = new WeakMap();\nconst ittrProxiedCursorToOriginalProxy = new WeakMap();\nconst cursorIteratorTraps = {\n get(target, prop) {\n if (!advanceMethodProps.includes(prop))\n return target[prop];\n let cachedFunc = methodMap[prop];\n if (!cachedFunc) {\n cachedFunc = methodMap[prop] = function (...args) {\n advanceResults.set(this, ittrProxiedCursorToOriginalProxy.get(this)[prop](...args));\n };\n }\n return cachedFunc;\n },\n};\nasync function* iterate(...args) {\n // tslint:disable-next-line:no-this-assignment\n let cursor = this;\n if (!(cursor instanceof IDBCursor)) {\n cursor = await cursor.openCursor(...args);\n }\n if (!cursor)\n return;\n cursor = cursor;\n const proxiedCursor = new Proxy(cursor, cursorIteratorTraps);\n ittrProxiedCursorToOriginalProxy.set(proxiedCursor, cursor);\n // Map this double-proxy back to the original, so other cursor methods work.\n reverseTransformCache.set(proxiedCursor, unwrap(cursor));\n while (cursor) {\n yield proxiedCursor;\n // If one of the advancing methods was not called, call continue().\n cursor = await (advanceResults.get(proxiedCursor) || cursor.continue());\n advanceResults.delete(proxiedCursor);\n }\n}\nfunction isIteratorProp(target, prop) {\n return ((prop === Symbol.asyncIterator &&\n instanceOfAny(target, [IDBIndex, IDBObjectStore, IDBCursor])) ||\n (prop === 'iterate' && instanceOfAny(target, [IDBIndex, IDBObjectStore])));\n}\nreplaceTraps((oldTraps) => ({\n ...oldTraps,\n get(target, prop, receiver) {\n if (isIteratorProp(target, prop))\n return iterate;\n return oldTraps.get(target, prop, receiver);\n },\n has(target, prop) {\n return isIteratorProp(target, prop) || oldTraps.has(target, prop);\n },\n}));\n\nexport { deleteDB, openDB, unwrap, wrap };\n","import { create, type StateCreator } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { newLogger, type Logger, type LogLevel } from './logger';\nimport { orderFor, findApi, nextLocalId } from './helpers';\nimport type { ApiFunctions, SyncOptions, SyncState, SyncedStateCreator, PendingChange, UseStoreWithSync } from './types';\nimport { pull } from './pull';\nimport { pushOne } from './push';\n\nexport { createIndexedDBStorage } from './indexedDBStorage';\nexport { nextLocalId } from './helpers';\nexport type { ApiFunctions, UseStoreWithSync, SyncState } from './types';\n\nexport enum SyncAction {\n CreateOrUpdate = 'create-or-update',\n Remove = 'remove',\n}\n\nexport enum MissingRemoteRecordStrategy {\n Ignore = 'ignore',\n DeleteLocalRecord = 'delete-local-record',\n InsertRemoteRecord = 'insert-remote-record',\n}\n\nconst DEFAULT_SYNC_INTERVAL_MILLIS = 5000;\nconst DEFAULT_LOGGER: Logger = console;\nconst DEFAULT_MIN_LOG_LEVEL: LogLevel = 'debug';\nconst DEFAULT_MISSING_REMOTE_RECORD_STRATEGY: MissingRemoteRecordStrategy = MissingRemoteRecordStrategy.Ignore;\n\nexport function createWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n): Promise<UseStoreWithSync<TStore>> {\n const store = create(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions)) as UseStoreWithSync<TStore>;\n\n return new Promise<UseStoreWithSync<TStore>>((resolve) => {\n store.persist.onFinishHydration((_state) => {\n resolve(store);\n });\n });\n}\n\nexport function persistWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n) {\n const syncInterval = syncOptions.syncInterval ?? DEFAULT_SYNC_INTERVAL_MILLIS;\n const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ?? DEFAULT_MISSING_REMOTE_RECORD_STRATEGY;\n const logger = newLogger(syncOptions.logger ?? DEFAULT_LOGGER, syncOptions.minLogLevel ?? DEFAULT_MIN_LOG_LEVEL);\n\n const baseOnRehydrate = persistOptions?.onRehydrateStorage;\n const basePartialize = persistOptions?.partialize;\n\n const wrappedPersistOptions = {\n ...persistOptions,\n onRehydrateStorage: () => {\n logger.debug('[zync] rehydration:start');\n\n return (state: any, error: any) => {\n if (error) {\n logger.error('[zync] rehydration:failed', error);\n } else {\n baseOnRehydrate?.(state, error);\n logger.debug('[zync] rehydration:complete', state);\n }\n };\n },\n partialize: (s: any) => {\n // Select state to be persisted\n\n const base = basePartialize ? basePartialize(s) : s;\n const { syncState, ...rest } = base || {};\n return {\n ...rest,\n syncState: {\n firstLoadDone: syncState.firstLoadDone,\n pendingChanges: syncState.pendingChanges,\n lastPulled: syncState.lastPulled,\n },\n };\n },\n merge: (persisted: any, current: any) => {\n // Here after hydration.\n // `persisted` is state from storage that's just loaded (possibly asynchronously e.g. IndexedDB)\n // `current` is what the user has defined (they may have added or removed state keys)\n // Zync is designed to not be used until hydration is complete, so we don't expect to have to\n // merge user mutated state (i.e. current) into persisted. So we do the Zustand recommended pattern of\n // shallow copy where persisted keys win:\n const state = { ...current, ...persisted };\n\n return {\n ...state,\n syncState: {\n ...state.syncState,\n status: 'idle', // this confirms 'hydrating' is done\n },\n };\n },\n };\n\n const creator: StateCreator<TStore & SyncState, [], []> = (set: any, get: any, storeApi: any) => {\n let syncIntervalId: any;\n\n async function syncOnce() {\n const state: SyncState = get();\n if (!state.syncState.enabled || state.syncState.status !== 'idle') return;\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'syncing',\n },\n }));\n\n let syncError: Error | undefined;\n\n // 1) PULL for each stateKey\n for (const stateKey of Object.keys(syncApi)) {\n try {\n const api = findApi(stateKey, syncApi);\n await pull(set, get, stateKey, api, logger);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] pull:error stateKey=${stateKey}`, err);\n }\n }\n\n // 2) PUSH queued changes\n const snapshot: PendingChange[] = [...(get().syncState.pendingChanges || [])];\n\n // Deterministic ordering: Create -> Update -> Remove so dependencies (e.g. id assignment) happen early\n snapshot.sort((a, b) => orderFor(a.action) - orderFor(b.action));\n\n for (const change of snapshot) {\n try {\n const api = findApi(change.stateKey, syncApi);\n await pushOne(\n set,\n get,\n change,\n api,\n logger,\n queueToSync,\n missingStrategy,\n syncOptions.onMissingRemoteRecordDuringUpdate,\n syncOptions.onAfterRemoteAdd,\n );\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] push:error change=${change}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'idle',\n error: syncError,\n },\n }));\n\n if (get().syncState.pendingChanges.length > 0 && !syncError) {\n // If there are pending changes and no sync error, we can sync again\n await syncOnce();\n }\n }\n\n async function startFirstLoad() {\n let syncError: Error | undefined;\n\n for (const stateKey of Object.keys(syncApi)) {\n try {\n logger.info(`[zync] firstLoad:start stateKey=${stateKey}`);\n\n const api = findApi(stateKey, syncApi);\n let lastId; // Start as undefined to allow the userland api code to set the initial value+type\n\n // Batch until empty\n while (true) {\n const batch = await api.firstLoad(lastId);\n if (!batch?.length) break;\n\n // Merge batch\n set((state: any) => {\n const local: any[] = state[stateKey] || [];\n const localById = new Map<any, any>(local.filter((l) => l.id).map((l) => [l.id, l]));\n\n let newest = new Date(state.syncState.lastPulled[stateKey] || 0);\n const next = [...local];\n for (const remote of batch) {\n const remoteUpdated = new Date(remote.updated_at || 0);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n if (remote.deleted) continue;\n\n const localItem = remote.id ? localById.get(remote.id) : undefined;\n if (localItem) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n const idx = next.findIndex((i) => i._localId === localItem._localId);\n if (idx >= 0) next[idx] = merged;\n } else {\n next.push({\n ...remote,\n _localId: nextLocalId(),\n });\n }\n }\n\n return {\n [stateKey]: next,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n\n lastId = batch[batch.length - 1].id;\n }\n\n logger.info(`[zync] firstLoad:done stateKey=${stateKey}`);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] firstLoad:error stateKey=${stateKey}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n firstLoadDone: true,\n error: syncError,\n },\n }));\n }\n\n function queueToSync(action: any, stateKey: string, ...localIds: string[]) {\n set((state: any) => {\n const pendingChanges: any[] = state.syncState.pendingChanges || [];\n\n for (const localId of localIds) {\n const item = state[stateKey].find((i: any) => i._localId === localId);\n if (!item) {\n logger.error(`[zync] queueToSync:no-local-item localId=${localId}`);\n continue;\n }\n\n const queueItem = pendingChanges.find((p) => p.localId === localId && p.stateKey === stateKey);\n if (queueItem) {\n queueItem.version += 1;\n\n if (queueItem.action === SyncAction.CreateOrUpdate && action === SyncAction.Remove && item.id) {\n queueItem.action = SyncAction.Remove;\n queueItem.id = item.id;\n }\n logger.debug(`[zync] queueToSync:adjusted action=${action} localId=${localId} v=${queueItem.version}`);\n } else {\n pendingChanges.push({ action, stateKey, localId, id: item.id, version: 1 });\n logger.debug(`[zync] queueToSync:added action=${action} localId=${localId}`);\n }\n }\n\n return {\n syncState: {\n ...(state.syncState || {}),\n pendingChanges,\n },\n };\n });\n syncOnce();\n }\n\n function setAndSync(partial: any) {\n if (typeof partial === 'function') {\n set((state: any) => ({ ...partial(state) }));\n } else {\n set(partial);\n }\n syncOnce();\n }\n\n function enable(enabled: boolean) {\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n enabled,\n },\n }));\n\n enableSyncTimer(enabled);\n addVisibilityChangeListener(enabled);\n }\n\n function enableSyncTimer(enabled: boolean) {\n clearInterval(syncIntervalId);\n syncIntervalId = undefined;\n if (enabled) {\n syncIntervalId = setInterval(syncOnce, syncInterval);\n syncOnce();\n }\n }\n\n function addVisibilityChangeListener(add: boolean) {\n if (add) {\n document.addEventListener('visibilitychange', onVisibilityChange);\n } else {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n }\n\n function onVisibilityChange() {\n if (document.visibilityState === 'visible') {\n logger.debug('[zync] sync:start-in-foreground');\n enableSyncTimer(true);\n } else {\n logger.debug('[zync] sync:pause-in-background');\n enableSyncTimer(false);\n }\n }\n\n // public useStore.sync api, similar in principle to useStore.persist\n storeApi.sync = {\n enable,\n startFirstLoad,\n };\n\n const userState = stateCreator(setAndSync, get, queueToSync) as TStore;\n\n return {\n ...userState,\n syncState: {\n // set defaults\n status: 'hydrating',\n error: undefined,\n enabled: false,\n firstLoadDone: false,\n pendingChanges: [],\n lastPulled: {},\n },\n } as TStore & SyncState;\n };\n\n return persist(creator, wrappedPersistOptions);\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';\n\nexport interface Logger {\n debug: (...args: any[]) => void;\n info: (...args: any[]) => void;\n warn: (...args: any[]) => void;\n error: (...args: any[]) => void;\n}\n\nexport function newLogger(base: Logger, min: LogLevel): Logger {\n const order: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n none: 100,\n };\n const threshold = order[min];\n const enabled = (lvl: LogLevel) => order[lvl] >= threshold;\n return {\n debug: (...a: any[]) => enabled('debug') && base.debug?.(...a),\n info: (...a: any[]) => enabled('info') && base.info?.(...a),\n warn: (...a: any[]) => enabled('warn') && base.warn?.(...a),\n error: (...a: any[]) => enabled('error') && base.error?.(...a),\n };\n}\n","import { SyncAction } from './index';\nimport type { ApiFunctions, PendingChange } from './types';\n\nexport function nextLocalId(): string {\n return crypto.randomUUID();\n}\n\nexport function orderFor(a: SyncAction): number {\n switch (a) {\n case SyncAction.CreateOrUpdate:\n return 1;\n case SyncAction.Remove:\n return 2;\n }\n}\n\nexport function omitSyncFields(item: any, fields: readonly string[]) {\n const result = { ...item };\n for (const k of fields) delete result[k];\n return result;\n}\n\nexport function samePendingVersion(get: any, stateKey: string, localId: string, version: number): boolean {\n const q: PendingChange[] = get().syncState.pendingChanges || [];\n const curChange = q.find((p) => p.localId === localId && p.stateKey === stateKey);\n return curChange?.version === version;\n}\n\nexport function removeFromPendingChanges(set: any, localId: string, stateKey: string) {\n set((s: any) => {\n const queue: PendingChange[] = (s.syncState.pendingChanges || []).filter((p: PendingChange) => !(p.localId === localId && p.stateKey === stateKey));\n return {\n syncState: {\n ...(s.syncState || {}),\n pendingChanges: queue,\n },\n };\n });\n}\n\nexport function findApi(stateKey: string, syncApi: Record<string, ApiFunctions>) {\n const api = syncApi[stateKey];\n if (!api || !api.add || !api.update || !api.remove || !api.list || !api.firstLoad) {\n throw new Error(`Missing API function(s) for state key: ${stateKey}.`);\n }\n return api;\n}\n","import type { ApiFunctions, PendingChange, SyncedRecord } from './types';\nimport { SyncAction } from './index';\nimport { nextLocalId } from './helpers';\n\nexport async function pull(set: any, get: any, stateKey: string, api: ApiFunctions, logger: any) {\n const lastPulled: Record<string, string> = get().syncState.lastPulled || {};\n const lastPulledAt = new Date(lastPulled[stateKey] || new Date(0));\n\n logger.debug(`[zync] pull:start stateKey=${stateKey} since=${lastPulledAt.toISOString()}`);\n\n const serverData = (await api.list(lastPulledAt)) as SyncedRecord[];\n if (!serverData?.length) return;\n\n let newest = lastPulledAt;\n set((state: any) => {\n const pendingChanges: PendingChange[] = state.syncState.pendingChanges || [];\n const localItems: any[] = state[stateKey] || [];\n let nextItems = [...localItems];\n const localById = new Map<any, any>(localItems.filter((l) => l.id).map((l) => [l.id, l]));\n // prevent resurrecting deleted items by pulling them again\n const pendingRemovalById = new Set(pendingChanges.filter((p) => p.stateKey === stateKey && p.action === SyncAction.Remove).map((p) => p.id));\n\n for (const remote of serverData) {\n const remoteUpdated = new Date(remote.updated_at);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n // If a Remove is pending for this localId, skip merging/adding to avoid flicker\n if (pendingRemovalById.has(remote.id)) {\n logger.debug(`[zync] pull:skip-pending-remove stateKey=${stateKey} id=${remote.id}`);\n continue;\n }\n\n const localItem = localById.get(remote.id);\n if (remote.deleted) {\n if (localItem) {\n nextItems = nextItems.filter((i: any) => i.id !== remote.id);\n logger.debug(`[zync] pull:remove stateKey=${stateKey} id=${remote.id}`);\n }\n continue;\n }\n\n const pending = localItem && pendingChanges.some((p: any) => p.stateKey === stateKey && p.localId === localItem._localId);\n if (localItem && !pending) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n nextItems = nextItems.map((i: any) => (i._localId === localItem._localId ? merged : i));\n logger.debug(`[zync] pull:merge stateKey=${stateKey} id=${remote.id}`);\n } else if (!localItem) {\n // Add remote item (no local or pending collisions)\n nextItems = [...nextItems, { ...remote, _localId: nextLocalId() }];\n logger.debug(`[zync] pull:add stateKey=${stateKey} id=${remote.id}`);\n }\n }\n\n return {\n [stateKey]: nextItems,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n}\n","import { removeFromPendingChanges, omitSyncFields, samePendingVersion } from './helpers';\nimport { MissingRemoteRecordStrategy, SyncAction } from './index';\nimport type { AfterRemoteAddCallback, ApiFunctions, MissingRemoteRecordDuringUpdateCallback } from './types';\n\nconst SYNC_FIELDS = ['id', '_localId', 'updated_at', 'deleted'] as const;\n\nexport async function pushOne(\n set: any,\n get: any,\n change: any,\n api: ApiFunctions,\n logger: any,\n queueToSync: any,\n missingStrategy: MissingRemoteRecordStrategy,\n onMissingRemoteRecordDuringUpdate?: MissingRemoteRecordDuringUpdateCallback,\n onAfterRemoteAdd?: AfterRemoteAddCallback,\n) {\n logger.debug(`[zync] push:attempt action=${change.action} stateKey=${change.stateKey} localId=${change.localId}`);\n\n const { action, stateKey, localId, id, version } = change;\n\n switch (action) {\n case SyncAction.Remove:\n await api.remove(id);\n logger.debug(`[zync] push:remove:success ${stateKey} ${localId} ${id}`);\n removeFromPendingChanges(set, localId, stateKey);\n break;\n\n case SyncAction.CreateOrUpdate: {\n const state = get();\n const items: any[] = state[stateKey] || [];\n const item = items.find((i) => i._localId === localId);\n if (!item) {\n logger.warn(`[zync] push:create-or-update:no-local-item`, {\n stateKey,\n localId,\n });\n removeFromPendingChanges(set, localId, stateKey);\n return;\n }\n\n const omittedItem = omitSyncFields(item, SYNC_FIELDS);\n if (item.id) {\n // Update\n const changed = await api.update(item.id, omittedItem);\n if (changed) {\n logger.debug('[zync] push:update:success', {\n stateKey,\n localId,\n id: item.id,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n return;\n } else {\n logger.warn('[zync] push:update:missing-remote', {\n stateKey,\n localId,\n id: item.id,\n });\n\n switch (missingStrategy) {\n case MissingRemoteRecordStrategy.DeleteLocalRecord:\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).filter((i: any) => i._localId !== localId),\n }));\n break;\n\n case MissingRemoteRecordStrategy.InsertRemoteRecord: {\n omittedItem._localId = crypto.randomUUID();\n omittedItem.updated_at = new Date().toISOString();\n\n // replace old with new copy without id so it becomes a Create\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? omittedItem : i)),\n }));\n\n queueToSync(SyncAction.CreateOrUpdate, stateKey, omittedItem._localId);\n break;\n }\n }\n removeFromPendingChanges(set, localId, stateKey);\n // Call hook so userland can alert the user etc.\n onMissingRemoteRecordDuringUpdate?.(missingStrategy, omittedItem, omittedItem._localId);\n }\n return;\n }\n\n // Create\n const result = await api.add(omittedItem);\n if (result) {\n logger.debug('[zync] push:create:success', {\n stateKey,\n localId,\n id: result.id,\n });\n\n // Merge server-assigned fields (id, updated_at, etc) directly into local entity\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? { ...i, ...result } : i)),\n }));\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n // Call hook so userland can perform any cascading adjustments\n onAfterRemoteAdd?.(set, get, queueToSync, stateKey, {\n ...item,\n ...result,\n });\n } else {\n logger.warn('[zync] push:create:no-result', {\n stateKey,\n localId,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n }\n break;\n }\n }\n}\n","import type { IDBPDatabase } from 'idb';\n\nexport function createIndexedDBStorage(options: { dbName: string; storeName: string }) {\n const dbName = options.dbName;\n const storeName = options.storeName;\n\n // dbPromise is created lazily by initDB() to avoid pulling `idb` into bundles\n let dbPromise: Promise<IDBPDatabase<any>> | null = null;\n\n async function initDB(): Promise<IDBPDatabase<any>> {\n if (dbPromise) return dbPromise;\n try {\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, 1, {\n upgrade(db: IDBPDatabase<any>) {\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName);\n }\n },\n });\n return dbPromise;\n } catch (_e) {\n throw new Error('Missing optional dependency \"idb\". Install it to use IndexedDB storage: npm install idb');\n }\n }\n\n async function ensureStore(): Promise<void> {\n const db = await initDB();\n if (db.objectStoreNames.contains(storeName)) return;\n const nextVersion = (db.version || 0) + 1;\n try {\n db.close();\n } catch (_e) {\n // ignore\n }\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, nextVersion, {\n upgrade(upg: IDBPDatabase<any>) {\n if (!upg.objectStoreNames.contains(storeName)) upg.createObjectStore(storeName);\n },\n });\n await dbPromise;\n }\n\n async function withRetry<T>(fn: (db: IDBPDatabase<any>) => Promise<T>): Promise<T> {\n try {\n const db = await initDB();\n return await fn(db);\n } catch (err: any) {\n const msg = String(err && err.message ? err.message : err);\n if (err && (err.name === 'NotFoundError' || /objectStore/i.test(msg))) {\n await ensureStore();\n const db2 = await initDB();\n return await fn(db2);\n }\n throw err;\n }\n }\n\n return {\n getItem: async (name: string): Promise<string | null> => {\n return withRetry(async (db) => {\n let v = await db.get(storeName, name);\n v = v ?? null; // Zustand expects null for missing keys\n return v;\n });\n },\n setItem: async (name: string, value: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.put(storeName, value, name);\n });\n },\n removeItem: async (name: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.delete(storeName, name);\n });\n },\n };\n}\n"],"mappings":"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","names":["target","SyncAction","MissingRemoteRecordStrategy","state"]}
|
package/dist/index.d.cts
CHANGED
|
@@ -18,14 +18,13 @@ interface ApiFunctions {
|
|
|
18
18
|
firstLoad: (lastId: any) => Promise<any[]>;
|
|
19
19
|
}
|
|
20
20
|
type AfterRemoteAddCallback = (set: any, get: any, queue: QueueToSyncCallback, stateKey: string, item: SyncedRecord) => void;
|
|
21
|
-
type MissingRemoteRecordDuringUpdateCallback = (strategy:
|
|
22
|
-
type MissingRemoteRecordDuringUpdateStrategy = 'ignore' | 'deleteLocalRecord' | 'insertNewRemoteRecord';
|
|
21
|
+
type MissingRemoteRecordDuringUpdateCallback = (strategy: MissingRemoteRecordStrategy, item: SyncedRecord, newLocalId?: string) => void;
|
|
23
22
|
interface SyncOptions {
|
|
24
23
|
syncInterval?: number;
|
|
25
24
|
logger?: any;
|
|
26
25
|
minLogLevel?: LogLevel;
|
|
27
26
|
onAfterRemoteAdd?: AfterRemoteAddCallback;
|
|
28
|
-
missingRemoteRecordDuringUpdateStrategy?:
|
|
27
|
+
missingRemoteRecordDuringUpdateStrategy?: MissingRemoteRecordStrategy;
|
|
29
28
|
onMissingRemoteRecordDuringUpdate?: MissingRemoteRecordDuringUpdateCallback;
|
|
30
29
|
}
|
|
31
30
|
type SyncState = {
|
|
@@ -75,10 +74,15 @@ declare function createIndexedDBStorage(options: {
|
|
|
75
74
|
declare function nextLocalId(): string;
|
|
76
75
|
|
|
77
76
|
declare enum SyncAction {
|
|
78
|
-
CreateOrUpdate = "
|
|
77
|
+
CreateOrUpdate = "create-or-update",
|
|
79
78
|
Remove = "remove"
|
|
80
79
|
}
|
|
80
|
+
declare enum MissingRemoteRecordStrategy {
|
|
81
|
+
Ignore = "ignore",
|
|
82
|
+
DeleteLocalRecord = "delete-local-record",
|
|
83
|
+
InsertRemoteRecord = "insert-remote-record"
|
|
84
|
+
}
|
|
81
85
|
declare function createWithSync<TStore extends object>(stateCreator: SyncedStateCreator<TStore>, persistOptions: any, syncApi: Record<string, ApiFunctions>, syncOptions?: SyncOptions): Promise<UseStoreWithSync<TStore>>;
|
|
82
86
|
declare function persistWithSync<TStore extends object>(stateCreator: SyncedStateCreator<TStore>, persistOptions: any, syncApi: Record<string, ApiFunctions>, syncOptions?: SyncOptions): StateCreator<TStore & SyncState, [], [["zustand/persist", TStore & SyncState]]>;
|
|
83
87
|
|
|
84
|
-
export { type ApiFunctions, SyncAction, type SyncState, type UseStoreWithSync, createIndexedDBStorage, createWithSync, nextLocalId, persistWithSync };
|
|
88
|
+
export { type ApiFunctions, MissingRemoteRecordStrategy, SyncAction, type SyncState, type UseStoreWithSync, createIndexedDBStorage, createWithSync, nextLocalId, persistWithSync };
|
package/dist/index.d.ts
CHANGED
|
@@ -18,14 +18,13 @@ interface ApiFunctions {
|
|
|
18
18
|
firstLoad: (lastId: any) => Promise<any[]>;
|
|
19
19
|
}
|
|
20
20
|
type AfterRemoteAddCallback = (set: any, get: any, queue: QueueToSyncCallback, stateKey: string, item: SyncedRecord) => void;
|
|
21
|
-
type MissingRemoteRecordDuringUpdateCallback = (strategy:
|
|
22
|
-
type MissingRemoteRecordDuringUpdateStrategy = 'ignore' | 'deleteLocalRecord' | 'insertNewRemoteRecord';
|
|
21
|
+
type MissingRemoteRecordDuringUpdateCallback = (strategy: MissingRemoteRecordStrategy, item: SyncedRecord, newLocalId?: string) => void;
|
|
23
22
|
interface SyncOptions {
|
|
24
23
|
syncInterval?: number;
|
|
25
24
|
logger?: any;
|
|
26
25
|
minLogLevel?: LogLevel;
|
|
27
26
|
onAfterRemoteAdd?: AfterRemoteAddCallback;
|
|
28
|
-
missingRemoteRecordDuringUpdateStrategy?:
|
|
27
|
+
missingRemoteRecordDuringUpdateStrategy?: MissingRemoteRecordStrategy;
|
|
29
28
|
onMissingRemoteRecordDuringUpdate?: MissingRemoteRecordDuringUpdateCallback;
|
|
30
29
|
}
|
|
31
30
|
type SyncState = {
|
|
@@ -75,10 +74,15 @@ declare function createIndexedDBStorage(options: {
|
|
|
75
74
|
declare function nextLocalId(): string;
|
|
76
75
|
|
|
77
76
|
declare enum SyncAction {
|
|
78
|
-
CreateOrUpdate = "
|
|
77
|
+
CreateOrUpdate = "create-or-update",
|
|
79
78
|
Remove = "remove"
|
|
80
79
|
}
|
|
80
|
+
declare enum MissingRemoteRecordStrategy {
|
|
81
|
+
Ignore = "ignore",
|
|
82
|
+
DeleteLocalRecord = "delete-local-record",
|
|
83
|
+
InsertRemoteRecord = "insert-remote-record"
|
|
84
|
+
}
|
|
81
85
|
declare function createWithSync<TStore extends object>(stateCreator: SyncedStateCreator<TStore>, persistOptions: any, syncApi: Record<string, ApiFunctions>, syncOptions?: SyncOptions): Promise<UseStoreWithSync<TStore>>;
|
|
82
86
|
declare function persistWithSync<TStore extends object>(stateCreator: SyncedStateCreator<TStore>, persistOptions: any, syncApi: Record<string, ApiFunctions>, syncOptions?: SyncOptions): StateCreator<TStore & SyncState, [], [["zustand/persist", TStore & SyncState]]>;
|
|
83
87
|
|
|
84
|
-
export { type ApiFunctions, SyncAction, type SyncState, type UseStoreWithSync, createIndexedDBStorage, createWithSync, nextLocalId, persistWithSync };
|
|
88
|
+
export { type ApiFunctions, MissingRemoteRecordStrategy, SyncAction, type SyncState, type UseStoreWithSync, createIndexedDBStorage, createWithSync, nextLocalId, persistWithSync };
|
package/dist/index.js
CHANGED
|
@@ -27,7 +27,7 @@ function nextLocalId() {
|
|
|
27
27
|
}
|
|
28
28
|
function orderFor(a) {
|
|
29
29
|
switch (a) {
|
|
30
|
-
case "
|
|
30
|
+
case "create-or-update" /* CreateOrUpdate */:
|
|
31
31
|
return 1;
|
|
32
32
|
case "remove" /* Remove */:
|
|
33
33
|
return 2;
|
|
@@ -129,7 +129,7 @@ async function pushOne(set, get, change, api, logger, queueToSync, missingStrate
|
|
|
129
129
|
logger.debug(`[zync] push:remove:success ${stateKey} ${localId} ${id}`);
|
|
130
130
|
removeFromPendingChanges(set, localId, stateKey);
|
|
131
131
|
break;
|
|
132
|
-
case "
|
|
132
|
+
case "create-or-update" /* CreateOrUpdate */: {
|
|
133
133
|
const state = get();
|
|
134
134
|
const items = state[stateKey] || [];
|
|
135
135
|
const item = items.find((i) => i._localId === localId);
|
|
@@ -161,18 +161,18 @@ async function pushOne(set, get, change, api, logger, queueToSync, missingStrate
|
|
|
161
161
|
id: item.id
|
|
162
162
|
});
|
|
163
163
|
switch (missingStrategy) {
|
|
164
|
-
case "
|
|
164
|
+
case "delete-local-record" /* DeleteLocalRecord */:
|
|
165
165
|
set((s) => ({
|
|
166
166
|
[stateKey]: (s[stateKey] || []).filter((i) => i._localId !== localId)
|
|
167
167
|
}));
|
|
168
168
|
break;
|
|
169
|
-
case "
|
|
169
|
+
case "insert-remote-record" /* InsertRemoteRecord */: {
|
|
170
170
|
omittedItem._localId = crypto.randomUUID();
|
|
171
171
|
omittedItem.updated_at = (/* @__PURE__ */ new Date()).toISOString();
|
|
172
172
|
set((s) => ({
|
|
173
173
|
[stateKey]: (s[stateKey] || []).map((i) => i._localId === localId ? omittedItem : i)
|
|
174
174
|
}));
|
|
175
|
-
queueToSync("
|
|
175
|
+
queueToSync("create-or-update" /* CreateOrUpdate */, stateKey, omittedItem._localId);
|
|
176
176
|
break;
|
|
177
177
|
}
|
|
178
178
|
}
|
|
@@ -292,14 +292,20 @@ function createIndexedDBStorage(options) {
|
|
|
292
292
|
|
|
293
293
|
// src/index.ts
|
|
294
294
|
var SyncAction = /* @__PURE__ */ ((SyncAction2) => {
|
|
295
|
-
SyncAction2["CreateOrUpdate"] = "
|
|
295
|
+
SyncAction2["CreateOrUpdate"] = "create-or-update";
|
|
296
296
|
SyncAction2["Remove"] = "remove";
|
|
297
297
|
return SyncAction2;
|
|
298
298
|
})(SyncAction || {});
|
|
299
|
+
var MissingRemoteRecordStrategy = /* @__PURE__ */ ((MissingRemoteRecordStrategy2) => {
|
|
300
|
+
MissingRemoteRecordStrategy2["Ignore"] = "ignore";
|
|
301
|
+
MissingRemoteRecordStrategy2["DeleteLocalRecord"] = "delete-local-record";
|
|
302
|
+
MissingRemoteRecordStrategy2["InsertRemoteRecord"] = "insert-remote-record";
|
|
303
|
+
return MissingRemoteRecordStrategy2;
|
|
304
|
+
})(MissingRemoteRecordStrategy || {});
|
|
299
305
|
var DEFAULT_SYNC_INTERVAL_MILLIS = 5e3;
|
|
300
306
|
var DEFAULT_LOGGER = console;
|
|
301
307
|
var DEFAULT_MIN_LOG_LEVEL = "debug";
|
|
302
|
-
var
|
|
308
|
+
var DEFAULT_MISSING_REMOTE_RECORD_STRATEGY = "ignore" /* Ignore */;
|
|
303
309
|
function createWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}) {
|
|
304
310
|
const store = create(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions));
|
|
305
311
|
return new Promise((resolve) => {
|
|
@@ -310,7 +316,7 @@ function createWithSync(stateCreator, persistOptions, syncApi, syncOptions = {})
|
|
|
310
316
|
}
|
|
311
317
|
function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}) {
|
|
312
318
|
const syncInterval = syncOptions.syncInterval ?? DEFAULT_SYNC_INTERVAL_MILLIS;
|
|
313
|
-
const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ??
|
|
319
|
+
const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ?? DEFAULT_MISSING_REMOTE_RECORD_STRATEGY;
|
|
314
320
|
const logger = newLogger(syncOptions.logger ?? DEFAULT_LOGGER, syncOptions.minLogLevel ?? DEFAULT_MIN_LOG_LEVEL);
|
|
315
321
|
const baseOnRehydrate = persistOptions?.onRehydrateStorage;
|
|
316
322
|
const basePartialize = persistOptions?.partialize;
|
|
@@ -478,11 +484,11 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
478
484
|
const queueItem = pendingChanges.find((p) => p.localId === localId && p.stateKey === stateKey);
|
|
479
485
|
if (queueItem) {
|
|
480
486
|
queueItem.version += 1;
|
|
481
|
-
if (queueItem.action === "
|
|
487
|
+
if (queueItem.action === "create-or-update" /* CreateOrUpdate */ && action === "remove" /* Remove */ && item.id) {
|
|
482
488
|
queueItem.action = "remove" /* Remove */;
|
|
483
489
|
queueItem.id = item.id;
|
|
484
490
|
}
|
|
485
|
-
logger.debug(`[zync] queueToSync:adjusted
|
|
491
|
+
logger.debug(`[zync] queueToSync:adjusted action=${action} localId=${localId} v=${queueItem.version}`);
|
|
486
492
|
} else {
|
|
487
493
|
pendingChanges.push({ action, stateKey, localId, id: item.id, version: 1 });
|
|
488
494
|
logger.debug(`[zync] queueToSync:added action=${action} localId=${localId}`);
|
|
@@ -560,6 +566,7 @@ function persistWithSync(stateCreator, persistOptions, syncApi, syncOptions = {}
|
|
|
560
566
|
return persist(creator, wrappedPersistOptions);
|
|
561
567
|
}
|
|
562
568
|
export {
|
|
569
|
+
MissingRemoteRecordStrategy,
|
|
563
570
|
SyncAction,
|
|
564
571
|
createIndexedDBStorage,
|
|
565
572
|
createWithSync,
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts","../src/logger.ts","../src/helpers.ts","../src/pull.ts","../src/push.ts","../src/indexedDBStorage.ts"],"sourcesContent":["import { create, type StateCreator } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { newLogger, type Logger, type LogLevel } from './logger';\nimport { orderFor, findApi, nextLocalId } from './helpers';\nimport type {\n ApiFunctions,\n MissingRemoteRecordDuringUpdateStrategy,\n SyncOptions,\n SyncState,\n SyncedStateCreator,\n PendingChange,\n UseStoreWithSync,\n} from './types';\nimport { pull } from './pull';\nimport { pushOne } from './push';\n\nexport { createIndexedDBStorage } from './indexedDBStorage';\nexport { nextLocalId } from './helpers';\nexport type { ApiFunctions, UseStoreWithSync, SyncState } from './types';\n\nexport enum SyncAction {\n CreateOrUpdate = 'createOrUpdate',\n Remove = 'remove',\n}\n\nconst DEFAULT_SYNC_INTERVAL_MILLIS = 5000;\nconst DEFAULT_LOGGER: Logger = console;\nconst DEFAULT_MIN_LOG_LEVEL: LogLevel = 'debug';\nconst DEFAULT_MISSING_REMOTE_RECORD_ON_UPDATE_STRATEGY: MissingRemoteRecordDuringUpdateStrategy = 'ignore';\n\nexport function createWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n): Promise<UseStoreWithSync<TStore>> {\n const store = create(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions)) as UseStoreWithSync<TStore>;\n\n return new Promise<UseStoreWithSync<TStore>>((resolve) => {\n store.persist.onFinishHydration((_state) => {\n resolve(store);\n });\n });\n}\n\nexport function persistWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n) {\n const syncInterval = syncOptions.syncInterval ?? DEFAULT_SYNC_INTERVAL_MILLIS;\n const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ?? DEFAULT_MISSING_REMOTE_RECORD_ON_UPDATE_STRATEGY;\n const logger = newLogger(syncOptions.logger ?? DEFAULT_LOGGER, syncOptions.minLogLevel ?? DEFAULT_MIN_LOG_LEVEL);\n\n const baseOnRehydrate = persistOptions?.onRehydrateStorage;\n const basePartialize = persistOptions?.partialize;\n\n const wrappedPersistOptions = {\n ...persistOptions,\n onRehydrateStorage: () => {\n logger.debug('[zync] rehydration:start');\n\n return (state: any, error: any) => {\n if (error) {\n logger.error('[zync] rehydration:failed', error);\n } else {\n baseOnRehydrate?.(state, error);\n logger.debug('[zync] rehydration:complete', state);\n }\n };\n },\n partialize: (s: any) => {\n // Select state to be persisted\n\n const base = basePartialize ? basePartialize(s) : s;\n const { syncState, ...rest } = base || {};\n return {\n ...rest,\n syncState: {\n firstLoadDone: syncState.firstLoadDone,\n pendingChanges: syncState.pendingChanges,\n lastPulled: syncState.lastPulled,\n },\n };\n },\n merge: (persisted: any, current: any) => {\n // Here after hydration.\n // `persisted` is state from storage that's just loaded (possibly ascynchronously e.g. IndexedDB)\n // `current` is what the user has defined (they may have added or removed state keys)\n // Zync is designed to not be used until hydration is complete, so we don't expect to have to\n // merge user mutated state (i.e. current) into persisted. So we do the Zustand recommended pattern of\n // shallow copy where persisted keys win:\n const state = { ...current, ...persisted };\n\n return {\n ...state,\n syncState: {\n ...state.syncState,\n status: 'idle', // this confirms 'hydrating' is done\n },\n };\n },\n };\n\n const creator: StateCreator<TStore & SyncState, [], []> = (set: any, get: any, storeApi: any) => {\n let syncIntervalId: any;\n\n async function syncOnce() {\n const state: SyncState = get();\n if (!state.syncState.enabled || state.syncState.status !== 'idle') return;\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'syncing',\n },\n }));\n\n let syncError: Error | undefined;\n\n // 1) PULL for each stateKey\n for (const stateKey of Object.keys(syncApi)) {\n try {\n const api = findApi(stateKey, syncApi);\n await pull(set, get, stateKey, api, logger);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] pull:error stateKey=${stateKey}`, err);\n }\n }\n\n // 2) PUSH queued changes\n const snapshot: PendingChange[] = [...(get().syncState.pendingChanges || [])];\n\n // Deterministic ordering: Create -> Update -> Remove so dependencies (e.g. id assignment) happen early\n snapshot.sort((a, b) => orderFor(a.action) - orderFor(b.action));\n\n for (const change of snapshot) {\n try {\n const api = findApi(change.stateKey, syncApi);\n await pushOne(\n set,\n get,\n change,\n api,\n logger,\n queueToSync,\n missingStrategy,\n syncOptions.onMissingRemoteRecordDuringUpdate,\n syncOptions.onAfterRemoteAdd,\n );\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] push:error change=${change}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'idle',\n error: syncError,\n },\n }));\n\n if (get().syncState.pendingChanges.length > 0 && !syncError) {\n // If there are pending changes and no sync error, we can sync again\n await syncOnce();\n }\n }\n\n async function startFirstLoad() {\n let syncError: Error | undefined;\n\n for (const stateKey of Object.keys(syncApi)) {\n try {\n logger.info(`[zync] firstLoad:start stateKey=${stateKey}`);\n\n const api = findApi(stateKey, syncApi);\n let lastId; // Start as undefined to allow the userland api code to set the initial value+type\n\n // Batch until empty\n while (true) {\n const batch = await api.firstLoad(lastId);\n if (!batch?.length) break;\n\n // Merge batch\n set((state: any) => {\n const local: any[] = state[stateKey] || [];\n const localById = new Map<any, any>(local.filter((l) => l.id).map((l) => [l.id, l]));\n\n let newest = new Date(state.syncState.lastPulled[stateKey] || 0);\n const next = [...local];\n for (const remote of batch) {\n const remoteUpdated = new Date(remote.updated_at || 0);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n if (remote.deleted) continue;\n\n const localItem = remote.id ? localById.get(remote.id) : undefined;\n if (localItem) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n const idx = next.findIndex((i) => i._localId === localItem._localId);\n if (idx >= 0) next[idx] = merged;\n } else {\n next.push({\n ...remote,\n _localId: nextLocalId(),\n });\n }\n }\n\n return {\n [stateKey]: next,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n\n lastId = batch[batch.length - 1].id;\n }\n\n logger.info(`[zync] firstLoad:done stateKey=${stateKey}`);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] firstLoad:error stateKey=${stateKey}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n firstLoadDone: true,\n error: syncError,\n },\n }));\n }\n\n function queueToSync(action: any, stateKey: string, ...localIds: string[]) {\n set((state: any) => {\n const pendingChanges: any[] = state.syncState.pendingChanges || [];\n\n for (const localId of localIds) {\n const item = state[stateKey].find((i: any) => i._localId === localId);\n if (!item) {\n logger.error(`[zync] queueToSync:no-local-item localId=${localId}`);\n continue;\n }\n\n const queueItem = pendingChanges.find((p) => p.localId === localId && p.stateKey === stateKey);\n if (queueItem) {\n queueItem.version += 1;\n\n if (queueItem.action === SyncAction.CreateOrUpdate && action === SyncAction.Remove && item.id) {\n queueItem.action = SyncAction.Remove;\n queueItem.id = item.id;\n }\n logger.debug(`[zync] queueToSync:adjusted v=${queueItem.version} action=${action} localId=${localId}`);\n } else {\n pendingChanges.push({ action, stateKey, localId, id: item.id, version: 1 });\n logger.debug(`[zync] queueToSync:added action=${action} localId=${localId}`);\n }\n }\n\n return {\n syncState: {\n ...(state.syncState || {}),\n pendingChanges,\n },\n };\n });\n syncOnce();\n }\n\n function setAndSync(partial: any) {\n if (typeof partial === 'function') {\n set((state: any) => ({ ...partial(state) }));\n } else {\n set(partial);\n }\n syncOnce();\n }\n\n function enable(enabled: boolean) {\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n enabled,\n },\n }));\n\n enableSyncTimer(enabled);\n addVisibilityChangeListener(enabled);\n }\n\n function enableSyncTimer(enabled: boolean) {\n clearInterval(syncIntervalId);\n syncIntervalId = undefined;\n if (enabled) {\n syncIntervalId = setInterval(syncOnce, syncInterval);\n syncOnce();\n }\n }\n\n function addVisibilityChangeListener(add: boolean) {\n if (add) {\n document.addEventListener('visibilitychange', onVisibilityChange);\n } else {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n }\n\n function onVisibilityChange() {\n if (document.visibilityState === 'visible') {\n logger.debug('[zync] sync:start-in-foreground');\n enableSyncTimer(true);\n } else {\n logger.debug('[zync] sync:pause-in-background');\n enableSyncTimer(false);\n }\n }\n\n // public useStore.sync api, similar in principle to useStore.persist\n storeApi.sync = {\n enable,\n startFirstLoad,\n };\n\n const userState = stateCreator(setAndSync, get, queueToSync) as TStore;\n\n return {\n ...userState,\n syncState: {\n // set defaults\n status: 'hydrating',\n error: undefined,\n enabled: false,\n firstLoadDone: false,\n pendingChanges: [],\n lastPulled: {},\n },\n } as TStore & SyncState;\n };\n\n return persist(creator, wrappedPersistOptions);\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';\n\nexport interface Logger {\n debug: (...args: any[]) => void;\n info: (...args: any[]) => void;\n warn: (...args: any[]) => void;\n error: (...args: any[]) => void;\n}\n\nexport function newLogger(base: Logger, min: LogLevel): Logger {\n const order: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n none: 100,\n };\n const threshold = order[min];\n const enabled = (lvl: LogLevel) => order[lvl] >= threshold;\n return {\n debug: (...a: any[]) => enabled('debug') && base.debug?.(...a),\n info: (...a: any[]) => enabled('info') && base.info?.(...a),\n warn: (...a: any[]) => enabled('warn') && base.warn?.(...a),\n error: (...a: any[]) => enabled('error') && base.error?.(...a),\n };\n}\n","import { SyncAction } from './index';\nimport type { ApiFunctions, PendingChange } from './types';\n\nexport function nextLocalId(): string {\n return crypto.randomUUID();\n}\n\nexport function orderFor(a: SyncAction): number {\n switch (a) {\n case SyncAction.CreateOrUpdate:\n return 1;\n case SyncAction.Remove:\n return 2;\n }\n}\n\nexport function omitSyncFields(item: any, fields: readonly string[]) {\n const result = { ...item };\n for (const k of fields) delete result[k];\n return result;\n}\n\nexport function samePendingVersion(get: any, stateKey: string, localId: string, version: number): boolean {\n const q: PendingChange[] = get().syncState.pendingChanges || [];\n const curChange = q.find((p) => p.localId === localId && p.stateKey === stateKey);\n return curChange?.version === version;\n}\n\nexport function removeFromPendingChanges(set: any, localId: string, stateKey: string) {\n set((s: any) => {\n const queue: PendingChange[] = (s.syncState.pendingChanges || []).filter((p: PendingChange) => !(p.localId === localId && p.stateKey === stateKey));\n return {\n syncState: {\n ...(s.syncState || {}),\n pendingChanges: queue,\n },\n };\n });\n}\n\nexport function findApi(stateKey: string, syncApi: Record<string, ApiFunctions>) {\n const api = syncApi[stateKey];\n if (!api || !api.add || !api.update || !api.remove || !api.list || !api.firstLoad) {\n throw new Error(`Missing API function(s) for state key: ${stateKey}.`);\n }\n return api;\n}\n","import type { ApiFunctions, PendingChange, SyncedRecord } from './types';\nimport { SyncAction } from './index';\nimport { nextLocalId } from './helpers';\n\nexport async function pull(set: any, get: any, stateKey: string, api: ApiFunctions, logger: any) {\n const lastPulled: Record<string, string> = get().syncState.lastPulled || {};\n const lastPulledAt = new Date(lastPulled[stateKey] || new Date(0));\n\n logger.debug(`[zync] pull:start stateKey=${stateKey} since=${lastPulledAt.toISOString()}`);\n\n const serverData = (await api.list(lastPulledAt)) as SyncedRecord[];\n if (!serverData?.length) return;\n\n let newest = lastPulledAt;\n set((state: any) => {\n const pendingChanges: PendingChange[] = state.syncState.pendingChanges || [];\n const localItems: any[] = state[stateKey] || [];\n let nextItems = [...localItems];\n const localById = new Map<any, any>(localItems.filter((l) => l.id).map((l) => [l.id, l]));\n // prevent resurrecting deleted items by pulling them again\n const pendingRemovalById = new Set(pendingChanges.filter((p) => p.stateKey === stateKey && p.action === SyncAction.Remove).map((p) => p.id));\n\n for (const remote of serverData) {\n const remoteUpdated = new Date(remote.updated_at);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n // If a Remove is pending for this localId, skip merging/adding to avoid flicker\n if (pendingRemovalById.has(remote.id)) {\n logger.debug(`[zync] pull:skip-pending-remove stateKey=${stateKey} id=${remote.id}`);\n continue;\n }\n\n const localItem = localById.get(remote.id);\n if (remote.deleted) {\n if (localItem) {\n nextItems = nextItems.filter((i: any) => i.id !== remote.id);\n logger.debug(`[zync] pull:remove stateKey=${stateKey} id=${remote.id}`);\n }\n continue;\n }\n\n const pending = localItem && pendingChanges.some((p: any) => p.stateKey === stateKey && p.localId === localItem._localId);\n if (localItem && !pending) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n nextItems = nextItems.map((i: any) => (i._localId === localItem._localId ? merged : i));\n logger.debug(`[zync] pull:merge stateKey=${stateKey} id=${remote.id}`);\n } else if (!localItem) {\n // Add remote item (no local or pending collisions)\n nextItems = [...nextItems, { ...remote, _localId: nextLocalId() }];\n logger.debug(`[zync] pull:add stateKey=${stateKey} id=${remote.id}`);\n }\n }\n\n return {\n [stateKey]: nextItems,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n}\n","import { removeFromPendingChanges, omitSyncFields, samePendingVersion } from './helpers';\nimport { SyncAction } from './index';\nimport type { ApiFunctions } from './types';\n\nconst SYNC_FIELDS = ['id', '_localId', 'updated_at', 'deleted'] as const;\n\nexport async function pushOne(\n set: any,\n get: any,\n change: any,\n api: ApiFunctions,\n logger: any,\n queueToSync: any,\n missingStrategy: string,\n onMissingRemoteRecordDuringUpdate?: any,\n onAfterRemoteAdd?: any,\n) {\n logger.debug(`[zync] push:attempt action=${change.action} stateKey=${change.stateKey} localId=${change.localId}`);\n\n const { action, stateKey, localId, id, version } = change;\n\n switch (action) {\n case SyncAction.Remove:\n await api.remove(id);\n logger.debug(`[zync] push:remove:success ${stateKey} ${localId} ${id}`);\n removeFromPendingChanges(set, localId, stateKey);\n break;\n\n case SyncAction.CreateOrUpdate: {\n const state = get();\n const items: any[] = state[stateKey] || [];\n const item = items.find((i) => i._localId === localId);\n if (!item) {\n logger.warn(`[zync] push:create-or-update:no-local-item`, {\n stateKey,\n localId,\n });\n removeFromPendingChanges(set, localId, stateKey);\n return;\n }\n\n const omittedItem = omitSyncFields(item, SYNC_FIELDS);\n if (item.id) {\n // Update\n const changed = await api.update(item.id, omittedItem);\n if (changed) {\n logger.debug('[zync] push:update:success', {\n stateKey,\n localId,\n id: item.id,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n return;\n } else {\n logger.warn('[zync] push:update:missing-remote', {\n stateKey,\n localId,\n id: item.id,\n });\n\n switch (missingStrategy) {\n case 'deleteLocalRecord':\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).filter((i: any) => i._localId !== localId),\n }));\n break;\n\n case 'insertNewRemoteRecord': {\n omittedItem._localId = crypto.randomUUID();\n omittedItem.updated_at = new Date().toISOString();\n\n // replace old with new copy without id so it becomes a Create\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? omittedItem : i)),\n }));\n\n queueToSync(SyncAction.CreateOrUpdate, stateKey, omittedItem._localId);\n break;\n }\n }\n removeFromPendingChanges(set, localId, stateKey);\n // Call hook so userland can alert the user etc.\n onMissingRemoteRecordDuringUpdate?.(missingStrategy, omittedItem, omittedItem._localId);\n }\n return;\n }\n\n // Create\n const result = await api.add(omittedItem);\n if (result) {\n logger.debug('[zync] push:create:success', {\n stateKey,\n localId,\n id: result.id,\n });\n\n // Merge server-assigned fields (id, updated_at, etc) directly into local entity\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? { ...i, ...result } : i)),\n }));\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n // Call hook so userland can perform any cascading adjustments\n onAfterRemoteAdd?.(set, get, queueToSync, stateKey, {\n ...item,\n ...result,\n });\n } else {\n logger.warn('[zync] push:create:no-result', {\n stateKey,\n localId,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n }\n break;\n }\n }\n}\n","import type { IDBPDatabase } from 'idb';\n\nexport function createIndexedDBStorage(options: { dbName: string; storeName: string }) {\n const dbName = options.dbName;\n const storeName = options.storeName;\n\n // dbPromise is created lazily by initDB() to avoid pulling `idb` into bundles\n let dbPromise: Promise<IDBPDatabase<any>> | null = null;\n\n async function initDB(): Promise<IDBPDatabase<any>> {\n if (dbPromise) return dbPromise;\n try {\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, 1, {\n upgrade(db: IDBPDatabase<any>) {\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName);\n }\n },\n });\n return dbPromise;\n } catch (_e) {\n throw new Error('Missing optional dependency \"idb\". Install it to use IndexedDB storage: npm install idb');\n }\n }\n\n async function ensureStore(): Promise<void> {\n const db = await initDB();\n if (db.objectStoreNames.contains(storeName)) return;\n const nextVersion = (db.version || 0) + 1;\n try {\n db.close();\n } catch (_e) {\n // ignore\n }\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, nextVersion, {\n upgrade(upg: IDBPDatabase<any>) {\n if (!upg.objectStoreNames.contains(storeName)) upg.createObjectStore(storeName);\n },\n });\n await dbPromise;\n }\n\n async function withRetry<T>(fn: (db: IDBPDatabase<any>) => Promise<T>): Promise<T> {\n try {\n const db = await initDB();\n return await fn(db);\n } catch (err: any) {\n const msg = String(err && err.message ? err.message : err);\n if (err && (err.name === 'NotFoundError' || /objectStore/i.test(msg))) {\n await ensureStore();\n const db2 = await initDB();\n return await fn(db2);\n }\n throw err;\n }\n }\n\n return {\n getItem: async (name: string): Promise<string | null> => {\n return withRetry(async (db) => {\n let v = await db.get(storeName, name);\n v = v ?? null; // Zustand expects null for missing keys\n return v;\n });\n },\n setItem: async (name: string, value: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.put(storeName, value, name);\n });\n },\n removeItem: async (name: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.delete(storeName, name);\n });\n },\n };\n}\n"],"mappings":"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","names":["SyncAction","state"]}
|
|
1
|
+
{"version":3,"sources":["../src/index.ts","../src/logger.ts","../src/helpers.ts","../src/pull.ts","../src/push.ts","../src/indexedDBStorage.ts"],"sourcesContent":["import { create, type StateCreator } from 'zustand';\nimport { persist } from 'zustand/middleware';\nimport { newLogger, type Logger, type LogLevel } from './logger';\nimport { orderFor, findApi, nextLocalId } from './helpers';\nimport type { ApiFunctions, SyncOptions, SyncState, SyncedStateCreator, PendingChange, UseStoreWithSync } from './types';\nimport { pull } from './pull';\nimport { pushOne } from './push';\n\nexport { createIndexedDBStorage } from './indexedDBStorage';\nexport { nextLocalId } from './helpers';\nexport type { ApiFunctions, UseStoreWithSync, SyncState } from './types';\n\nexport enum SyncAction {\n CreateOrUpdate = 'create-or-update',\n Remove = 'remove',\n}\n\nexport enum MissingRemoteRecordStrategy {\n Ignore = 'ignore',\n DeleteLocalRecord = 'delete-local-record',\n InsertRemoteRecord = 'insert-remote-record',\n}\n\nconst DEFAULT_SYNC_INTERVAL_MILLIS = 5000;\nconst DEFAULT_LOGGER: Logger = console;\nconst DEFAULT_MIN_LOG_LEVEL: LogLevel = 'debug';\nconst DEFAULT_MISSING_REMOTE_RECORD_STRATEGY: MissingRemoteRecordStrategy = MissingRemoteRecordStrategy.Ignore;\n\nexport function createWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n): Promise<UseStoreWithSync<TStore>> {\n const store = create(persistWithSync(stateCreator, persistOptions, syncApi, syncOptions)) as UseStoreWithSync<TStore>;\n\n return new Promise<UseStoreWithSync<TStore>>((resolve) => {\n store.persist.onFinishHydration((_state) => {\n resolve(store);\n });\n });\n}\n\nexport function persistWithSync<TStore extends object>(\n stateCreator: SyncedStateCreator<TStore>,\n persistOptions: any,\n syncApi: Record<string, ApiFunctions>,\n syncOptions: SyncOptions = {},\n) {\n const syncInterval = syncOptions.syncInterval ?? DEFAULT_SYNC_INTERVAL_MILLIS;\n const missingStrategy = syncOptions.missingRemoteRecordDuringUpdateStrategy ?? DEFAULT_MISSING_REMOTE_RECORD_STRATEGY;\n const logger = newLogger(syncOptions.logger ?? DEFAULT_LOGGER, syncOptions.minLogLevel ?? DEFAULT_MIN_LOG_LEVEL);\n\n const baseOnRehydrate = persistOptions?.onRehydrateStorage;\n const basePartialize = persistOptions?.partialize;\n\n const wrappedPersistOptions = {\n ...persistOptions,\n onRehydrateStorage: () => {\n logger.debug('[zync] rehydration:start');\n\n return (state: any, error: any) => {\n if (error) {\n logger.error('[zync] rehydration:failed', error);\n } else {\n baseOnRehydrate?.(state, error);\n logger.debug('[zync] rehydration:complete', state);\n }\n };\n },\n partialize: (s: any) => {\n // Select state to be persisted\n\n const base = basePartialize ? basePartialize(s) : s;\n const { syncState, ...rest } = base || {};\n return {\n ...rest,\n syncState: {\n firstLoadDone: syncState.firstLoadDone,\n pendingChanges: syncState.pendingChanges,\n lastPulled: syncState.lastPulled,\n },\n };\n },\n merge: (persisted: any, current: any) => {\n // Here after hydration.\n // `persisted` is state from storage that's just loaded (possibly asynchronously e.g. IndexedDB)\n // `current` is what the user has defined (they may have added or removed state keys)\n // Zync is designed to not be used until hydration is complete, so we don't expect to have to\n // merge user mutated state (i.e. current) into persisted. So we do the Zustand recommended pattern of\n // shallow copy where persisted keys win:\n const state = { ...current, ...persisted };\n\n return {\n ...state,\n syncState: {\n ...state.syncState,\n status: 'idle', // this confirms 'hydrating' is done\n },\n };\n },\n };\n\n const creator: StateCreator<TStore & SyncState, [], []> = (set: any, get: any, storeApi: any) => {\n let syncIntervalId: any;\n\n async function syncOnce() {\n const state: SyncState = get();\n if (!state.syncState.enabled || state.syncState.status !== 'idle') return;\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'syncing',\n },\n }));\n\n let syncError: Error | undefined;\n\n // 1) PULL for each stateKey\n for (const stateKey of Object.keys(syncApi)) {\n try {\n const api = findApi(stateKey, syncApi);\n await pull(set, get, stateKey, api, logger);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] pull:error stateKey=${stateKey}`, err);\n }\n }\n\n // 2) PUSH queued changes\n const snapshot: PendingChange[] = [...(get().syncState.pendingChanges || [])];\n\n // Deterministic ordering: Create -> Update -> Remove so dependencies (e.g. id assignment) happen early\n snapshot.sort((a, b) => orderFor(a.action) - orderFor(b.action));\n\n for (const change of snapshot) {\n try {\n const api = findApi(change.stateKey, syncApi);\n await pushOne(\n set,\n get,\n change,\n api,\n logger,\n queueToSync,\n missingStrategy,\n syncOptions.onMissingRemoteRecordDuringUpdate,\n syncOptions.onAfterRemoteAdd,\n );\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] push:error change=${change}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n status: 'idle',\n error: syncError,\n },\n }));\n\n if (get().syncState.pendingChanges.length > 0 && !syncError) {\n // If there are pending changes and no sync error, we can sync again\n await syncOnce();\n }\n }\n\n async function startFirstLoad() {\n let syncError: Error | undefined;\n\n for (const stateKey of Object.keys(syncApi)) {\n try {\n logger.info(`[zync] firstLoad:start stateKey=${stateKey}`);\n\n const api = findApi(stateKey, syncApi);\n let lastId; // Start as undefined to allow the userland api code to set the initial value+type\n\n // Batch until empty\n while (true) {\n const batch = await api.firstLoad(lastId);\n if (!batch?.length) break;\n\n // Merge batch\n set((state: any) => {\n const local: any[] = state[stateKey] || [];\n const localById = new Map<any, any>(local.filter((l) => l.id).map((l) => [l.id, l]));\n\n let newest = new Date(state.syncState.lastPulled[stateKey] || 0);\n const next = [...local];\n for (const remote of batch) {\n const remoteUpdated = new Date(remote.updated_at || 0);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n if (remote.deleted) continue;\n\n const localItem = remote.id ? localById.get(remote.id) : undefined;\n if (localItem) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n const idx = next.findIndex((i) => i._localId === localItem._localId);\n if (idx >= 0) next[idx] = merged;\n } else {\n next.push({\n ...remote,\n _localId: nextLocalId(),\n });\n }\n }\n\n return {\n [stateKey]: next,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n\n lastId = batch[batch.length - 1].id;\n }\n\n logger.info(`[zync] firstLoad:done stateKey=${stateKey}`);\n } catch (err) {\n syncError = syncError ?? (err as Error);\n logger.error(`[zync] firstLoad:error stateKey=${stateKey}`, err);\n }\n }\n\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n firstLoadDone: true,\n error: syncError,\n },\n }));\n }\n\n function queueToSync(action: any, stateKey: string, ...localIds: string[]) {\n set((state: any) => {\n const pendingChanges: any[] = state.syncState.pendingChanges || [];\n\n for (const localId of localIds) {\n const item = state[stateKey].find((i: any) => i._localId === localId);\n if (!item) {\n logger.error(`[zync] queueToSync:no-local-item localId=${localId}`);\n continue;\n }\n\n const queueItem = pendingChanges.find((p) => p.localId === localId && p.stateKey === stateKey);\n if (queueItem) {\n queueItem.version += 1;\n\n if (queueItem.action === SyncAction.CreateOrUpdate && action === SyncAction.Remove && item.id) {\n queueItem.action = SyncAction.Remove;\n queueItem.id = item.id;\n }\n logger.debug(`[zync] queueToSync:adjusted action=${action} localId=${localId} v=${queueItem.version}`);\n } else {\n pendingChanges.push({ action, stateKey, localId, id: item.id, version: 1 });\n logger.debug(`[zync] queueToSync:added action=${action} localId=${localId}`);\n }\n }\n\n return {\n syncState: {\n ...(state.syncState || {}),\n pendingChanges,\n },\n };\n });\n syncOnce();\n }\n\n function setAndSync(partial: any) {\n if (typeof partial === 'function') {\n set((state: any) => ({ ...partial(state) }));\n } else {\n set(partial);\n }\n syncOnce();\n }\n\n function enable(enabled: boolean) {\n set((state: any) => ({\n syncState: {\n ...(state.syncState || {}),\n enabled,\n },\n }));\n\n enableSyncTimer(enabled);\n addVisibilityChangeListener(enabled);\n }\n\n function enableSyncTimer(enabled: boolean) {\n clearInterval(syncIntervalId);\n syncIntervalId = undefined;\n if (enabled) {\n syncIntervalId = setInterval(syncOnce, syncInterval);\n syncOnce();\n }\n }\n\n function addVisibilityChangeListener(add: boolean) {\n if (add) {\n document.addEventListener('visibilitychange', onVisibilityChange);\n } else {\n document.removeEventListener('visibilitychange', onVisibilityChange);\n }\n }\n\n function onVisibilityChange() {\n if (document.visibilityState === 'visible') {\n logger.debug('[zync] sync:start-in-foreground');\n enableSyncTimer(true);\n } else {\n logger.debug('[zync] sync:pause-in-background');\n enableSyncTimer(false);\n }\n }\n\n // public useStore.sync api, similar in principle to useStore.persist\n storeApi.sync = {\n enable,\n startFirstLoad,\n };\n\n const userState = stateCreator(setAndSync, get, queueToSync) as TStore;\n\n return {\n ...userState,\n syncState: {\n // set defaults\n status: 'hydrating',\n error: undefined,\n enabled: false,\n firstLoadDone: false,\n pendingChanges: [],\n lastPulled: {},\n },\n } as TStore & SyncState;\n };\n\n return persist(creator, wrappedPersistOptions);\n}\n","export type LogLevel = 'debug' | 'info' | 'warn' | 'error' | 'none';\n\nexport interface Logger {\n debug: (...args: any[]) => void;\n info: (...args: any[]) => void;\n warn: (...args: any[]) => void;\n error: (...args: any[]) => void;\n}\n\nexport function newLogger(base: Logger, min: LogLevel): Logger {\n const order: Record<LogLevel, number> = {\n debug: 10,\n info: 20,\n warn: 30,\n error: 40,\n none: 100,\n };\n const threshold = order[min];\n const enabled = (lvl: LogLevel) => order[lvl] >= threshold;\n return {\n debug: (...a: any[]) => enabled('debug') && base.debug?.(...a),\n info: (...a: any[]) => enabled('info') && base.info?.(...a),\n warn: (...a: any[]) => enabled('warn') && base.warn?.(...a),\n error: (...a: any[]) => enabled('error') && base.error?.(...a),\n };\n}\n","import { SyncAction } from './index';\nimport type { ApiFunctions, PendingChange } from './types';\n\nexport function nextLocalId(): string {\n return crypto.randomUUID();\n}\n\nexport function orderFor(a: SyncAction): number {\n switch (a) {\n case SyncAction.CreateOrUpdate:\n return 1;\n case SyncAction.Remove:\n return 2;\n }\n}\n\nexport function omitSyncFields(item: any, fields: readonly string[]) {\n const result = { ...item };\n for (const k of fields) delete result[k];\n return result;\n}\n\nexport function samePendingVersion(get: any, stateKey: string, localId: string, version: number): boolean {\n const q: PendingChange[] = get().syncState.pendingChanges || [];\n const curChange = q.find((p) => p.localId === localId && p.stateKey === stateKey);\n return curChange?.version === version;\n}\n\nexport function removeFromPendingChanges(set: any, localId: string, stateKey: string) {\n set((s: any) => {\n const queue: PendingChange[] = (s.syncState.pendingChanges || []).filter((p: PendingChange) => !(p.localId === localId && p.stateKey === stateKey));\n return {\n syncState: {\n ...(s.syncState || {}),\n pendingChanges: queue,\n },\n };\n });\n}\n\nexport function findApi(stateKey: string, syncApi: Record<string, ApiFunctions>) {\n const api = syncApi[stateKey];\n if (!api || !api.add || !api.update || !api.remove || !api.list || !api.firstLoad) {\n throw new Error(`Missing API function(s) for state key: ${stateKey}.`);\n }\n return api;\n}\n","import type { ApiFunctions, PendingChange, SyncedRecord } from './types';\nimport { SyncAction } from './index';\nimport { nextLocalId } from './helpers';\n\nexport async function pull(set: any, get: any, stateKey: string, api: ApiFunctions, logger: any) {\n const lastPulled: Record<string, string> = get().syncState.lastPulled || {};\n const lastPulledAt = new Date(lastPulled[stateKey] || new Date(0));\n\n logger.debug(`[zync] pull:start stateKey=${stateKey} since=${lastPulledAt.toISOString()}`);\n\n const serverData = (await api.list(lastPulledAt)) as SyncedRecord[];\n if (!serverData?.length) return;\n\n let newest = lastPulledAt;\n set((state: any) => {\n const pendingChanges: PendingChange[] = state.syncState.pendingChanges || [];\n const localItems: any[] = state[stateKey] || [];\n let nextItems = [...localItems];\n const localById = new Map<any, any>(localItems.filter((l) => l.id).map((l) => [l.id, l]));\n // prevent resurrecting deleted items by pulling them again\n const pendingRemovalById = new Set(pendingChanges.filter((p) => p.stateKey === stateKey && p.action === SyncAction.Remove).map((p) => p.id));\n\n for (const remote of serverData) {\n const remoteUpdated = new Date(remote.updated_at);\n if (remoteUpdated > newest) newest = remoteUpdated;\n\n // If a Remove is pending for this localId, skip merging/adding to avoid flicker\n if (pendingRemovalById.has(remote.id)) {\n logger.debug(`[zync] pull:skip-pending-remove stateKey=${stateKey} id=${remote.id}`);\n continue;\n }\n\n const localItem = localById.get(remote.id);\n if (remote.deleted) {\n if (localItem) {\n nextItems = nextItems.filter((i: any) => i.id !== remote.id);\n logger.debug(`[zync] pull:remove stateKey=${stateKey} id=${remote.id}`);\n }\n continue;\n }\n\n const pending = localItem && pendingChanges.some((p: any) => p.stateKey === stateKey && p.localId === localItem._localId);\n if (localItem && !pending) {\n const merged = {\n ...localItem,\n ...remote,\n _localId: localItem._localId,\n };\n nextItems = nextItems.map((i: any) => (i._localId === localItem._localId ? merged : i));\n logger.debug(`[zync] pull:merge stateKey=${stateKey} id=${remote.id}`);\n } else if (!localItem) {\n // Add remote item (no local or pending collisions)\n nextItems = [...nextItems, { ...remote, _localId: nextLocalId() }];\n logger.debug(`[zync] pull:add stateKey=${stateKey} id=${remote.id}`);\n }\n }\n\n return {\n [stateKey]: nextItems,\n syncState: {\n ...(state.syncState || {}),\n lastPulled: {\n ...(state.syncState.lastPulled || {}),\n [stateKey]: newest.toISOString(),\n },\n },\n };\n });\n}\n","import { removeFromPendingChanges, omitSyncFields, samePendingVersion } from './helpers';\nimport { MissingRemoteRecordStrategy, SyncAction } from './index';\nimport type { AfterRemoteAddCallback, ApiFunctions, MissingRemoteRecordDuringUpdateCallback } from './types';\n\nconst SYNC_FIELDS = ['id', '_localId', 'updated_at', 'deleted'] as const;\n\nexport async function pushOne(\n set: any,\n get: any,\n change: any,\n api: ApiFunctions,\n logger: any,\n queueToSync: any,\n missingStrategy: MissingRemoteRecordStrategy,\n onMissingRemoteRecordDuringUpdate?: MissingRemoteRecordDuringUpdateCallback,\n onAfterRemoteAdd?: AfterRemoteAddCallback,\n) {\n logger.debug(`[zync] push:attempt action=${change.action} stateKey=${change.stateKey} localId=${change.localId}`);\n\n const { action, stateKey, localId, id, version } = change;\n\n switch (action) {\n case SyncAction.Remove:\n await api.remove(id);\n logger.debug(`[zync] push:remove:success ${stateKey} ${localId} ${id}`);\n removeFromPendingChanges(set, localId, stateKey);\n break;\n\n case SyncAction.CreateOrUpdate: {\n const state = get();\n const items: any[] = state[stateKey] || [];\n const item = items.find((i) => i._localId === localId);\n if (!item) {\n logger.warn(`[zync] push:create-or-update:no-local-item`, {\n stateKey,\n localId,\n });\n removeFromPendingChanges(set, localId, stateKey);\n return;\n }\n\n const omittedItem = omitSyncFields(item, SYNC_FIELDS);\n if (item.id) {\n // Update\n const changed = await api.update(item.id, omittedItem);\n if (changed) {\n logger.debug('[zync] push:update:success', {\n stateKey,\n localId,\n id: item.id,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n return;\n } else {\n logger.warn('[zync] push:update:missing-remote', {\n stateKey,\n localId,\n id: item.id,\n });\n\n switch (missingStrategy) {\n case MissingRemoteRecordStrategy.DeleteLocalRecord:\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).filter((i: any) => i._localId !== localId),\n }));\n break;\n\n case MissingRemoteRecordStrategy.InsertRemoteRecord: {\n omittedItem._localId = crypto.randomUUID();\n omittedItem.updated_at = new Date().toISOString();\n\n // replace old with new copy without id so it becomes a Create\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? omittedItem : i)),\n }));\n\n queueToSync(SyncAction.CreateOrUpdate, stateKey, omittedItem._localId);\n break;\n }\n }\n removeFromPendingChanges(set, localId, stateKey);\n // Call hook so userland can alert the user etc.\n onMissingRemoteRecordDuringUpdate?.(missingStrategy, omittedItem, omittedItem._localId);\n }\n return;\n }\n\n // Create\n const result = await api.add(omittedItem);\n if (result) {\n logger.debug('[zync] push:create:success', {\n stateKey,\n localId,\n id: result.id,\n });\n\n // Merge server-assigned fields (id, updated_at, etc) directly into local entity\n set((s: any) => ({\n [stateKey]: (s[stateKey] || []).map((i: any) => (i._localId === localId ? { ...i, ...result } : i)),\n }));\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n // Call hook so userland can perform any cascading adjustments\n onAfterRemoteAdd?.(set, get, queueToSync, stateKey, {\n ...item,\n ...result,\n });\n } else {\n logger.warn('[zync] push:create:no-result', {\n stateKey,\n localId,\n });\n if (samePendingVersion(get, stateKey, localId, version)) {\n removeFromPendingChanges(set, localId, stateKey);\n }\n }\n break;\n }\n }\n}\n","import type { IDBPDatabase } from 'idb';\n\nexport function createIndexedDBStorage(options: { dbName: string; storeName: string }) {\n const dbName = options.dbName;\n const storeName = options.storeName;\n\n // dbPromise is created lazily by initDB() to avoid pulling `idb` into bundles\n let dbPromise: Promise<IDBPDatabase<any>> | null = null;\n\n async function initDB(): Promise<IDBPDatabase<any>> {\n if (dbPromise) return dbPromise;\n try {\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, 1, {\n upgrade(db: IDBPDatabase<any>) {\n if (!db.objectStoreNames.contains(storeName)) {\n db.createObjectStore(storeName);\n }\n },\n });\n return dbPromise;\n } catch (_e) {\n throw new Error('Missing optional dependency \"idb\". Install it to use IndexedDB storage: npm install idb');\n }\n }\n\n async function ensureStore(): Promise<void> {\n const db = await initDB();\n if (db.objectStoreNames.contains(storeName)) return;\n const nextVersion = (db.version || 0) + 1;\n try {\n db.close();\n } catch (_e) {\n // ignore\n }\n const idb = await import(/* webpackChunkName: \"idb\" */ 'idb');\n dbPromise = idb.openDB(dbName, nextVersion, {\n upgrade(upg: IDBPDatabase<any>) {\n if (!upg.objectStoreNames.contains(storeName)) upg.createObjectStore(storeName);\n },\n });\n await dbPromise;\n }\n\n async function withRetry<T>(fn: (db: IDBPDatabase<any>) => Promise<T>): Promise<T> {\n try {\n const db = await initDB();\n return await fn(db);\n } catch (err: any) {\n const msg = String(err && err.message ? err.message : err);\n if (err && (err.name === 'NotFoundError' || /objectStore/i.test(msg))) {\n await ensureStore();\n const db2 = await initDB();\n return await fn(db2);\n }\n throw err;\n }\n }\n\n return {\n getItem: async (name: string): Promise<string | null> => {\n return withRetry(async (db) => {\n let v = await db.get(storeName, name);\n v = v ?? null; // Zustand expects null for missing keys\n return v;\n });\n },\n setItem: async (name: string, value: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.put(storeName, value, name);\n });\n },\n removeItem: async (name: string): Promise<void> => {\n return withRetry(async (db) => {\n await db.delete(storeName, name);\n });\n },\n };\n}\n"],"mappings":"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","names":["SyncAction","MissingRemoteRecordStrategy","state"]}
|