'use strict'; var core = require('@shared-state/core'); function createPersistenceSharedState(storage, key, initialValueOrGetter, options) { var version = options === null || options === void 0 ? void 0 : options.version; var migrator = options === null || options === void 0 ? void 0 : options.migrator; var onHydrationStart = options === null || options === void 0 ? void 0 : options.onHydrationStart; var onHydrationEnd = options === null || options === void 0 ? void 0 : options.onHydrationEnd; var onMutationStart = options === null || options === void 0 ? void 0 : options.onMutationStart; var onMutationEnd = options === null || options === void 0 ? void 0 : options.onMutationEnd; var sharedState = core.createSharedState(initialValueOrGetter); var subscriberCount = 0; var hydrationState = core.createSharedState(false); var mutationState = core.createSharedState(false); var lastModified = 0; var hydrated = false; var getInitialValue = function getInitialValue() { return typeof initialValueOrGetter === "function" ? initialValueOrGetter() : initialValueOrGetter; }; var persistentValueToSharedStateValue = function persistentValueToSharedStateValue(persistentValue) { if (persistentValue === null) return getInitialValue(); if (persistentValue.version === version) { return persistentValue.value; } else { if (!migrator) return getInitialValue(); if (Object.hasOwn(persistentValue, "value")) { return migrator(persistentValue.value, persistentValue.version); } else { return migrator(persistentValue); // persistentValue有可能是不支持的数据结构,此时将完整的值返回给用户处理 } } }; var pendingTaskQueue = []; var resolveNextPendingTask = function resolveNextPendingTask() { if (pendingTaskQueue.length > 0) { var task = pendingTaskQueue.shift(); task === null || task === void 0 || task(); } }; var hydrate = function hydrate() { var pending = hydrationState.get() || mutationState.get(); if (pending) { pendingTaskQueue.splice(0); pendingTaskQueue.push(function () { return hydrate(); }); return; } hydrated = true; onHydrationStart === null || onHydrationStart === void 0 || onHydrationStart(); hydrationState.set(true); var commit = function commit(persistentValue) { if (persistentValue !== null && persistentValue.lastModified > lastModified) { sharedState.set(persistentValueToSharedStateValue(persistentValue)); lastModified = persistentValue.lastModified; } hydrationState.set(false); onHydrationEnd === null || onHydrationEnd === void 0 || onHydrationEnd(); resolveNextPendingTask(); }; var throwError = function throwError(error) { hydrationState.set(false); onHydrationEnd === null || onHydrationEnd === void 0 || onHydrationEnd(error); resolveNextPendingTask(); }; try { var getStorageResult = storage.get(key); if (getStorageResult instanceof Promise) { getStorageResult.then(function (persistentValue) { return commit(persistentValue); })["catch"](function (error) { return throwError(error); }); } else { commit(getStorageResult); } } catch (error) { throwError(error); } }; var mutate = function mutate(valueOrUpdater) { if (typeof valueOrUpdater === "function" && !hydrated && !lastModified) { hydrate(); pendingTaskQueue.push(function () { return mutate(valueOrUpdater); }); return; } var pending = hydrationState.get() || mutationState.get(); if (pending) { if (typeof valueOrUpdater !== "function") { pendingTaskQueue.splice(0); } pendingTaskQueue.push(function () { return mutate(valueOrUpdater); }); return; } var previousValue = sharedState.get(); var nextValue = typeof valueOrUpdater === "function" ? valueOrUpdater(previousValue) : valueOrUpdater; if (Object.is(nextValue, previousValue)) return; onMutationStart === null || onMutationStart === void 0 || onMutationStart(); mutationState.set(true); var time = new Date().getTime(); var commit = function commit() { if (time > lastModified) { sharedState.set(nextValue); lastModified = time; } mutationState.set(false); onMutationEnd === null || onMutationEnd === void 0 || onMutationEnd(); resolveNextPendingTask(); }; var throwError = function throwError(error) { mutationState.set(false); onMutationEnd === null || onMutationEnd === void 0 || onMutationEnd(error); resolveNextPendingTask(); }; try { var setStorageResult = storage.set(key, { value: nextValue, version: version, lastModified: time }); if (setStorageResult instanceof Promise) { setStorageResult.then(function () { return commit(); })["catch"](function (error) { return throwError(error); }); } else { commit(); } } catch (error) { throwError(error); } }; var storageSubscribeHandler = function storageSubscribeHandler(updateKey, nextValue, previousValue) { var _nextValue$lastModifi; if (updateKey !== key || Object.is(nextValue, previousValue) || nextValue && nextValue.lastModified < lastModified) return; sharedState.set(persistentValueToSharedStateValue(nextValue)); lastModified = (_nextValue$lastModifi = nextValue === null || nextValue === void 0 ? void 0 : nextValue.lastModified) !== null && _nextValue$lastModifi !== void 0 ? _nextValue$lastModifi : new Date().getTime(); }; return { hydrate: hydrate, get: function get() { if (!hydrated && !lastModified) hydrate(); return sharedState.get(); }, set: mutate, subscribe: function subscribe(handler) { if (subscriberCount === 0) { var _storage$subscribe; (_storage$subscribe = storage.subscribe) === null || _storage$subscribe === void 0 || _storage$subscribe.call(storage, storageSubscribeHandler); } sharedState.subscribe(handler); subscriberCount++; }, unsubscribe: function unsubscribe(handler) { sharedState.unsubscribe(handler); subscriberCount--; if (subscriberCount === 0) { var _storage$unsubscribe; (_storage$unsubscribe = storage.unsubscribe) === null || _storage$unsubscribe === void 0 || _storage$unsubscribe.call(storage, storageSubscribeHandler); } }, hydrationState: hydrationState, mutationState: mutationState }; } function withConverter(storage, options) { var serialize = options.serialize, deserialize = options.deserialize; var internalHandlerMap = new Map(); var deserializeValue = function deserializeValue(value) { if (value === null) return null; try { return deserialize(value); } catch (_unused) { return null; } }; return { get: function get(key) { var getStorageResult = storage.get(key); if (getStorageResult instanceof Promise) { return getStorageResult.then(deserializeValue); } else { return deserializeValue(getStorageResult); } }, set: function set(key, value) { return storage.set(key, serialize(value)); }, subscribe: storage.subscribe ? function (handler) { var _storage$subscribe; var internalHandler = function internalHandler(key, nextValue, previousValue) { return handler(key, nextValue !== null ? deserializeValue(nextValue) : null, previousValue !== null ? deserializeValue(previousValue) : null); }; internalHandlerMap.set(handler, internalHandler); (_storage$subscribe = storage.subscribe) === null || _storage$subscribe === void 0 || _storage$subscribe.call(storage, internalHandler); } : undefined, unsubscribe: storage.unsubscribe ? function (handler) { var internalHandler = internalHandlerMap.get(handler); if (internalHandler) { var _storage$unsubscribe; (_storage$unsubscribe = storage.unsubscribe) === null || _storage$unsubscribe === void 0 || _storage$unsubscribe.call(storage, internalHandler); internalHandlerMap["delete"](handler); } } : undefined }; } function createWebPersistenceStorage(webStorage, options) { var storageEventHandlerMap = new Map(); return withConverter({ get: function get(key) { return webStorage.getItem(String(key)); }, set: function set(key, value) { return webStorage.setItem(String(key), value); }, subscribe: function subscribe(handler) { var storageEventHandler = function storageEventHandler(event) { return event.key && handler(event.key, event.newValue, event.oldValue); }; storageEventHandlerMap.set(handler, storageEventHandler); window.addEventListener("storage", storageEventHandler); }, unsubscribe: function unsubscribe(handler) { var storageEventHandler = storageEventHandlerMap.get(handler); if (storageEventHandler) { window.removeEventListener("storage", storageEventHandler); storageEventHandlerMap["delete"](handler); } } }, { serialize: (options === null || options === void 0 ? void 0 : options.serialize) || JSON.stringify, deserialize: (options === null || options === void 0 ? void 0 : options.deserialize) || JSON.parse }); } exports.createPersistenceSharedState = createPersistenceSharedState; exports.createWebPersistenceStorage = createWebPersistenceStorage; exports.withConverter = withConverter;