@akanjs/store 0.0.54 → 0.0.56

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/index.mjs ADDED
@@ -0,0 +1 @@
1
+ export * from "./src";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@akanjs/store",
3
- "version": "0.0.54",
3
+ "version": "0.0.56",
4
4
  "type": "commonjs",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,5 +17,11 @@
17
17
  "dependencies": {
18
18
  "react": "^18.3.1",
19
19
  "zustand": "^5.0.2"
20
+ },
21
+ "exports": {
22
+ ".": {
23
+ "require": "./index.js",
24
+ "import": "./index.mjs"
25
+ }
20
26
  }
21
27
  }
package/src/index.mjs ADDED
@@ -0,0 +1,2 @@
1
+ export * from "./types";
2
+ export * from "./storeDecorators";
@@ -0,0 +1,1095 @@
1
+ "use client";
2
+ import { DataList } from "@akanjs/base";
3
+ import {
4
+ applyMixins,
5
+ capitalize,
6
+ deepObjectify,
7
+ isQueryEqual,
8
+ Logger,
9
+ lowerlize,
10
+ pathSet
11
+ } from "@akanjs/common";
12
+ import {
13
+ getClassMeta,
14
+ getFieldMetas,
15
+ getFullModelRef,
16
+ getLightModelRef
17
+ } from "@akanjs/constant";
18
+ import { msg } from "@akanjs/dictionary";
19
+ import {
20
+ getGqlOnStorage,
21
+ immerify
22
+ } from "@akanjs/signal";
23
+ import { useEffect, useRef } from "react";
24
+ import { create } from "zustand";
25
+ import { devtools, subscribeWithSelector } from "zustand/middleware";
26
+ import { immer } from "zustand/middleware/immer";
27
+ const st = {};
28
+ class StoreStorage {
29
+ }
30
+ const getStoreMeta = (storeName) => {
31
+ const storeMeta = Reflect.getMetadata(storeName, StoreStorage.prototype);
32
+ if (!storeMeta)
33
+ throw new Error(`storeMeta is not defined: ${storeName}`);
34
+ return storeMeta;
35
+ };
36
+ const setStoreMeta = (storeName, storeMeta) => {
37
+ Reflect.defineMetadata(storeName, storeMeta, StoreStorage.prototype);
38
+ };
39
+ const getStoreNames = () => {
40
+ const storeNames = Reflect.getMetadataKeys(StoreStorage.prototype);
41
+ if (!storeNames)
42
+ throw new Error(`storeNames is not defined`);
43
+ return storeNames;
44
+ };
45
+ const createState = (gql) => {
46
+ const [fieldName, className] = [lowerlize(gql.refName), capitalize(gql.refName)];
47
+ const names = {
48
+ model: fieldName,
49
+ Model: className,
50
+ modelLoading: `${fieldName}Loading`,
51
+ modelForm: `${fieldName}Form`,
52
+ modelFormLoading: `${fieldName}FormLoading`,
53
+ modelSubmit: `${fieldName}Submit`,
54
+ modelViewAt: `${fieldName}ViewAt`,
55
+ modelModal: `${fieldName}Modal`,
56
+ modelOperation: `${fieldName}Operation`,
57
+ defaultModel: `default${className}`,
58
+ defaultModelInsight: `default${className}Insight`,
59
+ modelList: `${fieldName}List`,
60
+ modelListLoading: `${fieldName}ListLoading`,
61
+ modelInitList: `${fieldName}InitList`,
62
+ modelInitAt: `${fieldName}InitAt`,
63
+ modelSelection: `${fieldName}Selection`,
64
+ modelInsight: `${fieldName}Insight`,
65
+ lastPageOfModel: `lastPageOf${className}`,
66
+ pageOfModel: `pageOf${className}`,
67
+ limitOfModel: `limitOf${className}`,
68
+ queryArgsOfModel: `queryArgsOf${className}`,
69
+ sortOfModel: `sortOf${className}`
70
+ };
71
+ const baseState = {
72
+ [names.model]: null,
73
+ [names.modelLoading]: true,
74
+ [names.modelForm]: { ...gql[names.defaultModel] },
75
+ [names.modelFormLoading]: true,
76
+ [names.modelSubmit]: { disabled: true, loading: false, times: 0 },
77
+ [names.modelViewAt]: /* @__PURE__ */ new Date(0),
78
+ [names.modelModal]: null,
79
+ [names.modelOperation]: "sleep"
80
+ };
81
+ const sliceState = gql.slices.reduce((acc, { sliceName, defaultArgs }) => {
82
+ const SliceName = capitalize(sliceName);
83
+ const namesOfSlice = {
84
+ defaultModel: SliceName.replace(names.Model, names.defaultModel),
85
+ //clusterInSelf Cluster
86
+ modelList: sliceName.replace(names.model, names.modelList),
87
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading),
88
+ modelInitList: sliceName.replace(names.model, names.modelInitList),
89
+ modelInitAt: sliceName.replace(names.model, names.modelInitAt),
90
+ modelSelection: sliceName.replace(names.model, names.modelSelection),
91
+ modelInsight: sliceName.replace(names.model, names.modelInsight),
92
+ lastPageOfModel: SliceName.replace(names.Model, names.lastPageOfModel),
93
+ pageOfModel: SliceName.replace(names.Model, names.pageOfModel),
94
+ limitOfModel: SliceName.replace(names.Model, names.limitOfModel),
95
+ queryArgsOfModel: SliceName.replace(names.Model, names.queryArgsOfModel),
96
+ sortOfModel: SliceName.replace(names.Model, names.sortOfModel)
97
+ };
98
+ const singleSliceState = {
99
+ [namesOfSlice.defaultModel]: { ...gql[names.defaultModel] },
100
+ [namesOfSlice.modelList]: new DataList(),
101
+ [namesOfSlice.modelListLoading]: true,
102
+ [namesOfSlice.modelInitList]: new DataList(),
103
+ [namesOfSlice.modelInitAt]: /* @__PURE__ */ new Date(0),
104
+ [namesOfSlice.modelSelection]: new DataList(),
105
+ [namesOfSlice.modelInsight]: gql[names.defaultModelInsight],
106
+ [namesOfSlice.lastPageOfModel]: 1,
107
+ [namesOfSlice.pageOfModel]: 1,
108
+ [namesOfSlice.limitOfModel]: 20,
109
+ [namesOfSlice.queryArgsOfModel]: defaultArgs,
110
+ [namesOfSlice.sortOfModel]: "latest"
111
+ };
112
+ return Object.assign(acc, singleSliceState);
113
+ }, {});
114
+ return { ...baseState, ...sliceState };
115
+ };
116
+ const createActions = (gql) => {
117
+ const formSetterActions = makeFormSetter(gql);
118
+ const baseActions = makeActions(gql);
119
+ return { ...formSetterActions, ...baseActions };
120
+ };
121
+ const makeFormSetter = (gql) => {
122
+ const fileGql = getGqlOnStorage("file");
123
+ const [fieldName, className] = [lowerlize(gql.refName), capitalize(gql.refName)];
124
+ const modelRef = getFullModelRef(gql.refName);
125
+ const fieldMetas = getFieldMetas(modelRef);
126
+ const names = {
127
+ model: fieldName,
128
+ Model: className,
129
+ modelForm: `${fieldName}Form`,
130
+ writeOnModel: `writeOn${className}`,
131
+ addModelFiles: `add${className}Files`
132
+ };
133
+ const baseSetAction = {
134
+ [names.writeOnModel]: function(path, value) {
135
+ this.set((state) => {
136
+ pathSet(state[names.modelForm], path, value);
137
+ });
138
+ }
139
+ };
140
+ const fieldSetAction = fieldMetas.reduce((acc, fieldMeta) => {
141
+ const [fieldKeyName, classKeyName] = [lowerlize(fieldMeta.key), capitalize(fieldMeta.key)];
142
+ const namesOfField = {
143
+ field: fieldKeyName,
144
+ Field: classKeyName,
145
+ setFieldOnModel: `set${classKeyName}On${className}`,
146
+ addFieldOnModel: `add${classKeyName}On${className}`,
147
+ subFieldOnModel: `sub${classKeyName}On${className}`,
148
+ addOrSubFieldOnModel: `addOrSub${classKeyName}On${className}`,
149
+ uploadFieldOnModel: `upload${classKeyName}On${className}`
150
+ };
151
+ const singleFieldSetAction = {
152
+ [namesOfField.setFieldOnModel]: function(value) {
153
+ this.set((state) => {
154
+ const setValue = fieldMeta.isClass ? immerify(fieldMeta.modelRef, value) : value;
155
+ state[names.modelForm][namesOfField.field] = setValue;
156
+ });
157
+ },
158
+ ...fieldMeta.isArray ? {
159
+ [namesOfField.addFieldOnModel]: function(value, options = {}) {
160
+ const form = this.get()[names.modelForm];
161
+ const length = form[namesOfField.field].length;
162
+ if (options.limit && options.limit <= length)
163
+ return;
164
+ const idx = options.idx ?? length;
165
+ const setValue = fieldMeta.isClass ? immerify(fieldMeta.modelRef, value) : value;
166
+ this.set((state) => {
167
+ state[names.modelForm][namesOfField.field] = [
168
+ ...form[namesOfField.field].slice(0, idx),
169
+ ...Array.isArray(setValue) ? setValue : [setValue],
170
+ ...form[namesOfField.field].slice(idx)
171
+ ];
172
+ });
173
+ },
174
+ [namesOfField.subFieldOnModel]: function(idx) {
175
+ const form = this.get()[names.modelForm];
176
+ this.set((state) => {
177
+ state[names.modelForm][namesOfField.field] = typeof idx === "number" ? form[namesOfField.field].filter((_, i) => i !== idx) : form[namesOfField.field].filter((_, i) => !idx.includes(i));
178
+ });
179
+ },
180
+ [namesOfField.addOrSubFieldOnModel]: function(value, options = {}) {
181
+ const { [names.modelForm]: form } = this.get();
182
+ const index = form[namesOfField.field].findIndex((v) => v === value);
183
+ if (index === -1)
184
+ this[namesOfField.addFieldOnModel](value, options);
185
+ else
186
+ this[namesOfField.subFieldOnModel](index);
187
+ }
188
+ } : {},
189
+ ...fieldMeta.name === "File" ? {
190
+ [namesOfField.uploadFieldOnModel]: async function(fileList, index) {
191
+ const form = this.get()[names.modelForm];
192
+ if (!fileList.length)
193
+ return;
194
+ const files = await gql[names.addModelFiles](
195
+ fileList,
196
+ form.id
197
+ );
198
+ if (fieldMeta.isArray) {
199
+ const idx = index ?? form[namesOfField.field].length;
200
+ this.set((state) => {
201
+ state[names.modelForm][namesOfField.field] = [
202
+ ...form[namesOfField.field].slice(0, idx),
203
+ ...files,
204
+ ...form[namesOfField.field].slice(idx)
205
+ ];
206
+ });
207
+ } else {
208
+ this.set((state) => {
209
+ state[names.modelForm][namesOfField.field] = files[0];
210
+ });
211
+ }
212
+ files.map((file) => {
213
+ const intervalKey = setInterval(() => {
214
+ void (async () => {
215
+ const currentFile = await fileGql.file(file.id);
216
+ if (fieldMeta.isArray)
217
+ this.set((state) => {
218
+ state[names.modelForm][namesOfField.field] = state[names.modelForm][namesOfField.field].map(
219
+ (file2) => file2.id === currentFile.id ? currentFile : file2
220
+ );
221
+ });
222
+ else
223
+ this.set((state) => {
224
+ state[names.modelForm][namesOfField.field] = currentFile;
225
+ });
226
+ if (currentFile.status !== "uploading")
227
+ clearInterval(intervalKey);
228
+ })();
229
+ }, 3e3);
230
+ });
231
+ }
232
+ } : {}
233
+ };
234
+ return Object.assign(acc, singleFieldSetAction);
235
+ }, {});
236
+ return Object.assign(fieldSetAction, baseSetAction);
237
+ };
238
+ const makeActions = (gql) => {
239
+ const [fieldName, className] = [lowerlize(gql.refName), capitalize(gql.refName)];
240
+ const modelRef = getFullModelRef(className);
241
+ const lightModelRef = getLightModelRef(modelRef);
242
+ const names = {
243
+ model: fieldName,
244
+ _model: `_${fieldName}`,
245
+ Model: className,
246
+ purifyModel: `purify${className}`,
247
+ crystalizeModel: `crystalize${className}`,
248
+ lightCrystalizeModel: `lightCrystalize${className}`,
249
+ crystalizeInsight: `crystalize${className}Insight`,
250
+ modelOperation: `${fieldName}Operation`,
251
+ defaultModel: `default${className}`,
252
+ modelInsight: `${fieldName}Insight`,
253
+ modelForm: `${fieldName}Form`,
254
+ modelSubmit: `${fieldName}Submit`,
255
+ modelLoading: `${fieldName}Loading`,
256
+ modelFormLoading: `${fieldName}FormLoading`,
257
+ modelList: `${fieldName}List`,
258
+ modelListLoading: `${fieldName}ListLoading`,
259
+ modelSelection: `${fieldName}Selection`,
260
+ createModelInForm: `create${className}InForm`,
261
+ updateModelInForm: `modify${className}InForm`,
262
+ createModel: `create${className}`,
263
+ updateModel: `update${className}`,
264
+ removeModel: `remove${className}`,
265
+ checkModelSubmitable: `check${className}Submitable`,
266
+ submitModel: `submit${className}`,
267
+ newModel: `new${className}`,
268
+ editModel: `edit${className}`,
269
+ mergeModel: `merge${className}`,
270
+ viewModel: `view${className}`,
271
+ setModel: `set${className}`,
272
+ resetModel: `reset${className}`,
273
+ modelViewAt: `${fieldName}ViewAt`,
274
+ modelModal: `${fieldName}Modal`,
275
+ initModel: `init${className}`,
276
+ modelInitList: `${fieldName}InitList`,
277
+ modelInitAt: `${fieldName}InitAt`,
278
+ refreshModel: `refresh${className}`,
279
+ selectModel: `select${className}`,
280
+ setPageOfModel: `setPageOf${className}`,
281
+ addPageOfModel: `addPageOf${className}`,
282
+ setLimitOfModel: `setLimitOf${className}`,
283
+ setQueryArgsOfModel: `setQueryArgsOf${className}`,
284
+ setSortOfModel: `setSortOf${className}`,
285
+ lastPageOfModel: `lastPageOf${className}`,
286
+ pageOfModel: `pageOf${className}`,
287
+ limitOfModel: `limitOf${className}`,
288
+ queryArgsOfModel: `queryArgsOf${className}`,
289
+ sortOfModel: `sortOf${className}`
290
+ };
291
+ const baseAction = {
292
+ [names.createModelInForm]: async function({ idx, path, modal, sliceName = names.model, onError, onSuccess } = {}) {
293
+ const SliceName = capitalize(sliceName);
294
+ const namesOfSlice = {
295
+ defaultModel: SliceName.replace(names.Model, names.defaultModel),
296
+ modelList: sliceName.replace(names.model, names.modelList),
297
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading),
298
+ modelInsight: sliceName.replace(names.model, names.modelInsight)
299
+ };
300
+ const currentState = this.get();
301
+ const modelForm = currentState[names.modelForm];
302
+ const modelList = currentState[namesOfSlice.modelList];
303
+ const modelListLoading = currentState[namesOfSlice.modelListLoading];
304
+ const modelInsight = currentState[namesOfSlice.modelInsight];
305
+ const defaultModel = currentState[namesOfSlice.defaultModel];
306
+ const modelInput = gql[names.purifyModel](modelForm);
307
+ if (!modelInput)
308
+ return;
309
+ this.set({ [names.modelLoading]: true });
310
+ const model = await gql[names.createModel](modelInput, { onError });
311
+ const newModelList = modelListLoading ? modelList : new DataList([...modelList.slice(0, idx ?? 0), model, ...modelList.slice(idx ?? 0)]);
312
+ const newModelInsight = gql[names.crystalizeInsight]({
313
+ ...modelInsight,
314
+ count: modelInsight.count + 1
315
+ });
316
+ this.set({
317
+ [names.modelForm]: immerify(modelRef, defaultModel),
318
+ [names.model]: model,
319
+ [names.modelLoading]: false,
320
+ [namesOfSlice.modelList]: newModelList,
321
+ [namesOfSlice.modelInsight]: newModelInsight,
322
+ [names.modelViewAt]: /* @__PURE__ */ new Date(),
323
+ [names.modelModal]: modal ?? null,
324
+ ...typeof path === "string" && path ? { [path]: model } : {}
325
+ });
326
+ await onSuccess?.(model);
327
+ },
328
+ [names.updateModelInForm]: async function({ path, modal, sliceName = names.model, onError, onSuccess } = {}) {
329
+ const SliceName = capitalize(sliceName);
330
+ const namesOfSlice = {
331
+ defaultModel: SliceName.replace(names.Model, names.defaultModel)
332
+ };
333
+ const currentState = this.get();
334
+ const model = currentState[names.model];
335
+ const modelForm = currentState[names.modelForm];
336
+ const defaultModel = currentState[namesOfSlice.defaultModel];
337
+ const modelInput = gql[names.purifyModel](modelForm);
338
+ if (!modelInput)
339
+ return;
340
+ if (model?.id === modelForm.id)
341
+ this.set({ [names.modelLoading]: modelForm.id });
342
+ const updatedModel = await gql[names.updateModel](modelForm.id, modelInput, {
343
+ onError
344
+ });
345
+ this.set({
346
+ ...model?.id === updatedModel.id ? { [names.model]: updatedModel, [names.modelLoading]: false, [names.modelViewAt]: /* @__PURE__ */ new Date() } : {},
347
+ [names.modelForm]: immerify(modelRef, defaultModel),
348
+ [names.modelModal]: modal ?? null,
349
+ ...typeof path === "string" && path ? { [path]: updatedModel } : {}
350
+ });
351
+ const updatedLightModel = gql[names.lightCrystalizeModel](updatedModel);
352
+ gql.slices.forEach(({ sliceName: sliceName2 }) => {
353
+ const namesOfSlice2 = {
354
+ modelList: sliceName2.replace(names.model, names.modelList),
355
+ modelListLoading: sliceName2.replace(names.model, names.modelListLoading)
356
+ };
357
+ const currentState2 = this.get();
358
+ const modelList = currentState2[namesOfSlice2.modelList];
359
+ const modelListLoading = currentState2[namesOfSlice2.modelListLoading];
360
+ if (modelListLoading || !modelList.has(updatedModel.id))
361
+ return;
362
+ const newModelList = new DataList(modelList).set(updatedLightModel);
363
+ this.set({ [namesOfSlice2.modelList]: newModelList });
364
+ });
365
+ await onSuccess?.(updatedModel);
366
+ },
367
+ [names.createModel]: async function(data, { idx, path, modal, sliceName = names.model, onError, onSuccess } = {}) {
368
+ const SliceName = capitalize(sliceName);
369
+ const namesOfSlice = {
370
+ defaultModel: SliceName.replace(names.Model, names.defaultModel),
371
+ modelList: sliceName.replace(names.model, names.modelList),
372
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading),
373
+ modelInsight: sliceName.replace(names.model, names.modelInsight)
374
+ };
375
+ const currentState = this.get();
376
+ const modelList = currentState[namesOfSlice.modelList];
377
+ const modelListLoading = currentState[namesOfSlice.modelListLoading];
378
+ const modelInsight = currentState[namesOfSlice.modelInsight];
379
+ const modelInput = gql[names.purifyModel](data);
380
+ if (!modelInput)
381
+ return;
382
+ this.set({ [names.modelLoading]: true });
383
+ const model = await gql[names.createModel](modelInput, { onError });
384
+ const newModelList = modelListLoading ? modelList : new DataList([...modelList.slice(0, idx ?? 0), model, ...modelList.slice(idx ?? 0)]);
385
+ const newModelInsight = gql[names.crystalizeInsight]({
386
+ ...modelInsight,
387
+ count: modelInsight.count + 1
388
+ });
389
+ this.set({
390
+ [names.model]: model,
391
+ [names.modelLoading]: false,
392
+ [namesOfSlice.modelList]: newModelList,
393
+ [namesOfSlice.modelInsight]: newModelInsight,
394
+ [names.modelViewAt]: /* @__PURE__ */ new Date(),
395
+ [names.modelModal]: modal ?? null,
396
+ ...typeof path === "string" && path ? { [path]: model } : {}
397
+ });
398
+ await onSuccess?.(model);
399
+ },
400
+ [names.updateModel]: async function(id, data, { idx, path, modal, sliceName = names.model, onError, onSuccess } = {}) {
401
+ const currentState = this.get();
402
+ const model = currentState[names.model];
403
+ const modelInput = gql[names.purifyModel](data);
404
+ if (!modelInput)
405
+ return;
406
+ if (model?.id === id)
407
+ this.set({ [names.modelLoading]: id });
408
+ const updatedModel = await gql[names.updateModel](id, modelInput, { onError });
409
+ this.set({
410
+ ...model?.id === updatedModel.id ? { [names.model]: updatedModel, [names.modelLoading]: false, [names.modelViewAt]: /* @__PURE__ */ new Date() } : {},
411
+ [names.modelModal]: modal ?? null,
412
+ ...typeof path === "string" && path ? { [path]: updatedModel } : {}
413
+ });
414
+ const updatedLightModel = gql[names.lightCrystalizeModel](updatedModel);
415
+ gql.slices.forEach(({ sliceName: sliceName2 }) => {
416
+ const namesOfSlice = {
417
+ modelList: sliceName2.replace(names.model, names.modelList),
418
+ modelListLoading: sliceName2.replace(names.model, names.modelListLoading)
419
+ };
420
+ const currentState2 = this.get();
421
+ const modelList = currentState2[namesOfSlice.modelList];
422
+ const modelListLoading = currentState2[namesOfSlice.modelListLoading];
423
+ if (modelListLoading || !modelList.has(updatedModel.id))
424
+ return;
425
+ const newModelList = new DataList(modelList).set(updatedLightModel);
426
+ this.set({ [namesOfSlice.modelList]: newModelList });
427
+ });
428
+ await onSuccess?.(updatedModel);
429
+ },
430
+ [names.removeModel]: async function(id, options) {
431
+ const { modal, ...fetchPolicyOptions } = options ?? {};
432
+ const model = await gql[names.removeModel](
433
+ id,
434
+ fetchPolicyOptions
435
+ );
436
+ const lightModel = gql[names.lightCrystalizeModel](model);
437
+ gql.slices.forEach(({ sliceName }) => {
438
+ const namesOfSlice = {
439
+ modelList: sliceName.replace(names.model, names.modelList),
440
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading),
441
+ modelSelection: sliceName.replace(names.model, names.modelSelection),
442
+ modelInsight: sliceName.replace(names.model, names.modelInsight)
443
+ };
444
+ const currentState = this.get();
445
+ const modelList = currentState[namesOfSlice.modelList];
446
+ const modelListLoading = currentState[namesOfSlice.modelListLoading];
447
+ const modelSelection = currentState[namesOfSlice.modelSelection];
448
+ const modelInsight = currentState[namesOfSlice.modelInsight];
449
+ if (modelListLoading || !modelList.has(model.id))
450
+ return;
451
+ const newModelList = new DataList(modelList);
452
+ if (model.removedAt) {
453
+ newModelList.delete(id);
454
+ const newModelInsight = gql[names.crystalizeInsight]({
455
+ ...modelInsight,
456
+ count: modelInsight.count - 1
457
+ });
458
+ const newModelSelection = new DataList(modelSelection);
459
+ newModelSelection.delete(id);
460
+ this.set({
461
+ [namesOfSlice.modelList]: newModelList,
462
+ [namesOfSlice.modelInsight]: newModelInsight,
463
+ ...modelSelection.has(model.id) ? { [namesOfSlice.modelSelection]: newModelSelection } : {},
464
+ ...modal !== void 0 ? { [names.modelModal]: modal } : {}
465
+ });
466
+ } else {
467
+ newModelList.set(lightModel);
468
+ this.set({
469
+ [namesOfSlice.modelList]: newModelList,
470
+ ...modal !== void 0 ? { [names.modelModal]: modal } : {}
471
+ });
472
+ }
473
+ });
474
+ },
475
+ [names.checkModelSubmitable]: function(disabled) {
476
+ const currentState = this.get();
477
+ const modelForm = currentState[names.modelForm];
478
+ const modelSubmit = currentState[names.modelSubmit];
479
+ const modelInput = gql[names.purifyModel](modelForm);
480
+ this.set({ [names.modelSubmit]: { ...modelSubmit, disabled: !modelInput || disabled } });
481
+ },
482
+ [names.submitModel]: async function(option) {
483
+ const currentState = this.get();
484
+ const modelForm = currentState[names.modelForm];
485
+ const modelSubmit = currentState[names.modelSubmit];
486
+ this.set({ [names.modelSubmit]: { ...modelSubmit, loading: true } });
487
+ if (modelForm.id)
488
+ await this[names.updateModelInForm](option);
489
+ else
490
+ await this[names.createModelInForm](option);
491
+ this.set({ [names.modelSubmit]: { ...modelSubmit, loading: false, times: modelSubmit.times + 1 } });
492
+ },
493
+ [names.newModel]: function(partial = {}, { modal, setDefault, sliceName = names.model } = {}) {
494
+ const SliceName = capitalize(sliceName);
495
+ const namesOfSlice = {
496
+ defaultModel: SliceName.replace(names.Model, names.defaultModel)
497
+ };
498
+ const currentState = this.get();
499
+ const defaultModel = currentState[namesOfSlice.defaultModel];
500
+ this.set({
501
+ [names.modelForm]: immerify(modelRef, { ...defaultModel, ...partial }),
502
+ [namesOfSlice.defaultModel]: setDefault ? immerify(modelRef, { ...defaultModel, ...partial }) : defaultModel,
503
+ [names.model]: null,
504
+ [names.modelModal]: modal ?? "edit",
505
+ [names.modelFormLoading]: false
506
+ });
507
+ },
508
+ [names.editModel]: async function(modelOrId, { modal, onError } = {}) {
509
+ const id = typeof modelOrId === "string" ? modelOrId : modelOrId.id;
510
+ this.set({ [names.modelFormLoading]: id, [names.modelModal]: modal ?? "edit" });
511
+ this.set((state) => {
512
+ state[names.modelForm].id = id;
513
+ });
514
+ const model = await gql[names.model](id, { onError });
515
+ const modelForm = deepObjectify(model);
516
+ this.set({
517
+ [names.model]: model,
518
+ [names.modelFormLoading]: false,
519
+ [names.modelViewAt]: /* @__PURE__ */ new Date(),
520
+ [names.modelForm]: modelForm
521
+ });
522
+ },
523
+ [names.mergeModel]: async function(modelOrId, data, options) {
524
+ const id = typeof modelOrId === "string" ? modelOrId : modelOrId.id;
525
+ const currentState = this.get();
526
+ const model = currentState[names.model];
527
+ if (id === model?.id)
528
+ this.set({ modelLoading: id });
529
+ const updatedModel = await gql[names.mergeModel](modelOrId, data, options);
530
+ this.set({
531
+ [names.model]: id === model?.id ? updatedModel : model,
532
+ [names.modelLoading]: false
533
+ });
534
+ const updatedLightModel = gql[names.lightCrystalizeModel](updatedModel);
535
+ gql.slices.forEach(({ sliceName }) => {
536
+ const namesOfSlice = {
537
+ modelList: sliceName.replace(names.model, names.modelList),
538
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading)
539
+ };
540
+ const currentState2 = this.get();
541
+ const modelList = currentState2[namesOfSlice.modelList];
542
+ const modelListLoading = currentState2[namesOfSlice.modelListLoading];
543
+ if (modelListLoading || !modelList.has(updatedModel.id))
544
+ return;
545
+ const newModelList = new DataList(modelList).set(updatedLightModel);
546
+ this.set({ [namesOfSlice.modelList]: newModelList });
547
+ });
548
+ },
549
+ [names.viewModel]: async function(modelOrId, { modal, onError } = {}) {
550
+ const id = typeof modelOrId === "string" ? modelOrId : modelOrId.id;
551
+ this.set({ [names.modelModal]: modal ?? "view", [names.modelLoading]: id });
552
+ const model = await gql[names.model](id, { onError });
553
+ this.set({ [names.model]: model, [names.modelViewAt]: /* @__PURE__ */ new Date(), [names.modelLoading]: false });
554
+ },
555
+ [names.setModel]: function(fullOrLightModel) {
556
+ const currentState = this.get();
557
+ const model = currentState[names.model];
558
+ const isFull = fullOrLightModel instanceof modelRef;
559
+ if (isFull) {
560
+ const crystalizedModel = gql[names.crystalizeModel](fullOrLightModel);
561
+ this.set({ [names.model]: crystalizedModel });
562
+ } else if (model?.id === fullOrLightModel.id) {
563
+ const crystalizedModel = gql[names.crystalizeModel]({ ...model, ...fullOrLightModel });
564
+ this.set({ [names.model]: crystalizedModel });
565
+ }
566
+ const lightModel = gql[names.lightCrystalizeModel](fullOrLightModel);
567
+ gql.slices.forEach(({ sliceName }) => {
568
+ const namesOfSlice = {
569
+ modelList: sliceName.replace(names.model, names.modelList),
570
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading)
571
+ };
572
+ const modelList = currentState[namesOfSlice.modelList];
573
+ const modelListLoading = currentState[namesOfSlice.modelListLoading];
574
+ if (modelListLoading || !modelList.has(lightModel.id))
575
+ return;
576
+ this.set({ [namesOfSlice.modelList]: modelList.set(lightModel).save() });
577
+ });
578
+ },
579
+ [names.resetModel]: function(model) {
580
+ const currentState = this.get();
581
+ const defaultModel = currentState[names.defaultModel];
582
+ this.set({
583
+ [names.model]: model ?? null,
584
+ [names.modelViewAt]: /* @__PURE__ */ new Date(0),
585
+ [names.modelForm]: immerify(modelRef, defaultModel),
586
+ [names.modelModal]: null
587
+ });
588
+ return model ?? null;
589
+ }
590
+ };
591
+ const sliceAction = gql.slices.reduce((acc, { sliceName, argLength }) => {
592
+ const SliceName = capitalize(sliceName);
593
+ const namesOfSlice = {
594
+ defaultModel: SliceName.replace(names.Model, names.defaultModel),
595
+ modelInsight: sliceName.replace(names.model, names.modelInsight),
596
+ modelList: sliceName.replace(names.model, names.modelList),
597
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading),
598
+ initModel: SliceName.replace(names.Model, names.initModel),
599
+ modelInitList: SliceName.replace(names.Model, names.modelInitList),
600
+ modelInitAt: SliceName.replace(names.Model, names.modelInitAt),
601
+ refreshModel: SliceName.replace(names.Model, names.refreshModel),
602
+ selectModel: SliceName.replace(names.Model, names.selectModel),
603
+ setPageOfModel: SliceName.replace(names.Model, names.setPageOfModel),
604
+ addPageOfModel: SliceName.replace(names.Model, names.addPageOfModel),
605
+ setLimitOfModel: SliceName.replace(names.Model, names.setLimitOfModel),
606
+ setQueryArgsOfModel: SliceName.replace(names.Model, names.setQueryArgsOfModel),
607
+ setSortOfModel: SliceName.replace(names.Model, names.setSortOfModel),
608
+ lastPageOfModel: SliceName.replace(names.Model, names.lastPageOfModel),
609
+ pageOfModel: SliceName.replace(names.Model, names.pageOfModel),
610
+ limitOfModel: SliceName.replace(names.Model, names.limitOfModel),
611
+ queryArgsOfModel: SliceName.replace(names.Model, names.queryArgsOfModel),
612
+ sortOfModel: SliceName.replace(names.Model, names.sortOfModel),
613
+ modelSelection: SliceName.replace(names.Model, names.modelSelection)
614
+ };
615
+ const singleSliceAction = {
616
+ [namesOfSlice.initModel]: async function(...args) {
617
+ const initArgLength = Math.min(args.length, argLength);
618
+ const initForm = { invalidate: false, ...args[argLength] ?? {} };
619
+ const queryArgs = new Array(initArgLength).fill(null).map((_, i) => args[i]);
620
+ const defaultModel = immerify(modelRef, { ...gql[names.defaultModel], ...initForm.default ?? {} });
621
+ this.set({ [names.defaultModel]: defaultModel });
622
+ await this[namesOfSlice.refreshModel](
623
+ ...initArgLength === argLength ? [...queryArgs, initForm] : queryArgs
624
+ );
625
+ },
626
+ [namesOfSlice.refreshModel]: async function(...args) {
627
+ const refreshArgLength = Math.min(args.length, argLength);
628
+ const currentState = this.get();
629
+ const existingQueryArgs = currentState[namesOfSlice.queryArgsOfModel];
630
+ const queryArgs = [
631
+ ...new Array(refreshArgLength).fill(null).map((_, i) => args[i]),
632
+ ...existingQueryArgs.slice(refreshArgLength, argLength)
633
+ ];
634
+ const initForm = args[argLength] ?? {};
635
+ const {
636
+ page = currentState[namesOfSlice.pageOfModel],
637
+ limit = currentState[namesOfSlice.limitOfModel],
638
+ sort = currentState[namesOfSlice.sortOfModel],
639
+ invalidate = true
640
+ } = initForm;
641
+ const modelOperation = currentState[names.modelOperation];
642
+ const queryArgsOfModel = currentState[namesOfSlice.queryArgsOfModel];
643
+ const pageOfModel = currentState[namesOfSlice.pageOfModel];
644
+ const limitOfModel = currentState[namesOfSlice.limitOfModel];
645
+ const sortOfModel = currentState[namesOfSlice.sortOfModel];
646
+ if (!invalidate && !["sleep", "reset"].includes(modelOperation) && isQueryEqual(queryArgs, queryArgsOfModel) && page === pageOfModel && limit === limitOfModel && isQueryEqual(sort, sortOfModel))
647
+ return;
648
+ else
649
+ this.set({ [namesOfSlice.modelListLoading]: true });
650
+ const [modelDataList, modelInsight] = await Promise.all([
651
+ gql[namesOfSlice.modelList](
652
+ ...queryArgs,
653
+ (page - 1) * limit,
654
+ limit,
655
+ sort,
656
+ { onError: initForm.onError }
657
+ ),
658
+ gql[namesOfSlice.modelInsight](...queryArgs, {
659
+ onError: initForm.onError
660
+ })
661
+ ]);
662
+ const modelList = new DataList(modelDataList);
663
+ this.set({
664
+ [namesOfSlice.modelList]: modelList,
665
+ [namesOfSlice.modelListLoading]: false,
666
+ [namesOfSlice.modelInsight]: modelInsight,
667
+ [namesOfSlice.modelInitList]: modelList,
668
+ [namesOfSlice.modelInitAt]: /* @__PURE__ */ new Date(),
669
+ [namesOfSlice.lastPageOfModel]: Math.max(Math.floor((modelInsight.count - 1) / limit) + 1, 1),
670
+ [namesOfSlice.limitOfModel]: limit,
671
+ [namesOfSlice.queryArgsOfModel]: queryArgs,
672
+ [namesOfSlice.sortOfModel]: sort,
673
+ [namesOfSlice.pageOfModel]: page,
674
+ [names.modelOperation]: "idle"
675
+ });
676
+ },
677
+ [namesOfSlice.selectModel]: function(model, { refresh, remove } = {}) {
678
+ const models = Array.isArray(model) ? model : [model];
679
+ const currentState = this.get();
680
+ const modelSelection = currentState[namesOfSlice.modelSelection];
681
+ if (refresh)
682
+ this.set({ [namesOfSlice.modelSelection]: new DataList(models) });
683
+ else if (remove) {
684
+ const newModelSelection = new DataList(modelSelection);
685
+ models.map((model2) => newModelSelection.delete(model2.id));
686
+ this.set({ [namesOfSlice.modelSelection]: newModelSelection });
687
+ } else {
688
+ this.set({ [namesOfSlice.modelSelection]: new DataList([...modelSelection.values, ...models]) });
689
+ }
690
+ },
691
+ [namesOfSlice.setPageOfModel]: async function(page, options) {
692
+ const currentState = this.get();
693
+ const queryArgsOfModel = currentState[namesOfSlice.queryArgsOfModel];
694
+ const pageOfModel = currentState[namesOfSlice.pageOfModel];
695
+ const limitOfModel = currentState[namesOfSlice.limitOfModel];
696
+ const sortOfModel = currentState[namesOfSlice.sortOfModel];
697
+ if (pageOfModel === page)
698
+ return;
699
+ this.set({ [namesOfSlice.modelListLoading]: true });
700
+ const modelDataList = await gql[namesOfSlice.modelList](
701
+ ...queryArgsOfModel,
702
+ (page - 1) * limitOfModel,
703
+ limitOfModel,
704
+ sortOfModel,
705
+ options
706
+ );
707
+ const modelList = new DataList(modelDataList);
708
+ this.set({
709
+ [namesOfSlice.modelList]: modelList,
710
+ [namesOfSlice.pageOfModel]: page,
711
+ [namesOfSlice.modelListLoading]: false
712
+ });
713
+ },
714
+ [namesOfSlice.addPageOfModel]: async function(page, options) {
715
+ const currentState = this.get();
716
+ const modelList = currentState[namesOfSlice.modelList];
717
+ const queryArgsOfModel = currentState[namesOfSlice.queryArgsOfModel];
718
+ const pageOfModel = currentState[namesOfSlice.pageOfModel];
719
+ const limitOfModel = currentState[namesOfSlice.limitOfModel];
720
+ const sortOfModel = currentState[namesOfSlice.sortOfModel];
721
+ if (pageOfModel === page)
722
+ return;
723
+ const addFront = page < pageOfModel;
724
+ const modelDataList = await gql[namesOfSlice.modelList](
725
+ ...queryArgsOfModel,
726
+ (page - 1) * limitOfModel,
727
+ limitOfModel,
728
+ sortOfModel,
729
+ options
730
+ );
731
+ const newModelList = new DataList(
732
+ addFront ? [...modelDataList, ...modelList] : [...modelList, ...modelDataList]
733
+ );
734
+ this.set({ [namesOfSlice.modelList]: newModelList, [namesOfSlice.pageOfModel]: page });
735
+ },
736
+ [namesOfSlice.setLimitOfModel]: async function(limit, options) {
737
+ const currentState = this.get();
738
+ const modelInsight = currentState[namesOfSlice.modelInsight];
739
+ const queryArgsOfModel = currentState[namesOfSlice.queryArgsOfModel];
740
+ const pageOfModel = currentState[namesOfSlice.pageOfModel];
741
+ const limitOfModel = currentState[namesOfSlice.limitOfModel];
742
+ const sortOfModel = currentState[namesOfSlice.sortOfModel];
743
+ if (limitOfModel === limit)
744
+ return;
745
+ const skip = (pageOfModel - 1) * limitOfModel;
746
+ const page = Math.max(Math.floor((skip - 1) / limit) + 1, 1);
747
+ const modelDataList = await gql[namesOfSlice.modelList](
748
+ ...queryArgsOfModel,
749
+ (page - 1) * limit,
750
+ limit,
751
+ sortOfModel,
752
+ options
753
+ );
754
+ const modelList = new DataList(modelDataList);
755
+ this.set({
756
+ [namesOfSlice.modelList]: modelList,
757
+ [namesOfSlice.lastPageOfModel]: Math.max(Math.floor((modelInsight.count - 1) / limit) + 1, 1),
758
+ [namesOfSlice.limitOfModel]: limit,
759
+ [namesOfSlice.pageOfModel]: page
760
+ });
761
+ },
762
+ [namesOfSlice.setQueryArgsOfModel]: async function(...args) {
763
+ const queryArgs = new Array(argLength).fill(null).map((_, i) => args[i]);
764
+ const options = args[argLength];
765
+ const currentState = this.get();
766
+ const queryArgsOfModel = currentState[namesOfSlice.queryArgsOfModel];
767
+ const limitOfModel = currentState[namesOfSlice.limitOfModel];
768
+ const sortOfModel = currentState[namesOfSlice.sortOfModel];
769
+ if (isQueryEqual(queryArgsOfModel, queryArgs)) {
770
+ Logger.trace(`${namesOfSlice.queryArgsOfModel} store-level cache hit`);
771
+ return;
772
+ }
773
+ this.set({ [namesOfSlice.modelListLoading]: true });
774
+ const [modelDataList, modelInsight] = await Promise.all([
775
+ gql[namesOfSlice.modelList](
776
+ ...queryArgs,
777
+ 0,
778
+ limitOfModel,
779
+ sortOfModel,
780
+ options
781
+ ),
782
+ gql[namesOfSlice.modelInsight](...queryArgs, options)
783
+ ]);
784
+ const modelList = new DataList(modelDataList);
785
+ this.set({
786
+ [namesOfSlice.queryArgsOfModel]: queryArgs,
787
+ [namesOfSlice.modelList]: modelList,
788
+ [namesOfSlice.modelInsight]: modelInsight,
789
+ [namesOfSlice.lastPageOfModel]: Math.max(Math.floor((modelInsight.count - 1) / limitOfModel) + 1, 1),
790
+ [namesOfSlice.pageOfModel]: 1,
791
+ [namesOfSlice.modelSelection]: /* @__PURE__ */ new Map(),
792
+ [namesOfSlice.modelListLoading]: false
793
+ });
794
+ },
795
+ [namesOfSlice.setSortOfModel]: async function(sort, options) {
796
+ const currentState = this.get();
797
+ const queryArgsOfModel = currentState[namesOfSlice.queryArgsOfModel];
798
+ const limitOfModel = currentState[namesOfSlice.limitOfModel];
799
+ const sortOfModel = currentState[namesOfSlice.sortOfModel];
800
+ if (sortOfModel === sort)
801
+ return;
802
+ this.set({ [namesOfSlice.modelListLoading]: true });
803
+ const modelDataList = await gql[namesOfSlice.modelList](
804
+ ...queryArgsOfModel,
805
+ 0,
806
+ limitOfModel,
807
+ sort,
808
+ options
809
+ );
810
+ const modelList = new DataList(modelDataList);
811
+ this.set({
812
+ [namesOfSlice.modelList]: modelList,
813
+ [namesOfSlice.sortOfModel]: sort,
814
+ [namesOfSlice.pageOfModel]: 1,
815
+ [namesOfSlice.modelListLoading]: false
816
+ });
817
+ }
818
+ };
819
+ return Object.assign(acc, singleSliceAction);
820
+ }, {});
821
+ return { ...baseAction, ...sliceAction };
822
+ };
823
+ const stateOf = (gql, state) => {
824
+ const applyState = Object.assign(createState(gql), state);
825
+ const applyAction = createActions(gql);
826
+ setStoreMeta(gql.refName, {
827
+ refName: gql.refName,
828
+ useKeys: Object.keys(applyState),
829
+ doKeys: Object.keys(applyAction),
830
+ slices: gql.slices
831
+ });
832
+ const applyStore = { ...applyState, ...applyAction };
833
+ class StateStore {
834
+ get;
835
+ set;
836
+ pick;
837
+ }
838
+ Object.keys(applyStore).forEach(
839
+ (key) => Object.defineProperty(StateStore.prototype, key, { value: applyStore[key] })
840
+ );
841
+ return StateStore;
842
+ };
843
+ const scalarStateOf = (refName, state) => {
844
+ const applyState = state;
845
+ setStoreMeta(refName, { refName, useKeys: Object.keys(applyState), doKeys: [], slices: [] });
846
+ class StateStore {
847
+ get;
848
+ set;
849
+ pick;
850
+ }
851
+ Object.keys(applyState).forEach(
852
+ (key) => Object.defineProperty(StateStore.prototype, key, { value: applyState[key] })
853
+ );
854
+ return StateStore;
855
+ };
856
+ const Store = (returnsOrObj) => {
857
+ const refName = typeof returnsOrObj === "object" ? returnsOrObj.name : lowerlize(getClassMeta(returnsOrObj()).refName);
858
+ const storeMeta = getStoreMeta(refName);
859
+ return function(target) {
860
+ const customDoKeys = Object.getOwnPropertyNames(target.prototype).filter((key) => key !== "constructor");
861
+ setStoreMeta(refName, { ...storeMeta, doKeys: [...storeMeta.doKeys, ...customDoKeys] });
862
+ };
863
+ };
864
+ const createSelectors = (_store, store = {}) => {
865
+ store.get = _store.getState;
866
+ store.set = (s) => {
867
+ if (typeof s === "function")
868
+ _store.setState((st2) => {
869
+ s(st2);
870
+ });
871
+ else
872
+ _store.setState(s);
873
+ };
874
+ store.sel = (selectFn, equals) => _store(selectFn, equals);
875
+ const state = store.get();
876
+ store.sub = _store.subscribe;
877
+ const useReference = (selectFn) => {
878
+ const ref = useRef(selectFn(store.get()));
879
+ useEffect(() => {
880
+ return store.sub(selectFn, (val) => ref.current = val);
881
+ }, []);
882
+ return ref;
883
+ };
884
+ store.ref = useReference;
885
+ const existingUse = store.use;
886
+ const existingDo = store.do;
887
+ const existingSlice = store.slice;
888
+ if (!existingUse)
889
+ Object.assign(store, { use: {} });
890
+ if (!existingDo)
891
+ Object.assign(store, { do: {} });
892
+ if (!existingSlice)
893
+ Object.assign(store, { slice: {} });
894
+ for (const k of Object.keys(state)) {
895
+ if (typeof state[k] !== "function") {
896
+ store.use[k] = () => store.sel((s) => s[k]);
897
+ const setKey = `set${capitalize(k)}`;
898
+ if (!state[setKey])
899
+ store.do[setKey] = (value) => {
900
+ store.set({ [k]: value });
901
+ };
902
+ } else {
903
+ store.do[k] = async (...args) => {
904
+ try {
905
+ Logger.verbose(`${k} action loading...`);
906
+ const start = Date.now();
907
+ await state[k](...args);
908
+ const end = Date.now();
909
+ Logger.verbose(`=> ${k} action dispatched (${end - start}ms)`);
910
+ } catch (e) {
911
+ const errKey = typeof e === "string" ? e : e.message;
912
+ msg.error(errKey, { key: k });
913
+ throw e;
914
+ }
915
+ };
916
+ }
917
+ }
918
+ const storeNames = getStoreNames();
919
+ for (const storeName of storeNames) {
920
+ const [fieldName, className] = [lowerlize(storeName), capitalize(storeName)];
921
+ const names = {
922
+ model: fieldName,
923
+ Model: className,
924
+ defaultModel: `default${className}`,
925
+ modelInsight: `${fieldName}Insight`,
926
+ modelList: `${fieldName}List`,
927
+ modelListLoading: `${fieldName}ListLoading`,
928
+ modelInitList: `${fieldName}InitList`,
929
+ modelInitAt: `${fieldName}InitAt`,
930
+ pageOfModel: `pageOf${className}`,
931
+ limitOfModel: `limitOf${className}`,
932
+ queryArgsOfModel: `queryArgsOf${className}`,
933
+ sortOfModel: `sortOf${className}`,
934
+ modelSelection: `${fieldName}Selection`,
935
+ initModel: `init${className}`,
936
+ refreshModel: `refresh${className}`,
937
+ selectModel: `select${className}`,
938
+ setPageOfModel: `setPageOf${className}`,
939
+ addPageOfModel: `addPageOf${className}`,
940
+ setLimitOfModel: `setLimitOf${className}`,
941
+ setQueryArgsOfModel: `setQueryArgsOf${className}`,
942
+ setSortOfModel: `setSortOf${className}`,
943
+ lastPageOfModel: `lastPageOf${className}`
944
+ };
945
+ const storeMeta = getStoreMeta(storeName);
946
+ storeMeta.slices.forEach(({ sliceName, argLength, refName }) => {
947
+ const SliceName = capitalize(sliceName);
948
+ const namesOfSliceState = {
949
+ defaultModel: SliceName.replace(names.Model, names.defaultModel),
950
+ modelInitList: SliceName.replace(names.Model, names.modelInitList),
951
+ modelInsight: sliceName.replace(names.model, names.modelInsight),
952
+ modelList: sliceName.replace(names.model, names.modelList),
953
+ modelListLoading: sliceName.replace(names.model, names.modelListLoading),
954
+ modelInitAt: SliceName.replace(names.Model, names.modelInitAt),
955
+ lastPageOfModel: SliceName.replace(names.Model, names.lastPageOfModel),
956
+ pageOfModel: SliceName.replace(names.Model, names.pageOfModel),
957
+ limitOfModel: SliceName.replace(names.Model, names.limitOfModel),
958
+ queryArgsOfModel: SliceName.replace(names.Model, names.queryArgsOfModel),
959
+ sortOfModel: SliceName.replace(names.Model, names.sortOfModel),
960
+ modelSelection: SliceName.replace(names.Model, names.modelSelection)
961
+ };
962
+ const namesOfSliceAction = {
963
+ initModel: SliceName.replace(names.Model, names.initModel),
964
+ refreshModel: SliceName.replace(names.Model, names.refreshModel),
965
+ selectModel: SliceName.replace(names.Model, names.selectModel),
966
+ setPageOfModel: SliceName.replace(names.Model, names.setPageOfModel),
967
+ addPageOfModel: SliceName.replace(names.Model, names.addPageOfModel),
968
+ setLimitOfModel: SliceName.replace(names.Model, names.setLimitOfModel),
969
+ setQueryArgsOfModel: SliceName.replace(names.Model, names.setQueryArgsOfModel),
970
+ setSortOfModel: SliceName.replace(names.Model, names.setSortOfModel)
971
+ };
972
+ store.slice[sliceName] = { do: {}, use: {} };
973
+ const targetSlice = store.slice[sliceName];
974
+ Object.keys(namesOfSliceAction).forEach((key) => {
975
+ targetSlice.do[names[key]] = store.do[namesOfSliceAction[key]];
976
+ });
977
+ Object.keys(namesOfSliceState).map((key) => {
978
+ targetSlice.use[names[key]] = store.use[namesOfSliceState[key]];
979
+ targetSlice.do[`set${capitalize(names[key])}`] = store.do[`set${capitalize(namesOfSliceState[key])}`];
980
+ });
981
+ targetSlice.sliceName = sliceName;
982
+ targetSlice.refName = refName;
983
+ targetSlice.argLength = argLength;
984
+ });
985
+ }
986
+ return store;
987
+ };
988
+ const makePicker = (set, get) => (...fields) => {
989
+ const state = get();
990
+ const ret = {};
991
+ for (const field of fields) {
992
+ const val = state[field];
993
+ if (!val)
994
+ throw new Error(`Field ${field} is not ready`);
995
+ if (typeof val === "string" && val.length === 0)
996
+ throw new Error(`Field is empty string (${field})`);
997
+ else if (["self", "me"].includes(field) && !state[field].id?.length)
998
+ throw new Error("Self or Me Id is not defined");
999
+ ret[field] = val;
1000
+ }
1001
+ return ret;
1002
+ };
1003
+ const makeStore = (st2, storeRef, { library } = {}) => {
1004
+ if (library)
1005
+ return st2;
1006
+ const zustandStore = create(
1007
+ devtools(
1008
+ subscribeWithSelector(
1009
+ immer((set, get) => {
1010
+ const store = {};
1011
+ const pick = makePicker(set, get);
1012
+ Object.getOwnPropertyNames(storeRef.prototype).forEach((key) => {
1013
+ const descriptor = Object.getOwnPropertyDescriptor(storeRef.prototype, key);
1014
+ if (descriptor)
1015
+ store[key] = descriptor.value;
1016
+ });
1017
+ Object.assign(store, { set, get, pick });
1018
+ return store;
1019
+ })
1020
+ ),
1021
+ { name: "root", anonymousActionType: "root", type: "root" }
1022
+ )
1023
+ );
1024
+ return createSelectors(zustandStore, st2);
1025
+ };
1026
+ const MixStore = (s1, s2, s3, s4, s5, s6, s7, s8, s9, s10, s11, s12, s13, s14, s15, s16, s17, s18, s19, s20, s21, s22, s23, s24, s25, s26, s27, s28, s29, s30) => {
1027
+ const stores = [
1028
+ s1,
1029
+ s2,
1030
+ s3,
1031
+ s4,
1032
+ s5,
1033
+ s6,
1034
+ s7,
1035
+ s8,
1036
+ s9,
1037
+ s10,
1038
+ s11,
1039
+ s12,
1040
+ s13,
1041
+ s14,
1042
+ s15,
1043
+ s16,
1044
+ s17,
1045
+ s18,
1046
+ s19,
1047
+ s20,
1048
+ s21,
1049
+ s22,
1050
+ s23,
1051
+ s24,
1052
+ s25,
1053
+ s26,
1054
+ s27,
1055
+ s28,
1056
+ s29,
1057
+ s30
1058
+ ].filter((s) => !!s);
1059
+ class Mix {
1060
+ }
1061
+ applyMixins(Mix, stores);
1062
+ return Mix;
1063
+ };
1064
+ const rootStoreOf = (store) => {
1065
+ return Object.getPrototypeOf(store);
1066
+ };
1067
+ const Toast = ({ root, duration = 3 } = {}) => {
1068
+ return function(target, key, descriptor) {
1069
+ const originMethod = descriptor.value;
1070
+ descriptor.value = async function(...args) {
1071
+ try {
1072
+ msg.loading(`${root ? `${root}.` : ""}${key}-loading`, { key, duration });
1073
+ const result = await originMethod.apply(this, args);
1074
+ msg.success(`${root ? `${root}.` : ""}${key}-success`, { key, duration });
1075
+ return result;
1076
+ } catch (err) {
1077
+ const errKey = typeof err === "string" ? err : err.message;
1078
+ msg.error(errKey, { key, duration });
1079
+ Logger.error(`${key} action error return: ${err}`);
1080
+ }
1081
+ };
1082
+ };
1083
+ };
1084
+ export {
1085
+ MixStore,
1086
+ Store,
1087
+ Toast,
1088
+ createActions,
1089
+ createState,
1090
+ makeStore,
1091
+ rootStoreOf,
1092
+ scalarStateOf,
1093
+ st,
1094
+ stateOf
1095
+ };
package/src/types.mjs ADDED
File without changes