@composy/store-vue 0.0.1
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 +154 -0
- package/dist/index.js +1536 -0
- package/dist/index.js.map +1 -0
- package/dist/index.min.js +1008 -0
- package/dist/index.min.js.map +1 -0
- package/es/composables/defineSetupStore.d.ts +120 -0
- package/es/composables/defineSetupStore.d.ts.map +1 -0
- package/es/composables/defineSetupStore.js +29 -0
- package/es/composables/defineSetupStore.js.map +1 -0
- package/es/composables/index.d.ts +24 -0
- package/es/composables/index.d.ts.map +1 -0
- package/es/composables/index.js +21 -0
- package/es/composables/useFormStore.d.ts +131 -0
- package/es/composables/useFormStore.d.ts.map +1 -0
- package/es/composables/useFormStore.js +189 -0
- package/es/composables/useFormStore.js.map +1 -0
- package/es/composables/useOptimistic.d.ts +67 -0
- package/es/composables/useOptimistic.d.ts.map +1 -0
- package/es/composables/useOptimistic.js +64 -0
- package/es/composables/useOptimistic.js.map +1 -0
- package/es/composables/usePersist.d.ts +68 -0
- package/es/composables/usePersist.d.ts.map +1 -0
- package/es/composables/usePersist.js +96 -0
- package/es/composables/usePersist.js.map +1 -0
- package/es/composables/usePersistedState.d.ts +59 -0
- package/es/composables/usePersistedState.d.ts.map +1 -0
- package/es/composables/usePersistedState.js +121 -0
- package/es/composables/usePersistedState.js.map +1 -0
- package/es/composables/useSharedState.d.ts +62 -0
- package/es/composables/useSharedState.d.ts.map +1 -0
- package/es/composables/useSharedState.js +94 -0
- package/es/composables/useSharedState.js.map +1 -0
- package/es/composables/useStore.d.ts +99 -0
- package/es/composables/useStore.d.ts.map +1 -0
- package/es/composables/useStore.js +61 -0
- package/es/composables/useStore.js.map +1 -0
- package/es/composables/useStoreDevtools.d.ts +31 -0
- package/es/composables/useStoreDevtools.d.ts.map +1 -0
- package/es/composables/useStoreDevtools.js +112 -0
- package/es/composables/useStoreDevtools.js.map +1 -0
- package/es/composables/useStoreSnapshot.d.ts +122 -0
- package/es/composables/useStoreSnapshot.d.ts.map +1 -0
- package/es/composables/useStoreSnapshot.js +209 -0
- package/es/composables/useStoreSnapshot.js.map +1 -0
- package/es/composables/useSubscribe.d.ts +90 -0
- package/es/composables/useSubscribe.d.ts.map +1 -0
- package/es/composables/useSubscribe.js +53 -0
- package/es/composables/useSubscribe.js.map +1 -0
- package/es/context/injection-keys.d.ts +8 -0
- package/es/context/injection-keys.d.ts.map +1 -0
- package/es/context/injection-keys.js +17 -0
- package/es/context/injection-keys.js.map +1 -0
- package/es/index.d.ts +24 -0
- package/es/index.d.ts.map +1 -0
- package/es/index.js +32 -0
- package/es/index.js.map +1 -0
- package/es/plugins/engine-plugin.d.ts +36 -0
- package/es/plugins/engine-plugin.d.ts.map +1 -0
- package/es/plugins/engine-plugin.js +83 -0
- package/es/plugins/engine-plugin.js.map +1 -0
- package/es/plugins/enhanced-persist-plugin.d.ts +3 -0
- package/es/plugins/enhanced-persist-plugin.d.ts.map +1 -0
- package/es/plugins/enhanced-persist-plugin.js +12 -0
- package/es/plugins/index.d.ts +7 -0
- package/es/plugins/index.d.ts.map +1 -0
- package/es/plugins/index.js +15 -0
- package/es/plugins/pinia-plugin.d.ts +68 -0
- package/es/plugins/pinia-plugin.d.ts.map +1 -0
- package/es/plugins/pinia-plugin.js +172 -0
- package/es/plugins/pinia-plugin.js.map +1 -0
- package/es/plugins/registry-plugin.d.ts +2 -0
- package/es/plugins/registry-plugin.d.ts.map +1 -0
- package/es/plugins/registry-plugin.js +12 -0
- package/es/plugins/vue-plugin.d.ts +10 -0
- package/es/plugins/vue-plugin.d.ts.map +1 -0
- package/es/plugins/vue-plugin.js +24 -0
- package/es/plugins/vue-plugin.js.map +1 -0
- package/es/runtime/install-store-app.d.ts +23 -0
- package/es/runtime/install-store-app.d.ts.map +1 -0
- package/es/runtime/install-store-app.js +54 -0
- package/es/runtime/install-store-app.js.map +1 -0
- package/es/runtime/store-plugin-options.d.ts +40 -0
- package/es/runtime/store-plugin-options.d.ts.map +1 -0
- package/es/runtime/store-plugin-options.js +24 -0
- package/es/runtime/store-plugin-options.js.map +1 -0
- package/es/runtime/store-registry.d.ts +64 -0
- package/es/runtime/store-registry.d.ts.map +1 -0
- package/es/runtime/store-registry.js +102 -0
- package/es/runtime/store-registry.js.map +1 -0
- package/es/runtime/store-runtime.d.ts +46 -0
- package/es/runtime/store-runtime.d.ts.map +1 -0
- package/es/runtime/store-runtime.js +58 -0
- package/es/runtime/store-runtime.js.map +1 -0
- package/es/types.d.ts +167 -0
- package/es/types.d.ts.map +1 -0
- package/es/types.js +10 -0
- package/esm/composables/defineSetupStore.d.ts +120 -0
- package/esm/composables/defineSetupStore.d.ts.map +1 -0
- package/esm/composables/defineSetupStore.js +29 -0
- package/esm/composables/defineSetupStore.js.map +1 -0
- package/esm/composables/index.d.ts +24 -0
- package/esm/composables/index.d.ts.map +1 -0
- package/esm/composables/index.js +21 -0
- package/esm/composables/useFormStore.d.ts +131 -0
- package/esm/composables/useFormStore.d.ts.map +1 -0
- package/esm/composables/useFormStore.js +189 -0
- package/esm/composables/useFormStore.js.map +1 -0
- package/esm/composables/useOptimistic.d.ts +67 -0
- package/esm/composables/useOptimistic.d.ts.map +1 -0
- package/esm/composables/useOptimistic.js +64 -0
- package/esm/composables/useOptimistic.js.map +1 -0
- package/esm/composables/usePersist.d.ts +68 -0
- package/esm/composables/usePersist.d.ts.map +1 -0
- package/esm/composables/usePersist.js +96 -0
- package/esm/composables/usePersist.js.map +1 -0
- package/esm/composables/usePersistedState.d.ts +59 -0
- package/esm/composables/usePersistedState.d.ts.map +1 -0
- package/esm/composables/usePersistedState.js +121 -0
- package/esm/composables/usePersistedState.js.map +1 -0
- package/esm/composables/useSharedState.d.ts +62 -0
- package/esm/composables/useSharedState.d.ts.map +1 -0
- package/esm/composables/useSharedState.js +94 -0
- package/esm/composables/useSharedState.js.map +1 -0
- package/esm/composables/useStore.d.ts +99 -0
- package/esm/composables/useStore.d.ts.map +1 -0
- package/esm/composables/useStore.js +61 -0
- package/esm/composables/useStore.js.map +1 -0
- package/esm/composables/useStoreDevtools.d.ts +31 -0
- package/esm/composables/useStoreDevtools.d.ts.map +1 -0
- package/esm/composables/useStoreDevtools.js +112 -0
- package/esm/composables/useStoreDevtools.js.map +1 -0
- package/esm/composables/useStoreSnapshot.d.ts +122 -0
- package/esm/composables/useStoreSnapshot.d.ts.map +1 -0
- package/esm/composables/useStoreSnapshot.js +209 -0
- package/esm/composables/useStoreSnapshot.js.map +1 -0
- package/esm/composables/useSubscribe.d.ts +90 -0
- package/esm/composables/useSubscribe.d.ts.map +1 -0
- package/esm/composables/useSubscribe.js +53 -0
- package/esm/composables/useSubscribe.js.map +1 -0
- package/esm/context/injection-keys.d.ts +8 -0
- package/esm/context/injection-keys.d.ts.map +1 -0
- package/esm/context/injection-keys.js +17 -0
- package/esm/context/injection-keys.js.map +1 -0
- package/esm/index.d.ts +24 -0
- package/esm/index.d.ts.map +1 -0
- package/esm/index.js +34 -0
- package/esm/index.js.map +1 -0
- package/esm/plugins/engine-plugin.d.ts +36 -0
- package/esm/plugins/engine-plugin.d.ts.map +1 -0
- package/esm/plugins/engine-plugin.js +83 -0
- package/esm/plugins/engine-plugin.js.map +1 -0
- package/esm/plugins/enhanced-persist-plugin.d.ts +3 -0
- package/esm/plugins/enhanced-persist-plugin.d.ts.map +1 -0
- package/esm/plugins/enhanced-persist-plugin.js +12 -0
- package/esm/plugins/index.d.ts +7 -0
- package/esm/plugins/index.d.ts.map +1 -0
- package/esm/plugins/index.js +16 -0
- package/esm/plugins/pinia-plugin.d.ts +68 -0
- package/esm/plugins/pinia-plugin.d.ts.map +1 -0
- package/esm/plugins/pinia-plugin.js +172 -0
- package/esm/plugins/pinia-plugin.js.map +1 -0
- package/esm/plugins/registry-plugin.d.ts +2 -0
- package/esm/plugins/registry-plugin.d.ts.map +1 -0
- package/esm/plugins/registry-plugin.js +12 -0
- package/esm/plugins/vue-plugin.d.ts +10 -0
- package/esm/plugins/vue-plugin.d.ts.map +1 -0
- package/esm/plugins/vue-plugin.js +24 -0
- package/esm/plugins/vue-plugin.js.map +1 -0
- package/esm/runtime/install-store-app.d.ts +23 -0
- package/esm/runtime/install-store-app.d.ts.map +1 -0
- package/esm/runtime/install-store-app.js +54 -0
- package/esm/runtime/install-store-app.js.map +1 -0
- package/esm/runtime/store-plugin-options.d.ts +40 -0
- package/esm/runtime/store-plugin-options.d.ts.map +1 -0
- package/esm/runtime/store-plugin-options.js +24 -0
- package/esm/runtime/store-plugin-options.js.map +1 -0
- package/esm/runtime/store-registry.d.ts +64 -0
- package/esm/runtime/store-registry.d.ts.map +1 -0
- package/esm/runtime/store-registry.js +94 -0
- package/esm/runtime/store-registry.js.map +1 -0
- package/esm/runtime/store-runtime.d.ts +46 -0
- package/esm/runtime/store-runtime.d.ts.map +1 -0
- package/esm/runtime/store-runtime.js +58 -0
- package/esm/runtime/store-runtime.js.map +1 -0
- package/esm/types.d.ts +167 -0
- package/esm/types.d.ts.map +1 -0
- package/esm/types.js +10 -0
- package/lib/composables/defineSetupStore.cjs +33 -0
- package/lib/composables/defineSetupStore.cjs.map +1 -0
- package/lib/composables/defineSetupStore.d.ts +120 -0
- package/lib/composables/index.cjs +46 -0
- package/lib/composables/index.d.ts +24 -0
- package/lib/composables/useFormStore.cjs +197 -0
- package/lib/composables/useFormStore.cjs.map +1 -0
- package/lib/composables/useFormStore.d.ts +131 -0
- package/lib/composables/useOptimistic.cjs +66 -0
- package/lib/composables/useOptimistic.cjs.map +1 -0
- package/lib/composables/useOptimistic.d.ts +67 -0
- package/lib/composables/usePersist.cjs +100 -0
- package/lib/composables/usePersist.cjs.map +1 -0
- package/lib/composables/usePersist.d.ts +68 -0
- package/lib/composables/usePersistedState.cjs +123 -0
- package/lib/composables/usePersistedState.cjs.map +1 -0
- package/lib/composables/usePersistedState.d.ts +59 -0
- package/lib/composables/useSharedState.cjs +96 -0
- package/lib/composables/useSharedState.cjs.map +1 -0
- package/lib/composables/useSharedState.d.ts +62 -0
- package/lib/composables/useStore.cjs +65 -0
- package/lib/composables/useStore.cjs.map +1 -0
- package/lib/composables/useStore.d.ts +99 -0
- package/lib/composables/useStoreDevtools.cjs +114 -0
- package/lib/composables/useStoreDevtools.cjs.map +1 -0
- package/lib/composables/useStoreDevtools.d.ts +31 -0
- package/lib/composables/useStoreSnapshot.cjs +211 -0
- package/lib/composables/useStoreSnapshot.cjs.map +1 -0
- package/lib/composables/useStoreSnapshot.d.ts +122 -0
- package/lib/composables/useSubscribe.cjs +57 -0
- package/lib/composables/useSubscribe.cjs.map +1 -0
- package/lib/composables/useSubscribe.d.ts +90 -0
- package/lib/context/injection-keys.cjs +21 -0
- package/lib/context/injection-keys.cjs.map +1 -0
- package/lib/context/injection-keys.d.ts +8 -0
- package/lib/index.cjs +235 -0
- package/lib/index.cjs.map +1 -0
- package/lib/index.d.ts +24 -0
- package/lib/package.json +3 -0
- package/lib/plugins/engine-plugin.cjs +90 -0
- package/lib/plugins/engine-plugin.cjs.map +1 -0
- package/lib/plugins/engine-plugin.d.ts +36 -0
- package/lib/plugins/enhanced-persist-plugin.cjs +15 -0
- package/lib/plugins/enhanced-persist-plugin.d.ts +3 -0
- package/lib/plugins/index.cjs +28 -0
- package/lib/plugins/index.d.ts +7 -0
- package/lib/plugins/pinia-plugin.cjs +177 -0
- package/lib/plugins/pinia-plugin.cjs.map +1 -0
- package/lib/plugins/pinia-plugin.d.ts +68 -0
- package/lib/plugins/registry-plugin.cjs +18 -0
- package/lib/plugins/registry-plugin.d.ts +2 -0
- package/lib/plugins/vue-plugin.cjs +26 -0
- package/lib/plugins/vue-plugin.cjs.map +1 -0
- package/lib/plugins/vue-plugin.d.ts +10 -0
- package/lib/runtime/install-store-app.cjs +57 -0
- package/lib/runtime/install-store-app.cjs.map +1 -0
- package/lib/runtime/install-store-app.d.ts +23 -0
- package/lib/runtime/store-plugin-options.cjs +26 -0
- package/lib/runtime/store-plugin-options.cjs.map +1 -0
- package/lib/runtime/store-plugin-options.d.ts +40 -0
- package/lib/runtime/store-registry.cjs +108 -0
- package/lib/runtime/store-registry.cjs.map +1 -0
- package/lib/runtime/store-registry.d.ts +64 -0
- package/lib/runtime/store-runtime.cjs +62 -0
- package/lib/runtime/store-runtime.cjs.map +1 -0
- package/lib/runtime/store-runtime.d.ts +46 -0
- package/lib/types.cjs +12 -0
- package/lib/types.d.ts +167 -0
- package/package.json +115 -0
package/dist/index.js
ADDED
|
@@ -0,0 +1,1536 @@
|
|
|
1
|
+
/*!
|
|
2
|
+
* ***********************************
|
|
3
|
+
* @composy/store-vue v0.0.1 *
|
|
4
|
+
* Built with rollup *
|
|
5
|
+
* Build time: 2024-08-17 11:39:29 *
|
|
6
|
+
* Build mode: production *
|
|
7
|
+
* Minified: No *
|
|
8
|
+
* ***********************************
|
|
9
|
+
*/
|
|
10
|
+
"use strict";
|
|
11
|
+
(function(global, factory) {
|
|
12
|
+
typeof exports === "object" && typeof module !== "undefined" ? factory(exports, require("pinia"), require("vue"), require("@composy/store-core"), require("@composy/store-core/engine")) : typeof define === "function" && define.amd ? define([
|
|
13
|
+
"exports",
|
|
14
|
+
"pinia",
|
|
15
|
+
"vue",
|
|
16
|
+
"@composy/store-core",
|
|
17
|
+
"@composy/store-core/engine"
|
|
18
|
+
], factory) : (global = typeof globalThis !== "undefined" ? globalThis : global || self, factory(global.LDesignStoreVue = {}, global.Pinia, global.Vue, global.ComposyStoreCore, global.ComposyStoreCore));
|
|
19
|
+
})(this, function(exports, pinia, vue, _composy_store_core, _composy_store_core_engine) {
|
|
20
|
+
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
21
|
+
//#region src/composables/defineSetupStore.ts
|
|
22
|
+
function defineSetupStore(id, setup) {
|
|
23
|
+
return (0, pinia.defineStore)(id, setup);
|
|
24
|
+
}
|
|
25
|
+
function createStoreState(initial) {
|
|
26
|
+
const result = {};
|
|
27
|
+
for (const key of Object.keys(initial)) result[key] = (0, vue.ref)(initial[key]);
|
|
28
|
+
return result;
|
|
29
|
+
}
|
|
30
|
+
function createStoreGetters(getters) {
|
|
31
|
+
const result = {};
|
|
32
|
+
for (const key of Object.keys(getters)) result[key] = (0, vue.computed)(getters[key]);
|
|
33
|
+
return result;
|
|
34
|
+
}
|
|
35
|
+
//#endregion
|
|
36
|
+
//#region src/composables/useFormStore.ts
|
|
37
|
+
const DEFAULT_REQUIRED_MESSAGE = "此字段为必填项";
|
|
38
|
+
const DEFAULT_PATTERN_MESSAGE = "格式不正确";
|
|
39
|
+
const DEFAULT_EMAIL_MESSAGE = "邮箱格式不正确";
|
|
40
|
+
const EMAIL_PATTERN = /^[^\s@]+@[^@][^.@]*\.[^\s@]+$/;
|
|
41
|
+
function useFormStore(options) {
|
|
42
|
+
const { initialValues, validationRules = {}, onSubmit, validateOn = "blur" } = options;
|
|
43
|
+
const storedInitialValues = (0, _composy_store_core.deepClone)(initialValues);
|
|
44
|
+
const values = (0, vue.reactive)((0, _composy_store_core.deepClone)(storedInitialValues));
|
|
45
|
+
const valueRecord = values;
|
|
46
|
+
const initialValueRecord = storedInitialValues;
|
|
47
|
+
const fieldKeys = Object.keys(storedInitialValues);
|
|
48
|
+
const fields = (0, vue.reactive)(fieldKeys.reduce((acc, key) => {
|
|
49
|
+
acc[key] = {
|
|
50
|
+
touched: false,
|
|
51
|
+
dirty: false,
|
|
52
|
+
error: null,
|
|
53
|
+
validating: false
|
|
54
|
+
};
|
|
55
|
+
return acc;
|
|
56
|
+
}, {}));
|
|
57
|
+
const isSubmitting = (0, vue.ref)(false);
|
|
58
|
+
const submitError = (0, vue.ref)(null);
|
|
59
|
+
const submitCount = (0, vue.ref)(0);
|
|
60
|
+
const isDirty = (0, vue.computed)(() => fieldKeys.some((key) => fields[key]?.dirty));
|
|
61
|
+
const isValid = (0, vue.computed)(() => fieldKeys.every((key) => !fields[key]?.error));
|
|
62
|
+
const errors = (0, vue.computed)(() => {
|
|
63
|
+
return fieldKeys.reduce((acc, key) => {
|
|
64
|
+
acc[key] = fields[key]?.error ?? null;
|
|
65
|
+
return acc;
|
|
66
|
+
}, {});
|
|
67
|
+
});
|
|
68
|
+
fieldKeys.forEach((key) => {
|
|
69
|
+
(0, vue.watch)(() => valueRecord[key], (newValue) => {
|
|
70
|
+
const field = fields[key];
|
|
71
|
+
if (field) field.dirty = !(0, _composy_store_core.deepEqual)(newValue, initialValueRecord[key]);
|
|
72
|
+
if (validateOn === "change" && field?.touched) validateField(key);
|
|
73
|
+
}, { deep: true });
|
|
74
|
+
});
|
|
75
|
+
function setFieldValue(field, value) {
|
|
76
|
+
valueRecord[field] = value;
|
|
77
|
+
}
|
|
78
|
+
function setFieldTouched(field) {
|
|
79
|
+
const fieldState = fields[field];
|
|
80
|
+
if (fieldState) fieldState.touched = true;
|
|
81
|
+
if (validateOn === "blur") validateField(field);
|
|
82
|
+
}
|
|
83
|
+
async function validateField(field) {
|
|
84
|
+
const fieldState = fields[field];
|
|
85
|
+
if (!fieldState) return null;
|
|
86
|
+
const fieldRules = validationRules[field];
|
|
87
|
+
if (!fieldRules) {
|
|
88
|
+
fieldState.error = null;
|
|
89
|
+
return null;
|
|
90
|
+
}
|
|
91
|
+
fieldState.validating = true;
|
|
92
|
+
try {
|
|
93
|
+
const value = values[field];
|
|
94
|
+
if (fieldRules.required) {
|
|
95
|
+
if (value === "" || value === null || value === void 0) {
|
|
96
|
+
const message = typeof fieldRules.required === "string" ? fieldRules.required : DEFAULT_REQUIRED_MESSAGE;
|
|
97
|
+
fieldState.error = message;
|
|
98
|
+
return message;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
if (fieldRules.rules) for (const rule of fieldRules.rules) {
|
|
102
|
+
const error = await rule(value, valueRecord);
|
|
103
|
+
if (error) {
|
|
104
|
+
fieldState.error = error;
|
|
105
|
+
return error;
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
fieldState.error = null;
|
|
109
|
+
return null;
|
|
110
|
+
} finally {
|
|
111
|
+
fieldState.validating = false;
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
async function validateAll() {
|
|
115
|
+
return (await Promise.all(fieldKeys.map((key) => validateField(key)))).every((result) => result === null);
|
|
116
|
+
}
|
|
117
|
+
async function handleSubmit() {
|
|
118
|
+
submitCount.value++;
|
|
119
|
+
submitError.value = null;
|
|
120
|
+
fieldKeys.forEach((key) => {
|
|
121
|
+
const field = fields[key];
|
|
122
|
+
if (field) field.touched = true;
|
|
123
|
+
});
|
|
124
|
+
if (!await validateAll() || !onSubmit) return;
|
|
125
|
+
isSubmitting.value = true;
|
|
126
|
+
try {
|
|
127
|
+
await onSubmit((0, _composy_store_core.deepClone)(values));
|
|
128
|
+
} catch (error) {
|
|
129
|
+
submitError.value = error instanceof Error ? error.message : String(error);
|
|
130
|
+
} finally {
|
|
131
|
+
isSubmitting.value = false;
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
function reset(newInitialValues) {
|
|
135
|
+
if (newInitialValues) Object.assign(initialValueRecord, (0, _composy_store_core.deepClone)(newInitialValues));
|
|
136
|
+
fieldKeys.forEach((key) => {
|
|
137
|
+
valueRecord[key] = (0, _composy_store_core.deepClone)(initialValueRecord[key]);
|
|
138
|
+
const field = fields[key];
|
|
139
|
+
if (field) {
|
|
140
|
+
field.touched = false;
|
|
141
|
+
field.dirty = false;
|
|
142
|
+
field.error = null;
|
|
143
|
+
field.validating = false;
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
submitError.value = null;
|
|
147
|
+
}
|
|
148
|
+
function resetField(field) {
|
|
149
|
+
const fieldKey = field;
|
|
150
|
+
valueRecord[fieldKey] = (0, _composy_store_core.deepClone)(initialValueRecord[fieldKey]);
|
|
151
|
+
const fieldState = fields[fieldKey];
|
|
152
|
+
if (fieldState) {
|
|
153
|
+
fieldState.touched = false;
|
|
154
|
+
fieldState.dirty = false;
|
|
155
|
+
fieldState.error = null;
|
|
156
|
+
fieldState.validating = false;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
return {
|
|
160
|
+
values,
|
|
161
|
+
fields,
|
|
162
|
+
isDirty,
|
|
163
|
+
isValid,
|
|
164
|
+
isSubmitting,
|
|
165
|
+
submitError,
|
|
166
|
+
submitCount,
|
|
167
|
+
setFieldValue,
|
|
168
|
+
setFieldTouched,
|
|
169
|
+
validateField,
|
|
170
|
+
validateAll,
|
|
171
|
+
handleSubmit,
|
|
172
|
+
reset,
|
|
173
|
+
resetField,
|
|
174
|
+
errors
|
|
175
|
+
};
|
|
176
|
+
}
|
|
177
|
+
function required(message = DEFAULT_REQUIRED_MESSAGE) {
|
|
178
|
+
return (value) => {
|
|
179
|
+
if (value === "" || value === null || value === void 0) return message;
|
|
180
|
+
return null;
|
|
181
|
+
};
|
|
182
|
+
}
|
|
183
|
+
function minLength(min, message) {
|
|
184
|
+
return (value) => {
|
|
185
|
+
if (typeof value === "string" && value.length < min) return message ?? `\u81F3\u5C11\u9700\u8981 ${min} \u4E2A\u5B57\u7B26`;
|
|
186
|
+
return null;
|
|
187
|
+
};
|
|
188
|
+
}
|
|
189
|
+
function maxLength(max, message) {
|
|
190
|
+
return (value) => {
|
|
191
|
+
if (typeof value === "string" && value.length > max) return message ?? `\u4E0D\u80FD\u8D85\u8FC7 ${max} \u4E2A\u5B57\u7B26`;
|
|
192
|
+
return null;
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
function pattern(regex, message = DEFAULT_PATTERN_MESSAGE) {
|
|
196
|
+
return (value) => {
|
|
197
|
+
if (typeof value === "string" && !regex.test(value)) return message;
|
|
198
|
+
return null;
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function email(message = DEFAULT_EMAIL_MESSAGE) {
|
|
202
|
+
return pattern(EMAIL_PATTERN, message);
|
|
203
|
+
}
|
|
204
|
+
function numberRange(min, max, message) {
|
|
205
|
+
return (value) => {
|
|
206
|
+
if (typeof value === "number" && (value < min || value > max)) return message ?? `\u5FC5\u987B\u5728 ${min} \u5230 ${max} \u4E4B\u95F4`;
|
|
207
|
+
return null;
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
//#endregion
|
|
211
|
+
//#region src/composables/useOptimistic.ts
|
|
212
|
+
function uid() {
|
|
213
|
+
return `${Date.now()}-${Math.random().toString(36).slice(2, 8)}`;
|
|
214
|
+
}
|
|
215
|
+
function useOptimistic(initialState) {
|
|
216
|
+
const state = (0, vue.ref)((0, _composy_store_core.deepClone)(initialState));
|
|
217
|
+
const isPending = (0, vue.ref)(false);
|
|
218
|
+
const isRolledBack = (0, vue.ref)(false);
|
|
219
|
+
const pending = (0, vue.ref)([]);
|
|
220
|
+
async function mutate(optimisticValue, confirm) {
|
|
221
|
+
const snapshot = (0, _composy_store_core.deepClone)(state.value);
|
|
222
|
+
const entryId = uid();
|
|
223
|
+
const entry = {
|
|
224
|
+
id: entryId,
|
|
225
|
+
snapshot,
|
|
226
|
+
status: "pending",
|
|
227
|
+
timestamp: Date.now()
|
|
228
|
+
};
|
|
229
|
+
pending.value = [...pending.value, entry];
|
|
230
|
+
isPending.value = true;
|
|
231
|
+
isRolledBack.value = false;
|
|
232
|
+
if (typeof optimisticValue === "function") state.value = optimisticValue(state.value);
|
|
233
|
+
else state.value = optimisticValue;
|
|
234
|
+
try {
|
|
235
|
+
await confirm();
|
|
236
|
+
pending.value = pending.value.map((e) => e.id === entryId ? {
|
|
237
|
+
...e,
|
|
238
|
+
status: "confirmed"
|
|
239
|
+
} : e);
|
|
240
|
+
} catch {
|
|
241
|
+
state.value = snapshot;
|
|
242
|
+
isRolledBack.value = true;
|
|
243
|
+
pending.value = pending.value.map((e) => e.id === entryId ? {
|
|
244
|
+
...e,
|
|
245
|
+
status: "rolled-back"
|
|
246
|
+
} : e);
|
|
247
|
+
} finally {
|
|
248
|
+
pending.value = pending.value.filter((e) => e.status === "pending");
|
|
249
|
+
isPending.value = pending.value.length > 0;
|
|
250
|
+
}
|
|
251
|
+
}
|
|
252
|
+
return {
|
|
253
|
+
state,
|
|
254
|
+
isPending,
|
|
255
|
+
pending,
|
|
256
|
+
isRolledBack,
|
|
257
|
+
mutate
|
|
258
|
+
};
|
|
259
|
+
}
|
|
260
|
+
//#endregion
|
|
261
|
+
//#region src/composables/usePersist.ts
|
|
262
|
+
function getStorage$2(type) {
|
|
263
|
+
if (typeof window === "undefined") return null;
|
|
264
|
+
return type === "localStorage" ? localStorage : sessionStorage;
|
|
265
|
+
}
|
|
266
|
+
function usePersist(options) {
|
|
267
|
+
const { key, storage: storageType = "localStorage", defaultValue, serialize = JSON.stringify, deserialize = JSON.parse } = options;
|
|
268
|
+
const storage = getStorage$2(storageType);
|
|
269
|
+
const value = (0, vue.ref)(defaultValue);
|
|
270
|
+
const restore = () => {
|
|
271
|
+
if (!storage) return;
|
|
272
|
+
try {
|
|
273
|
+
const stored = storage.getItem(key);
|
|
274
|
+
if (stored !== null) value.value = deserialize(stored);
|
|
275
|
+
} catch (error) {
|
|
276
|
+
console.error(`[usePersist] \u6062\u590D\u5931\u8D25 (${key}):`, error);
|
|
277
|
+
}
|
|
278
|
+
};
|
|
279
|
+
const save = () => {
|
|
280
|
+
if (!storage) return;
|
|
281
|
+
try {
|
|
282
|
+
storage.setItem(key, serialize(value.value));
|
|
283
|
+
} catch (error) {
|
|
284
|
+
console.error(`[usePersist] \u4FDD\u5B58\u5931\u8D25 (${key}):`, error);
|
|
285
|
+
}
|
|
286
|
+
};
|
|
287
|
+
const clear = () => {
|
|
288
|
+
if (!storage) return;
|
|
289
|
+
try {
|
|
290
|
+
storage.removeItem(key);
|
|
291
|
+
value.value = defaultValue;
|
|
292
|
+
} catch (error) {
|
|
293
|
+
console.error(`[usePersist] \u6E05\u9664\u5931\u8D25 (${key}):`, error);
|
|
294
|
+
}
|
|
295
|
+
};
|
|
296
|
+
(0, vue.onMounted)(() => {
|
|
297
|
+
restore();
|
|
298
|
+
});
|
|
299
|
+
(0, vue.watch)(value, () => {
|
|
300
|
+
save();
|
|
301
|
+
}, { deep: true });
|
|
302
|
+
return {
|
|
303
|
+
value,
|
|
304
|
+
save,
|
|
305
|
+
restore,
|
|
306
|
+
clear
|
|
307
|
+
};
|
|
308
|
+
}
|
|
309
|
+
function usePersistedRef(key, defaultValue, storage = "localStorage") {
|
|
310
|
+
const { value } = usePersist({
|
|
311
|
+
key,
|
|
312
|
+
storage,
|
|
313
|
+
defaultValue
|
|
314
|
+
});
|
|
315
|
+
return value;
|
|
316
|
+
}
|
|
317
|
+
function usePersistedRefWithTTL(key, defaultValue, ttl) {
|
|
318
|
+
const { value } = usePersist({
|
|
319
|
+
key,
|
|
320
|
+
defaultValue: {
|
|
321
|
+
value: defaultValue,
|
|
322
|
+
expiry: 0
|
|
323
|
+
},
|
|
324
|
+
serialize: (data) => JSON.stringify(data),
|
|
325
|
+
deserialize: (str) => {
|
|
326
|
+
const data = JSON.parse(str);
|
|
327
|
+
if (data.expiry && Date.now() > data.expiry) return {
|
|
328
|
+
value: defaultValue,
|
|
329
|
+
expiry: 0
|
|
330
|
+
};
|
|
331
|
+
return data;
|
|
332
|
+
}
|
|
333
|
+
});
|
|
334
|
+
const wrappedRef = (0, vue.ref)(value.value.value);
|
|
335
|
+
(0, vue.watch)(wrappedRef, (newValue) => {
|
|
336
|
+
value.value = {
|
|
337
|
+
value: newValue,
|
|
338
|
+
expiry: Date.now() + ttl
|
|
339
|
+
};
|
|
340
|
+
});
|
|
341
|
+
return wrappedRef;
|
|
342
|
+
}
|
|
343
|
+
//#endregion
|
|
344
|
+
//#region src/composables/usePersistedState.ts
|
|
345
|
+
function defaultSerializer(value) {
|
|
346
|
+
return JSON.stringify(value);
|
|
347
|
+
}
|
|
348
|
+
function defaultDeserializer(value) {
|
|
349
|
+
try {
|
|
350
|
+
return JSON.parse(value);
|
|
351
|
+
} catch {
|
|
352
|
+
return value;
|
|
353
|
+
}
|
|
354
|
+
}
|
|
355
|
+
function getStorage$1(type) {
|
|
356
|
+
if (typeof window === "undefined") return null;
|
|
357
|
+
return type === "localStorage" ? window.localStorage : window.sessionStorage;
|
|
358
|
+
}
|
|
359
|
+
function usePersistedState(options) {
|
|
360
|
+
const { key, storage: storageType = "localStorage", defaultValue, serializer = defaultSerializer, deserializer = defaultDeserializer, syncTabs = false, debounce: debounceDelay = 0, deep = true, ttl, onBeforeChange, onAfterChange, onBeforeRestore, onAfterRestore } = options;
|
|
361
|
+
const storage = getStorage$1(storageType);
|
|
362
|
+
const createDefaultValue = () => (0, _composy_store_core.deepClone)(defaultValue);
|
|
363
|
+
const state = (0, vue.ref)(createDefaultValue());
|
|
364
|
+
const save = () => {
|
|
365
|
+
if (!storage) return;
|
|
366
|
+
try {
|
|
367
|
+
const item = {
|
|
368
|
+
value: serializer(state.value),
|
|
369
|
+
timestamp: Date.now(),
|
|
370
|
+
expiresAt: ttl ? Date.now() + ttl : void 0
|
|
371
|
+
};
|
|
372
|
+
storage.setItem(key, JSON.stringify(item));
|
|
373
|
+
} catch (error) {
|
|
374
|
+
console.error(`[usePersistedState] \u4FDD\u5B58\u5931\u8D25 (${key}):`, error);
|
|
375
|
+
}
|
|
376
|
+
};
|
|
377
|
+
const clear = () => {
|
|
378
|
+
if (!storage) return;
|
|
379
|
+
try {
|
|
380
|
+
storage.removeItem(key);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
console.error(`[usePersistedState] \u6E05\u9664\u5931\u8D25 (${key}):`, error);
|
|
383
|
+
}
|
|
384
|
+
};
|
|
385
|
+
const restore = () => {
|
|
386
|
+
if (!storage) return;
|
|
387
|
+
try {
|
|
388
|
+
const stored = storage.getItem(key);
|
|
389
|
+
if (!stored) return;
|
|
390
|
+
const item = JSON.parse(stored);
|
|
391
|
+
if (item.expiresAt && Date.now() > item.expiresAt) {
|
|
392
|
+
clear();
|
|
393
|
+
return;
|
|
394
|
+
}
|
|
395
|
+
let value = deserializer(item.value);
|
|
396
|
+
if (onBeforeRestore) value = onBeforeRestore(value);
|
|
397
|
+
state.value = value;
|
|
398
|
+
onAfterRestore?.(value);
|
|
399
|
+
} catch (error) {
|
|
400
|
+
console.error(`[usePersistedState] \u6062\u590D\u5931\u8D25 (${key}):`, error);
|
|
401
|
+
}
|
|
402
|
+
};
|
|
403
|
+
const reset = () => {
|
|
404
|
+
state.value = createDefaultValue();
|
|
405
|
+
clear();
|
|
406
|
+
};
|
|
407
|
+
const isExpired = () => {
|
|
408
|
+
if (!storage || !ttl) return false;
|
|
409
|
+
try {
|
|
410
|
+
const stored = storage.getItem(key);
|
|
411
|
+
if (!stored) return false;
|
|
412
|
+
const item = JSON.parse(stored);
|
|
413
|
+
return item.expiresAt ? Date.now() > item.expiresAt : false;
|
|
414
|
+
} catch {
|
|
415
|
+
return false;
|
|
416
|
+
}
|
|
417
|
+
};
|
|
418
|
+
const debouncedSave = debounceDelay > 0 ? (0, _composy_store_core.debounce)(save, debounceDelay) : null;
|
|
419
|
+
const handleStorageEvent = (event) => {
|
|
420
|
+
if (event.key !== key || !event.newValue) return;
|
|
421
|
+
try {
|
|
422
|
+
const item = JSON.parse(event.newValue);
|
|
423
|
+
if (item.expiresAt && Date.now() > item.expiresAt) return;
|
|
424
|
+
state.value = deserializer(item.value);
|
|
425
|
+
} catch (error) {
|
|
426
|
+
console.error(`[usePersistedState] \u540C\u6B65\u5931\u8D25 (${key}):`, error);
|
|
427
|
+
}
|
|
428
|
+
};
|
|
429
|
+
restore();
|
|
430
|
+
(0, vue.watch)(state, (newValue, oldValue) => {
|
|
431
|
+
if (onBeforeChange?.(newValue, oldValue) === false) return;
|
|
432
|
+
if (debouncedSave) debouncedSave();
|
|
433
|
+
else save();
|
|
434
|
+
onAfterChange?.(newValue, oldValue);
|
|
435
|
+
}, { deep });
|
|
436
|
+
if (syncTabs && typeof window !== "undefined") window.addEventListener("storage", handleStorageEvent);
|
|
437
|
+
(0, vue.onUnmounted)(() => {
|
|
438
|
+
debouncedSave?.cancel();
|
|
439
|
+
if (syncTabs && typeof window !== "undefined") window.removeEventListener("storage", handleStorageEvent);
|
|
440
|
+
});
|
|
441
|
+
return {
|
|
442
|
+
state,
|
|
443
|
+
save,
|
|
444
|
+
restore,
|
|
445
|
+
clear,
|
|
446
|
+
reset,
|
|
447
|
+
isExpired
|
|
448
|
+
};
|
|
449
|
+
}
|
|
450
|
+
//#endregion
|
|
451
|
+
//#region src/composables/useSharedState.ts
|
|
452
|
+
function useSharedState(channelName, initialState, options = {}) {
|
|
453
|
+
const { immediate = false, deep = true } = options;
|
|
454
|
+
const state = (0, vue.ref)((0, _composy_store_core.deepClone)(initialState));
|
|
455
|
+
const peerCount = (0, vue.ref)(0);
|
|
456
|
+
const lastSyncAt = (0, vue.ref)(null);
|
|
457
|
+
let channel = null;
|
|
458
|
+
let isReceiving = false;
|
|
459
|
+
if (typeof BroadcastChannel === "undefined") {
|
|
460
|
+
console.warn("[useSharedState] BroadcastChannel not supported in this environment");
|
|
461
|
+
return {
|
|
462
|
+
state,
|
|
463
|
+
broadcast: () => {},
|
|
464
|
+
peerCount,
|
|
465
|
+
lastSyncAt,
|
|
466
|
+
close: () => {}
|
|
467
|
+
};
|
|
468
|
+
}
|
|
469
|
+
try {
|
|
470
|
+
channel = new BroadcastChannel(channelName);
|
|
471
|
+
} catch (e) {
|
|
472
|
+
console.warn("[useSharedState] Failed to create BroadcastChannel:", e);
|
|
473
|
+
return {
|
|
474
|
+
state,
|
|
475
|
+
broadcast: () => {},
|
|
476
|
+
peerCount,
|
|
477
|
+
lastSyncAt,
|
|
478
|
+
close: () => {}
|
|
479
|
+
};
|
|
480
|
+
}
|
|
481
|
+
function broadcast() {
|
|
482
|
+
if (!channel) return;
|
|
483
|
+
try {
|
|
484
|
+
channel.postMessage({
|
|
485
|
+
type: "state-update",
|
|
486
|
+
payload: (0, _composy_store_core.deepClone)(state.value),
|
|
487
|
+
timestamp: Date.now()
|
|
488
|
+
});
|
|
489
|
+
} catch (e) {
|
|
490
|
+
console.warn("[useSharedState] broadcast error:", e);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
channel.onmessage = (event) => {
|
|
494
|
+
const msg = event.data;
|
|
495
|
+
if (!msg || typeof msg !== "object") return;
|
|
496
|
+
if (msg.type === "state-update") {
|
|
497
|
+
isReceiving = true;
|
|
498
|
+
state.value = msg.payload;
|
|
499
|
+
lastSyncAt.value = msg.timestamp || Date.now();
|
|
500
|
+
isReceiving = false;
|
|
501
|
+
} else if (msg.type === "ping") channel?.postMessage({ type: "pong" });
|
|
502
|
+
else if (msg.type === "pong") peerCount.value++;
|
|
503
|
+
};
|
|
504
|
+
const stopWatch = (0, vue.watch)(state, () => {
|
|
505
|
+
if (!isReceiving) broadcast();
|
|
506
|
+
}, { deep });
|
|
507
|
+
function close() {
|
|
508
|
+
stopWatch();
|
|
509
|
+
if (channel) {
|
|
510
|
+
channel.close();
|
|
511
|
+
channel = null;
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
if (immediate) broadcast();
|
|
515
|
+
if (channel) {
|
|
516
|
+
peerCount.value = 0;
|
|
517
|
+
channel.postMessage({ type: "ping" });
|
|
518
|
+
}
|
|
519
|
+
(0, vue.onUnmounted)(() => {
|
|
520
|
+
close();
|
|
521
|
+
});
|
|
522
|
+
return {
|
|
523
|
+
state,
|
|
524
|
+
broadcast,
|
|
525
|
+
peerCount,
|
|
526
|
+
lastSyncAt,
|
|
527
|
+
close
|
|
528
|
+
};
|
|
529
|
+
}
|
|
530
|
+
//#endregion
|
|
531
|
+
//#region src/composables/useStore.ts
|
|
532
|
+
function useStore(useStoreHook, _options = {}) {
|
|
533
|
+
const store = useStoreHook();
|
|
534
|
+
const refs = (0, pinia.storeToRefs)(store);
|
|
535
|
+
const reset = () => {
|
|
536
|
+
if ("$reset" in store && typeof store.$reset === "function") store.$reset();
|
|
537
|
+
};
|
|
538
|
+
const patch = (partial) => {
|
|
539
|
+
if ("$patch" in store && typeof store.$patch === "function") store.$patch(partial);
|
|
540
|
+
};
|
|
541
|
+
return {
|
|
542
|
+
store,
|
|
543
|
+
refs,
|
|
544
|
+
reset,
|
|
545
|
+
patch
|
|
546
|
+
};
|
|
547
|
+
}
|
|
548
|
+
function useSimpleStore(initialState) {
|
|
549
|
+
const state = (0, vue.ref)({ ...initialState });
|
|
550
|
+
const initialStateCopy = { ...initialState };
|
|
551
|
+
const setState = (partial) => {
|
|
552
|
+
Object.assign(state.value, partial);
|
|
553
|
+
};
|
|
554
|
+
const reset = () => {
|
|
555
|
+
state.value = { ...initialStateCopy };
|
|
556
|
+
};
|
|
557
|
+
const subscribe = (callback) => {
|
|
558
|
+
return (0, vue.watch)(state, (newState) => {
|
|
559
|
+
callback(newState);
|
|
560
|
+
}, { deep: true });
|
|
561
|
+
};
|
|
562
|
+
return {
|
|
563
|
+
state,
|
|
564
|
+
setState,
|
|
565
|
+
reset,
|
|
566
|
+
subscribe
|
|
567
|
+
};
|
|
568
|
+
}
|
|
569
|
+
function useComputedStore(state, getters) {
|
|
570
|
+
const computedGetters = {};
|
|
571
|
+
for (const key in getters) computedGetters[key] = (0, vue.computed)(() => getters[key](state.value));
|
|
572
|
+
return {
|
|
573
|
+
state,
|
|
574
|
+
getters: computedGetters
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
//#endregion
|
|
578
|
+
//#region src/composables/useStoreDevtools.ts
|
|
579
|
+
const STORE_REFRESH_EVENTS = /* @__PURE__ */ new Set([
|
|
580
|
+
"store:created",
|
|
581
|
+
"store:disposed",
|
|
582
|
+
"state:changed"
|
|
583
|
+
]);
|
|
584
|
+
function formatTime(timestamp) {
|
|
585
|
+
const date = new Date(timestamp);
|
|
586
|
+
return `${date.getHours().toString().padStart(2, "0")}:${date.getMinutes().toString().padStart(2, "0")}:${date.getSeconds().toString().padStart(2, "0")}.${date.getMilliseconds().toString().padStart(3, "0")}`;
|
|
587
|
+
}
|
|
588
|
+
function getPinia() {
|
|
589
|
+
return (0, pinia.getActivePinia)() ?? null;
|
|
590
|
+
}
|
|
591
|
+
function snapshotStore(store, id) {
|
|
592
|
+
return {
|
|
593
|
+
id,
|
|
594
|
+
state: (0, _composy_store_core.deepClone)(store.$state),
|
|
595
|
+
active: true
|
|
596
|
+
};
|
|
597
|
+
}
|
|
598
|
+
function useStoreDevtools(options = {}) {
|
|
599
|
+
const { maxLogEntries = 200 } = options;
|
|
600
|
+
const stores = (0, vue.ref)([]);
|
|
601
|
+
const eventLog = (0, vue.ref)([]);
|
|
602
|
+
const isMonitoring = (0, vue.ref)(false);
|
|
603
|
+
let unsubscribe = null;
|
|
604
|
+
function refreshStores() {
|
|
605
|
+
const pinia$2 = getPinia();
|
|
606
|
+
if (!pinia$2?._s) {
|
|
607
|
+
stores.value = [];
|
|
608
|
+
return;
|
|
609
|
+
}
|
|
610
|
+
stores.value = Array.from(pinia$2._s.entries(), ([id, store]) => {
|
|
611
|
+
return snapshotStore(store, id);
|
|
612
|
+
});
|
|
613
|
+
}
|
|
614
|
+
function startMonitoring() {
|
|
615
|
+
if (isMonitoring.value) return;
|
|
616
|
+
isMonitoring.value = true;
|
|
617
|
+
unsubscribe = _composy_store_core.globalEventBus.on("*", (data) => {
|
|
618
|
+
const entry = {
|
|
619
|
+
type: data.type,
|
|
620
|
+
payload: data.payload,
|
|
621
|
+
timestamp: data.timestamp,
|
|
622
|
+
time: formatTime(data.timestamp)
|
|
623
|
+
};
|
|
624
|
+
eventLog.value = [entry, ...eventLog.value].slice(0, maxLogEntries);
|
|
625
|
+
if (STORE_REFRESH_EVENTS.has(data.type)) refreshStores();
|
|
626
|
+
});
|
|
627
|
+
}
|
|
628
|
+
function stopMonitoring() {
|
|
629
|
+
if (!isMonitoring.value) return;
|
|
630
|
+
isMonitoring.value = false;
|
|
631
|
+
unsubscribe?.();
|
|
632
|
+
unsubscribe = null;
|
|
633
|
+
}
|
|
634
|
+
function clearLog() {
|
|
635
|
+
eventLog.value = [];
|
|
636
|
+
}
|
|
637
|
+
function getStoreState(id) {
|
|
638
|
+
const store = getPinia()?._s?.get(id);
|
|
639
|
+
if (!store) return null;
|
|
640
|
+
return (0, _composy_store_core.deepClone)(store.$state);
|
|
641
|
+
}
|
|
642
|
+
function resetStore(id) {
|
|
643
|
+
const store = getPinia()?._s?.get(id);
|
|
644
|
+
if (!store || typeof store.$reset !== "function") return false;
|
|
645
|
+
store.$reset();
|
|
646
|
+
refreshStores();
|
|
647
|
+
return true;
|
|
648
|
+
}
|
|
649
|
+
function resetAllStores() {
|
|
650
|
+
const pinia$3 = getPinia();
|
|
651
|
+
if (!pinia$3?._s) return;
|
|
652
|
+
pinia$3._s.forEach((store) => {
|
|
653
|
+
if (typeof store.$reset === "function") store.$reset();
|
|
654
|
+
});
|
|
655
|
+
refreshStores();
|
|
656
|
+
}
|
|
657
|
+
refreshStores();
|
|
658
|
+
(0, vue.onUnmounted)(() => {
|
|
659
|
+
stopMonitoring();
|
|
660
|
+
});
|
|
661
|
+
return {
|
|
662
|
+
stores,
|
|
663
|
+
eventLog,
|
|
664
|
+
isMonitoring,
|
|
665
|
+
startMonitoring,
|
|
666
|
+
stopMonitoring,
|
|
667
|
+
clearLog,
|
|
668
|
+
refreshStores,
|
|
669
|
+
getStoreState,
|
|
670
|
+
resetStore,
|
|
671
|
+
resetAllStores
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
//#endregion
|
|
675
|
+
//#region src/composables/useStoreSnapshot.ts
|
|
676
|
+
function generateId() {
|
|
677
|
+
return `${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
|
|
678
|
+
}
|
|
679
|
+
function computeDiff(oldObj, newObj, path = "") {
|
|
680
|
+
const diffs = [];
|
|
681
|
+
if (typeof oldObj !== typeof newObj) {
|
|
682
|
+
diffs.push({
|
|
683
|
+
path: path || ".",
|
|
684
|
+
oldValue: oldObj,
|
|
685
|
+
newValue: newObj,
|
|
686
|
+
type: "change"
|
|
687
|
+
});
|
|
688
|
+
return diffs;
|
|
689
|
+
}
|
|
690
|
+
if (typeof oldObj !== "object" || oldObj === null || newObj === null) {
|
|
691
|
+
if (!Object.is(oldObj, newObj)) diffs.push({
|
|
692
|
+
path: path || ".",
|
|
693
|
+
oldValue: oldObj,
|
|
694
|
+
newValue: newObj,
|
|
695
|
+
type: "change"
|
|
696
|
+
});
|
|
697
|
+
return diffs;
|
|
698
|
+
}
|
|
699
|
+
if (Array.isArray(oldObj) && Array.isArray(newObj)) {
|
|
700
|
+
const maxLen = Math.max(oldObj.length, newObj.length);
|
|
701
|
+
for (let i = 0; i < maxLen; i++) {
|
|
702
|
+
const itemPath = path ? `${path}[${i}]` : `[${i}]`;
|
|
703
|
+
if (i >= oldObj.length) diffs.push({
|
|
704
|
+
path: itemPath,
|
|
705
|
+
oldValue: void 0,
|
|
706
|
+
newValue: newObj[i],
|
|
707
|
+
type: "add"
|
|
708
|
+
});
|
|
709
|
+
else if (i >= newObj.length) diffs.push({
|
|
710
|
+
path: itemPath,
|
|
711
|
+
oldValue: oldObj[i],
|
|
712
|
+
newValue: void 0,
|
|
713
|
+
type: "remove"
|
|
714
|
+
});
|
|
715
|
+
else diffs.push(...computeDiff(oldObj[i], newObj[i], itemPath));
|
|
716
|
+
}
|
|
717
|
+
return diffs;
|
|
718
|
+
}
|
|
719
|
+
const oldKeys = new Set(Object.keys(oldObj));
|
|
720
|
+
const newKeys = new Set(Object.keys(newObj));
|
|
721
|
+
for (const key of newKeys) if (!oldKeys.has(key)) diffs.push({
|
|
722
|
+
path: path ? `${path}.${key}` : key,
|
|
723
|
+
oldValue: void 0,
|
|
724
|
+
newValue: newObj[key],
|
|
725
|
+
type: "add"
|
|
726
|
+
});
|
|
727
|
+
for (const key of oldKeys) if (!newKeys.has(key)) diffs.push({
|
|
728
|
+
path: path ? `${path}.${key}` : key,
|
|
729
|
+
oldValue: oldObj[key],
|
|
730
|
+
newValue: void 0,
|
|
731
|
+
type: "remove"
|
|
732
|
+
});
|
|
733
|
+
for (const key of oldKeys) if (newKeys.has(key)) diffs.push(...computeDiff(oldObj[key], newObj[key], path ? `${path}.${key}` : key));
|
|
734
|
+
return diffs;
|
|
735
|
+
}
|
|
736
|
+
function useStoreSnapshot(state, setState, options = {}) {
|
|
737
|
+
const { maxSnapshots = 100, autoRecord = false, debounceMs = 300, deep = true } = options;
|
|
738
|
+
const snapshots = (0, vue.ref)([]);
|
|
739
|
+
const currentIndex = (0, vue.ref)(-1);
|
|
740
|
+
let debounceTimer;
|
|
741
|
+
let isRestoring = false;
|
|
742
|
+
const getState = () => {
|
|
743
|
+
return typeof state === "function" ? state() : state.value;
|
|
744
|
+
};
|
|
745
|
+
const canUndo = (0, vue.computed)(() => currentIndex.value > 0);
|
|
746
|
+
const canRedo = (0, vue.computed)(() => currentIndex.value < snapshots.value.length - 1);
|
|
747
|
+
const takeSnapshot = (label, meta) => {
|
|
748
|
+
const currentState = getState();
|
|
749
|
+
const snapshot = {
|
|
750
|
+
id: generateId(),
|
|
751
|
+
state: (0, _composy_store_core.deepClone)(currentState),
|
|
752
|
+
timestamp: Date.now(),
|
|
753
|
+
label,
|
|
754
|
+
meta
|
|
755
|
+
};
|
|
756
|
+
if (currentIndex.value < snapshots.value.length - 1) snapshots.value = snapshots.value.slice(0, currentIndex.value + 1);
|
|
757
|
+
snapshots.value.push(snapshot);
|
|
758
|
+
currentIndex.value = snapshots.value.length - 1;
|
|
759
|
+
if (snapshots.value.length > maxSnapshots) {
|
|
760
|
+
snapshots.value.shift();
|
|
761
|
+
currentIndex.value--;
|
|
762
|
+
}
|
|
763
|
+
return snapshot;
|
|
764
|
+
};
|
|
765
|
+
const restoreSnapshot = (id) => {
|
|
766
|
+
const index = snapshots.value.findIndex((s) => s.id === id);
|
|
767
|
+
if (index === -1) return false;
|
|
768
|
+
isRestoring = true;
|
|
769
|
+
try {
|
|
770
|
+
setState((0, _composy_store_core.deepClone)(snapshots.value[index].state));
|
|
771
|
+
currentIndex.value = index;
|
|
772
|
+
return true;
|
|
773
|
+
} finally {
|
|
774
|
+
isRestoring = false;
|
|
775
|
+
}
|
|
776
|
+
};
|
|
777
|
+
const undo = () => {
|
|
778
|
+
if (!canUndo.value) return false;
|
|
779
|
+
currentIndex.value--;
|
|
780
|
+
isRestoring = true;
|
|
781
|
+
try {
|
|
782
|
+
setState((0, _composy_store_core.deepClone)(snapshots.value[currentIndex.value].state));
|
|
783
|
+
return true;
|
|
784
|
+
} finally {
|
|
785
|
+
isRestoring = false;
|
|
786
|
+
}
|
|
787
|
+
};
|
|
788
|
+
const redo = () => {
|
|
789
|
+
if (!canRedo.value) return false;
|
|
790
|
+
currentIndex.value++;
|
|
791
|
+
isRestoring = true;
|
|
792
|
+
try {
|
|
793
|
+
setState((0, _composy_store_core.deepClone)(snapshots.value[currentIndex.value].state));
|
|
794
|
+
return true;
|
|
795
|
+
} finally {
|
|
796
|
+
isRestoring = false;
|
|
797
|
+
}
|
|
798
|
+
};
|
|
799
|
+
const goto = (index) => {
|
|
800
|
+
if (index < 0 || index >= snapshots.value.length) return false;
|
|
801
|
+
currentIndex.value = index;
|
|
802
|
+
isRestoring = true;
|
|
803
|
+
try {
|
|
804
|
+
setState((0, _composy_store_core.deepClone)(snapshots.value[index].state));
|
|
805
|
+
return true;
|
|
806
|
+
} finally {
|
|
807
|
+
isRestoring = false;
|
|
808
|
+
}
|
|
809
|
+
};
|
|
810
|
+
const clearSnapshots = () => {
|
|
811
|
+
snapshots.value = [];
|
|
812
|
+
currentIndex.value = -1;
|
|
813
|
+
};
|
|
814
|
+
const getDiff = (snapshotId1, snapshotId2) => {
|
|
815
|
+
const snapshot1 = snapshots.value.find((s) => s.id === snapshotId1);
|
|
816
|
+
const snapshot2 = snapshots.value.find((s) => s.id === snapshotId2);
|
|
817
|
+
if (!snapshot1 || !snapshot2) return [];
|
|
818
|
+
return computeDiff(snapshot1.state, snapshot2.state);
|
|
819
|
+
};
|
|
820
|
+
const exportSnapshots = () => {
|
|
821
|
+
return JSON.stringify({
|
|
822
|
+
snapshots: snapshots.value,
|
|
823
|
+
currentIndex: currentIndex.value,
|
|
824
|
+
exportedAt: Date.now()
|
|
825
|
+
});
|
|
826
|
+
};
|
|
827
|
+
const importSnapshots = (data) => {
|
|
828
|
+
try {
|
|
829
|
+
const parsed = JSON.parse(data);
|
|
830
|
+
if (!Array.isArray(parsed.snapshots)) return false;
|
|
831
|
+
snapshots.value = parsed.snapshots;
|
|
832
|
+
currentIndex.value = Math.min(parsed.currentIndex ?? snapshots.value.length - 1, snapshots.value.length - 1);
|
|
833
|
+
return true;
|
|
834
|
+
} catch {
|
|
835
|
+
return false;
|
|
836
|
+
}
|
|
837
|
+
};
|
|
838
|
+
if (autoRecord) {
|
|
839
|
+
const stopWatch = (0, vue.watch)(typeof state === "function" ? (0, vue.computed)(state) : state, (newState, oldState) => {
|
|
840
|
+
if (isRestoring) return;
|
|
841
|
+
if ((0, _composy_store_core.deepEqual)(newState, oldState)) return;
|
|
842
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
843
|
+
debounceTimer = setTimeout(() => {
|
|
844
|
+
takeSnapshot();
|
|
845
|
+
}, debounceMs);
|
|
846
|
+
}, { deep });
|
|
847
|
+
takeSnapshot("初始状态");
|
|
848
|
+
(0, vue.onUnmounted)(() => {
|
|
849
|
+
stopWatch();
|
|
850
|
+
if (debounceTimer) clearTimeout(debounceTimer);
|
|
851
|
+
});
|
|
852
|
+
}
|
|
853
|
+
return {
|
|
854
|
+
snapshots,
|
|
855
|
+
currentIndex,
|
|
856
|
+
canUndo,
|
|
857
|
+
canRedo,
|
|
858
|
+
takeSnapshot,
|
|
859
|
+
restoreSnapshot,
|
|
860
|
+
undo,
|
|
861
|
+
redo,
|
|
862
|
+
goto,
|
|
863
|
+
clearSnapshots,
|
|
864
|
+
getDiff,
|
|
865
|
+
exportSnapshots,
|
|
866
|
+
importSnapshots
|
|
867
|
+
};
|
|
868
|
+
}
|
|
869
|
+
//#endregion
|
|
870
|
+
//#region src/composables/useSubscribe.ts
|
|
871
|
+
function useSubscribe(store, callback, options = {}) {
|
|
872
|
+
const { detached = false } = options;
|
|
873
|
+
if (store.$subscribe) {
|
|
874
|
+
const unsubscribe = store.$subscribe((mutation, state) => {
|
|
875
|
+
callback(mutation, state);
|
|
876
|
+
}, { detached });
|
|
877
|
+
if (!detached) (0, vue.onUnmounted)(() => {
|
|
878
|
+
unsubscribe();
|
|
879
|
+
});
|
|
880
|
+
return unsubscribe;
|
|
881
|
+
}
|
|
882
|
+
console.warn("[useSubscribe] Store 不支持 $subscribe 方法");
|
|
883
|
+
return () => {};
|
|
884
|
+
}
|
|
885
|
+
function useOnAction(store, callback, detached = false) {
|
|
886
|
+
if (store.$onAction) {
|
|
887
|
+
const unsubscribe = store.$onAction(callback, detached);
|
|
888
|
+
if (!detached) (0, vue.onUnmounted)(() => {
|
|
889
|
+
unsubscribe();
|
|
890
|
+
});
|
|
891
|
+
return unsubscribe;
|
|
892
|
+
}
|
|
893
|
+
console.warn("[useOnAction] Store 不支持 $onAction 方法");
|
|
894
|
+
return () => {};
|
|
895
|
+
}
|
|
896
|
+
function useWatch(source, callback, options = {}) {
|
|
897
|
+
const { immediate = false, deep = false, detached = false } = options;
|
|
898
|
+
const stop = (0, vue.watch)(source, (newValue, oldValue) => {
|
|
899
|
+
callback(newValue, oldValue);
|
|
900
|
+
}, {
|
|
901
|
+
immediate,
|
|
902
|
+
deep
|
|
903
|
+
});
|
|
904
|
+
if (!detached) (0, vue.onUnmounted)(() => {
|
|
905
|
+
stop();
|
|
906
|
+
});
|
|
907
|
+
return stop;
|
|
908
|
+
}
|
|
909
|
+
//#endregion
|
|
910
|
+
//#region src/context/injection-keys.ts
|
|
911
|
+
const STORE_API_SYMBOL = /* @__PURE__ */ Symbol("ldesign-store-api");
|
|
912
|
+
const STORE_PINIA_SYMBOL = /* @__PURE__ */ Symbol("ldesign-store-pinia");
|
|
913
|
+
const STORE_RUNTIME_SYMBOL = /* @__PURE__ */ Symbol("ldesign-store-runtime");
|
|
914
|
+
//#endregion
|
|
915
|
+
//#region src/plugins/pinia-plugin.ts
|
|
916
|
+
const STORE_PERSIST_DISPOSE_KEY = /* @__PURE__ */ Symbol("ldesign-store-persist-dispose");
|
|
917
|
+
const activePersistControllers = /* @__PURE__ */ new Set();
|
|
918
|
+
function getStorage(type) {
|
|
919
|
+
if (typeof window === "undefined") return null;
|
|
920
|
+
return type === "localStorage" ? window.localStorage : window.sessionStorage;
|
|
921
|
+
}
|
|
922
|
+
function normalizePersistConfig(value) {
|
|
923
|
+
if (!value) return null;
|
|
924
|
+
return typeof value === "boolean" ? {} : value;
|
|
925
|
+
}
|
|
926
|
+
function filterState(state, includePaths, excludePaths) {
|
|
927
|
+
if (includePaths?.length) {
|
|
928
|
+
const pickedState = {};
|
|
929
|
+
includePaths.forEach((path) => {
|
|
930
|
+
const value = (0, _composy_store_core.getByPath)(state, path);
|
|
931
|
+
if (value !== void 0) (0, _composy_store_core.setByPath)(pickedState, path, (0, _composy_store_core.deepClone)(value));
|
|
932
|
+
});
|
|
933
|
+
return pickedState;
|
|
934
|
+
}
|
|
935
|
+
if (excludePaths?.length) {
|
|
936
|
+
const nextState = (0, _composy_store_core.deepClone)(state);
|
|
937
|
+
excludePaths.forEach((path) => {
|
|
938
|
+
(0, _composy_store_core.deleteByPath)(nextState, path);
|
|
939
|
+
});
|
|
940
|
+
return nextState;
|
|
941
|
+
}
|
|
942
|
+
return (0, _composy_store_core.deepClone)(state);
|
|
943
|
+
}
|
|
944
|
+
function restoreStoreState(store, nextState) {
|
|
945
|
+
store.$patch((state) => {
|
|
946
|
+
(0, _composy_store_core.deepMerge)(state, nextState);
|
|
947
|
+
});
|
|
948
|
+
}
|
|
949
|
+
function patchPersistDispose(store, cleanup) {
|
|
950
|
+
const restorePatchedDispose = store[STORE_PERSIST_DISPOSE_KEY];
|
|
951
|
+
if (restorePatchedDispose) restorePatchedDispose();
|
|
952
|
+
const originalDispose = store.$dispose;
|
|
953
|
+
store.$dispose = function patchedDispose() {
|
|
954
|
+
cleanup();
|
|
955
|
+
return originalDispose.call(this);
|
|
956
|
+
};
|
|
957
|
+
store[STORE_PERSIST_DISPOSE_KEY] = () => {
|
|
958
|
+
store.$dispose = originalDispose;
|
|
959
|
+
delete store[STORE_PERSIST_DISPOSE_KEY];
|
|
960
|
+
};
|
|
961
|
+
}
|
|
962
|
+
function createPersistPluginController(options = {}) {
|
|
963
|
+
const { storage: defaultStorage = "localStorage", keyPrefix = "ldesign-store:", debounce: debounceDelay = 100, debug = false, syncTabs: defaultSyncTabs = false, defaultTTL } = options;
|
|
964
|
+
const cleanupMap = /* @__PURE__ */ new Map();
|
|
965
|
+
const dispose = () => {
|
|
966
|
+
cleanupMap.forEach((cleanup) => cleanup());
|
|
967
|
+
cleanupMap.clear();
|
|
968
|
+
activePersistControllers.delete(dispose);
|
|
969
|
+
};
|
|
970
|
+
activePersistControllers.add(dispose);
|
|
971
|
+
const plugin = (context) => {
|
|
972
|
+
const { store, options: storeOptions } = context;
|
|
973
|
+
const config = normalizePersistConfig(storeOptions.persist);
|
|
974
|
+
if (!config) return;
|
|
975
|
+
const storage = getStorage(config.storage === "sessionStorage" ? "sessionStorage" : defaultStorage);
|
|
976
|
+
const serializer = config.serializer?.serialize ?? JSON.stringify;
|
|
977
|
+
const deserialize = config.serializer?.deserialize ?? JSON.parse;
|
|
978
|
+
const syncTabs = config.syncTabs ?? defaultSyncTabs;
|
|
979
|
+
const ttl = config.ttl ?? defaultTTL;
|
|
980
|
+
const key = `${keyPrefix}${config.key || store.$id}`;
|
|
981
|
+
if (!storage) {
|
|
982
|
+
if (debug) console.warn(`[PersistPlugin] Storage \u4E0D\u53EF\u7528 (${store.$id})`);
|
|
983
|
+
return;
|
|
984
|
+
}
|
|
985
|
+
let isRestoring = false;
|
|
986
|
+
const applyPersistedValue = (rawState) => {
|
|
987
|
+
const nextState = deserialize(rawState);
|
|
988
|
+
isRestoring = true;
|
|
989
|
+
try {
|
|
990
|
+
config.beforeRestore?.({ store });
|
|
991
|
+
restoreStoreState(store, nextState);
|
|
992
|
+
config.afterRestore?.({ store });
|
|
993
|
+
} finally {
|
|
994
|
+
isRestoring = false;
|
|
995
|
+
}
|
|
996
|
+
};
|
|
997
|
+
const restoreState = () => {
|
|
998
|
+
try {
|
|
999
|
+
const stored = storage.getItem(key);
|
|
1000
|
+
if (!stored) return;
|
|
1001
|
+
const storageItem = JSON.parse(stored);
|
|
1002
|
+
if (storageItem.expiresAt && Date.now() > storageItem.expiresAt) {
|
|
1003
|
+
storage.removeItem(key);
|
|
1004
|
+
return;
|
|
1005
|
+
}
|
|
1006
|
+
applyPersistedValue(storageItem.state);
|
|
1007
|
+
if (debug) console.info(`[PersistPlugin] \u5DF2\u6062\u590D\u72B6\u6001 (${store.$id})`);
|
|
1008
|
+
} catch (error) {
|
|
1009
|
+
console.error(`[PersistPlugin] \u6062\u590D\u72B6\u6001\u5931\u8D25 (${store.$id}):`, error);
|
|
1010
|
+
}
|
|
1011
|
+
};
|
|
1012
|
+
const persistState = () => {
|
|
1013
|
+
if (isRestoring) return;
|
|
1014
|
+
try {
|
|
1015
|
+
const filteredState = filterState(store.$state, config.paths, config.excludePaths);
|
|
1016
|
+
const payload = {
|
|
1017
|
+
state: serializer(filteredState),
|
|
1018
|
+
timestamp: Date.now(),
|
|
1019
|
+
expiresAt: ttl ? Date.now() + ttl : void 0,
|
|
1020
|
+
version: 1
|
|
1021
|
+
};
|
|
1022
|
+
storage.setItem(key, JSON.stringify(payload));
|
|
1023
|
+
if (debug) console.info(`[PersistPlugin] \u5DF2\u4FDD\u5B58\u72B6\u6001 (${store.$id})`);
|
|
1024
|
+
} catch (error) {
|
|
1025
|
+
console.error(`[PersistPlugin] \u4FDD\u5B58\u72B6\u6001\u5931\u8D25 (${store.$id}):`, error);
|
|
1026
|
+
}
|
|
1027
|
+
};
|
|
1028
|
+
const saveState = (0, _composy_store_core.debounce)(persistState, config.debounce ?? debounceDelay);
|
|
1029
|
+
const stopSubscribe = store.$subscribe(() => {
|
|
1030
|
+
if (!isRestoring) saveState();
|
|
1031
|
+
});
|
|
1032
|
+
let stopStorageSync = () => {};
|
|
1033
|
+
if (syncTabs && typeof window !== "undefined") {
|
|
1034
|
+
const handleStorage = (event) => {
|
|
1035
|
+
if (event.key !== key || !event.newValue) return;
|
|
1036
|
+
try {
|
|
1037
|
+
const storageItem = JSON.parse(event.newValue);
|
|
1038
|
+
if (storageItem.expiresAt && Date.now() > storageItem.expiresAt) return;
|
|
1039
|
+
applyPersistedValue(storageItem.state);
|
|
1040
|
+
} catch (error) {
|
|
1041
|
+
console.error(`[PersistPlugin] \u540C\u6B65\u72B6\u6001\u5931\u8D25 (${store.$id}):`, error);
|
|
1042
|
+
}
|
|
1043
|
+
};
|
|
1044
|
+
window.addEventListener("storage", handleStorage);
|
|
1045
|
+
stopStorageSync = () => {
|
|
1046
|
+
window.removeEventListener("storage", handleStorage);
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
const cleanup = () => {
|
|
1050
|
+
saveState.cancel();
|
|
1051
|
+
stopSubscribe();
|
|
1052
|
+
stopStorageSync();
|
|
1053
|
+
cleanupMap.delete(key);
|
|
1054
|
+
};
|
|
1055
|
+
cleanupMap.set(key, cleanup);
|
|
1056
|
+
patchPersistDispose(store, cleanup);
|
|
1057
|
+
restoreState();
|
|
1058
|
+
};
|
|
1059
|
+
return {
|
|
1060
|
+
plugin,
|
|
1061
|
+
dispose
|
|
1062
|
+
};
|
|
1063
|
+
}
|
|
1064
|
+
function createPersistPlugin(options = {}) {
|
|
1065
|
+
return createPersistPluginController(options).plugin;
|
|
1066
|
+
}
|
|
1067
|
+
function createEnhancedPersistPlugin(options = {}) {
|
|
1068
|
+
return createPersistPluginController(options).plugin;
|
|
1069
|
+
}
|
|
1070
|
+
function cleanupEnhancedPersist() {
|
|
1071
|
+
Array.from(activePersistControllers).forEach((dispose) => dispose());
|
|
1072
|
+
}
|
|
1073
|
+
//#endregion
|
|
1074
|
+
//#region src/runtime/store-plugin-options.ts
|
|
1075
|
+
function normalizeStoreRuntimeOptions(options = {}) {
|
|
1076
|
+
return {
|
|
1077
|
+
pinia: options.pinia,
|
|
1078
|
+
persist: options.persist ?? false,
|
|
1079
|
+
persistOptions: options.persistOptions ?? {},
|
|
1080
|
+
globalProperties: options.globalProperties ?? true,
|
|
1081
|
+
provide: options.provide ?? true,
|
|
1082
|
+
debug: options.debug ?? false
|
|
1083
|
+
};
|
|
1084
|
+
}
|
|
1085
|
+
//#endregion
|
|
1086
|
+
//#region src/runtime/store-registry.ts
|
|
1087
|
+
const STORE_DISPOSE_PATCH_KEY = /* @__PURE__ */ Symbol("ldesign-store-registry-dispose");
|
|
1088
|
+
function patchStoreDispose(store, unregister) {
|
|
1089
|
+
const restorePatchedDispose = store[STORE_DISPOSE_PATCH_KEY];
|
|
1090
|
+
if (restorePatchedDispose) restorePatchedDispose();
|
|
1091
|
+
const originalDispose = store.$dispose;
|
|
1092
|
+
store.$dispose = function patchedDispose() {
|
|
1093
|
+
unregister(store.$id);
|
|
1094
|
+
return originalDispose.call(this);
|
|
1095
|
+
};
|
|
1096
|
+
store[STORE_DISPOSE_PATCH_KEY] = () => {
|
|
1097
|
+
store.$dispose = originalDispose;
|
|
1098
|
+
delete store[STORE_DISPOSE_PATCH_KEY];
|
|
1099
|
+
};
|
|
1100
|
+
}
|
|
1101
|
+
function createStoreRegistry() {
|
|
1102
|
+
const stores = /* @__PURE__ */ new Map();
|
|
1103
|
+
const unregister = (storeId) => {
|
|
1104
|
+
stores.delete(storeId);
|
|
1105
|
+
};
|
|
1106
|
+
const register = (store) => {
|
|
1107
|
+
stores.set(store.$id, store);
|
|
1108
|
+
patchStoreDispose(store, unregister);
|
|
1109
|
+
};
|
|
1110
|
+
const hasStore = (storeId) => {
|
|
1111
|
+
return stores.has(storeId);
|
|
1112
|
+
};
|
|
1113
|
+
const getStore = (storeId) => {
|
|
1114
|
+
return stores.get(storeId);
|
|
1115
|
+
};
|
|
1116
|
+
const getStoreIds = () => {
|
|
1117
|
+
return Array.from(stores.keys());
|
|
1118
|
+
};
|
|
1119
|
+
const resetAll = () => {
|
|
1120
|
+
stores.forEach((store) => {
|
|
1121
|
+
if (typeof store.$reset !== "function") return;
|
|
1122
|
+
try {
|
|
1123
|
+
store.$reset();
|
|
1124
|
+
} catch {}
|
|
1125
|
+
});
|
|
1126
|
+
};
|
|
1127
|
+
const clear = () => {
|
|
1128
|
+
stores.clear();
|
|
1129
|
+
};
|
|
1130
|
+
const registerExistingStores = (pinia) => {
|
|
1131
|
+
pinia._s?.forEach((store) => register(store));
|
|
1132
|
+
};
|
|
1133
|
+
const createStoreAPI = (pinia) => {
|
|
1134
|
+
return {
|
|
1135
|
+
pinia,
|
|
1136
|
+
getStore,
|
|
1137
|
+
hasStore,
|
|
1138
|
+
getStoreIds,
|
|
1139
|
+
resetAll
|
|
1140
|
+
};
|
|
1141
|
+
};
|
|
1142
|
+
return {
|
|
1143
|
+
stores,
|
|
1144
|
+
register,
|
|
1145
|
+
unregister,
|
|
1146
|
+
hasStore,
|
|
1147
|
+
getStore,
|
|
1148
|
+
getStoreIds,
|
|
1149
|
+
resetAll,
|
|
1150
|
+
clear,
|
|
1151
|
+
registerExistingStores,
|
|
1152
|
+
createStoreAPI
|
|
1153
|
+
};
|
|
1154
|
+
}
|
|
1155
|
+
let globalRegistry = createStoreRegistry();
|
|
1156
|
+
function setGlobalStoreRegistry(registry) {
|
|
1157
|
+
globalRegistry = registry ?? createStoreRegistry();
|
|
1158
|
+
}
|
|
1159
|
+
function getStoreRegistry() {
|
|
1160
|
+
return globalRegistry.stores;
|
|
1161
|
+
}
|
|
1162
|
+
function createStoreRegistryPlugin(registry = globalRegistry) {
|
|
1163
|
+
return ({ store }) => {
|
|
1164
|
+
registry.register(store);
|
|
1165
|
+
};
|
|
1166
|
+
}
|
|
1167
|
+
//#endregion
|
|
1168
|
+
//#region src/runtime/store-runtime.ts
|
|
1169
|
+
const STORE_RUNTIME_KEY = /* @__PURE__ */ Symbol("ldesign-store-runtime");
|
|
1170
|
+
let globalStoreRuntime = null;
|
|
1171
|
+
function getGlobalStoreAPI$1() {
|
|
1172
|
+
return globalStoreRuntime?.storeAPI ?? null;
|
|
1173
|
+
}
|
|
1174
|
+
function setGlobalStoreRuntime(runtime) {
|
|
1175
|
+
globalStoreRuntime = runtime;
|
|
1176
|
+
setGlobalStoreRegistry(runtime?.registry ?? null);
|
|
1177
|
+
}
|
|
1178
|
+
function createStoreRuntime(options = {}) {
|
|
1179
|
+
const resolvedOptions = normalizeStoreRuntimeOptions(options);
|
|
1180
|
+
const pinia$1 = resolvedOptions.pinia ?? (0, pinia.createPinia)();
|
|
1181
|
+
if (pinia$1[STORE_RUNTIME_KEY]) return pinia$1[STORE_RUNTIME_KEY];
|
|
1182
|
+
const registry = createStoreRegistry();
|
|
1183
|
+
const persistController = resolvedOptions.persist ? createPersistPluginController({
|
|
1184
|
+
...resolvedOptions.persistOptions,
|
|
1185
|
+
debug: resolvedOptions.debug || resolvedOptions.persistOptions.debug
|
|
1186
|
+
}) : null;
|
|
1187
|
+
pinia$1.use(createStoreRegistryPlugin(registry));
|
|
1188
|
+
persistController && pinia$1.use(persistController.plugin);
|
|
1189
|
+
registry.registerExistingStores(pinia$1);
|
|
1190
|
+
const runtime = {
|
|
1191
|
+
pinia: pinia$1,
|
|
1192
|
+
registry,
|
|
1193
|
+
storeAPI: registry.createStoreAPI(pinia$1),
|
|
1194
|
+
options: resolvedOptions,
|
|
1195
|
+
/**
|
|
1196
|
+
* 清理函数
|
|
1197
|
+
* 释放所有资源:清除运行时标记、持久化插件、注册表
|
|
1198
|
+
*/
|
|
1199
|
+
dispose: () => {
|
|
1200
|
+
if (pinia$1[STORE_RUNTIME_KEY] === runtime) delete pinia$1[STORE_RUNTIME_KEY];
|
|
1201
|
+
persistController?.dispose();
|
|
1202
|
+
registry.clear();
|
|
1203
|
+
if (globalStoreRuntime === runtime) setGlobalStoreRuntime(null);
|
|
1204
|
+
}
|
|
1205
|
+
};
|
|
1206
|
+
pinia$1[STORE_RUNTIME_KEY] = runtime;
|
|
1207
|
+
return runtime;
|
|
1208
|
+
}
|
|
1209
|
+
//#endregion
|
|
1210
|
+
//#region src/runtime/install-store-app.ts
|
|
1211
|
+
const STORE_APP_RUNTIME_KEY = /* @__PURE__ */ Symbol("ldesign-store-app-runtime");
|
|
1212
|
+
function isPiniaInstalled(app, runtime) {
|
|
1213
|
+
return app.config.globalProperties.$pinia === runtime.pinia;
|
|
1214
|
+
}
|
|
1215
|
+
function patchUnmount(app, runtime) {
|
|
1216
|
+
const originalUnmount = app.unmount;
|
|
1217
|
+
app.unmount = function patchedUnmount() {
|
|
1218
|
+
if (app[STORE_APP_RUNTIME_KEY] === runtime) {
|
|
1219
|
+
delete app[STORE_APP_RUNTIME_KEY];
|
|
1220
|
+
runtime.dispose();
|
|
1221
|
+
}
|
|
1222
|
+
return originalUnmount.call(this);
|
|
1223
|
+
};
|
|
1224
|
+
}
|
|
1225
|
+
function getInstalledStoreRuntime(app) {
|
|
1226
|
+
return app[STORE_APP_RUNTIME_KEY];
|
|
1227
|
+
}
|
|
1228
|
+
function installStoreRuntime(app, runtime) {
|
|
1229
|
+
const storeApp = app;
|
|
1230
|
+
const installedRuntime = storeApp[STORE_APP_RUNTIME_KEY];
|
|
1231
|
+
if (installedRuntime) {
|
|
1232
|
+
setGlobalStoreRuntime(installedRuntime);
|
|
1233
|
+
return installedRuntime;
|
|
1234
|
+
}
|
|
1235
|
+
if (!isPiniaInstalled(app, runtime)) app.use(runtime.pinia);
|
|
1236
|
+
storeApp[STORE_APP_RUNTIME_KEY] = runtime;
|
|
1237
|
+
if (runtime.options.provide) {
|
|
1238
|
+
app.provide(STORE_RUNTIME_SYMBOL, runtime);
|
|
1239
|
+
app.provide(STORE_API_SYMBOL, runtime.storeAPI);
|
|
1240
|
+
app.provide(STORE_PINIA_SYMBOL, runtime.pinia);
|
|
1241
|
+
app.provide("store", runtime.storeAPI);
|
|
1242
|
+
app.provide("pinia", runtime.pinia);
|
|
1243
|
+
}
|
|
1244
|
+
if (runtime.options.globalProperties) app.config.globalProperties.$store = runtime.storeAPI;
|
|
1245
|
+
patchUnmount(storeApp, runtime);
|
|
1246
|
+
setGlobalStoreRuntime(runtime);
|
|
1247
|
+
return runtime;
|
|
1248
|
+
}
|
|
1249
|
+
//#endregion
|
|
1250
|
+
//#region src/plugins/engine-plugin.ts
|
|
1251
|
+
function isVueApp(value) {
|
|
1252
|
+
return !!value && typeof value.use === "function";
|
|
1253
|
+
}
|
|
1254
|
+
function resolveVueApp(engine, context, payload) {
|
|
1255
|
+
const appPayload = payload;
|
|
1256
|
+
const app = appPayload?.app ?? appPayload?.framework?.app ?? engine.getApp?.() ?? context.framework?.app;
|
|
1257
|
+
return isVueApp(app) ? app : void 0;
|
|
1258
|
+
}
|
|
1259
|
+
function getGlobalStoreAPI() {
|
|
1260
|
+
return getGlobalStoreAPI$1();
|
|
1261
|
+
}
|
|
1262
|
+
function createStoreEnginePlugin(options = {}) {
|
|
1263
|
+
const { debug = false, dependencies = [], name = "store", version = "1.0.0" } = options;
|
|
1264
|
+
let bridge = null;
|
|
1265
|
+
const createBridge = () => {
|
|
1266
|
+
const activeBridge = (0, _composy_store_core_engine.createStoreEngineBridge)({
|
|
1267
|
+
name,
|
|
1268
|
+
version,
|
|
1269
|
+
debug,
|
|
1270
|
+
createRuntime: () => createStoreRuntime({
|
|
1271
|
+
pinia: options.pinia,
|
|
1272
|
+
persist: options.persist,
|
|
1273
|
+
persistOptions: options.persistOptions,
|
|
1274
|
+
globalProperties: options.globalProperties,
|
|
1275
|
+
provide: options.provide,
|
|
1276
|
+
debug
|
|
1277
|
+
}),
|
|
1278
|
+
attachToApp: (app, runtime) => installStoreRuntime(app, runtime),
|
|
1279
|
+
getRuntimeFromApp: (app) => getInstalledStoreRuntime(app),
|
|
1280
|
+
isApp: isVueApp,
|
|
1281
|
+
resolveApp: resolveVueApp
|
|
1282
|
+
});
|
|
1283
|
+
bridge = activeBridge;
|
|
1284
|
+
return activeBridge;
|
|
1285
|
+
};
|
|
1286
|
+
const getBridge = () => {
|
|
1287
|
+
return bridge ?? createBridge();
|
|
1288
|
+
};
|
|
1289
|
+
return {
|
|
1290
|
+
name,
|
|
1291
|
+
version,
|
|
1292
|
+
dependencies,
|
|
1293
|
+
/**
|
|
1294
|
+
* 安装到引擎上下文(异步)
|
|
1295
|
+
* 通过 bridge 将 store 能力注册到引擎
|
|
1296
|
+
*/
|
|
1297
|
+
async install(context) {
|
|
1298
|
+
await getBridge().install(context);
|
|
1299
|
+
},
|
|
1300
|
+
/**
|
|
1301
|
+
* 安装到 Vue App
|
|
1302
|
+
* 将 store 运行时连接到 Vue 应用实例
|
|
1303
|
+
*/
|
|
1304
|
+
installVue(app) {
|
|
1305
|
+
getBridge().attachToApp(app);
|
|
1306
|
+
},
|
|
1307
|
+
/**
|
|
1308
|
+
* 从引擎上下文卸载(异步)
|
|
1309
|
+
* 清理 bridge 引用
|
|
1310
|
+
*/
|
|
1311
|
+
async uninstall(context) {
|
|
1312
|
+
await getBridge().uninstall(context);
|
|
1313
|
+
bridge = null;
|
|
1314
|
+
}
|
|
1315
|
+
};
|
|
1316
|
+
}
|
|
1317
|
+
//#endregion
|
|
1318
|
+
//#region src/plugins/vue-plugin.ts
|
|
1319
|
+
function createStoreVuePlugin(options = {}) {
|
|
1320
|
+
return { install(app) {
|
|
1321
|
+
const runtime = createStoreRuntime(options);
|
|
1322
|
+
const installedRuntime = installStoreRuntime(app, runtime);
|
|
1323
|
+
if (installedRuntime !== runtime) runtime.dispose();
|
|
1324
|
+
if (installedRuntime.options.debug) console.info("[StoreVuePlugin] installed");
|
|
1325
|
+
} };
|
|
1326
|
+
}
|
|
1327
|
+
//#endregion
|
|
1328
|
+
//#region src/index.ts
|
|
1329
|
+
const version = "1.0.0";
|
|
1330
|
+
const name = "@composy/store-vue";
|
|
1331
|
+
//#endregion
|
|
1332
|
+
Object.defineProperty(exports, "batch", {
|
|
1333
|
+
enumerable: true,
|
|
1334
|
+
get: function() {
|
|
1335
|
+
return _composy_store_core.batch;
|
|
1336
|
+
}
|
|
1337
|
+
});
|
|
1338
|
+
exports.cleanupEnhancedPersist = cleanupEnhancedPersist;
|
|
1339
|
+
Object.defineProperty(exports, "combineSelectors", {
|
|
1340
|
+
enumerable: true,
|
|
1341
|
+
get: function() {
|
|
1342
|
+
return _composy_store_core.combineSelectors;
|
|
1343
|
+
}
|
|
1344
|
+
});
|
|
1345
|
+
Object.defineProperty(exports, "composePlugins", {
|
|
1346
|
+
enumerable: true,
|
|
1347
|
+
get: function() {
|
|
1348
|
+
return _composy_store_core.composePlugins;
|
|
1349
|
+
}
|
|
1350
|
+
});
|
|
1351
|
+
Object.defineProperty(exports, "createAsyncAction", {
|
|
1352
|
+
enumerable: true,
|
|
1353
|
+
get: function() {
|
|
1354
|
+
return _composy_store_core.createAsyncAction;
|
|
1355
|
+
}
|
|
1356
|
+
});
|
|
1357
|
+
Object.defineProperty(exports, "createBatchManager", {
|
|
1358
|
+
enumerable: true,
|
|
1359
|
+
get: function() {
|
|
1360
|
+
return _composy_store_core.createBatchManager;
|
|
1361
|
+
}
|
|
1362
|
+
});
|
|
1363
|
+
exports.createEnhancedPersistPlugin = createEnhancedPersistPlugin;
|
|
1364
|
+
Object.defineProperty(exports, "createEventBus", {
|
|
1365
|
+
enumerable: true,
|
|
1366
|
+
get: function() {
|
|
1367
|
+
return _composy_store_core.createEventBus;
|
|
1368
|
+
}
|
|
1369
|
+
});
|
|
1370
|
+
Object.defineProperty(exports, "createLoggerMiddleware", {
|
|
1371
|
+
enumerable: true,
|
|
1372
|
+
get: function() {
|
|
1373
|
+
return _composy_store_core.createLoggerMiddleware;
|
|
1374
|
+
}
|
|
1375
|
+
});
|
|
1376
|
+
Object.defineProperty(exports, "createMiddlewareManager", {
|
|
1377
|
+
enumerable: true,
|
|
1378
|
+
get: function() {
|
|
1379
|
+
return _composy_store_core.createMiddlewareManager;
|
|
1380
|
+
}
|
|
1381
|
+
});
|
|
1382
|
+
exports.createPersistPlugin = createPersistPlugin;
|
|
1383
|
+
Object.defineProperty(exports, "createPinia", {
|
|
1384
|
+
enumerable: true,
|
|
1385
|
+
get: function() {
|
|
1386
|
+
return pinia.createPinia;
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1389
|
+
Object.defineProperty(exports, "createPluginFactory", {
|
|
1390
|
+
enumerable: true,
|
|
1391
|
+
get: function() {
|
|
1392
|
+
return _composy_store_core.createPluginFactory;
|
|
1393
|
+
}
|
|
1394
|
+
});
|
|
1395
|
+
Object.defineProperty(exports, "createPubSub", {
|
|
1396
|
+
enumerable: true,
|
|
1397
|
+
get: function() {
|
|
1398
|
+
return _composy_store_core.createPubSub;
|
|
1399
|
+
}
|
|
1400
|
+
});
|
|
1401
|
+
Object.defineProperty(exports, "createPubSubWithValue", {
|
|
1402
|
+
enumerable: true,
|
|
1403
|
+
get: function() {
|
|
1404
|
+
return _composy_store_core.createPubSubWithValue;
|
|
1405
|
+
}
|
|
1406
|
+
});
|
|
1407
|
+
Object.defineProperty(exports, "createSelector", {
|
|
1408
|
+
enumerable: true,
|
|
1409
|
+
get: function() {
|
|
1410
|
+
return _composy_store_core.createSelector;
|
|
1411
|
+
}
|
|
1412
|
+
});
|
|
1413
|
+
exports.createStoreEnginePlugin = createStoreEnginePlugin;
|
|
1414
|
+
exports.createStoreGetters = createStoreGetters;
|
|
1415
|
+
exports.createStoreRegistryPlugin = createStoreRegistryPlugin;
|
|
1416
|
+
exports.createStoreState = createStoreState;
|
|
1417
|
+
exports.createStoreVuePlugin = createStoreVuePlugin;
|
|
1418
|
+
Object.defineProperty(exports, "createTimeTravelMiddleware", {
|
|
1419
|
+
enumerable: true,
|
|
1420
|
+
get: function() {
|
|
1421
|
+
return _composy_store_core.createTimeTravelMiddleware;
|
|
1422
|
+
}
|
|
1423
|
+
});
|
|
1424
|
+
Object.defineProperty(exports, "createValidationMiddleware", {
|
|
1425
|
+
enumerable: true,
|
|
1426
|
+
get: function() {
|
|
1427
|
+
return _composy_store_core.createValidationMiddleware;
|
|
1428
|
+
}
|
|
1429
|
+
});
|
|
1430
|
+
Object.defineProperty(exports, "deepClone", {
|
|
1431
|
+
enumerable: true,
|
|
1432
|
+
get: function() {
|
|
1433
|
+
return _composy_store_core.deepClone;
|
|
1434
|
+
}
|
|
1435
|
+
});
|
|
1436
|
+
Object.defineProperty(exports, "deepMerge", {
|
|
1437
|
+
enumerable: true,
|
|
1438
|
+
get: function() {
|
|
1439
|
+
return _composy_store_core.deepMerge;
|
|
1440
|
+
}
|
|
1441
|
+
});
|
|
1442
|
+
exports.defineSetupStore = defineSetupStore;
|
|
1443
|
+
Object.defineProperty(exports, "defineStore", {
|
|
1444
|
+
enumerable: true,
|
|
1445
|
+
get: function() {
|
|
1446
|
+
return pinia.defineStore;
|
|
1447
|
+
}
|
|
1448
|
+
});
|
|
1449
|
+
Object.defineProperty(exports, "defineStorePlugin", {
|
|
1450
|
+
enumerable: true,
|
|
1451
|
+
get: function() {
|
|
1452
|
+
return _composy_store_core.defineStorePlugin;
|
|
1453
|
+
}
|
|
1454
|
+
});
|
|
1455
|
+
exports.email = email;
|
|
1456
|
+
Object.defineProperty(exports, "getActivePinia", {
|
|
1457
|
+
enumerable: true,
|
|
1458
|
+
get: function() {
|
|
1459
|
+
return pinia.getActivePinia;
|
|
1460
|
+
}
|
|
1461
|
+
});
|
|
1462
|
+
exports.getGlobalStoreAPI = getGlobalStoreAPI;
|
|
1463
|
+
exports.getStoreRegistry = getStoreRegistry;
|
|
1464
|
+
Object.defineProperty(exports, "globalEventBus", {
|
|
1465
|
+
enumerable: true,
|
|
1466
|
+
get: function() {
|
|
1467
|
+
return _composy_store_core.globalEventBus;
|
|
1468
|
+
}
|
|
1469
|
+
});
|
|
1470
|
+
Object.defineProperty(exports, "mapActions", {
|
|
1471
|
+
enumerable: true,
|
|
1472
|
+
get: function() {
|
|
1473
|
+
return pinia.mapActions;
|
|
1474
|
+
}
|
|
1475
|
+
});
|
|
1476
|
+
Object.defineProperty(exports, "mapGetters", {
|
|
1477
|
+
enumerable: true,
|
|
1478
|
+
get: function() {
|
|
1479
|
+
return pinia.mapGetters;
|
|
1480
|
+
}
|
|
1481
|
+
});
|
|
1482
|
+
Object.defineProperty(exports, "mapState", {
|
|
1483
|
+
enumerable: true,
|
|
1484
|
+
get: function() {
|
|
1485
|
+
return pinia.mapState;
|
|
1486
|
+
}
|
|
1487
|
+
});
|
|
1488
|
+
Object.defineProperty(exports, "mapStores", {
|
|
1489
|
+
enumerable: true,
|
|
1490
|
+
get: function() {
|
|
1491
|
+
return pinia.mapStores;
|
|
1492
|
+
}
|
|
1493
|
+
});
|
|
1494
|
+
Object.defineProperty(exports, "mapWritableState", {
|
|
1495
|
+
enumerable: true,
|
|
1496
|
+
get: function() {
|
|
1497
|
+
return pinia.mapWritableState;
|
|
1498
|
+
}
|
|
1499
|
+
});
|
|
1500
|
+
exports.maxLength = maxLength;
|
|
1501
|
+
exports.minLength = minLength;
|
|
1502
|
+
exports.name = name;
|
|
1503
|
+
exports.numberRange = numberRange;
|
|
1504
|
+
exports.pattern = pattern;
|
|
1505
|
+
exports.required = required;
|
|
1506
|
+
Object.defineProperty(exports, "setActivePinia", {
|
|
1507
|
+
enumerable: true,
|
|
1508
|
+
get: function() {
|
|
1509
|
+
return pinia.setActivePinia;
|
|
1510
|
+
}
|
|
1511
|
+
});
|
|
1512
|
+
Object.defineProperty(exports, "storeToRefs", {
|
|
1513
|
+
enumerable: true,
|
|
1514
|
+
get: function() {
|
|
1515
|
+
return pinia.storeToRefs;
|
|
1516
|
+
}
|
|
1517
|
+
});
|
|
1518
|
+
exports.useComputedStore = useComputedStore;
|
|
1519
|
+
exports.useFormStore = useFormStore;
|
|
1520
|
+
exports.useOnAction = useOnAction;
|
|
1521
|
+
exports.useOptimistic = useOptimistic;
|
|
1522
|
+
exports.usePersist = usePersist;
|
|
1523
|
+
exports.usePersistedRef = usePersistedRef;
|
|
1524
|
+
exports.usePersistedRefWithTTL = usePersistedRefWithTTL;
|
|
1525
|
+
exports.usePersistedState = usePersistedState;
|
|
1526
|
+
exports.useSharedState = useSharedState;
|
|
1527
|
+
exports.useSimpleStore = useSimpleStore;
|
|
1528
|
+
exports.useStore = useStore;
|
|
1529
|
+
exports.useStoreDevtools = useStoreDevtools;
|
|
1530
|
+
exports.useStoreSnapshot = useStoreSnapshot;
|
|
1531
|
+
exports.useSubscribe = useSubscribe;
|
|
1532
|
+
exports.useWatch = useWatch;
|
|
1533
|
+
exports.version = version;
|
|
1534
|
+
});
|
|
1535
|
+
/*! End of @composy/store-vue | Powered by @composy/builder */
|
|
1536
|
+
//# sourceMappingURL=index.js.map
|