v-dict 1.2.10 → 2.0.0

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.
@@ -0,0 +1,128 @@
1
+ // src/util.ts
2
+ var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
3
+ function isFunction(fn) {
4
+ return typeof fn === "function";
5
+ }
6
+ function clearObj(obj) {
7
+ for (const key of Object.keys(obj)) {
8
+ delete obj[key];
9
+ }
10
+ }
11
+ function mapToObj(map, {
12
+ obj = {},
13
+ itemTransformer
14
+ } = {}) {
15
+ var _a;
16
+ clearObj(obj);
17
+ for (const [key, value] of map) {
18
+ obj[key] = (_a = itemTransformer == null ? void 0 : itemTransformer(value)) != null ? _a : value;
19
+ }
20
+ return obj;
21
+ }
22
+ function checkObjItem(item, key, transformer) {
23
+ if (item.value === void 0) {
24
+ item.value = key;
25
+ }
26
+ if (isFunction(transformer)) {
27
+ item.value = transformer(item.value);
28
+ }
29
+ }
30
+ function mapToList(map, {
31
+ list = [],
32
+ itemTransformer
33
+ } = {}) {
34
+ const values = isFunction(itemTransformer) ? map.values().map(itemTransformer) : map.values();
35
+ list.splice(0, list.length, ...values);
36
+ return list;
37
+ }
38
+ function toMap(data, { map = /* @__PURE__ */ new Map(), pickValues = [], omitValues = [], transformer } = {}) {
39
+ const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
40
+ map.clear();
41
+ Object.entries(data).filter(([key, item]) => {
42
+ checkObjItem(item, key, transformer);
43
+ return filterFn(item.value);
44
+ }).forEach(([, item]) => map.set(item.value, item));
45
+ return map;
46
+ }
47
+ var defineDictData = (data) => data;
48
+ var { toString } = Object.prototype;
49
+ function isPlainObject(obj) {
50
+ return toString.call(obj) === "[object Object]";
51
+ }
52
+ function merge(target, ...sources) {
53
+ if (!sources.length)
54
+ return target;
55
+ const source = sources.shift();
56
+ if (source && isPlainObject(source)) {
57
+ for (const key of Reflect.ownKeys(source)) {
58
+ const value = source[key];
59
+ if (isPlainObject(value)) {
60
+ if (!isPlainObject(target[key])) {
61
+ target[key] = {};
62
+ }
63
+ merge(target[key], value);
64
+ } else {
65
+ target[key] = value;
66
+ }
67
+ }
68
+ }
69
+ return merge(target, ...sources);
70
+ }
71
+ function cloneDeep(value) {
72
+ if (value === null || typeof value !== "object") {
73
+ return value;
74
+ }
75
+ if (Array.isArray(value)) {
76
+ return value.map(cloneDeep);
77
+ }
78
+ if (value instanceof Date) {
79
+ return new Date(value.getTime());
80
+ }
81
+ if (value instanceof RegExp) {
82
+ return new RegExp(value.source, value.flags);
83
+ }
84
+ if (value instanceof Map) {
85
+ const copy = /* @__PURE__ */ new Map();
86
+ value.forEach((val, key) => {
87
+ copy.set(cloneDeep(key), cloneDeep(val));
88
+ });
89
+ return copy;
90
+ }
91
+ if (value instanceof Set) {
92
+ const copy = /* @__PURE__ */ new Set();
93
+ value.forEach((val) => {
94
+ copy.add(cloneDeep(val));
95
+ });
96
+ return copy;
97
+ }
98
+ if (isPlainObject(value)) {
99
+ const copy = {};
100
+ for (const key of Reflect.ownKeys(value)) {
101
+ copy[key] = cloneDeep(value[key]);
102
+ }
103
+ return copy;
104
+ }
105
+ return value;
106
+ }
107
+
108
+ // src/create-promise.ts
109
+ var noop = () => {
110
+ };
111
+ function createPromise(executor) {
112
+ let resolve = noop;
113
+ let reject = noop;
114
+ const promise = new Promise((_resolve, _reject) => {
115
+ resolve = _resolve;
116
+ reject = _reject;
117
+ executor == null ? void 0 : executor(_resolve, _reject);
118
+ });
119
+ promise.resolve = resolve;
120
+ promise.reject = reject;
121
+ promise.isPending = true;
122
+ promise.finally(() => {
123
+ promise.isPending = false;
124
+ });
125
+ return promise;
126
+ }
127
+
128
+ export { cloneDeep, createPromise, defineDictData, isFunction, mapToList, mapToObj, merge, toMap, warn };
package/dist/index.cjs CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  var vue = require('vue');
4
4
 
5
- // src/dict-manager.ts
5
+ // src/vue/vue-dict-manager.ts
6
6
 
7
7
  // src/create-promise.ts
8
8
  var noop = () => {
@@ -25,6 +25,7 @@ function createPromise(executor) {
25
25
  }
26
26
 
27
27
  // src/util.ts
28
+ var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
28
29
  function isFunction(fn) {
29
30
  return typeof fn === "function";
30
31
  }
@@ -33,10 +34,14 @@ function clearObj(obj) {
33
34
  delete obj[key];
34
35
  }
35
36
  }
36
- function mapToObj(map, obj = {}) {
37
+ function mapToObj(map, {
38
+ obj = {},
39
+ itemTransformer
40
+ } = {}) {
41
+ var _a;
37
42
  clearObj(obj);
38
43
  for (const [key, value] of map) {
39
- obj[key] = value;
44
+ obj[key] = (_a = itemTransformer == null ? void 0 : itemTransformer(value)) != null ? _a : value;
40
45
  }
41
46
  return obj;
42
47
  }
@@ -48,20 +53,17 @@ function checkObjItem(item, key, transformer) {
48
53
  item.value = transformer(item.value);
49
54
  }
50
55
  }
