@composy/store-vue 0.0.1 → 0.0.2
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/CHANGELOG.md +59 -0
- package/README.md +169 -154
- package/dist/index.js +151 -53
- package/dist/index.js.map +1 -1
- package/dist/index.min.js +242 -170
- package/dist/index.min.js.map +1 -1
- package/es/.dts-output-manifest.json +1 -0
- package/es/.dts.tsbuildinfo +1 -0
- package/es/composables/defineSetupStore.d.ts +0 -1
- package/es/composables/defineSetupStore.d.ts.map +1 -1
- package/es/composables/defineSetupStore.js +1 -1
- package/es/composables/defineSetupStore.js.map +1 -1
- package/es/composables/index.d.ts +8 -9
- package/es/composables/index.d.ts.map +1 -1
- package/es/composables/index.js +1 -1
- package/es/composables/useFormStore.d.ts +0 -1
- package/es/composables/useFormStore.d.ts.map +1 -1
- package/es/composables/useFormStore.js +1 -1
- package/es/composables/useFormStore.js.map +1 -1
- package/es/composables/useOptimistic.d.ts +1 -52
- package/es/composables/useOptimistic.d.ts.map +1 -1
- package/es/composables/useOptimistic.js +35 -20
- package/es/composables/useOptimistic.js.map +1 -1
- package/es/composables/usePersist.d.ts +0 -1
- package/es/composables/usePersist.d.ts.map +1 -1
- package/es/composables/usePersist.js +16 -7
- package/es/composables/usePersist.js.map +1 -1
- package/es/composables/usePersistedState.d.ts +0 -1
- package/es/composables/usePersistedState.d.ts.map +1 -1
- package/es/composables/usePersistedState.js +16 -3
- package/es/composables/usePersistedState.js.map +1 -1
- package/es/composables/useSharedState.d.ts +0 -1
- package/es/composables/useSharedState.d.ts.map +1 -1
- package/es/composables/useSharedState.js +25 -8
- package/es/composables/useSharedState.js.map +1 -1
- package/es/composables/useStore.d.ts +0 -1
- package/es/composables/useStore.js +1 -1
- package/es/composables/useStore.js.map +1 -1
- package/es/composables/useStoreDevtools.d.ts +0 -1
- package/es/composables/useStoreDevtools.d.ts.map +1 -1
- package/es/composables/useStoreDevtools.js +1 -1
- package/es/composables/useStoreDevtools.js.map +1 -1
- package/es/composables/useStoreSnapshot.d.ts +0 -1
- package/es/composables/useStoreSnapshot.d.ts.map +1 -1
- package/es/composables/useStoreSnapshot.js +18 -8
- package/es/composables/useStoreSnapshot.js.map +1 -1
- package/es/composables/useSubscribe.d.ts +0 -1
- package/es/composables/useSubscribe.d.ts.map +1 -1
- package/es/composables/useSubscribe.js +1 -1
- package/es/composables/useSubscribe.js.map +1 -1
- package/es/context/injection-keys.d.ts +0 -1
- package/es/context/injection-keys.d.ts.map +1 -1
- package/es/context/injection-keys.js +1 -1
- package/es/context/injection-keys.js.map +1 -1
- package/es/index.d.ts +1 -2
- package/es/index.js +2 -2
- package/es/index.js.map +1 -1
- package/es/plugins/engine-plugin.d.ts +1 -2
- package/es/plugins/engine-plugin.d.ts.map +1 -1
- package/es/plugins/engine-plugin.js +2 -2
- package/es/plugins/engine-plugin.js.map +1 -1
- package/es/plugins/enhanced-persist-plugin.d.ts +0 -1
- package/es/plugins/enhanced-persist-plugin.js +1 -1
- package/es/plugins/index.d.ts +0 -1
- package/es/plugins/index.js +1 -1
- package/es/plugins/pinia-plugin.d.ts +0 -1
- package/es/plugins/pinia-plugin.d.ts.map +1 -1
- package/es/plugins/pinia-plugin.js +24 -6
- package/es/plugins/pinia-plugin.js.map +1 -1
- package/es/plugins/registry-plugin.d.ts +0 -1
- package/es/plugins/registry-plugin.js +1 -1
- package/es/plugins/vue-plugin.d.ts +0 -1
- package/es/plugins/vue-plugin.d.ts.map +1 -1
- package/es/plugins/vue-plugin.js +1 -1
- package/es/plugins/vue-plugin.js.map +1 -1
- package/es/runtime/install-store-app.d.ts +0 -1
- package/es/runtime/install-store-app.js +1 -1
- package/es/runtime/install-store-app.js.map +1 -1
- package/es/runtime/store-plugin-options.d.ts +0 -1
- package/es/runtime/store-plugin-options.js +1 -1
- package/es/runtime/store-plugin-options.js.map +1 -1
- package/es/runtime/store-registry.d.ts +0 -1
- package/es/runtime/store-registry.d.ts.map +1 -1
- package/es/runtime/store-registry.js +14 -4
- package/es/runtime/store-registry.js.map +1 -1
- package/es/runtime/store-runtime.d.ts +1 -2
- package/es/runtime/store-runtime.d.ts.map +1 -1
- package/es/runtime/store-runtime.js +8 -2
- package/es/runtime/store-runtime.js.map +1 -1
- package/es/types.d.ts +2 -1
- package/es/types.d.ts.map +1 -1
- package/es/types.js +1 -1
- package/esm/composables/defineSetupStore.d.ts.map +1 -1
- package/esm/composables/defineSetupStore.js +1 -1
- package/esm/composables/defineSetupStore.js.map +1 -1
- package/esm/composables/index.d.ts +8 -8
- package/esm/composables/index.d.ts.map +1 -1
- package/esm/composables/index.js +1 -1
- package/esm/composables/useFormStore.d.ts.map +1 -1
- package/esm/composables/useFormStore.js +1 -1
- package/esm/composables/useFormStore.js.map +1 -1
- package/esm/composables/useOptimistic.d.ts +1 -51
- package/esm/composables/useOptimistic.d.ts.map +1 -1
- package/esm/composables/useOptimistic.js +35 -20
- package/esm/composables/useOptimistic.js.map +1 -1
- package/esm/composables/usePersist.d.ts.map +1 -1
- package/esm/composables/usePersist.js +16 -7
- package/esm/composables/usePersist.js.map +1 -1
- package/esm/composables/usePersistedState.d.ts.map +1 -1
- package/esm/composables/usePersistedState.js +16 -3
- package/esm/composables/usePersistedState.js.map +1 -1
- package/esm/composables/useSharedState.d.ts.map +1 -1
- package/esm/composables/useSharedState.js +25 -8
- package/esm/composables/useSharedState.js.map +1 -1
- package/esm/composables/useStore.js +1 -1
- package/esm/composables/useStore.js.map +1 -1
- package/esm/composables/useStoreDevtools.d.ts.map +1 -1
- package/esm/composables/useStoreDevtools.js +1 -1
- package/esm/composables/useStoreDevtools.js.map +1 -1
- package/esm/composables/useStoreSnapshot.d.ts.map +1 -1
- package/esm/composables/useStoreSnapshot.js +18 -8
- package/esm/composables/useStoreSnapshot.js.map +1 -1
- package/esm/composables/useSubscribe.d.ts.map +1 -1
- package/esm/composables/useSubscribe.js +1 -1
- package/esm/composables/useSubscribe.js.map +1 -1
- package/esm/context/injection-keys.d.ts.map +1 -1
- package/esm/context/injection-keys.js +1 -1
- package/esm/context/injection-keys.js.map +1 -1
- package/esm/index.d.ts +1 -1
- package/esm/index.js +2 -2
- package/esm/index.js.map +1 -1
- package/esm/plugins/engine-plugin.d.ts +1 -1
- package/esm/plugins/engine-plugin.d.ts.map +1 -1
- package/esm/plugins/engine-plugin.js +2 -2
- package/esm/plugins/engine-plugin.js.map +1 -1
- package/esm/plugins/enhanced-persist-plugin.js +1 -1
- package/esm/plugins/index.js +1 -1
- package/esm/plugins/pinia-plugin.d.ts.map +1 -1
- package/esm/plugins/pinia-plugin.js +24 -6
- package/esm/plugins/pinia-plugin.js.map +1 -1
- package/esm/plugins/registry-plugin.js +1 -1
- package/esm/plugins/vue-plugin.d.ts.map +1 -1
- package/esm/plugins/vue-plugin.js +1 -1
- package/esm/plugins/vue-plugin.js.map +1 -1
- package/esm/runtime/install-store-app.js +1 -1
- package/esm/runtime/install-store-app.js.map +1 -1
- package/esm/runtime/store-plugin-options.js +1 -1
- package/esm/runtime/store-plugin-options.js.map +1 -1
- package/esm/runtime/store-registry.d.ts.map +1 -1
- package/esm/runtime/store-registry.js +14 -4
- package/esm/runtime/store-registry.js.map +1 -1
- package/esm/runtime/store-runtime.d.ts +1 -1
- package/esm/runtime/store-runtime.d.ts.map +1 -1
- package/esm/runtime/store-runtime.js +8 -2
- package/esm/runtime/store-runtime.js.map +1 -1
- package/esm/types.d.ts +2 -0
- package/esm/types.d.ts.map +1 -1
- package/esm/types.js +1 -1
- package/lib/composables/defineSetupStore.cjs +1 -1
- package/lib/composables/defineSetupStore.cjs.map +1 -1
- package/lib/composables/{defineSetupStore.d.ts → defineSetupStore.d.cts} +0 -1
- package/lib/composables/defineSetupStore.d.cts.map +1 -0
- package/lib/composables/index.cjs +1 -1
- package/lib/composables/{index.d.ts → index.d.cts} +8 -9
- package/lib/composables/index.d.cts.map +1 -0
- package/lib/composables/useFormStore.cjs +1 -1
- package/lib/composables/useFormStore.cjs.map +1 -1
- package/lib/composables/{useFormStore.d.ts → useFormStore.d.cts} +0 -1
- package/lib/composables/useFormStore.d.cts.map +1 -0
- package/lib/composables/useOptimistic.cjs +35 -20
- package/lib/composables/useOptimistic.cjs.map +1 -1
- package/lib/composables/useOptimistic.d.cts +16 -0
- package/lib/composables/useOptimistic.d.cts.map +1 -0
- package/lib/composables/usePersist.cjs +16 -7
- package/lib/composables/usePersist.cjs.map +1 -1
- package/lib/composables/{usePersist.d.ts → usePersist.d.cts} +0 -1
- package/lib/composables/usePersist.d.cts.map +1 -0
- package/lib/composables/usePersistedState.cjs +16 -3
- package/lib/composables/usePersistedState.cjs.map +1 -1
- package/lib/composables/{usePersistedState.d.ts → usePersistedState.d.cts} +0 -1
- package/lib/composables/usePersistedState.d.cts.map +1 -0
- package/lib/composables/useSharedState.cjs +24 -7
- package/lib/composables/useSharedState.cjs.map +1 -1
- package/lib/composables/{useSharedState.d.ts → useSharedState.d.cts} +0 -1
- package/lib/composables/useSharedState.d.cts.map +1 -0
- package/lib/composables/useStore.cjs +1 -1
- package/lib/composables/useStore.cjs.map +1 -1
- package/lib/composables/{useStore.d.ts → useStore.d.cts} +0 -1
- package/lib/composables/useStore.d.cts.map +1 -0
- package/lib/composables/useStoreDevtools.cjs +1 -1
- package/lib/composables/useStoreDevtools.cjs.map +1 -1
- package/lib/composables/{useStoreDevtools.d.ts → useStoreDevtools.d.cts} +0 -1
- package/lib/composables/useStoreDevtools.d.cts.map +1 -0
- package/lib/composables/useStoreSnapshot.cjs +18 -8
- package/lib/composables/useStoreSnapshot.cjs.map +1 -1
- package/lib/composables/{useStoreSnapshot.d.ts → useStoreSnapshot.d.cts} +0 -1
- package/lib/composables/useStoreSnapshot.d.cts.map +1 -0
- package/lib/composables/useSubscribe.cjs +1 -1
- package/lib/composables/useSubscribe.cjs.map +1 -1
- package/lib/composables/{useSubscribe.d.ts → useSubscribe.d.cts} +0 -1
- package/lib/composables/useSubscribe.d.cts.map +1 -0
- package/lib/context/injection-keys.cjs +1 -1
- package/lib/context/injection-keys.cjs.map +1 -1
- package/lib/context/{injection-keys.d.ts → injection-keys.d.cts} +0 -1
- package/lib/context/injection-keys.d.cts.map +1 -0
- package/lib/index.cjs +2 -2
- package/lib/index.cjs.map +1 -1
- package/lib/{index.d.ts → index.d.cts} +1 -2
- package/lib/index.d.cts.map +1 -0
- package/lib/plugins/engine-plugin.cjs +2 -2
- package/lib/plugins/engine-plugin.cjs.map +1 -1
- package/lib/plugins/{engine-plugin.d.ts → engine-plugin.d.cts} +1 -2
- package/lib/plugins/engine-plugin.d.cts.map +1 -0
- package/lib/plugins/enhanced-persist-plugin.cjs +1 -1
- package/lib/plugins/{enhanced-persist-plugin.d.ts → enhanced-persist-plugin.d.cts} +0 -1
- package/lib/plugins/enhanced-persist-plugin.d.cts.map +1 -0
- package/lib/plugins/index.cjs +1 -1
- package/lib/plugins/{index.d.ts → index.d.cts} +0 -1
- package/lib/plugins/index.d.cts.map +1 -0
- package/lib/plugins/pinia-plugin.cjs +24 -6
- package/lib/plugins/pinia-plugin.cjs.map +1 -1
- package/lib/plugins/{pinia-plugin.d.ts → pinia-plugin.d.cts} +0 -1
- package/lib/plugins/pinia-plugin.d.cts.map +1 -0
- package/lib/plugins/registry-plugin.cjs +1 -1
- package/lib/plugins/{registry-plugin.d.ts → registry-plugin.d.cts} +0 -1
- package/lib/plugins/registry-plugin.d.cts.map +1 -0
- package/lib/plugins/vue-plugin.cjs +1 -1
- package/lib/plugins/vue-plugin.cjs.map +1 -1
- package/lib/plugins/{vue-plugin.d.ts → vue-plugin.d.cts} +0 -1
- package/lib/plugins/vue-plugin.d.cts.map +1 -0
- package/lib/runtime/install-store-app.cjs +1 -1
- package/lib/runtime/install-store-app.cjs.map +1 -1
- package/lib/runtime/{install-store-app.d.ts → install-store-app.d.cts} +0 -1
- package/lib/runtime/install-store-app.d.cts.map +1 -0
- package/lib/runtime/store-plugin-options.cjs +1 -1
- package/lib/runtime/store-plugin-options.cjs.map +1 -1
- package/lib/runtime/{store-plugin-options.d.ts → store-plugin-options.d.cts} +0 -1
- package/lib/runtime/store-plugin-options.d.cts.map +1 -0
- package/lib/runtime/store-registry.cjs +14 -4
- package/lib/runtime/store-registry.cjs.map +1 -1
- package/lib/runtime/{store-registry.d.ts → store-registry.d.cts} +0 -1
- package/lib/runtime/store-registry.d.cts.map +1 -0
- package/lib/runtime/store-runtime.cjs +8 -2
- package/lib/runtime/store-runtime.cjs.map +1 -1
- package/lib/runtime/{store-runtime.d.ts → store-runtime.d.cts} +1 -2
- package/lib/runtime/store-runtime.d.cts.map +1 -0
- package/lib/types.cjs +1 -1
- package/lib/{types.d.ts → types.d.cts} +2 -1
- package/lib/types.d.cts.map +1 -0
- package/package.json +19 -16
- package/lib/composables/useOptimistic.d.ts +0 -67
package/dist/index.js
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* ***********************************
|
|
3
3
|
* @composy/store-vue v0.0.1 *
|
|
4
4
|
* Built with rollup *
|
|
5
|
-
* Build time: 2024-
|
|
5
|
+
* Build time: 2024-10-12 17:40:04 *
|
|
6
6
|
* Build mode: production *
|
|
7
7
|
* Minified: No *
|
|
8
8
|
* ***********************************
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"vue",
|
|
16
16
|
"@composy/store-core",
|
|
17
17
|
"@composy/store-core/engine"
|
|
18
|
-
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.LDesignStoreVue = {}, global.Pinia, global.Vue, global.
|
|
18
|
+
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.LDesignStoreVue = {}, global.Pinia, global.Vue, global.LDesignStoreCore, global.LDesignStoreCore));
|
|
19
19
|
})(this, function(exports, pinia, vue, _composy_store_core, _composy_store_core_engine) {
|
|
20
20
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
21
21
|
//#region src/composables/defineSetupStore.ts
|
|
@@ -214,39 +214,54 @@
|
|
|
214
214
|
}
|
|
215
215
|
function useOptimistic(initialState) {
|
|
216
216
|
const state = (0, vue.ref)((0, _composy_store_core.deepClone)(initialState));
|
|
217
|
+
let committedState = (0, _composy_store_core.deepClone)(initialState);
|
|
218
|
+
const operations = [];
|
|
217
219
|
const isPending = (0, vue.ref)(false);
|
|
218
220
|
const isRolledBack = (0, vue.ref)(false);
|
|
219
221
|
const pending = (0, vue.ref)([]);
|
|
222
|
+
const refresh = () => {
|
|
223
|
+
let nextState = (0, _composy_store_core.deepClone)(committedState);
|
|
224
|
+
operations.forEach((operation) => {
|
|
225
|
+
if (operation.status !== "rolled-back") nextState = operation.apply(nextState);
|
|
226
|
+
});
|
|
227
|
+
state.value = (0, _composy_store_core.deepClone)(nextState);
|
|
228
|
+
pending.value = operations.filter((operation) => operation.status === "pending").map((operation) => ({
|
|
229
|
+
id: operation.id,
|
|
230
|
+
snapshot: (0, _composy_store_core.deepClone)(operation.snapshot),
|
|
231
|
+
status: operation.status,
|
|
232
|
+
timestamp: operation.timestamp
|
|
233
|
+
}));
|
|
234
|
+
isPending.value = pending.value.length > 0;
|
|
235
|
+
};
|
|
236
|
+
const reconcile = () => {
|
|
237
|
+
while (operations[0] && operations[0].status !== "pending") {
|
|
238
|
+
const operation = operations.shift();
|
|
239
|
+
if (!operation || operation.status === "rolled-back") continue;
|
|
240
|
+
committedState = operation.apply((0, _composy_store_core.deepClone)(committedState));
|
|
241
|
+
}
|
|
242
|
+
refresh();
|
|
243
|
+
};
|
|
220
244
|
async function mutate(optimisticValue, confirm) {
|
|
221
245
|
const snapshot = (0, _composy_store_core.deepClone)(state.value);
|
|
222
|
-
const
|
|
223
|
-
const
|
|
224
|
-
id:
|
|
246
|
+
const apply = typeof optimisticValue === "function" ? (previous) => (0, _composy_store_core.deepClone)(optimisticValue((0, _composy_store_core.deepClone)(previous))) : () => (0, _composy_store_core.deepClone)(optimisticValue);
|
|
247
|
+
const operation = {
|
|
248
|
+
id: uid(),
|
|
225
249
|
snapshot,
|
|
226
250
|
status: "pending",
|
|
227
|
-
timestamp: Date.now()
|
|
251
|
+
timestamp: Date.now(),
|
|
252
|
+
apply
|
|
228
253
|
};
|
|
229
|
-
|
|
230
|
-
isPending.value = true;
|
|
254
|
+
operations.push(operation);
|
|
231
255
|
isRolledBack.value = false;
|
|
232
|
-
|
|
233
|
-
else state.value = optimisticValue;
|
|
256
|
+
refresh();
|
|
234
257
|
try {
|
|
235
258
|
await confirm();
|
|
236
|
-
|
|
237
|
-
...e,
|
|
238
|
-
status: "confirmed"
|
|
239
|
-
} : e);
|
|
259
|
+
operation.status = "confirmed";
|
|
240
260
|
} catch {
|
|
241
|
-
|
|
261
|
+
operation.status = "rolled-back";
|
|
242
262
|
isRolledBack.value = true;
|
|
243
|
-
pending.value = pending.value.map((e) => e.id === entryId ? {
|
|
244
|
-
...e,
|
|
245
|
-
status: "rolled-back"
|
|
246
|
-
} : e);
|
|
247
263
|
} finally {
|
|
248
|
-
|
|
249
|
-
isPending.value = pending.value.length > 0;
|
|
264
|
+
reconcile();
|
|
250
265
|
}
|
|
251
266
|
}
|
|
252
267
|
return {
|
|
@@ -261,10 +276,14 @@
|
|
|
261
276
|
//#region src/composables/usePersist.ts
|
|
262
277
|
function getStorage$2(type) {
|
|
263
278
|
if (typeof window === "undefined") return null;
|
|
264
|
-
|
|
279
|
+
try {
|
|
280
|
+
return type === "localStorage" ? window.localStorage : window.sessionStorage;
|
|
281
|
+
} catch {
|
|
282
|
+
return null;
|
|
283
|
+
}
|
|
265
284
|
}
|
|
266
285
|
function usePersist(options) {
|
|
267
|
-
const { key, storage: storageType = "localStorage", defaultValue, serialize = JSON.stringify, deserialize = JSON.parse } = options;
|
|
286
|
+
const { key, storage: storageType = "localStorage", defaultValue, serialize = JSON.stringify, deserialize = JSON.parse, restoreOnMounted = true } = options;
|
|
268
287
|
const storage = getStorage$2(storageType);
|
|
269
288
|
const value = (0, vue.ref)(defaultValue);
|
|
270
289
|
const restore = () => {
|
|
@@ -293,7 +312,7 @@
|
|
|
293
312
|
console.error(`[usePersist] \u6E05\u9664\u5931\u8D25 (${key}):`, error);
|
|
294
313
|
}
|
|
295
314
|
};
|
|
296
|
-
(0, vue.onMounted)(() => {
|
|
315
|
+
if (restoreOnMounted) (0, vue.onMounted)(() => {
|
|
297
316
|
restore();
|
|
298
317
|
});
|
|
299
318
|
(0, vue.watch)(value, () => {
|
|
@@ -315,12 +334,13 @@
|
|
|
315
334
|
return value;
|
|
316
335
|
}
|
|
317
336
|
function usePersistedRefWithTTL(key, defaultValue, ttl) {
|
|
318
|
-
const
|
|
337
|
+
const persisted = usePersist({
|
|
319
338
|
key,
|
|
320
339
|
defaultValue: {
|
|
321
340
|
value: defaultValue,
|
|
322
341
|
expiry: 0
|
|
323
342
|
},
|
|
343
|
+
restoreOnMounted: false,
|
|
324
344
|
serialize: (data) => JSON.stringify(data),
|
|
325
345
|
deserialize: (str) => {
|
|
326
346
|
const data = JSON.parse(str);
|
|
@@ -331,13 +351,17 @@
|
|
|
331
351
|
return data;
|
|
332
352
|
}
|
|
333
353
|
});
|
|
334
|
-
|
|
354
|
+
persisted.restore();
|
|
355
|
+
const wrappedRef = (0, vue.ref)(persisted.value.value.value);
|
|
335
356
|
(0, vue.watch)(wrappedRef, (newValue) => {
|
|
336
|
-
value.value = {
|
|
357
|
+
persisted.value.value = {
|
|
337
358
|
value: newValue,
|
|
338
359
|
expiry: Date.now() + ttl
|
|
339
360
|
};
|
|
340
361
|
});
|
|
362
|
+
(0, vue.watch)(persisted.value, (stored) => {
|
|
363
|
+
if (!Object.is(wrappedRef.value, stored.value)) wrappedRef.value = stored.value;
|
|
364
|
+
}, { deep: true });
|
|
341
365
|
return wrappedRef;
|
|
342
366
|
}
|
|
343
367
|
//#endregion
|
|
@@ -361,6 +385,7 @@
|
|
|
361
385
|
const storage = getStorage$1(storageType);
|
|
362
386
|
const createDefaultValue = () => (0, _composy_store_core.deepClone)(defaultValue);
|
|
363
387
|
const state = (0, vue.ref)(createDefaultValue());
|
|
388
|
+
let skipNextSave = false;
|
|
364
389
|
const save = () => {
|
|
365
390
|
if (!storage) return;
|
|
366
391
|
try {
|
|
@@ -374,6 +399,7 @@
|
|
|
374
399
|
console.error(`[usePersistedState] \u4FDD\u5B58\u5931\u8D25 (${key}):`, error);
|
|
375
400
|
}
|
|
376
401
|
};
|
|
402
|
+
const debouncedSave = debounceDelay > 0 ? (0, _composy_store_core.debounce)(save, debounceDelay) : null;
|
|
377
403
|
const clear = () => {
|
|
378
404
|
if (!storage) return;
|
|
379
405
|
try {
|
|
@@ -401,6 +427,8 @@
|
|
|
401
427
|
}
|
|
402
428
|
};
|
|
403
429
|
const reset = () => {
|
|
430
|
+
debouncedSave?.cancel();
|
|
431
|
+
skipNextSave = true;
|
|
404
432
|
state.value = createDefaultValue();
|
|
405
433
|
clear();
|
|
406
434
|
};
|
|
@@ -415,9 +443,14 @@
|
|
|
415
443
|
return false;
|
|
416
444
|
}
|
|
417
445
|
};
|
|
418
|
-
const debouncedSave = debounceDelay > 0 ? (0, _composy_store_core.debounce)(save, debounceDelay) : null;
|
|
419
446
|
const handleStorageEvent = (event) => {
|
|
420
|
-
if (event.key !== key
|
|
447
|
+
if (event.key !== key) return;
|
|
448
|
+
if (!event.newValue) {
|
|
449
|
+
debouncedSave?.cancel();
|
|
450
|
+
skipNextSave = true;
|
|
451
|
+
state.value = createDefaultValue();
|
|
452
|
+
return;
|
|
453
|
+
}
|
|
421
454
|
try {
|
|
422
455
|
const item = JSON.parse(event.newValue);
|
|
423
456
|
if (item.expiresAt && Date.now() > item.expiresAt) return;
|
|
@@ -428,6 +461,10 @@
|
|
|
428
461
|
};
|
|
429
462
|
restore();
|
|
430
463
|
(0, vue.watch)(state, (newValue, oldValue) => {
|
|
464
|
+
if (skipNextSave) {
|
|
465
|
+
skipNextSave = false;
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
431
468
|
if (onBeforeChange?.(newValue, oldValue) === false) return;
|
|
432
469
|
if (debouncedSave) debouncedSave();
|
|
433
470
|
else save();
|
|
@@ -455,7 +492,11 @@
|
|
|
455
492
|
const peerCount = (0, vue.ref)(0);
|
|
456
493
|
const lastSyncAt = (0, vue.ref)(null);
|
|
457
494
|
let channel = null;
|
|
458
|
-
|
|
495
|
+
const originId = `${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
|
|
496
|
+
let revision = 0;
|
|
497
|
+
const latestRemoteRevision = /* @__PURE__ */ new Map();
|
|
498
|
+
let pendingRemoteState;
|
|
499
|
+
let hasPendingRemoteState = false;
|
|
459
500
|
if (typeof BroadcastChannel === "undefined") {
|
|
460
501
|
console.warn("[useSharedState] BroadcastChannel not supported in this environment");
|
|
461
502
|
return {
|
|
@@ -484,7 +525,9 @@
|
|
|
484
525
|
channel.postMessage({
|
|
485
526
|
type: "state-update",
|
|
486
527
|
payload: (0, _composy_store_core.deepClone)(state.value),
|
|
487
|
-
timestamp: Date.now()
|
|
528
|
+
timestamp: Date.now(),
|
|
529
|
+
origin: originId,
|
|
530
|
+
revision: ++revision
|
|
488
531
|
});
|
|
489
532
|
} catch (e) {
|
|
490
533
|
console.warn("[useSharedState] broadcast error:", e);
|
|
@@ -494,15 +537,26 @@
|
|
|
494
537
|
const msg = event.data;
|
|
495
538
|
if (!msg || typeof msg !== "object") return;
|
|
496
539
|
if (msg.type === "state-update") {
|
|
497
|
-
|
|
498
|
-
|
|
540
|
+
if (msg.origin === originId) return;
|
|
541
|
+
const remoteRevision = typeof msg.revision === "number" ? msg.revision : 0;
|
|
542
|
+
if (remoteRevision <= (latestRemoteRevision.get(String(msg.origin)) ?? -1)) return;
|
|
543
|
+
latestRemoteRevision.set(String(msg.origin), remoteRevision);
|
|
544
|
+
pendingRemoteState = (0, _composy_store_core.deepClone)(msg.payload);
|
|
545
|
+
hasPendingRemoteState = true;
|
|
546
|
+
state.value = pendingRemoteState;
|
|
499
547
|
lastSyncAt.value = msg.timestamp || Date.now();
|
|
500
|
-
isReceiving = false;
|
|
501
548
|
} else if (msg.type === "ping") channel?.postMessage({ type: "pong" });
|
|
502
549
|
else if (msg.type === "pong") peerCount.value++;
|
|
503
550
|
};
|
|
504
551
|
const stopWatch = (0, vue.watch)(state, () => {
|
|
505
|
-
if (
|
|
552
|
+
if (hasPendingRemoteState) {
|
|
553
|
+
if ((0, _composy_store_core.deepEqual)(state.value, pendingRemoteState)) {
|
|
554
|
+
hasPendingRemoteState = false;
|
|
555
|
+
return;
|
|
556
|
+
}
|
|
557
|
+
hasPendingRemoteState = false;
|
|
558
|
+
}
|
|
559
|
+
broadcast();
|
|
506
560
|
}, { deep });
|
|
507
561
|
function close() {
|
|
508
562
|
stopWatch();
|
|
@@ -739,6 +793,7 @@
|
|
|
739
793
|
const currentIndex = (0, vue.ref)(-1);
|
|
740
794
|
let debounceTimer;
|
|
741
795
|
let isRestoring = false;
|
|
796
|
+
let previousAutoRecordState;
|
|
742
797
|
const getState = () => {
|
|
743
798
|
return typeof state === "function" ? state() : state.value;
|
|
744
799
|
};
|
|
@@ -769,6 +824,7 @@
|
|
|
769
824
|
try {
|
|
770
825
|
setState((0, _composy_store_core.deepClone)(snapshots.value[index].state));
|
|
771
826
|
currentIndex.value = index;
|
|
827
|
+
previousAutoRecordState = (0, _composy_store_core.deepClone)(getState());
|
|
772
828
|
return true;
|
|
773
829
|
} finally {
|
|
774
830
|
isRestoring = false;
|
|
@@ -776,10 +832,12 @@
|
|
|
776
832
|
};
|
|
777
833
|
const undo = () => {
|
|
778
834
|
if (!canUndo.value) return false;
|
|
779
|
-
currentIndex.value
|
|
835
|
+
const targetIndex = currentIndex.value - 1;
|
|
780
836
|
isRestoring = true;
|
|
781
837
|
try {
|
|
782
|
-
setState((0, _composy_store_core.deepClone)(snapshots.value[
|
|
838
|
+
setState((0, _composy_store_core.deepClone)(snapshots.value[targetIndex].state));
|
|
839
|
+
currentIndex.value = targetIndex;
|
|
840
|
+
previousAutoRecordState = (0, _composy_store_core.deepClone)(getState());
|
|
783
841
|
return true;
|
|
784
842
|
} finally {
|
|
785
843
|
isRestoring = false;
|
|
@@ -787,10 +845,12 @@
|
|
|
787
845
|
};
|
|
788
846
|
const redo = () => {
|
|
789
847
|
if (!canRedo.value) return false;
|
|
790
|
-
currentIndex.value
|
|
848
|
+
const targetIndex = currentIndex.value + 1;
|
|
791
849
|
isRestoring = true;
|
|
792
850
|
try {
|
|
793
|
-
setState((0, _composy_store_core.deepClone)(snapshots.value[
|
|
851
|
+
setState((0, _composy_store_core.deepClone)(snapshots.value[targetIndex].state));
|
|
852
|
+
currentIndex.value = targetIndex;
|
|
853
|
+
previousAutoRecordState = (0, _composy_store_core.deepClone)(getState());
|
|
794
854
|
return true;
|
|
795
855
|
} finally {
|
|
796
856
|
isRestoring = false;
|
|
@@ -798,10 +858,11 @@
|
|
|
798
858
|
};
|
|
799
859
|
const goto = (index) => {
|
|
800
860
|
if (index < 0 || index >= snapshots.value.length) return false;
|
|
801
|
-
currentIndex.value = index;
|
|
802
861
|
isRestoring = true;
|
|
803
862
|
try {
|
|
804
863
|
setState((0, _composy_store_core.deepClone)(snapshots.value[index].state));
|
|
864
|
+
currentIndex.value = index;
|
|
865
|
+
previousAutoRecordState = (0, _composy_store_core.deepClone)(getState());
|
|
805
866
|
return true;
|
|
806
867
|
} finally {
|
|
807
868
|
isRestoring = false;
|
|
@@ -836,9 +897,12 @@
|
|
|
836
897
|
}
|
|
837
898
|
};
|
|
838
899
|
if (autoRecord) {
|
|
839
|
-
const
|
|
900
|
+
const stateRef = typeof state === "function" ? (0, vue.computed)(state) : state;
|
|
901
|
+
previousAutoRecordState = (0, _composy_store_core.deepClone)(getState());
|
|
902
|
+
const stopWatch = (0, vue.watch)(stateRef, (newState, oldState) => {
|
|
840
903
|
if (isRestoring) return;
|
|
841
|
-
if ((0, _composy_store_core.deepEqual)(newState, oldState)) return;
|
|
904
|
+
if ((0, _composy_store_core.deepEqual)(newState, previousAutoRecordState ?? oldState)) return;
|
|
905
|
+
previousAutoRecordState = (0, _composy_store_core.deepClone)(newState);
|
|
842
906
|
if (debounceTimer) clearTimeout(debounceTimer);
|
|
843
907
|
debounceTimer = setTimeout(() => {
|
|
844
908
|
takeSnapshot();
|
|
@@ -917,7 +981,11 @@
|
|
|
917
981
|
const activePersistControllers = /* @__PURE__ */ new Set();
|
|
918
982
|
function getStorage(type) {
|
|
919
983
|
if (typeof window === "undefined") return null;
|
|
920
|
-
|
|
984
|
+
try {
|
|
985
|
+
return type === "localStorage" ? window.localStorage : window.sessionStorage;
|
|
986
|
+
} catch {
|
|
987
|
+
return null;
|
|
988
|
+
}
|
|
921
989
|
}
|
|
922
990
|
function normalizePersistConfig(value) {
|
|
923
991
|
if (!value) return null;
|
|
@@ -962,17 +1030,21 @@
|
|
|
962
1030
|
function createPersistPluginController(options = {}) {
|
|
963
1031
|
const { storage: defaultStorage = "localStorage", keyPrefix = "ldesign-store:", debounce: debounceDelay = 100, debug = false, syncTabs: defaultSyncTabs = false, defaultTTL } = options;
|
|
964
1032
|
const cleanupMap = /* @__PURE__ */ new Map();
|
|
1033
|
+
let isDisposed = false;
|
|
965
1034
|
const dispose = () => {
|
|
1035
|
+
if (isDisposed) return;
|
|
1036
|
+
isDisposed = true;
|
|
966
1037
|
cleanupMap.forEach((cleanup) => cleanup());
|
|
967
1038
|
cleanupMap.clear();
|
|
968
1039
|
activePersistControllers.delete(dispose);
|
|
969
1040
|
};
|
|
970
1041
|
activePersistControllers.add(dispose);
|
|
971
1042
|
const plugin = (context) => {
|
|
1043
|
+
if (isDisposed) return;
|
|
972
1044
|
const { store, options: storeOptions } = context;
|
|
973
1045
|
const config = normalizePersistConfig(storeOptions.persist);
|
|
974
1046
|
if (!config) return;
|
|
975
|
-
const storage = getStorage(config.storage
|
|
1047
|
+
const storage = getStorage(config.storage ?? defaultStorage);
|
|
976
1048
|
const serializer = config.serializer?.serialize ?? JSON.stringify;
|
|
977
1049
|
const deserialize = config.serializer?.deserialize ?? JSON.parse;
|
|
978
1050
|
const syncTabs = config.syncTabs ?? defaultSyncTabs;
|
|
@@ -1032,7 +1104,16 @@
|
|
|
1032
1104
|
let stopStorageSync = () => {};
|
|
1033
1105
|
if (syncTabs && typeof window !== "undefined") {
|
|
1034
1106
|
const handleStorage = (event) => {
|
|
1035
|
-
if (event.key !== key
|
|
1107
|
+
if (event.key !== key) return;
|
|
1108
|
+
if (event.newValue === null) {
|
|
1109
|
+
isRestoring = true;
|
|
1110
|
+
try {
|
|
1111
|
+
store.$reset?.();
|
|
1112
|
+
} finally {
|
|
1113
|
+
isRestoring = false;
|
|
1114
|
+
}
|
|
1115
|
+
return;
|
|
1116
|
+
}
|
|
1036
1117
|
try {
|
|
1037
1118
|
const storageItem = JSON.parse(event.newValue);
|
|
1038
1119
|
if (storageItem.expiresAt && Date.now() > storageItem.expiresAt) return;
|
|
@@ -1050,9 +1131,10 @@
|
|
|
1050
1131
|
saveState.cancel();
|
|
1051
1132
|
stopSubscribe();
|
|
1052
1133
|
stopStorageSync();
|
|
1053
|
-
cleanupMap.delete(
|
|
1134
|
+
cleanupMap.delete(store);
|
|
1135
|
+
store[STORE_PERSIST_DISPOSE_KEY]?.();
|
|
1054
1136
|
};
|
|
1055
|
-
cleanupMap.set(
|
|
1137
|
+
cleanupMap.set(store, cleanup);
|
|
1056
1138
|
patchPersistDispose(store, cleanup);
|
|
1057
1139
|
restoreState();
|
|
1058
1140
|
};
|
|
@@ -1090,7 +1172,7 @@
|
|
|
1090
1172
|
if (restorePatchedDispose) restorePatchedDispose();
|
|
1091
1173
|
const originalDispose = store.$dispose;
|
|
1092
1174
|
store.$dispose = function patchedDispose() {
|
|
1093
|
-
unregister(
|
|
1175
|
+
unregister();
|
|
1094
1176
|
return originalDispose.call(this);
|
|
1095
1177
|
};
|
|
1096
1178
|
store[STORE_DISPOSE_PATCH_KEY] = () => {
|
|
@@ -1100,12 +1182,17 @@
|
|
|
1100
1182
|
}
|
|
1101
1183
|
function createStoreRegistry() {
|
|
1102
1184
|
const stores = /* @__PURE__ */ new Map();
|
|
1103
|
-
const unregister = (storeId) => {
|
|
1185
|
+
const unregister = (storeId, expectedStore) => {
|
|
1186
|
+
const store = stores.get(storeId);
|
|
1187
|
+
if (!store || expectedStore && store !== expectedStore) return;
|
|
1104
1188
|
stores.delete(storeId);
|
|
1189
|
+
store[STORE_DISPOSE_PATCH_KEY]?.();
|
|
1105
1190
|
};
|
|
1106
1191
|
const register = (store) => {
|
|
1192
|
+
const existingStore = stores.get(store.$id);
|
|
1193
|
+
if (existingStore && existingStore !== store) unregister(store.$id, existingStore);
|
|
1107
1194
|
stores.set(store.$id, store);
|
|
1108
|
-
patchStoreDispose(store, unregister);
|
|
1195
|
+
patchStoreDispose(store, () => unregister(store.$id, store));
|
|
1109
1196
|
};
|
|
1110
1197
|
const hasStore = (storeId) => {
|
|
1111
1198
|
return stores.has(storeId);
|
|
@@ -1125,6 +1212,9 @@
|
|
|
1125
1212
|
});
|
|
1126
1213
|
};
|
|
1127
1214
|
const clear = () => {
|
|
1215
|
+
stores.forEach((store) => {
|
|
1216
|
+
store[STORE_DISPOSE_PATCH_KEY]?.();
|
|
1217
|
+
});
|
|
1128
1218
|
stores.clear();
|
|
1129
1219
|
};
|
|
1130
1220
|
const registerExistingStores = (pinia) => {
|
|
@@ -1154,6 +1244,8 @@
|
|
|
1154
1244
|
}
|
|
1155
1245
|
let globalRegistry = createStoreRegistry();
|
|
1156
1246
|
function setGlobalStoreRegistry(registry) {
|
|
1247
|
+
if (registry === globalRegistry) return;
|
|
1248
|
+
globalRegistry.clear();
|
|
1157
1249
|
globalRegistry = registry ?? createStoreRegistry();
|
|
1158
1250
|
}
|
|
1159
1251
|
function getStoreRegistry() {
|
|
@@ -1180,11 +1272,15 @@
|
|
|
1180
1272
|
const pinia$1 = resolvedOptions.pinia ?? (0, pinia.createPinia)();
|
|
1181
1273
|
if (pinia$1[STORE_RUNTIME_KEY]) return pinia$1[STORE_RUNTIME_KEY];
|
|
1182
1274
|
const registry = createStoreRegistry();
|
|
1275
|
+
let isActive = true;
|
|
1183
1276
|
const persistController = resolvedOptions.persist ? createPersistPluginController({
|
|
1184
1277
|
...resolvedOptions.persistOptions,
|
|
1185
1278
|
debug: resolvedOptions.debug || resolvedOptions.persistOptions.debug
|
|
1186
1279
|
}) : null;
|
|
1187
|
-
|
|
1280
|
+
const registryPlugin = createStoreRegistryPlugin(registry);
|
|
1281
|
+
pinia$1.use((context) => {
|
|
1282
|
+
if (isActive) registryPlugin(context);
|
|
1283
|
+
});
|
|
1188
1284
|
persistController && pinia$1.use(persistController.plugin);
|
|
1189
1285
|
registry.registerExistingStores(pinia$1);
|
|
1190
1286
|
const runtime = {
|
|
@@ -1197,6 +1293,8 @@
|
|
|
1197
1293
|
* 释放所有资源:清除运行时标记、持久化插件、注册表
|
|
1198
1294
|
*/
|
|
1199
1295
|
dispose: () => {
|
|
1296
|
+
if (!isActive) return;
|
|
1297
|
+
isActive = false;
|
|
1200
1298
|
if (pinia$1[STORE_RUNTIME_KEY] === runtime) delete pinia$1[STORE_RUNTIME_KEY];
|
|
1201
1299
|
persistController?.dispose();
|
|
1202
1300
|
registry.clear();
|
|
@@ -1260,7 +1358,7 @@
|
|
|
1260
1358
|
return getGlobalStoreAPI$1();
|
|
1261
1359
|
}
|
|
1262
1360
|
function createStoreEnginePlugin(options = {}) {
|
|
1263
|
-
const { debug = false, dependencies = [], name = "store", version = "
|
|
1361
|
+
const { debug = false, dependencies = [], name = "store", version = "0.0.1" } = options;
|
|
1264
1362
|
let bridge = null;
|
|
1265
1363
|
const createBridge = () => {
|
|
1266
1364
|
const activeBridge = (0, _composy_store_core_engine.createStoreEngineBridge)({
|
|
@@ -1326,7 +1424,7 @@
|
|
|
1326
1424
|
}
|
|
1327
1425
|
//#endregion
|
|
1328
1426
|
//#region src/index.ts
|
|
1329
|
-
const version = "
|
|
1427
|
+
const version = "0.0.1";
|
|
1330
1428
|
const name = "@composy/store-vue";
|
|
1331
1429
|
//#endregion
|
|
1332
1430
|
Object.defineProperty(exports, "batch", {
|