v-dict 1.2.11 → 2.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.
@@ -1,4 +1,5 @@
1
1
  // src/util.ts
2
+ var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
2
3
  function isFunction(fn) {
3
4
  return typeof fn === "function";
4
5
  }
@@ -7,11 +8,13 @@ function clearObj(obj) {
7
8
  delete obj[key];
8
9
  }
9
10
  }
10
- function mapToObj(map, obj = {}, itemTransformer) {
11
- var _a;
11
+ function mapToObj(map, {
12
+ obj = {},
13
+ itemTransformer
14
+ } = {}) {
12
15
  clearObj(obj);
13
16
  for (const [key, value] of map) {
14
- obj[key] = (_a = itemTransformer == null ? void 0 : itemTransformer(value)) != null ? _a : value;
17
+ obj[key] = isFunction(itemTransformer) ? itemTransformer(value) : value;
15
18
  }
16
19
  return obj;
17
20
  }
@@ -23,21 +26,17 @@ function checkObjItem(item, key, transformer) {
23
26
  item.value = transformer(item.value);
24
27
  }
25
28
  }
26
- function mapToList(map, list = [], itemTransformer) {
27
- const values = itemTransformer ? map.values().map(itemTransformer) : map.values();
29
+ function mapToList(map, {
30
+ list = [],
31
+ itemTransformer
32
+ } = {}) {
33
+ const values = isFunction(itemTransformer) ? map.values().map(itemTransformer) : map.values();
28
34
  list.splice(0, list.length, ...values);
29
35
  return list;
30
36
  }
31
- function listToMap(list) {
32
- return new Map(list.map((item) => [item.value, item]));
33
- }
34
- function toMap(data, options = {}) {
35
- const { pickValues = [], omitValues = [], transformer } = options;
37
+ function toMap(data, { map = /* @__PURE__ */ new Map(), pickValues = [], omitValues = [], transformer } = {}) {
36
38
  const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
37
- if (Array.isArray(data)) {
38
- return listToMap(data.filter((item) => filterFn(item.value)));
39
- }
40
- const map = /* @__PURE__ */ new Map();
39
+ map.clear();
41
40
  Object.entries(data).filter(([key, item]) => {
42
41
  checkObjItem(item, key, transformer);
43
42
  return filterFn(item.value);
@@ -125,4 +124,4 @@ function createPromise(executor) {
125
124
  return promise;
126
125
  }
127
126
 
128
- export { clearObj, cloneDeep, createPromise, defineDictData, isFunction, mapToList, mapToObj, merge, toMap };
127
+ 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,11 +34,13 @@ function clearObj(obj) {
33
34
  delete obj[key];
34
35
  }
35
36
  }
36
- function mapToObj(map, obj = {}, itemTransformer) {
37
- var _a;
37
+ function mapToObj(map, {
38
+ obj = {},
39
+ itemTransformer
40
+ } = {}) {
38
41
  clearObj(obj);
39
42
  for (const [key, value] of map) {
40
- obj[key] = (_a = itemTransformer == null ? void 0 : itemTransformer(value)) != null ? _a : value;
43
+ obj[key] = isFunction(itemTransformer) ? itemTransformer(value) : value;
41
44
  }
42
45
  return obj;
43
46
  }
@@ -49,21 +52,17 @@ function checkObjItem(item, key, transformer) {
49
52
  item.value = transformer(item.value);
50
53
  }
51
54
  }
52
- function mapToList(map, list = [], itemTransformer) {
53
- const values = itemTransformer ? map.values().map(itemTransformer) : map.values();
55
+ function mapToList(map, {
56
+ list = [],
57
+ itemTransformer
58
+ } = {}) {
59
+ const values = isFunction(itemTransformer) ? map.values().map(itemTransformer) : map.values();
54
60
  list.splice(0, list.length, ...values);
55
61
  return list;
56
62
  }
57
- function listToMap(list) {
58
- return new Map(list.map((item) => [item.value, item]));
59
- }
60
- function toMap(data, options = {}) {
61
- const { pickValues = [], omitValues = [], transformer } = options;
63
+ function toMap(data, { map = /* @__PURE__ */ new Map(), pickValues = [], omitValues = [], transformer } = {}) {
62
64
  const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
63
- if (Array.isArray(data)) {
64
- return listToMap(data.filter((item) => filterFn(item.value)));
65
- }
66
- const map = /* @__PURE__ */ new Map();
65
+ map.clear();
67
66
  Object.entries(data).filter(([key, item]) => {
68
67
  checkObjItem(item, key, transformer);
69
68
  return filterFn(item.value);
@@ -131,8 +130,7 @@ function cloneDeep(value) {
131
130
  return value;
132
131
  }
133
132
 
134
- // src/dict-manager.ts
135
- var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
133
+ // src/vue/vue-dict-manager.ts
136
134
  function createDictManager(createDictManagerOptions = {}) {
137
135
  const {
138
136
  fetch: managerFetch,
@@ -148,12 +146,14 @@ function createDictManager(createDictManagerOptions = {}) {
148
146
  (_a = maps[code]) == null ? void 0 : _a.clear();
149
147
  return;
150
148
  }
151
- clearObj(maps);
149
+ Object.values(maps).forEach((map) => map.clear());
152
150
  }
153
151
  function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
154
152
  const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
155
153
  if (maps[code]) {
156
154
  warn(`code "${code}" already exists`);
155
+ } else {
156
+ maps[code] = /* @__PURE__ */ new Map();
157
157
  }
158
158
  const _defineDictOptions = Object.assign(
159
159
  {
@@ -167,9 +167,8 @@ function createDictManager(createDictManagerOptions = {}) {
167
167
  );
168
168
  defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
169
169
  const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
170
- const globalLoadPromise = vue.shallowRef(null);
171
- let loaded = false;
172
- maps[code] = /* @__PURE__ */ new Map();
170
+ let globalLoadPromise = null;
171
+ let init = false;
173
172
  async function loadDict(options, mapRef) {
174
173
  var _a;
175
174
  const dataMap = toMap(cloneDeep(data), { pickValues, omitValues, transformer });
@@ -191,21 +190,23 @@ function createDictManager(createDictManagerOptions = {}) {
191
190
  useDictOptions
192
191
  );
193
192
  const { clone, immediate, refresh } = useDictOptions;
194
- const loadPromise = !clone ? globalLoadPromise : vue.shallowRef(createPromise());
195
- const mapRef = !clone ? vue.toRef(maps, code) : vue.ref();
193
+ const loadPromise = vue.shallowRef(
194
+ !clone ? globalLoadPromise : createPromise()
195
+ );
196
+ const mapRef = !clone ? vue.toRef(maps, code) : vue.ref(/* @__PURE__ */ new Map());
196
197
  const objRef = vue.ref(/* @__PURE__ */ Object.create(null));
197
198
  const listRef = vue.ref([]);
198
199
  if (!remote || immediate) {
199
200
  if (clone) {
200
201
  load();
201
202
  } else {
202
- if (!globalLoadPromise.value) {
203
- globalLoadPromise.value = createPromise();
203
+ if (!globalLoadPromise) {
204
+ globalLoadPromise = createPromise();
204
205
  load();
205
206
  } else {
206
- globalLoadPromise.value.then(() => {
207
- if (!loaded) {
208
- loaded = true;
207
+ globalLoadPromise.then(() => {
208
+ if (!init) {
209
+ init = true;
209
210
  load();
210
211
  } else if (refresh) {
211
212
  load();
@@ -214,9 +215,9 @@ function createDictManager(createDictManagerOptions = {}) {
214
215
  }
215
216
  }
216
217
  } else {
217
- if (!globalLoadPromise.value) {
218
- globalLoadPromise.value = createPromise();
219
- globalLoadPromise.value.resolve();
218
+ if (!globalLoadPromise) {
219
+ globalLoadPromise = createPromise();
220
+ globalLoadPromise.resolve();
220
221
  }
221
222
  }
222
223
  function load(options) {
@@ -229,24 +230,30 @@ function createDictManager(createDictManagerOptions = {}) {
229
230
  return loadPromise.value;
230
231
  }
231
232
  function _clear() {
232
- var _a;
233
- (_a = mapRef.value) == null ? void 0 : _a.clear();
233
+ mapRef.value.clear();
234
234
  }
235
235
  vue.watch(
236
236
  mapRef,
237
237
  (newValue) => {
238
238
  newValue != null ? newValue : newValue = /* @__PURE__ */ new Map();
239
- mapToObj(newValue, objRef.value, itemTransformer);
240
- mapToList(newValue, listRef.value, itemTransformer);
239
+ mapToObj(newValue, {
240
+ obj: objRef.value,
241
+ itemTransformer
242
+ });
243
+ mapToList(newValue, {
244
+ list: listRef.value,
245
+ itemTransformer
246
+ });
241
247
  },
242
248
  { deep: true, immediate: true }
243
249
  );
244
250
  const E = vue.computed(() => {
251
+ var _a;
245
252
  const result = {};
246
253
  if (!mapRef.value)
247
254
  return result;
248
255
  for (const key of mapRef.value.keys()) {
249
- result[key] = key;
256
+ result[key] = (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key;
250
257
  }
251
258
  return result;
252
259
  });
@@ -266,7 +273,9 @@ function createDictManager(createDictManagerOptions = {}) {
266
273
  const reactiveCtx = vue.reactive(ctx);
267
274
  return vue.reactive({
268
275
  ...ctx,
276
+ // @ts-ignore
269
277
  ...managerExtra == null ? void 0 : managerExtra(reactiveCtx),
278
+ // @ts-ignore
270
279
  ...extra == null ? void 0 : extra(reactiveCtx)
271
280
  });
272
281
  }
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,8 +1,7 @@
1
- import { clearObj, isFunction, cloneDeep, createPromise, mapToObj, mapToList, toMap, merge } from './chunk-QAVWCRC2.js';
2
- export { defineDictData } from './chunk-QAVWCRC2.js';
1
+ import { warn, isFunction, cloneDeep, createPromise, mapToObj, mapToList, toMap, merge } from './chunk-E7KZBQBQ.js';
2
+ export { defineDictData } from './chunk-E7KZBQBQ.js';
3
3
  import { reactive, readonly, shallowRef, toRef, ref, watch, computed } from 'vue';
4
4
 
5
- var warn = (msg) => console.warn(`[v-dict]: ${msg}`);
6
5
  function createDictManager(createDictManagerOptions = {}) {
7
6
  const {
8
7
  fetch: managerFetch,
@@ -18,12 +17,14 @@ function createDictManager(createDictManagerOptions = {}) {
18
17
  (_a = maps[code]) == null ? void 0 : _a.clear();
19
18
  return;
20
19
  }
21
- clearObj(maps);
20
+ Object.values(maps).forEach((map) => map.clear());
22
21
  }
23
22
  function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
24
23
  const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
25
24
  if (maps[code]) {
26
25
  warn(`code "${code}" already exists`);
26
+ } else {
27
+ maps[code] = /* @__PURE__ */ new Map();
27
28
  }
28
29
  const _defineDictOptions = Object.assign(
29
30
  {
@@ -37,9 +38,8 @@ function createDictManager(createDictManagerOptions = {}) {
37
38
  );
38
39
  defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
39
40
  const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
40
- const globalLoadPromise = shallowRef(null);
41
- let loaded = false;
42
- maps[code] = /* @__PURE__ */ new Map();
41
+ let globalLoadPromise = null;
42
+ let init = false;
43
43
  async function loadDict(options, mapRef) {
44
44
  var _a;
45
45
  const dataMap = toMap(cloneDeep(data), { pickValues, omitValues, transformer });
@@ -61,21 +61,23 @@ function createDictManager(createDictManagerOptions = {}) {
61
61
  useDictOptions
62
62
  );
63
63
  const { clone, immediate, refresh } = useDictOptions;
64
- const loadPromise = !clone ? globalLoadPromise : shallowRef(createPromise());
65
- 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());
66
68
  const objRef = ref(/* @__PURE__ */ Object.create(null));
67
69
  const listRef = ref([]);
68
70
  if (!remote || immediate) {
69
71
  if (clone) {
70
72
  load();
71
73
  } else {
72
- if (!globalLoadPromise.value) {
73
- globalLoadPromise.value = createPromise();
74
+ if (!globalLoadPromise) {
75
+ globalLoadPromise = createPromise();
74
76
  load();
75
77
  } else {
76
- globalLoadPromise.value.then(() => {
77
- if (!loaded) {
78
- loaded = true;
78
+ globalLoadPromise.then(() => {
79
+ if (!init) {
80
+ init = true;
79
81
  load();
80
82
  } else if (refresh) {
81
83
  load();
@@ -84,9 +86,9 @@ function createDictManager(createDictManagerOptions = {}) {
84
86
  }
85
87
  }
86
88
  } else {
87
- if (!globalLoadPromise.value) {
88
- globalLoadPromise.value = createPromise();
89
- globalLoadPromise.value.resolve();
89
+ if (!globalLoadPromise) {
90
+ globalLoadPromise = createPromise();
91
+ globalLoadPromise.resolve();
90
92
  }
91
93
  }
92
94
  function load(options) {
@@ -99,24 +101,30 @@ function createDictManager(createDictManagerOptions = {}) {
99
101
  return loadPromise.value;
100
102
  }
101
103
  function _clear() {
102
- var _a;
103
- (_a = mapRef.value) == null ? void 0 : _a.clear();
104
+ mapRef.value.clear();
104
105
  }
105
106
  watch(
106
107
  mapRef,
107
108
  (newValue) => {
108
109
  newValue != null ? newValue : newValue = /* @__PURE__ */ new Map();
109
- mapToObj(newValue, objRef.value, itemTransformer);
110
- mapToList(newValue, listRef.value, itemTransformer);
110
+ mapToObj(newValue, {
111
+ obj: objRef.value,
112
+ itemTransformer
113
+ });
114
+ mapToList(newValue, {
115
+ list: listRef.value,
116
+ itemTransformer
117
+ });
111
118
  },
112
119
  { deep: true, immediate: true }
113
120
  );
114
121
  const E = computed(() => {
122
+ var _a;
115
123
  const result = {};
116
124
  if (!mapRef.value)
117
125
  return result;
118
126
  for (const key of mapRef.value.keys()) {
119
- result[key] = key;
127
+ result[key] = (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key;
120
128
  }
121
129
  return result;
122
130
  });
@@ -136,7 +144,9 @@ function createDictManager(createDictManagerOptions = {}) {
136
144
  const reactiveCtx = reactive(ctx);
137
145
  return reactive({
138
146
  ...ctx,
147
+ // @ts-ignore
139
148
  ...managerExtra == null ? void 0 : managerExtra(reactiveCtx),
149
+ // @ts-ignore
140
150
  ...extra == null ? void 0 : extra(reactiveCtx)
141
151
  });
142
152
  }
@@ -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,11 +34,13 @@ function clearObj(obj) {
33
34
  delete obj[key];
34
35
  }
35
36
  }
36
- function mapToObj(map, obj = {}, itemTransformer) {
37
- var _a;
37
+ function mapToObj(map, {
38
+ obj = {},
39
+ itemTransformer
40
+ } = {}) {
38
41
  clearObj(obj);
39
42
  for (const [key, value] of map) {
40
- obj[key] = (_a = itemTransformer == null ? void 0 : itemTransformer(value)) != null ? _a : value;
43
+ obj[key] = isFunction(itemTransformer) ? itemTransformer(value) : value;
41
44
  }
42
45
  return obj;
43
46
  }
@@ -49,21 +52,17 @@ function checkObjItem(item, key, transformer) {
49
52
  item.value = transformer(item.value);
50
53
  }
51
54
  }
52
- function mapToList(map, list = [], itemTransformer) {
53
- const values = itemTransformer ? map.values().map(itemTransformer) : map.values();
55
+ function mapToList(map, {
56
+ list = [],
57
+ itemTransformer
58
+ } = {}) {
59
+ const values = isFunction(itemTransformer) ? map.values().map(itemTransformer) : map.values();
54
60
  list.splice(0, list.length, ...values);
55
61
  return list;
56
62
  }
57
- function listToMap(list) {
58
- return new Map(list.map((item) => [item.value, item]));
59
- }
60
- function toMap(data, options = {}) {
61
- const { pickValues = [], omitValues = [], transformer } = options;
63
+ function toMap(data, { map = /* @__PURE__ */ new Map(), pickValues = [], omitValues = [], transformer } = {}) {
62
64
  const filterFn = (value) => (pickValues.length === 0 || pickValues.includes(value)) && !omitValues.includes(value);
63
- if (Array.isArray(data)) {
64
- return listToMap(data.filter((item) => filterFn(item.value)));
65
- }
66
- const map = /* @__PURE__ */ new Map();
65
+ map.clear();
67
66
  Object.entries(data).filter(([key, item]) => {
68
67
  checkObjItem(item, key, transformer);
69
68
  return filterFn(item.value);
@@ -132,7 +131,6 @@ function cloneDeep(value) {
132
131
  }
133
132
 
134
133
  // src/react/react-dict-manager.ts
135
- var warn = (msg) => console.warn(`[v-dict/react]: ${msg}`);
136
134
  function createDictManager(createDictManagerOptions = {}) {
137
135
  const {
138
136
  fetch: managerFetch,
@@ -140,20 +138,31 @@ function createDictManager(createDictManagerOptions = {}) {
140
138
  transformer: managerTransformer,
141
139
  itemTransformer: managerItemTransformer
142
140
  } = createDictManagerOptions;
143
- const maps = /* @__PURE__ */ Object.create(null);
144
141
  const defineDictOptionsMap = /* @__PURE__ */ new Map();
142
+ const maps = /* @__PURE__ */ Object.create(null);
143
+ const listenersMap = /* @__PURE__ */ Object.create(null);
144
+ function emitChange(code) {
145
+ var _a;
146
+ const listeners = code ? (_a = listenersMap[code]) != null ? _a : [] : Object.values(listenersMap).flat();
147
+ for (let listener of listeners) {
148
+ listener();
149
+ }
150
+ }
145
151
  function clear(code) {
146
152
  var _a;
147
153
  if (code) {
148
154
  (_a = maps[code]) == null ? void 0 : _a.clear();
149
- return;
155
+ } else {
156
+ Object.values(maps).forEach((map) => map == null ? void 0 : map.clear());
150
157
  }
151
- clearObj(maps);
158
+ emitChange(code);
152
159
  }
153
160
  function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
154
161
  const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
155
162
  if (maps[code]) {
156
163
  warn(`code "${code}" already exists`);
164
+ } else {
165
+ maps[code] = /* @__PURE__ */ new Map();
157
166
  }
158
167
  const _defineDictOptions = Object.assign(
159
168
  {
@@ -168,82 +177,99 @@ function createDictManager(createDictManagerOptions = {}) {
168
177
  defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
169
178
  const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
170
179
  let globalLoadPromise = null;
171
- let loaded = false;
172
- maps[code] = /* @__PURE__ */ new Map();
173
- async function loadDict(options, mapRef) {
180
+ let init = false;
181
+ async function loadDict(options, map = /* @__PURE__ */ new Map()) {
174
182
  var _a;
175
- const dataMap = toMap(cloneDeep(data), { pickValues, omitValues, transformer });
176
183
  if (remote) {
177
184
  const res = (_a = await (fetch == null ? void 0 : fetch(extendCode != null ? extendCode : code, options))) != null ? _a : [];
178
- mapRef.current = toMap(res, { pickValues, omitValues, transformer });
179
- dataMap.forEach((value, key) => {
180
- if (mapRef.current.has(key)) {
181
- merge(mapRef.current.get(key), value);
185
+ toMap(res, { pickValues, omitValues, transformer, map });
186
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer }).forEach(
187
+ (value, key) => {
188
+ if (map.has(key)) {
189
+ merge(map.get(key), value);
190
+ }
182
191
  }
183
- });
192
+ );
184
193
  } else {
185
- mapRef.current = dataMap;
194
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer, map });
186
195
  }
196
+ return map;
187
197
  }
188
- function useDict(useDictOptions = {}) {
189
- const mergedOptions = Object.assign(
190
- { clone: false, immediate: true, refresh: false },
191
- useDictOptions
198
+ function subscribeMap(listener) {
199
+ var _a;
200
+ listenersMap[code] = [...(_a = listenersMap[code]) != null ? _a : [], listener];
201
+ return () => {
202
+ listenersMap[code] = listenersMap[code].filter((l) => l !== listener);
203
+ };
204
+ }
205
+ function getMapSnapshot() {
206
+ return maps[code];
207
+ }
208
+ const createStateFromMap = (map = /* @__PURE__ */ new Map()) => {
209
+ const newObj = /* @__PURE__ */ Object.create(null);
210
+ const newList = [];
211
+ mapToObj(map, {
212
+ obj: newObj,
213
+ itemTransformer
214
+ });
215
+ mapToList(map, {
216
+ list: newList,
217
+ itemTransformer
218
+ });
219
+ const newE = Object.fromEntries(
220
+ Array.from(map.keys()).map((key) => {
221
+ var _a;
222
+ return [key, (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key];
223
+ })
192
224
  );
225
+ return {
226
+ map: newObj,
227
+ list: newList,
228
+ E: newE
229
+ };
230
+ };
231
+ function useDict(useDictOptions = {}) {
232
+ const mergedOptions = {
233
+ clone: false,
234
+ immediate: true,
235
+ refresh: false,
236
+ ...useDictOptions
237
+ };
193
238
  const { clone, immediate, refresh } = mergedOptions;
194
239
  const loadPromiseRef = react.useRef(
195
- !clone ? globalLoadPromise != null ? globalLoadPromise : createPromise() : createPromise()
240
+ !clone ? globalLoadPromise : createPromise()
241
+ );
242
+ const map = react.useSyncExternalStore(subscribeMap, getMapSnapshot);
243
+ const [clonedMap, setClonedMap] = react.useState(/* @__PURE__ */ new Map());
244
+ const state = react.useMemo(
245
+ () => createStateFromMap(!clone ? map : clonedMap),
246
+ [clone, map, clonedMap]
196
247
  );
197
- const mapRef = react.useRef(!clone ? maps[code] : /* @__PURE__ */ new Map());
198
- const objRef = react.useRef(/* @__PURE__ */ Object.create(null));
199
- const listRef = react.useRef([]);
200
- const synMapRef = () => {
201
- const newObj = /* @__PURE__ */ Object.create(null);
202
- const newList = [];
203
- mapToObj(mapRef.current, newObj, itemTransformer);
204
- mapToList(mapRef.current, newList, itemTransformer);
205
- objRef.current = newObj;
206
- listRef.current = newList;
207
- };
208
- const extractE = () => {
209
- return Object.fromEntries(
210
- Array.from(mapRef.current.keys()).map((key) => [String(key), String(key)])
211
- );
212
- };
213
- synMapRef();
214
- const [state, setState] = react.useState({
215
- map: objRef.current,
216
- list: listRef.current,
217
- E: extractE()
218
- });
219
248
  const load = react.useCallback((options) => {
220
249
  const oldLoadPromise = loadPromiseRef.current;
221
- const newLoadPromise = createPromise();
222
- loadPromiseRef.current = newLoadPromise;
223
- loadDict(Object.assign({}, mergedOptions, options), mapRef).then(() => {
224
- synMapRef();
225
- setState({
226
- map: objRef.current,
227
- list: listRef.current,
228
- E: extractE()
229
- });
250
+ loadPromiseRef.current = createPromise();
251
+ loadDict({ ...mergedOptions, ...options }).then((map2) => {
252
+ if (!clone) {
253
+ maps[code] = map2;
254
+ emitChange(code);
255
+ } else {
256
+ setClonedMap(map2);
257
+ }
230
258
  oldLoadPromise == null ? void 0 : oldLoadPromise.resolve(void 0);
231
- newLoadPromise.resolve(void 0);
259
+ loadPromiseRef.current.resolve(void 0);
232
260
  });
233
- return newLoadPromise;
261
+ return loadPromiseRef.current;
234
262
  }, []);
235
263
  const clear2 = react.useCallback(() => {
236
- var _a;
237
- (_a = mapRef.current) == null ? void 0 : _a.clear();
238
- setState({
239
- map: /* @__PURE__ */ Object.create(null),
240
- list: [],
241
- E: {}
242
- });
264
+ if (!clone) {
265
+ maps[code] = /* @__PURE__ */ new Map();
266
+ emitChange(code);
267
+ return;
268
+ }
269
+ setClonedMap(map);
243
270
  }, []);
244
271
  const getItem = react.useCallback((value) => {
245
- var _a;
246
- return value !== null && value !== void 0 ? (_a = mapRef.current) == null ? void 0 : _a.get(value) : null;
272
+ return value !== null && value !== void 0 ? state.map[value] : null;
247
273
  }, []);
248
274
  react.useEffect(() => {
249
275
  if (!remote || immediate) {
@@ -255,8 +281,8 @@ function createDictManager(createDictManagerOptions = {}) {
255
281
  load();
256
282
  } else {
257
283
  globalLoadPromise.then(() => {
258
- if (!loaded) {
259
- loaded = true;
284
+ if (!init) {
285
+ init = true;
260
286
  load();
261
287
  } else if (refresh) {
262
288
  load();
@@ -283,10 +309,12 @@ function createDictManager(createDictManagerOptions = {}) {
283
309
  };
284
310
  return {
285
311
  ..._ctx,
312
+ // @ts-ignore
286
313
  ...managerExtra == null ? void 0 : managerExtra(_ctx),
314
+ // @ts-ignore
287
315
  ...extra == null ? void 0 : extra(_ctx)
288
316
  };
289
- }, [state]);
317
+ }, [state, loadPromiseRef.current]);
290
318
  return ctx;
291
319
  }
292
320
  useDict.extend = (extendCode2, extendOptions) => {
@@ -1,8 +1,7 @@
1
- import { clearObj, isFunction, cloneDeep, createPromise, toMap, merge, mapToObj, mapToList } from '../chunk-QAVWCRC2.js';
2
- export { defineDictData } from '../chunk-QAVWCRC2.js';
3
- import { useRef, useState, useCallback, useEffect, useMemo } from 'react';
1
+ import { warn, isFunction, cloneDeep, createPromise, toMap, merge, mapToObj, mapToList } from '../chunk-E7KZBQBQ.js';
2
+ export { defineDictData } from '../chunk-E7KZBQBQ.js';
3
+ import { useRef, useSyncExternalStore, useState, useMemo, useCallback, useEffect } from 'react';
4
4
 
5
- var warn = (msg) => console.warn(`[v-dict/react]: ${msg}`);
6
5
  function createDictManager(createDictManagerOptions = {}) {
7
6
  const {
8
7
  fetch: managerFetch,
@@ -10,20 +9,31 @@ function createDictManager(createDictManagerOptions = {}) {
10
9
  transformer: managerTransformer,
11
10
  itemTransformer: managerItemTransformer
12
11
  } = createDictManagerOptions;
13
- const maps = /* @__PURE__ */ Object.create(null);
14
12
  const defineDictOptionsMap = /* @__PURE__ */ new Map();
13
+ const maps = /* @__PURE__ */ Object.create(null);
14
+ const listenersMap = /* @__PURE__ */ Object.create(null);
15
+ function emitChange(code) {
16
+ var _a;
17
+ const listeners = code ? (_a = listenersMap[code]) != null ? _a : [] : Object.values(listenersMap).flat();
18
+ for (let listener of listeners) {
19
+ listener();
20
+ }
21
+ }
15
22
  function clear(code) {
16
23
  var _a;
17
24
  if (code) {
18
25
  (_a = maps[code]) == null ? void 0 : _a.clear();
19
- return;
26
+ } else {
27
+ Object.values(maps).forEach((map) => map == null ? void 0 : map.clear());
20
28
  }
21
- clearObj(maps);
29
+ emitChange(code);
22
30
  }
23
31
  function _defineDict(defineDictInternalOptions, code, defineDictOptions) {
24
32
  const { pickValues, omitValues, extendCode } = defineDictInternalOptions;
25
33
  if (maps[code]) {
26
34
  warn(`code "${code}" already exists`);
35
+ } else {
36
+ maps[code] = /* @__PURE__ */ new Map();
27
37
  }
28
38
  const _defineDictOptions = Object.assign(
29
39
  {
@@ -38,82 +48,99 @@ function createDictManager(createDictManagerOptions = {}) {
38
48
  defineDictOptionsMap.set(code, cloneDeep(_defineDictOptions));
39
49
  const { data, remote, fetch, extra, transformer, itemTransformer } = _defineDictOptions;
40
50
  let globalLoadPromise = null;
41
- let loaded = false;
42
- maps[code] = /* @__PURE__ */ new Map();
43
- async function loadDict(options, mapRef) {
51
+ let init = false;
52
+ async function loadDict(options, map = /* @__PURE__ */ new Map()) {
44
53
  var _a;
45
- const dataMap = toMap(cloneDeep(data), { pickValues, omitValues, transformer });
46
54
  if (remote) {
47
55
  const res = (_a = await (fetch == null ? void 0 : fetch(extendCode != null ? extendCode : code, options))) != null ? _a : [];
48
- mapRef.current = toMap(res, { pickValues, omitValues, transformer });
49
- dataMap.forEach((value, key) => {
50
- if (mapRef.current.has(key)) {
51
- merge(mapRef.current.get(key), value);
56
+ toMap(res, { pickValues, omitValues, transformer, map });
57
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer }).forEach(
58
+ (value, key) => {
59
+ if (map.has(key)) {
60
+ merge(map.get(key), value);
61
+ }
52
62
  }
53
- });
63
+ );
54
64
  } else {
55
- mapRef.current = dataMap;
65
+ toMap(cloneDeep(data), { pickValues, omitValues, transformer, map });
56
66
  }
67
+ return map;
57
68
  }
58
- function useDict(useDictOptions = {}) {
59
- const mergedOptions = Object.assign(
60
- { clone: false, immediate: true, refresh: false },
61
- useDictOptions
69
+ function subscribeMap(listener) {
70
+ var _a;
71
+ listenersMap[code] = [...(_a = listenersMap[code]) != null ? _a : [], listener];
72
+ return () => {
73
+ listenersMap[code] = listenersMap[code].filter((l) => l !== listener);
74
+ };
75
+ }
76
+ function getMapSnapshot() {
77
+ return maps[code];
78
+ }
79
+ const createStateFromMap = (map = /* @__PURE__ */ new Map()) => {
80
+ const newObj = /* @__PURE__ */ Object.create(null);
81
+ const newList = [];
82
+ mapToObj(map, {
83
+ obj: newObj,
84
+ itemTransformer
85
+ });
86
+ mapToList(map, {
87
+ list: newList,
88
+ itemTransformer
89
+ });
90
+ const newE = Object.fromEntries(
91
+ Array.from(map.keys()).map((key) => {
92
+ var _a;
93
+ return [key, (_a = transformer == null ? void 0 : transformer(key)) != null ? _a : key];
94
+ })
62
95
  );
96
+ return {
97
+ map: newObj,
98
+ list: newList,
99
+ E: newE
100
+ };
101
+ };
102
+ function useDict(useDictOptions = {}) {
103
+ const mergedOptions = {
104
+ clone: false,
105
+ immediate: true,
106
+ refresh: false,
107
+ ...useDictOptions
108
+ };
63
109
  const { clone, immediate, refresh } = mergedOptions;
64
110
  const loadPromiseRef = useRef(
65
- !clone ? globalLoadPromise != null ? globalLoadPromise : createPromise() : createPromise()
111
+ !clone ? globalLoadPromise : createPromise()
112
+ );
113
+ const map = useSyncExternalStore(subscribeMap, getMapSnapshot);
114
+ const [clonedMap, setClonedMap] = useState(/* @__PURE__ */ new Map());
115
+ const state = useMemo(
116
+ () => createStateFromMap(!clone ? map : clonedMap),
117
+ [clone, map, clonedMap]
66
118
  );
67
- const mapRef = useRef(!clone ? maps[code] : /* @__PURE__ */ new Map());
68
- const objRef = useRef(/* @__PURE__ */ Object.create(null));
69
- const listRef = useRef([]);
70
- const synMapRef = () => {
71
- const newObj = /* @__PURE__ */ Object.create(null);
72
- const newList = [];
73
- mapToObj(mapRef.current, newObj, itemTransformer);
74
- mapToList(mapRef.current, newList, itemTransformer);
75
- objRef.current = newObj;
76
- listRef.current = newList;
77
- };
78
- const extractE = () => {
79
- return Object.fromEntries(
80
- Array.from(mapRef.current.keys()).map((key) => [String(key), String(key)])
81
- );
82
- };
83
- synMapRef();
84
- const [state, setState] = useState({
85
- map: objRef.current,
86
- list: listRef.current,
87
- E: extractE()
88
- });
89
119
  const load = useCallback((options) => {
90
120
  const oldLoadPromise = loadPromiseRef.current;
91
- const newLoadPromise = createPromise();
92
- loadPromiseRef.current = newLoadPromise;
93
- loadDict(Object.assign({}, mergedOptions, options), mapRef).then(() => {
94
- synMapRef();
95
- setState({
96
- map: objRef.current,
97
- list: listRef.current,
98
- E: extractE()
99
- });
121
+ loadPromiseRef.current = createPromise();
122
+ loadDict({ ...mergedOptions, ...options }).then((map2) => {
123
+ if (!clone) {
124
+ maps[code] = map2;
125
+ emitChange(code);
126
+ } else {
127
+ setClonedMap(map2);
128
+ }
100
129
  oldLoadPromise == null ? void 0 : oldLoadPromise.resolve(void 0);
101
- newLoadPromise.resolve(void 0);
130
+ loadPromiseRef.current.resolve(void 0);
102
131
  });
103
- return newLoadPromise;
132
+ return loadPromiseRef.current;
104
133
  }, []);
105
134
  const clear2 = useCallback(() => {
106
- var _a;
107
- (_a = mapRef.current) == null ? void 0 : _a.clear();
108
- setState({
109
- map: /* @__PURE__ */ Object.create(null),
110
- list: [],
111
- E: {}
112
- });
135
+ if (!clone) {
136
+ maps[code] = /* @__PURE__ */ new Map();
137
+ emitChange(code);
138
+ return;
139
+ }
140
+ setClonedMap(map);
113
141
  }, []);
114
142
  const getItem = useCallback((value) => {
115
- var _a;
116
- return value !== null && value !== void 0 ? (_a = mapRef.current) == null ? void 0 : _a.get(value) : null;
143
+ return value !== null && value !== void 0 ? state.map[value] : null;
117
144
  }, []);
118
145
  useEffect(() => {
119
146
  if (!remote || immediate) {
@@ -125,8 +152,8 @@ function createDictManager(createDictManagerOptions = {}) {
125
152
  load();
126
153
  } else {
127
154
  globalLoadPromise.then(() => {
128
- if (!loaded) {
129
- loaded = true;
155
+ if (!init) {
156
+ init = true;
130
157
  load();
131
158
  } else if (refresh) {
132
159
  load();
@@ -153,10 +180,12 @@ function createDictManager(createDictManagerOptions = {}) {
153
180
  };
154
181
  return {
155
182
  ..._ctx,
183
+ // @ts-ignore
156
184
  ...managerExtra == null ? void 0 : managerExtra(_ctx),
185
+ // @ts-ignore
157
186
  ...extra == null ? void 0 : extra(_ctx)
158
187
  };
159
- }, [state]);
188
+ }, [state, loadPromiseRef.current]);
160
189
  return ctx;
161
190
  }
162
191
  useDict.extend = (extendCode2, extendOptions) => {
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>, itemTransformer?: (item: DictItemRecord) => any): Recordable<DictItemRecord>;
5
- export declare function mapToList(map: DictMap, list?: DictItemRecord[], itemTransformer?: (item: DictItemRecord) => any): 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,6 +1,6 @@
1
1
  {
2
2
  "name": "v-dict",
3
- "version": "1.2.11",
3
+ "version": "2.0.1",
4
4
  "type": "module",
5
5
  "description": "Vue3 & React Dict Manager",
6
6
  "repository": {