51
- function mapToList(map, list = []) {
52
- list.splice(0, list.length, ...map.values());
56
+ function mapToList(map, {
57
+ list = [],
58
+ itemTransformer
59
+ } = {}) {
60
+ const values = isFunction(itemTransformer) ? map.values().map(itemTransformer) : map.values();
61
+ list.splice(0, list.length, ...values);
53
62
  return list;
54
63
  }
55
- function listToMap(list) {
56
- return new Map(list.map((item) => [item.value, item]));
57
- }
58
- function toMap(data, options = {}) {
59
- const { pickValues = [], omitValues = [], transformer } = options;
64
+ function toMap(data, { map = /* @__PURE__ */ new Map(), pickValues = [], omitValues = [], transformer } = {}) {
60
65
  const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
61
- if (Array.isArray(data)) {
62
- return listToMap(data.filter((item) => filterFn(item.value)));
63
- }
64
- const map = /* @__PURE__ */ new Map();
66
+ map.clear();
65
67
  Object.entries(data).filter(([key, item]) => {
66
68
  checkObjItem(item, key, transformer);
67
69
  return filterFn(item.value);
@@ -129,13 +131,13 @@ function cloneDeep(value) {
129
131
  return value;
130
132
  }
131
133
 
132
- // src/dict-manager.ts
133
- var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
134
+ // src/vue/vue-dict-manager.ts
134
135
  function createDictManager(createDictManagerOptions = {}) {
135
136
  const {
136
137
  fetch: managerFetch,
137
138
  extra: managerExtra,
138
- transformer: managerTransformer
139
+ transformer: managerTransformer,
140
+ itemTransformer: managerItemTransformer
139
141
  } = createDictManagerOptions;
140
142
  const maps = vue.reactive(/* @__PURE__ */ Object.create(null));
141
143
  const defineDictOptionsMap = /* @__PURE__ */ new Map();
@@ -145,22 +147,29 @@ function createDictManager(createDictManagerOptions = {}) {
145
147
  (_a = maps[code]) == null ? void 0 : _a.clear();
146
148
  return;
147
149
  }
148
- clearObj(maps);
150
+ Object.values(maps).forEach((map) => map.clear());
149
151
  }
150
152
  function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
151
153
  const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
152
154
  if (maps[code]) {
153
155
  warn(`code "${code}" already exists`);
156
+ } else {
157
+ maps[code] = /* @__PURE__ */ new Map();
154
158
  }
155
159
  const _defineDictOptions = Object.assign(
156
- { data: {}, remote: false, fetch: managerFetch, transformer: managerTransformer },
160
+ {
161
+ data: {},
162
+ remote: false,
163
+ fetch: managerFetch,
164
+ transformer: managerTransformer,
165
+ itemTransformer: managerItemTransformer
166
+ },
157
167
  isFunction(defineDictOptions) ? defineDictOptions() : defineDictOptions
158
168
  );
159
169
  defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
160
- const { data, remote, fetch, extra, transformer } = _defineDictOptions;
161
- const globalLoadPromise = vue.shallowRef(null);
162
- let loaded = false;
163
- maps[code] = /* @__PURE__ */ new Map();
170
+ const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
171
+ let globalLoadPromise = null;
172
+ let init = false;
164
173
  async function loadDict(options, mapRef) {
165
174
  var _a;
166
175
  const dataMap = toMap(cloneDeep(data), { pickValues, omitValues, transformer });
@@ -182,21 +191,23 @@ function createDictManager(createDictManagerOptions = {}) {
182
191
  useDictOptions
183
192
  );
184
193
  const { clone, immediate, refresh } = useDictOptions;
185
- const loadPromise = !clone ? globalLoadPromise : vue.shallowRef(createPromise());
186
- const mapRef = !clone ? vue.toRef(maps, code) : vue.ref();
194
+ const loadPromise = vue.shallowRef(
195
+ !clone ? globalLoadPromise : createPromise()
196
+ );
197
+ const mapRef = !clone ? vue.toRef(maps, code) : vue.ref(/* @__PURE__ */ new Map());
187
198
  const objRef = vue.ref(/* @__PURE__ */ Object.create(null));
188
199
  const listRef = vue.ref([]);
189
200
  if (!remote || immediate) {
190
201
  if (clone) {
191
202
  load();
192
203
  } else {
193
- if (!globalLoadPromise.value) {
194
- globalLoadPromise.value = createPromise();
204
+ if (!globalLoadPromise) {
205
+ globalLoadPromise = createPromise();
195
206
  load();
196
207
  } else {
197
- globalLoadPromise.value.then(() => {
198
- if (!loaded) {
199
- loaded = true;
208
+ globalLoadPromise.then(() => {
209
+ if (!init) {
210
+ init = true;
200
211
  load();
201
212
  } else if (refresh) {
202
213
  load();
@@ -205,9 +216,9 @@ function createDictManager(createDictManagerOptions = {}) {
205
216
  }
206
217
  }
207
218
  } else {
208
- if (!globalLoadPromise.value) {
209
- globalLoadPromise.value = createPromise();
210
- globalLoadPromise.value.resolve();
219
+ if (!globalLoadPromise) {
220
+ globalLoadPromise = createPromise();
221
+ globalLoadPromise.resolve();
211
222
  }
212
223
  }
213
224
  function load(options) {
@@ -220,24 +231,30 @@ function createDictManager(createDictManagerOptions = {}) {
220
231
  return loadPromise.value;
221
232
  }
222
233
  function _clear() {
223
- var _a;
224
- (_a = mapRef.value) == null ? void 0 : _a.clear();
234
+ mapRef.value.clear();
225
235
  }
226
236
  vue.watch(
227
237
  mapRef,
228
238
  (newValue) => {
229
239
  newValue != null ? newValue : newValue = /* @__PURE__ */ new Map();
230
- mapToObj(newValue, objRef.value);
231
- mapToList(newValue, listRef.value);
240
+ mapToObj(newValue, {
241
+ obj: objRef.value,
242
+ itemTransformer
243
+ });
244
+ mapToList(newValue, {
245
+ list: listRef.value,
246
+ itemTransformer
247
+ });
232
248
  },
233
249
  { deep: true, immediate: true }
234
250
  );
235
251
  const E = vue.computed(() => {
252
+ var _a;
236
253
  const result = {};
237
254
  if (!mapRef.value)
238
255
  return result;
239
256
  for (const key of mapRef.value.keys()) {
240
- result[key] = key;
257
+ result[key] = (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key;
241
258
  }
242
259
  return result;
243
260
  });
@@ -257,7 +274,9 @@ function createDictManager(createDictManagerOptions = {}) {
257
274
  const reactiveCtx = vue.reactive(ctx);
258
275
  return vue.reactive({
259
276
  ...ctx,
277
+ // @ts-ignore
260
278
  ...managerExtra == null ? void 0 : managerExtra(reactiveCtx),
279
+ // @ts-ignore
261
280
  ...extra == null ? void 0 : extra(reactiveCtx)
262
281
  });
263
282
  }
package/dist/index.d.ts CHANGED
@@ -1,3 +1 @@
1
- export type * from './types';
2
- export * from './dict-manager';
3
- export { defineDictData } from './util';
1
+ export * from './vue';
package/dist/index.js CHANGED
@@ -1,139 +1,13 @@
1
+ import { warn, isFunction, cloneDeep, createPromise, mapToObj, mapToList, toMap, merge } from './chunk-SXX4ZFIR.js';
2
+ export { defineDictData } from './chunk-SXX4ZFIR.js';
1
3
  import { reactive, readonly, shallowRef, toRef, ref, watch, computed } from 'vue';
2
4
 
3
- // src/dict-manager.ts
4
-
5
- // src/create-promise.ts
6
- var noop = () => {
7
- };
8
- function createPromise(executor) {
9
- let resolve = noop;
10
- let reject = noop;
11
- const promise = new Promise((_resolve, _reject) => {
12
- resolve = _resolve;
13
- reject = _reject;
14
- executor == null ? void 0 : executor(_resolve, _reject);
15
- });
16
- promise.resolve = resolve;
17
- promise.reject = reject;
18
- promise.isPending = true;
19
- promise.finally(() => {
20
- promise.isPending = false;
21
- });
22
- return promise;
23
- }
24
-
25
- // src/util.ts
26
- function isFunction(fn) {
27
- return typeof fn === "function";
28
- }
29
- function clearObj(obj) {
30
- for (const key of Object.keys(obj)) {
31
- delete obj[key];
32
- }
33
- }
34
- function mapToObj(map, obj = {}) {
35
- clearObj(obj);
36
- for (const [key, value] of map) {
37
- obj[key] = value;
38
- }
39
- return obj;
40
- }
41
- function checkObjItem(item, key, transformer) {
42
- if (item.value === void 0) {
43
- item.value = key;
44
- }
45
- if (isFunction(transformer)) {
46
- item.value = transformer(item.value);
47
- }
48
- }
49
- function mapToList(map, list = []) {
50
- list.splice(0, list.length, ...map.values());
51
- return list;
52
- }
53
- function listToMap(list) {
54
- return new Map(list.map((item) => [item.value, item]));
55
- }
56
- function toMap(data, options = {}) {
57
- const { pickValues = [], omitValues = [], transformer } = options;
58
- const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
59
- if (Array.isArray(data)) {
60
- return listToMap(data.filter((item) => filterFn(item.value)));
61
- }
62
- const map = /* @__PURE__ */ new Map();
63
- Object.entries(data).filter(([key, item]) => {
64
- checkObjItem(item, key, transformer);
65
- return filterFn(item.value);
66
- }).forEach(([, item]) => map.set(item.value, item));
67
- return map;
68
- }
69
- var defineDictData = (data) => data;
70
- var { toString } = Object.prototype;
71
- function isPlainObject(obj) {
72
- return toString.call(obj) === "[object Object]";
73
- }
74
- function merge(target, ...sources) {
75
- if (!sources.length)
76
- return target;
77
- const source = sources.shift();
78
- if (source && isPlainObject(source)) {
79
- for (const key of Reflect.ownKeys(source)) {
80
- const value = source[key];
81
- if (isPlainObject(value)) {
82
- if (!isPlainObject(target[key])) {
83
- target[key] = {};
84
- }
85
- merge(target[key], value);
86
- } else {
87
- target[key] = value;
88
- }
89
- }
90
- }
91
- return merge(target, ...sources);
92
- }
93
- function cloneDeep(value) {
94
- if (value === null || typeof value !== "object") {
95
- return value;
96
- }
97
- if (Array.isArray(value)) {
98
- return value.map(cloneDeep);
99
- }
100
- if (value instanceof Date) {
101
- return new Date(value.getTime());
102
- }
103
- if (value instanceof RegExp) {
104
- return new RegExp(value.source, value.flags);
105
- }
106
- if (value instanceof Map) {
107
- const copy = /* @__PURE__ */ new Map();
108
- value.forEach((val, key) => {
109
- copy.set(cloneDeep(key), cloneDeep(val));
110
- });
111
- return copy;
112
- }
113
- if (value instanceof Set) {
114
- const copy = /* @__PURE__ */ new Set();
115
- value.forEach((val) => {
116
- copy.add(cloneDeep(val));
117
- });
118
- return copy;
119
- }
120
- if (isPlainObject(value)) {
121
- const copy = {};
122
- for (const key of Reflect.ownKeys(value)) {
123
- copy[key] = cloneDeep(value[key]);
124
- }
125
- return copy;
126
- }
127
- return value;
128
- }
129
-
130
- // src/dict-manager.ts
131
- var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
132
5
  function createDictManager(createDictManagerOptions = {}) {
133
6
  const {
134
7
  fetch: managerFetch,
135
8
  extra: managerExtra,
136
- transformer: managerTransformer
9
+ transformer: managerTransformer,
10
+ itemTransformer: managerItemTransformer
137
11
  } = createDictManagerOptions;
138
12
  const maps = reactive(/* @__PURE__ */ Object.create(null));
139
13
  const defineDictOptionsMap = /* @__PURE__ */ new Map();
@@ -143,22 +17,29 @@ function createDictManager(createDictManagerOptions = {}) {
143
17
  (_a = maps[code]) == null ? void 0 : _a.clear();
144
18
  return;
145
19
  }
146
- clearObj(maps);
20
+ Object.values(maps).forEach((map) => map.clear());
147
21
  }
148
22
  function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
149
23
  const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
150
24
  if (maps[code]) {
151
25
  warn(`code "${code}" already exists`);
26
+ } else {
27
+ maps[code] = /* @__PURE__ */ new Map();
152
28
  }
153
29
  const _defineDictOptions = Object.assign(
154
- { data: {}, remote: false, fetch: managerFetch, transformer: managerTransformer },
30
+ {
31
+ data: {},
32
+ remote: false,
33
+ fetch: managerFetch,
34
+ transformer: managerTransformer,
35
+ itemTransformer: managerItemTransformer
36
+ },
155
37
  isFunction(defineDictOptions) ? defineDictOptions() : defineDictOptions
156
38
  );
157
39
  defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
158
- const { data, remote, fetch, extra, transformer } = _defineDictOptions;
159
- const globalLoadPromise = shallowRef(null);
160
- let loaded = false;
161
- maps[code] = /* @__PURE__ */ new Map();
40
+ const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
41
+ let globalLoadPromise = null;
42
+ let init = false;
162
43
  async function loadDict(options, mapRef) {
163
44
  var _a;
164
45
  const dataMap = toMap(cloneDeep(data), { pickValues, omitValues, transformer });
@@ -180,21 +61,23 @@ function createDictManager(createDictManagerOptions = {}) {
180
61
  useDictOptions
181
62
  );
182
63
  const { clone, immediate, refresh } = useDictOptions;
183
- const loadPromise = !clone ? globalLoadPromise : shallowRef(createPromise());
184
- const mapRef = !clone ? toRef(maps, code) : ref();
64
+ const loadPromise = shallowRef(
65
+ !clone ? globalLoadPromise : createPromise()
66
+ );
67
+ const mapRef = !clone ? toRef(maps, code) : ref(/* @__PURE__ */ new Map());
185
68
  const objRef = ref(/* @__PURE__ */ Object.create(null));
186
69
  const listRef = ref([]);
187
70
  if (!remote || immediate) {
188
71
  if (clone) {
189
72
  load();
190
73
  } else {
191
- if (!globalLoadPromise.value) {
192
- globalLoadPromise.value = createPromise();
74
+ if (!globalLoadPromise) {
75
+ globalLoadPromise = createPromise();
193
76
  load();
194
77
  } else {
195
- globalLoadPromise.value.then(() => {
196
- if (!loaded) {
197
- loaded = true;
78
+ globalLoadPromise.then(() => {
79
+ if (!init) {
80
+ init = true;
198
81
  load();
199
82
  } else if (refresh) {
200
83
  load();
@@ -203,9 +86,9 @@ function createDictManager(createDictManagerOptions = {}) {
203
86
  }
204
87
  }
205
88
  } else {
206
- if (!globalLoadPromise.value) {
207
- globalLoadPromise.value = createPromise();
208
- globalLoadPromise.value.resolve();
89
+ if (!globalLoadPromise) {
90
+ globalLoadPromise = createPromise();
91
+ globalLoadPromise.resolve();
209
92
  }
210
93
  }
211
94
  function load(options) {
@@ -218,24 +101,30 @@ function createDictManager(createDictManagerOptions = {}) {
218
101
  return loadPromise.value;
219
102
  }
220
103
  function _clear() {
221
- var _a;
222
- (_a = mapRef.value) == null ? void 0 : _a.clear();
104
+ mapRef.value.clear();
223
105
  }
224
106
  watch(
225
107
  mapRef,
226
108
  (newValue) => {
227
109
  newValue != null ? newValue : newValue = /* @__PURE__ */ new Map();
228
- mapToObj(newValue, objRef.value);
229
- mapToList(newValue, listRef.value);
110
+ mapToObj(newValue, {
111
+ obj: objRef.value,
112
+ itemTransformer
113
+ });
114
+ mapToList(newValue, {
115
+ list: listRef.value,
116
+ itemTransformer
117
+ });
230
118
  },
231
119
  { deep: true, immediate: true }
232
120
  );
233
121
  const E = computed(() => {
122
+ var _a;
234
123
  const result = {};
235
124
  if (!mapRef.value)
236
125
  return result;
237
126
  for (const key of mapRef.value.keys()) {
238
- result[key] = key;
127
+ result[key] = (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key;
239
128
  }
240
129
  return result;
241
130
  });
@@ -255,7 +144,9 @@ function createDictManager(createDictManagerOptions = {}) {
255
144
  const reactiveCtx = reactive(ctx);
256
145
  return reactive({
257
146
  ...ctx,
147
+ // @ts-ignore
258
148
  ...managerExtra == null ? void 0 : managerExtra(reactiveCtx),
149
+ // @ts-ignore
259
150
  ...extra == null ? void 0 : extra(reactiveCtx)
260
151
  });
261
152
  }
@@ -270,4 +161,4 @@ function createDictManager(createDictManagerOptions = {}) {
270
161
  return { defineDict, clear, maps: readonly(maps) };
271
162
  }
272
163
 
273
- export { createDictManager, defineDictData };
164
+ export { createDictManager };
@@ -0,0 +1,308 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+
5
+ // src/react/react-dict-manager.ts
6
+
7
+ // src/create-promise.ts
8
+ var noop = () => {
9
+ };
10
+ function createPromise(executor) {
11
+ let resolve = noop;
12
+ let reject = noop;
13
+ const promise = new Promise((_resolve, _reject) => {
14
+ resolve = _resolve;
15
+ reject = _reject;
16
+ executor == null ? void 0 : executor(_resolve, _reject);
17
+ });
18
+ promise.resolve = resolve;
19
+ promise.reject = reject;
20
+ promise.isPending = true;
21
+ promise.finally(() => {
22
+ promise.isPending = false;
23
+ });
24
+ return promise;
25
+ }
26
+
27
+ // src/util.ts
28
+ var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
29
+ function isFunction(fn) {
30
+ return typeof fn === "function";
31
+ }
32
+ function clearObj(obj) {
33
+ for (const key of Object.keys(obj)) {
34
+ delete obj[key];
35
+ }
36
+ }
37
+ function mapToObj(map, {
38
+ obj = {},
39
+ itemTransformer
40
+ } = {}) {
41
+ var _a;
42
+ clearObj(obj);
43
+ for (const [key, value] of map) {
44
+ obj[key] = (_a = itemTransformer == null ? void 0 : itemTransformer(value)) != null ? _a : value;
45
+ }
46
+ return obj;
47
+ }
48
+ function checkObjItem(item, key, transformer) {
49
+ if (item.value === void 0) {
50
+ item.value = key;
51
+ }
52
+ if (isFunction(transformer)) {
53
+ item.value = transformer(item.value);
54
+ }
55
+ }
56
+ function mapToList(map, {
57
+ list = [],
58
+ itemTransformer
59
+ } = {}) {
60
+ const values = isFunction(itemTransformer) ? map.values().map(itemTransformer) : map.values();
61
+ list.splice(0, list.length, ...values);
62
+ return list;
63
+ }
64
+ function toMap(data, { map = /* @__PURE__ */ new Map(), pickValues = [], omitValues = [], transformer } = {}) {
65
+ const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
66
+ map.clear();
67
+ Object.entries(data).filter(([key, item]) => {
68
+ checkObjItem(item, key, transformer);
69
+ return filterFn(item.value);
70
+ }).forEach(([, item]) => map.set(item.value, item));
71
+ return map;
72
+ }
73
+ var defineDictData = (data) => data;
74
+ var { toString } = Object.prototype;
75
+ function isPlainObject(obj) {
76
+ return toString.call(obj) === "[object Object]";
77
+ }
78
+ function merge(target, ...sources) {
79
+ if (!sources.length)
80
+ return target;
81
+ const source = sources.shift();
82
+ if (source && isPlainObject(source)) {
83
+ for (const key of Reflect.ownKeys(source)) {
84
+ const value = source[key];
85
+ if (isPlainObject(value)) {
86
+ if (!isPlainObject(target[key])) {
87
+ target[key] = {};
88
+ }
89
+ merge(target[key], value);
90
+ } else {
91
+ target[key] = value;
92
+ }
93
+ }
94
+ }
95
+ return merge(target, ...sources);
96
+ }
97
+ function cloneDeep(value) {
98
+ if (value === null || typeof value !== "object") {
99
+ return value;
100
+ }
101
+ if (Array.isArray(value)) {
102
+ return value.map(cloneDeep);
103
+ }
104
+ if (value instanceof Date) {
105
+ return new Date(value.getTime());
106
+ }
107
+ if (value instanceof RegExp) {
108
+ return new RegExp(value.source, value.flags);
109
+ }
110
+ if (value instanceof Map) {
111
+ const copy = /* @__PURE__ */ new Map();
112
+ value.forEach((val, key) => {
113
+ copy.set(cloneDeep(key), cloneDeep(val));
114
+ });
115
+ return copy;
116
+ }
117
+ if (value instanceof Set) {
118
+ const copy = /* @__PURE__ */ new Set();
119
+ value.forEach((val) => {
120
+ copy.add(cloneDeep(val));
121
+ });
122
+ return copy;
123
+ }
124
+ if (isPlainObject(value)) {
125
+ const copy = {};
126
+ for (const key of Reflect.ownKeys(value)) {
127
+ copy[key] = cloneDeep(value[key]);
128
+ }
129
+ return copy;
130
+ }
131
+ return value;
132
+ }
133
+
134
+ // src/react/react-dict-manager.ts
135
+ function createDictManager(createDictManagerOptions = {}) {
136
+ const {
137
+ fetch: managerFetch,
138
+ extra: managerExtra,
139
+ transformer: managerTransformer,
140
+ itemTransformer: managerItemTransformer
141
+ } = createDictManagerOptions;
142
+ const defineDictOptionsMap = /* @__PURE__ */ new Map();
143
+ const maps = /* @__PURE__ */ Object.create(null);
144
+ const versionMap = /* @__PURE__ */ Object.create(null);
145
+ function clear(code) {
146
+ var _a;
147
+ if (code) {
148
+ (_a = maps[code]) == null ? void 0 : _a.clear();
149
+ return;
150
+ }
151
+ Object.values(maps).forEach((map) => map.clear());
152
+ }
153
+ function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
154
+ const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
155
+ if (maps[code]) {
156
+ warn(`code "${code}" already exists`);
157
+ } else {
158
+ maps[code] = /* @__PURE__ */ new Map();
159
+ versionMap[code] = 0;
160
+ }
161
+ const _defineDictOptions = Object.assign(
162
+ {
163
+ data: {},
164
+ remote: false,
165
+ fetch: managerFetch,
166
+ transformer: managerTransformer,
167
+ itemTransformer: managerItemTransformer
168
+ },
169
+ isFunction(defineDictOptions) ? defineDictOptions() : defineDictOptions
170
+ );
171
+ defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
172
+ const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
173
+ let globalLoadPromise = null;
174
+ let init = false;
175
+ async function loadDict(options, mapRef) {
176
+ var _a;
177
+ if (remote) {
178
+ const res = (_a = await (fetch == null ? void 0 : fetch(extendCode != null ? extendCode : code, options))) != null ? _a : [];
179
+ toMap(res, { pickValues, omitValues, transformer, map: mapRef.current });
180
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer }).forEach(
181
+ (value, key) => {
182
+ if (mapRef.current.has(key)) {
183
+ merge(mapRef.current.get(key), value);
184
+ }
185
+ }
186
+ );
187
+ } else {
188
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer, map: mapRef.current });
189
+ }
190
+ versionMap[code] += 1;
191
+ }
192
+ function useDict(useDictOptions = {}) {
193
+ const mergedOptions = {
194
+ clone: false,
195
+ immediate: true,
196
+ refresh: false,
197
+ ...useDictOptions
198
+ };
199
+ const { clone, immediate, refresh } = mergedOptions;
200
+ const loadPromiseRef = react.useRef(
201
+ !clone ? globalLoadPromise : createPromise()
202
+ );
203
+ const mapRef = react.useRef(!clone ? maps[code] : /* @__PURE__ */ new Map());
204
+ const versionRef = react.useRef(0);
205
+ const getStateFromMapRef = () => {
206
+ const newObj = /* @__PURE__ */ Object.create(null);
207
+ const newList = [];
208
+ mapToObj(mapRef.current, {
209
+ obj: newObj,
210
+ itemTransformer
211
+ });
212
+ mapToList(mapRef.current, {
213
+ list: newList,
214
+ itemTransformer
215
+ });
216
+ const newE = Object.fromEntries(
217
+ Array.from(mapRef.current.keys()).map((key) => {
218
+ var _a;
219
+ return [key, (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key];
220
+ })
221
+ );
222
+ return {
223
+ map: newObj,
224
+ list: newList,
225
+ E: newE
226
+ };
227
+ };
228
+ const [state, setState] = react.useState(getStateFromMapRef());
229
+ if (versionRef.current !== versionMap[code]) {
230
+ versionRef.current = versionMap[code];
231
+ setState(getStateFromMapRef());
232
+ }
233
+ const load = react.useCallback((options) => {
234
+ const oldLoadPromise = loadPromiseRef.current;
235
+ loadPromiseRef.current = createPromise();
236
+ loadDict({ ...mergedOptions, ...options }, mapRef).then(() => {
237
+ setState(getStateFromMapRef());
238
+ oldLoadPromise == null ? void 0 : oldLoadPromise.resolve(void 0);
239
+ loadPromiseRef.current.resolve(void 0);
240
+ });
241
+ return loadPromiseRef.current;
242
+ }, []);
243
+ const clear2 = react.useCallback(() => {
244
+ mapRef.current.clear();
245
+ setState(getStateFromMapRef());
246
+ }, []);
247
+ const getItem = react.useCallback((value) => {
248
+ return value !== null && value !== void 0 ? mapRef.current.get(value) : null;
249
+ }, []);
250
+ react.useEffect(() => {
251
+ if (!remote || immediate) {
252
+ if (clone) {
253
+ load();
254
+ } else {
255
+ if (!globalLoadPromise) {
256
+ globalLoadPromise = createPromise();
257
+ load();
258
+ } else {
259
+ globalLoadPromise.then(() => {
260
+ if (!init) {
261
+ init = true;
262
+ load();
263
+ } else if (refresh) {
264
+ load();
265
+ }
266
+ });
267
+ }
268
+ }
269
+ } else {
270
+ if (!globalLoadPromise) {
271
+ globalLoadPromise = createPromise();
272
+ globalLoadPromise.resolve(void 0);
273
+ }
274
+ }
275
+ }, []);
276
+ const ctx = react.useMemo(() => {
277
+ const _ctx = {
278
+ map: state.map,
279
+ list: state.list,
280
+ E: state.E,
281
+ loadPromise: loadPromiseRef.current,
282
+ load,
283
+ getItem,
284
+ clear: clear2
285
+ };
286
+ return {
287
+ ..._ctx,
288
+ // @ts-ignore
289
+ ...managerExtra == null ? void 0 : managerExtra(_ctx),
290
+ // @ts-ignore
291
+ ...extra == null ? void 0 : extra(_ctx)
292
+ };
293
+ }, [state]);
294
+ return ctx;
295
+ }
296
+ useDict.extend = (extendCode2, extendOptions) => {
297
+ const { pickValues: pickValues2, omitValues: omitValues2 } = extendOptions != null ? extendOptions : {};
298
+ const options = defineDictOptionsMap.get(code);
299
+ return _defineDict({ pickValues: pickValues2, omitValues: omitValues2, extendCode: code }, extendCode2, options);
300
+ };
301
+ return useDict;
302
+ }
303
+ const defineDict = _defineDict.bind(null, {});
304
+ return { defineDict, clear, maps };
305
+ }
306
+
307
+ exports.createDictManager = createDictManager;
308
+ exports.defineDictData = defineDictData;
@@ -0,0 +1,3 @@
1
+ export type * from '../types';
2
+ export * from './react-dict-manager';
3
+ export { defineDictData } from '../util';
@@ -0,0 +1,177 @@
1
+ import { warn, isFunction, cloneDeep, createPromise, toMap, merge, mapToObj, mapToList } from '../chunk-SXX4ZFIR.js';
2
+ export { defineDictData } from '../chunk-SXX4ZFIR.js';
3
+ import { useRef, useState, useCallback, useEffect, useMemo } from 'react';
4
+
5
+ function createDictManager(createDictManagerOptions = {}) {
6
+ const {
7
+ fetch: managerFetch,
8
+ extra: managerExtra,
9
+ transformer: managerTransformer,
10
+ itemTransformer: managerItemTransformer
11
+ } = createDictManagerOptions;
12
+ const defineDictOptionsMap = /* @__PURE__ */ new Map();
13
+ const maps = /* @__PURE__ */ Object.create(null);
14
+ const versionMap = /* @__PURE__ */ Object.create(null);
15
+ function clear(code) {
16
+ var _a;
17
+ if (code) {
18
+ (_a = maps[code]) == null ? void 0 : _a.clear();
19
+ return;
20
+ }
21
+ Object.values(maps).forEach((map) => map.clear());
22
+ }
23
+ function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
24
+ const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
25
+ if (maps[code]) {
26
+ warn(`code "${code}" already exists`);
27
+ } else {
28
+ maps[code] = /* @__PURE__ */ new Map();
29
+ versionMap[code] = 0;
30
+ }
31
+ const _defineDictOptions = Object.assign(
32
+ {
33
+ data: {},
34
+ remote: false,
35
+ fetch: managerFetch,
36
+ transformer: managerTransformer,
37
+ itemTransformer: managerItemTransformer
38
+ },
39
+ isFunction(defineDictOptions) ? defineDictOptions() : defineDictOptions
40
+ );
41
+ defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
42
+ const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
43
+ let globalLoadPromise = null;
44
+ let init = false;
45
+ async function loadDict(options, mapRef) {
46
+ var _a;
47
+ if (remote) {
48
+ const res = (_a = await (fetch == null ? void 0 : fetch(extendCode != null ? extendCode : code, options))) != null ? _a : [];
49
+ toMap(res, { pickValues, omitValues, transformer, map: mapRef.current });
50
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer }).forEach(
51
+ (value, key) => {
52
+ if (mapRef.current.has(key)) {
53
+ merge(mapRef.current.get(key), value);
54
+ }
55
+ }
56
+ );
57
+ } else {
58
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer, map: mapRef.current });
59
+ }
60
+ versionMap[code] += 1;
61
+ }
62
+ function useDict(useDictOptions = {}) {
63
+ const mergedOptions = {
64
+ clone: false,
65
+ immediate: true,
66
+ refresh: false,
67
+ ...useDictOptions
68
+ };
69
+ const { clone, immediate, refresh } = mergedOptions;
70
+ const loadPromiseRef = useRef(
71
+ !clone ? globalLoadPromise : createPromise()
72
+ );
73
+ const mapRef = useRef(!clone ? maps[code] : /* @__PURE__ */ new Map());
74
+ const versionRef = useRef(0);
75
+ const getStateFromMapRef = () => {
76
+ const newObj = /* @__PURE__ */ Object.create(null);
77
+ const newList = [];
78
+ mapToObj(mapRef.current, {
79
+ obj: newObj,
80
+ itemTransformer
81
+ });
82
+ mapToList(mapRef.current, {
83
+ list: newList,
84
+ itemTransformer
85
+ });
86
+ const newE = Object.fromEntries(
87
+ Array.from(mapRef.current.keys()).map((key) => {
88
+ var _a;
89
+ return [key, (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key];
90
+ })
91
+ );
92
+ return {
93
+ map: newObj,
94
+ list: newList,
95
+ E: newE
96
+ };
97
+ };
98
+ const [state, setState] = useState(getStateFromMapRef());
99
+ if (versionRef.current !== versionMap[code]) {
100
+ versionRef.current = versionMap[code];
101
+ setState(getStateFromMapRef());
102
+ }
103
+ const load = useCallback((options) => {
104
+ const oldLoadPromise = loadPromiseRef.current;
105
+ loadPromiseRef.current = createPromise();
106
+ loadDict({ ...mergedOptions, ...options }, mapRef).then(() => {
107
+ setState(getStateFromMapRef());
108
+ oldLoadPromise == null ? void 0 : oldLoadPromise.resolve(void 0);
109
+ loadPromiseRef.current.resolve(void 0);
110
+ });
111
+ return loadPromiseRef.current;
112
+ }, []);
113
+ const clear2 = useCallback(() => {
114
+ mapRef.current.clear();
115
+ setState(getStateFromMapRef());
116
+ }, []);
117
+ const getItem = useCallback((value) => {
118
+ return value !== null && value !== void 0 ? mapRef.current.get(value) : null;
119
+ }, []);
120
+ useEffect(() => {
121
+ if (!remote || immediate) {
122
+ if (clone) {
123
+ load();
124
+ } else {
125
+ if (!globalLoadPromise) {
126
+ globalLoadPromise = createPromise();
127
+ load();
128
+ } else {
129
+ globalLoadPromise.then(() => {
130
+ if (!init) {
131
+ init = true;
132
+ load();
133
+ } else if (refresh) {
134
+ load();
135
+ }
136
+ });
137
+ }
138
+ }
139
+ } else {
140
+ if (!globalLoadPromise) {
141
+ globalLoadPromise = createPromise();
142
+ globalLoadPromise.resolve(void 0);
143
+ }
144
+ }
145
+ }, []);
146
+ const ctx = useMemo(() => {
147
+ const _ctx = {
148
+ map: state.map,
149
+ list: state.list,
150
+ E: state.E,
151
+ loadPromise: loadPromiseRef.current,
152
+ load,
153
+ getItem,
154
+ clear: clear2
155
+ };
156
+ return {
157
+ ..._ctx,
158
+ // @ts-ignore
159
+ ...managerExtra == null ? void 0 : managerExtra(_ctx),
160
+ // @ts-ignore
161
+ ...extra == null ? void 0 : extra(_ctx)
162
+ };
163
+ }, [state]);
164
+ return ctx;
165
+ }
166
+ useDict.extend = (extendCode2, extendOptions) => {
167
+ const { pickValues: pickValues2, omitValues: omitValues2 } = extendOptions != null ? extendOptions : {};
168
+ const options = defineDictOptionsMap.get(code);
169
+ return _defineDict({ pickValues: pickValues2, omitValues: omitValues2, extendCode: code }, extendCode2, options);
170
+ };
171
+ return useDict;
172
+ }
173
+ const defineDict = _defineDict.bind(null, {});
174
+ return { defineDict, clear, maps };
175
+ }
176
+
177
+ export { createDictManager };
@@ -0,0 +1,6 @@
1
+ import type { CreateDictManagerOptions, DefineDict, DictMap, ExtraGetter, Fetch, Recordable } from '../types';
2
+ export declare function createDictManager<E extends ExtraGetter, F extends Fetch>(createDictManagerOptions?: CreateDictManagerOptions<E, F>): {
3
+ defineDict: DefineDict<E, F>;
4
+ clear: (code?: string) => void;
5
+ maps: Recordable<DictMap>;
6
+ };
@@ -22,13 +22,14 @@ export type Dict<K extends PropertyKey = PropertyKey, I extends Recordable = Dic
22
22
  clear: () => void;
23
23
  getItem: (value?: I['value'] | Nil) => I | Nil;
24
24
  };
25
- export type Fetch = (code: string, options?: Recordable) => MaybePromise<DictItemRecord[]>;
25
+ export type Fetch = (code: string, options: Recordable) => MaybePromise<DictItemRecord[]>;
26
26
  type FetchOptions<F extends Fetch> = Parameters<F>[1] extends infer T ? T extends Nil ? {} : T : {};
27
27
  export type ExtraGetter<D extends Dict<string> = Dict<string>> = (dict: D) => Recordable;
28
28
  export interface CreateDictManagerOptions<E extends ExtraGetter, F extends Fetch> {
29
29
  fetch?: F;
30
30
  extra?: E;
31
31
  transformer?: (value: DictValue) => DictValue;
32
+ itemTransformer?: (item: DictItemRecord) => any;
32
33
  }
33
34
  export type UseDictOptions = {
34
35
  clone?: boolean;
@@ -56,7 +57,8 @@ export interface DefineDict<ME extends ExtraGetter, MF extends Fetch> {
56
57
  data?: D;
57
58
  extra?: E;
58
59
  transformer?: (value: DictValue) => DictValue;
59
- }>): UseDict<ReturnType<ME> & ReturnType<E>, D, MF>;
60
+ itemTransformer?: (item: DictItemRecord) => any;
61
+ }>): UseDict<ReturnType<ME> & ReturnType<E>, D, F extends undefined ? MF : F>;
60
62
  }
61
63
  export type VDictItem<T extends AnyFn> = ReturnType<T> extends {
62
64
  list: Array<infer R>;
package/dist/util.d.ts CHANGED
@@ -1,15 +1,22 @@
1
1
  import type { AnyFn, DictItemRecord, DictMap, DictValue, Merge, PlainObject, Recordable } from './types';
2
+ export declare const warn: (msg: string) => void;
2
3
  export declare function isFunction(fn: unknown): fn is AnyFn;
3
4
  export declare function clearObj(obj: Recordable): void;
4
- export declare function mapToObj(map: DictMap, obj?: Recordable<DictItemRecord>): Recordable<DictItemRecord>;
5
- export declare function mapToList(map: DictMap, list?: DictItemRecord[]): DictItemRecord[];
6
- export declare function listToMap(list: DictItemRecord[]): Map<DictValue, DictItemRecord>;
5
+ export declare function mapToObj(map: DictMap, { obj, itemTransformer }?: {
6
+ obj?: Recordable<DictItemRecord>;
7
+ itemTransformer?: (item: DictItemRecord) => any;
8
+ }): Recordable<DictItemRecord>;
9
+ export declare function mapToList(map: DictMap, { list, itemTransformer }?: {
10
+ list?: DictItemRecord[];
11
+ itemTransformer?: (item: DictItemRecord) => any;
12
+ }): DictItemRecord[];
7
13
  type MapOptions = {
14
+ map?: DictMap;
8
15
  pickValues?: DictValue[];
9
16
  omitValues?: DictValue[];
10
17
  transformer?: (value: DictValue) => DictValue;
11
18
  };
12
- export declare function toMap(data: Recordable<DictItemRecord> | DictItemRecord[], options?: MapOptions): DictMap;
19
+ export declare function toMap(data: Recordable<DictItemRecord> | DictItemRecord[], { map, pickValues, omitValues, transformer }?: MapOptions): DictMap;
13
20
  export declare const defineDictData: <T>(data: T) => T;
14
21
  export declare function isPlainObject(obj: any): obj is PlainObject;
15
22
  export declare function merge<T extends PlainObject, S extends PlainObject[]>(target: T, ...sources: S): Merge<[T, ...S]>;
@@ -0,0 +1,3 @@
1
+ export type * from '../types';
2
+ export * from './vue-dict-manager';
3
+ export { defineDictData } from '../util';
@@ -1,4 +1,4 @@
1
- import type { CreateDictManagerOptions, DefineDict, DictValue, ExtraGetter, Fetch } from './types';
1
+ import type { CreateDictManagerOptions, DefineDict, DictValue, ExtraGetter, Fetch } from '../types';
2
2
  export declare function createDictManager<E extends ExtraGetter, F extends Fetch>(createDictManagerOptions?: CreateDictManagerOptions<E, F>): {
3
3
  defineDict: DefineDict<E, F>;
4
4
  clear: (code?: string) => void;
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "v-dict",
3
- "version": "1.2.10",
3
+ "version": "2.0.0",
4
4
  "type": "module",
5
- "description": "Vue3 Dict Manager",
5
+ "description": "Vue3 & React Dict Manager",
6
6
  "repository": {
7
7
  "type": "git",
8
8
  "url": "https://github.com/xuuui/v-dict"
@@ -14,7 +14,12 @@
14
14
  ".": {
15
15
  "import": "./dist/index.js",
16
16
  "require": "./dist/index.cjs",
17
- "types": "./lib/index.d.ts"
17
+ "types": "./dist/index.d.ts"
18
+ },
19
+ "./react": {
20
+ "import": "./dist/react/index.js",
21
+ "require": "./dist/react/index.cjs",
22
+ "types": "./dist/react/index.d.ts"
18
23
  },
19
24
  "./*": "./*"
20
25
  },
@@ -32,19 +37,25 @@
32
37
  },
33
38
  "keywords": [
34
39
  "vue",
40
+ "react",
35
41
  "dict",
36
42
  "dictionary",
37
- "vue3"
43
+ "vue3",
44
+ "react-dict"
38
45
  ],
39
46
  "author": "",
40
47
  "license": "MIT",
41
48
  "dependencies": {},
42
49
  "peerDependencies": {
43
- "vue": "^3.0.0"
50
+ "vue": "^3.0.0",
51
+ "react": "^16.8.0 || ^17.0.0 || ^18.0.0",
52
+ "react-dom": "^16.8.0 || ^17.0.0 || ^18.0.0"
44
53
  },
45
54
  "devDependencies": {
46
55
  "@changesets/cli": "^2.27.1",
47
56
  "@types/node": "^20.11.0",
57
+ "@types/react": "^18.3.12",
58
+ "@types/react-dom": "^18.3.1",
48
59
  "tsup": "^8.0.1",
49
60
  "typescript": "^5.7.3",
50
61
  "vue": "^3.4.10"