@cmtlyt/lingshu-toolkit 0.3.0 → 0.4.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.
Files changed (56) hide show
  1. package/dist/607.js +446 -20
  2. package/dist/707.js +7 -2
  3. package/dist/react/index.js +1 -3
  4. package/dist/react/use-ref-state/index.js +1 -3
  5. package/dist/shared/allx/__test__/allsettled.test.d.ts +1 -0
  6. package/dist/shared/allx/__test__/basic.test.d.ts +1 -0
  7. package/dist/shared/allx/__test__/circular-dependency.test.d.ts +1 -0
  8. package/dist/shared/allx/__test__/dependency.test.d.ts +1 -0
  9. package/dist/shared/allx/__test__/edge-cases.test.d.ts +1 -0
  10. package/dist/shared/allx/__test__/error-handling.test.d.ts +1 -0
  11. package/dist/shared/allx/__test__/execution-order.test.d.ts +1 -0
  12. package/dist/shared/allx/__test__/falsy-values.test.d.ts +1 -0
  13. package/dist/shared/allx/__test__/performance.test.d.ts +1 -0
  14. package/dist/shared/allx/__test__/type-checking.test.d.ts +1 -0
  15. package/dist/shared/allx/__test__/use-cases.test.d.ts +1 -0
  16. package/dist/shared/allx/index.d.ts +13 -0
  17. package/dist/shared/allx/index.js +44 -0
  18. package/dist/shared/allx/types.d.ts +13 -0
  19. package/dist/shared/allx/types.js +0 -0
  20. package/dist/shared/allx/utils.d.ts +9 -0
  21. package/dist/shared/allx/utils.js +94 -0
  22. package/dist/shared/animation/index.d.ts +2 -2
  23. package/dist/shared/animation/index.js +19 -13
  24. package/dist/shared/animation/types.d.ts +6 -4
  25. package/dist/shared/animation/utils.d.ts +3 -5
  26. package/dist/shared/animation/utils.js +2 -6
  27. package/dist/shared/data-handler/tools.js +1 -3
  28. package/dist/shared/data-mixed-manager/__test__/basic.test.d.ts +1 -0
  29. package/dist/shared/data-mixed-manager/__test__/build-options.test.d.ts +1 -0
  30. package/dist/shared/data-mixed-manager/__test__/constructor-options.test.d.ts +1 -0
  31. package/dist/shared/data-mixed-manager/__test__/data-management.test.d.ts +1 -0
  32. package/dist/shared/data-mixed-manager/__test__/edge-cases.test.d.ts +1 -0
  33. package/dist/shared/data-mixed-manager/__test__/events.browser.test.d.ts +1 -0
  34. package/dist/shared/data-mixed-manager/__test__/events.test.d.ts +1 -0
  35. package/dist/shared/data-mixed-manager/__test__/fixed-slots.test.d.ts +1 -0
  36. package/dist/shared/data-mixed-manager/__test__/insert-mode.test.d.ts +1 -0
  37. package/dist/shared/data-mixed-manager/constants.d.ts +8 -0
  38. package/dist/shared/data-mixed-manager/constants.js +9 -0
  39. package/dist/shared/data-mixed-manager/index.d.ts +128 -0
  40. package/dist/shared/data-mixed-manager/index.js +226 -0
  41. package/dist/shared/data-mixed-manager/types.d.ts +90 -0
  42. package/dist/shared/data-mixed-manager/types.js +0 -0
  43. package/dist/shared/index.d.ts +3 -0
  44. package/dist/shared/index.js +2 -2
  45. package/dist/shared/throw-error/index.d.ts +1 -0
  46. package/dist/shared/throw-error/index.js +5 -2
  47. package/dist/shared/types/base.d.ts +3 -0
  48. package/dist/shared/utils/__test__/base.test.d.ts +1 -0
  49. package/dist/shared/utils/__test__/verify.test.d.ts +1 -0
  50. package/dist/shared/utils/base.d.ts +3 -0
  51. package/dist/shared/utils/base.js +6 -0
  52. package/dist/shared/utils/index.d.ts +2 -0
  53. package/dist/shared/utils/index.js +2 -0
  54. package/dist/shared/utils/verify.d.ts +53 -0
  55. package/dist/shared/utils/verify.js +67 -0
  56. package/package.json +6 -6
package/dist/607.js CHANGED
@@ -1,4 +1,70 @@
1
- import { dataHandler, logger, $dt, throwError, $t, throwType } from "./707.js";
1
+ import { throwType, createError, logger, $dt, throwError, getType, identity, dataHandler, $t, noop } from "./707.js";
2
+ function isSymbol(_v) {
3
+ return 'symbol' == typeof _v;
4
+ }
5
+ function isUndef(_v) {
6
+ return void 0 === _v;
7
+ }
8
+ function isNull(_v) {
9
+ return null === _v;
10
+ }
11
+ function isNullOrUndef(_v) {
12
+ return isNull(_v) || isUndef(_v);
13
+ }
14
+ function verify_isNaN(_v) {
15
+ return Number.isNaN(_v);
16
+ }
17
+ function isPlainSymbol(_v) {
18
+ return isSymbol(_v) && isUndef(Symbol.keyFor(_v));
19
+ }
20
+ function isObject(_v) {
21
+ return 'object' == typeof _v && !isNull(_v);
22
+ }
23
+ function isPlainObject(_v) {
24
+ return isObject(_v) && !isArray(_v);
25
+ }
26
+ function isArray(_v) {
27
+ return Array.isArray(_v);
28
+ }
29
+ function isEmptyArray(_v) {
30
+ return isArray(_v) && 0 === _v.length;
31
+ }
32
+ function isString(_v) {
33
+ return 'string' == typeof _v;
34
+ }
35
+ function isEmptyString(_v) {
36
+ return isString(_v) && 0 === _v.length;
37
+ }
38
+ function isNumber(_v) {
39
+ return 'number' == typeof _v;
40
+ }
41
+ function isPlainNumber(_v) {
42
+ return isNumber(_v) && !verify_isNaN(_v);
43
+ }
44
+ function isPropertyKey(_v) {
45
+ return isString(_v) || isNumber(_v) || isSymbol(_v);
46
+ }
47
+ function isBoolean(_v) {
48
+ return 'boolean' == typeof _v;
49
+ }
50
+ function isTrue(_v) {
51
+ return true === _v || isString(_v) && 'true' === _v.toLowerCase();
52
+ }
53
+ function isFalse(_v) {
54
+ return false === _v || isString(_v) && 'false' === _v.toLowerCase();
55
+ }
56
+ function isTruthy(_v) {
57
+ return !!_v;
58
+ }
59
+ function isFalsy(_v) {
60
+ return !(verify_isNaN(_v) || _v);
61
+ }
62
+ function isFunction(_v) {
63
+ return 'function' == typeof _v;
64
+ }
65
+ function isPromiseLike(_v) {
66
+ return isObject(_v) && isFunction(_v.then);
67
+ }
2
68
  function withResolvers() {
3
69
  return 'function' == typeof Promise.withResolvers ? Promise.withResolvers() : (()=>{
4
70
  const resolver = {
@@ -13,10 +79,135 @@ function withResolvers() {
13
79
  return resolver;
14
80
  })();
15
81
  }
16
- const noop = ()=>void 0;
17
- const identity = (_v)=>_v;
18
- function getType(_v) {
19
- return Object.prototype.toString.call(_v).slice(8, -1).toLowerCase();
82
+ function detectCycle(from, to, waitingForGraph) {
83
+ const visited = new Set();
84
+ const queue = [
85
+ to
86
+ ];
87
+ let head = 0;
88
+ while(head < queue.length){
89
+ const node = queue[head++];
90
+ if (node === from) return true;
91
+ if (visited.has(node)) continue;
92
+ visited.add(node);
93
+ const deps = waitingForGraph.get(node);
94
+ if (deps) {
95
+ const depsIter = deps.values();
96
+ for(let dep = depsIter.next(); !dep.done; dep = depsIter.next())queue.push(dep.value);
97
+ }
98
+ }
99
+ return false;
100
+ }
101
+ function getCached(results, depName, allSettled) {
102
+ if (Reflect.getOwnPropertyDescriptor(results, depName)) {
103
+ const cached = results[depName];
104
+ if (allSettled) return 'rejected' === cached.status ? Promise.reject(cached.reason) : Promise.resolve(cached.value);
105
+ return Promise.resolve(cached);
106
+ }
107
+ }
108
+ function createDepResolver(waitingFor, resolverMap, currentTask, depName) {
109
+ waitingFor.set(currentTask, (waitingFor.get(currentTask) || new Set()).add(depName));
110
+ const depResolvers = resolverMap.get(depName) || withResolvers();
111
+ resolverMap.set(depName, depResolvers);
112
+ return depResolvers.promise.then((value)=>{
113
+ waitingFor.get(currentTask)?.delete(depName);
114
+ return value;
115
+ }, (error)=>{
116
+ waitingFor.get(currentTask)?.delete(depName);
117
+ throw error;
118
+ });
119
+ }
120
+ function cleanWaitingForGraph(waitingForGraph, depName) {
121
+ waitingForGraph.forEach((deps, task)=>{
122
+ deps.delete(depName);
123
+ if (0 === deps.size) waitingForGraph.delete(task);
124
+ });
125
+ }
126
+ function createDepProxy(tasks, results, options) {
127
+ const resolverMap = new Map();
128
+ const taskNameSet = new Set(Reflect.ownKeys(tasks));
129
+ const waitingForGraph = new Map();
130
+ const resolveDepFor = (depName, value)=>{
131
+ const resolver = resolverMap.get(depName);
132
+ if (resolver) {
133
+ resolver.resolve(value);
134
+ resolverMap.delete(depName);
135
+ }
136
+ cleanWaitingForGraph(waitingForGraph, depName);
137
+ };
138
+ const rejectDepFor = (depName, error)=>{
139
+ const resolver = resolverMap.get(depName);
140
+ if (resolver) {
141
+ resolver.reject(error);
142
+ resolverMap.delete(depName);
143
+ }
144
+ cleanWaitingForGraph(waitingForGraph, depName);
145
+ };
146
+ const createContextFor = (currentTask)=>new Proxy({}, {
147
+ get (_, depName) {
148
+ if (!taskNameSet.has(depName)) return Promise.reject(createError('allx', `Unknown task "${String(depName)}"`));
149
+ const cached = getCached(results, depName, options.allSettled);
150
+ if (cached) return cached;
151
+ if (detectCycle(currentTask, depName, waitingForGraph)) return Promise.reject(createError('allx', `Circular dependency detected: "${String(currentTask)}" -> "${String(depName)}"`));
152
+ return createDepResolver(waitingForGraph, resolverMap, currentTask, depName);
153
+ }
154
+ });
155
+ return {
156
+ taskNameSet,
157
+ createContextFor,
158
+ resolveDepFor,
159
+ rejectDepFor
160
+ };
161
+ }
162
+ function getValueFormatFunc(options) {
163
+ if (!options) return (value, _type = 'fulfilled')=>value;
164
+ if (options.allSettled) return (value, status = 'fulfilled')=>'fulfilled' === status ? {
165
+ status,
166
+ value
167
+ } : {
168
+ status,
169
+ reason: value
170
+ };
171
+ return (value, _type = 'fulfilled')=>value;
172
+ }
173
+ const validInfo = $dt({
174
+ allSettled: $t.boolean(false)
175
+ });
176
+ async function allx(tasks, options) {
177
+ const validOptions = dataHandler(options || {}, validInfo, {
178
+ unwrap: true
179
+ });
180
+ const { allSettled } = validOptions;
181
+ const results = {};
182
+ const depCtrl = createDepProxy(tasks, results, validOptions);
183
+ const valueFormat = getValueFormatFunc(options);
184
+ const promises = [];
185
+ depCtrl.taskNameSet.forEach(async (taskName)=>{
186
+ const taskFn = tasks[taskName];
187
+ const context = {
188
+ $: depCtrl.createContextFor(taskName)
189
+ };
190
+ const taskResolvers = withResolvers();
191
+ taskResolvers.promise.then((value)=>{
192
+ results[taskName] = valueFormat(value, 'fulfilled');
193
+ depCtrl.resolveDepFor(taskName, value);
194
+ return value;
195
+ }, (error)=>{
196
+ if (allSettled) results[taskName] = valueFormat(error, 'rejected');
197
+ depCtrl.rejectDepFor(taskName, error);
198
+ });
199
+ promises.push(taskResolvers.promise);
200
+ if (isPromiseLike(taskFn)) return void await taskFn.then(taskResolvers.resolve, taskResolvers.reject);
201
+ if (!isFunction(taskFn)) return void taskResolvers.resolve(taskFn);
202
+ try {
203
+ const result = await taskFn.call(context);
204
+ taskResolvers.resolve(result);
205
+ } catch (error) {
206
+ taskResolvers.reject(error);
207
+ }
208
+ });
209
+ if (allSettled) return Promise.allSettled(promises).then(()=>results);
210
+ return Promise.all(promises).then(()=>results);
20
211
  }
21
212
  function getNextValueHandler(from, to, valueFormatter) {
22
213
  const type = getType(from);
@@ -148,17 +339,7 @@ function createRunningControllerSignal(startFn, options) {
148
339
  };
149
340
  return ctrl;
150
341
  }
151
- function* stepAnimation(from, to, step, options = {}) {
152
- if (!Number.isInteger(step) || step <= 0) throwError('stepAnimation', 'step must be a positive integer', RangeError);
153
- const { parser: valueParser = identity, formatter: valueFormatter = identity } = options;
154
- const [validFrom, validTo] = matchValid(from, to, valueParser);
155
- const getNextValue = getNextValueHandler(validFrom, validTo, valueFormatter);
156
- for(let i = 0; i <= step; i++){
157
- const value = getNextValue(i / step);
158
- yield value;
159
- }
160
- }
161
- const validInfo = $dt({
342
+ const animation_validInfo = $dt({
162
343
  autoStart: $t.boolean(true),
163
344
  easing: $t["function"](()=>identity),
164
345
  onStart: $t["function"](()=>noop),
@@ -166,17 +347,32 @@ const validInfo = $dt({
166
347
  onClear: $t["function"](()=>noop),
167
348
  onUpdate: $t["function"](()=>noop),
168
349
  onComplete: $t["function"](()=>noop),
350
+ formatterValue: $t["function"](()=>identity),
169
351
  formatter: $t["function"](()=>identity),
170
352
  parser: $t["function"](()=>identity)
171
353
  });
354
+ function* stepAnimation(from, to, step, options = {}) {
355
+ if (!Number.isInteger(step) || step <= 0) throwError('stepAnimation', 'step must be a positive integer', RangeError);
356
+ const validOptions = dataHandler(options, animation_validInfo, {
357
+ unwrap: true
358
+ });
359
+ const { parser: valueParser = identity, formatterValue = identity, formatter } = validOptions;
360
+ const [validFrom, validTo] = matchValid(from, to, valueParser);
361
+ const getNextValue = getNextValueHandler(validFrom, validTo, formatterValue);
362
+ for(let i = 0; i <= step; i++){
363
+ const value = formatter(getNextValue(i / step));
364
+ yield value;
365
+ }
366
+ }
172
367
  function animation(from, to, duration, options = {}) {
173
368
  if (duration <= 0 || !Number.isInteger(duration)) throwError('animation', 'duration must be a positive integer', RangeError);
174
- const validOptions = dataHandler(options, validInfo, {
369
+ const validOptions = dataHandler(options, animation_validInfo, {
175
370
  unwrap: true
176
371
  });
177
372
  const [validFrom, validTo] = matchValid(from, to, validOptions.parser);
178
- const { autoStart, easing, onComplete, onUpdate, formatter: valueFormatter } = validOptions;
179
- const getNextValue = getNextValueHandler(validFrom, validTo, valueFormatter);
373
+ const { autoStart, easing, onComplete, onUpdate, formatterValue, formatter } = validOptions;
374
+ const _getNextValue = getNextValueHandler(validFrom, validTo, formatterValue);
375
+ const getNextValue = (...args)=>formatter(_getNextValue(...args));
180
376
  let startTime = 0;
181
377
  let hasStarted = false;
182
378
  const rcSignal = createRunningControllerSignal(()=>{
@@ -307,5 +503,235 @@ function createStorageHandler(storageKey, initialData, options = {}) {
307
503
  }
308
504
  };
309
505
  }
506
+ const SLOT_TYPE = {
507
+ fixed: {
508
+ fixedFlag: Symbol('fixed')
509
+ },
510
+ insert: {
511
+ insertFlag: Symbol('insert')
512
+ }
513
+ };
514
+ const data_mixed_manager_validInfo = $dt({
515
+ name: $t.string('default'),
516
+ fixedSlots: $t.array([]),
517
+ dataList: $t.array([]),
518
+ listener: $t.object({})
519
+ });
520
+ class DataMixedManager extends EventTarget {
521
+ addEventListener(...args) {
522
+ return super.addEventListener.apply(this, args);
523
+ }
524
+ removeEventListener(...args) {
525
+ return super.removeEventListener.apply(this, args);
526
+ }
527
+ options;
528
+ fixedSlots = new Map();
529
+ dataList = [];
530
+ mixedData = [];
531
+ lastMixedSlotIdx = -1;
532
+ prevDataLength = 0;
533
+ isBatching = false;
534
+ constructor(options){
535
+ super();
536
+ const validOptions = dataHandler(options || {}, data_mixed_manager_validInfo, {
537
+ unwrap: true
538
+ });
539
+ const { fixedSlots, dataList, listener } = validOptions;
540
+ this.options = validOptions;
541
+ this.addFixedSlots(fixedSlots, {
542
+ lazy: true
543
+ });
544
+ this.appendList(dataList);
545
+ try {
546
+ this.initListener(listener);
547
+ } catch (error) {
548
+ throwError('dataMixedManager', error.message, error.constructor);
549
+ }
550
+ }
551
+ initListener(listener) {
552
+ const listenerNames = Object.keys(listener);
553
+ for(let i = 0, name = listenerNames[i], handler = listener[name]; i < listenerNames.length; name = listenerNames[++i], handler = listener[name])this.addEventListener(name, handler);
554
+ }
555
+ getTypeText(_type) {
556
+ switch(_type){
557
+ case SLOT_TYPE.fixed:
558
+ return 'fixed';
559
+ case SLOT_TYPE.insert:
560
+ return 'insert';
561
+ }
562
+ }
563
+ buildSlotConfig(config, type) {
564
+ const typeText = this.getTypeText(config.type || type);
565
+ return {
566
+ ...config,
567
+ type: typeText,
568
+ inputPosition: config.position,
569
+ insertMode: config.insertMode || 'cover'
570
+ };
571
+ }
572
+ addFixedSlot(config, buildOptions) {
573
+ const realConfig = this.reorderFixedSlots(this.buildSlotConfig(config, SLOT_TYPE.fixed));
574
+ this.fixedSlots.set(realConfig.position, realConfig);
575
+ this.buildMixedData(buildOptions);
576
+ return realConfig.position;
577
+ }
578
+ reorderFixedSlots(config) {
579
+ const { position: oldPosition, insertMode } = config;
580
+ if (null == insertMode || 'cover' === insertMode || !this.fixedSlots.has(oldPosition)) return {
581
+ ...config,
582
+ inputPosition: oldPosition
583
+ };
584
+ const position = 'after' === insertMode ? oldPosition + 1 : oldPosition;
585
+ for(let i = position + 1, preItem = this.fixedSlots.get(i - 1), currItem = this.fixedSlots.get(i); preItem; ++i, preItem = currItem, currItem = this.fixedSlots.get(i)){
586
+ preItem.position = i;
587
+ this.fixedSlots.set(i, preItem);
588
+ }
589
+ return {
590
+ ...config,
591
+ position,
592
+ inputPosition: oldPosition
593
+ };
594
+ }
595
+ addFixedSlots(configs, buildOptions) {
596
+ if (!configs.length) return [];
597
+ const positions = this.batchUpdate(()=>configs.map((config)=>this.addFixedSlot(config)));
598
+ this.buildMixedData(buildOptions);
599
+ return positions;
600
+ }
601
+ deleteFixedSlot(position, buildOptions) {
602
+ this.fixedSlots.delete(position);
603
+ this.buildMixedData(buildOptions);
604
+ }
605
+ deleteFixedSlots(positions, buildOptions) {
606
+ if (!positions.length) return;
607
+ this.batchUpdate(()=>positions.forEach((position)=>void this.deleteFixedSlot(position)));
608
+ this.buildMixedData(buildOptions);
609
+ }
610
+ batchUpdate(callback) {
611
+ try {
612
+ this.isBatching = true;
613
+ const result = callback();
614
+ return result;
615
+ } finally{
616
+ this.isBatching = false;
617
+ }
618
+ }
619
+ clearFixedSlots(buildOptions) {
620
+ this.fixedSlots.clear();
621
+ this.buildMixedData(buildOptions);
622
+ }
623
+ appendList(list, buildOptions) {
624
+ if (!list.length) return;
625
+ this.dataList.push(...list);
626
+ this.buildMixedData({
627
+ ...buildOptions,
628
+ lazy: true === (buildOptions || {}).lazy
629
+ });
630
+ }
631
+ clearList() {
632
+ this.dataList.length = 0;
633
+ this.mixedData.length = 0;
634
+ this.dispatch('change', {
635
+ mode: 'clear',
636
+ mixedData: this.getMixedData({
637
+ mode: 'rebuild'
638
+ })
639
+ });
640
+ this.dispatch('clear');
641
+ }
642
+ getMixedData(buildOptions) {
643
+ this.buildMixedData({
644
+ ...buildOptions,
645
+ lazy: false
646
+ });
647
+ return this.mixedData.slice();
648
+ }
649
+ dispatch(name, data) {
650
+ const detail = {
651
+ name: this.options.name,
652
+ ...data
653
+ };
654
+ this.dispatchEvent(new CustomEvent(name, {
655
+ detail
656
+ }));
657
+ if ("u" > typeof window) window.dispatchEvent(new CustomEvent(`[DMM]:${name}`, {
658
+ detail
659
+ }));
660
+ }
661
+ buildMixedData(buildOptions) {
662
+ if (this.isBatching) return;
663
+ const { lazy, mode } = buildOptions || {};
664
+ if ('rebuild' === mode) {
665
+ this.prevDataLength = 0;
666
+ this.lastMixedSlotIdx = -1;
667
+ }
668
+ if (false !== lazy || this.dataList.length <= this.prevDataLength) return;
669
+ let dataStartIdx = this.prevDataLength;
670
+ const dataEndIdx = this.dataList.length;
671
+ const newItemCount = dataEndIdx - dataStartIdx;
672
+ this.prevDataLength = dataEndIdx;
673
+ const isPatchMode = dataStartIdx > 0;
674
+ const filteredSlots = this.sliceSlots(isPatchMode ? this.mixedData.length : this.lastMixedSlotIdx, this.mixedData.length + newItemCount);
675
+ this.lastMixedSlotIdx = filteredSlots.at(-1) ?? this.lastMixedSlotIdx;
676
+ let mixedStartIdx = isPatchMode ? this.mixedData.length : 0;
677
+ this.mixedData.length = (isPatchMode ? newItemCount + mixedStartIdx : dataEndIdx) + filteredSlots.length;
678
+ for(let fpIdx = 0, fpItem = filteredSlots[fpIdx]; dataStartIdx < dataEndIdx; ++mixedStartIdx)if (mixedStartIdx === fpItem) {
679
+ const fixedSlot = this.fixedSlots.get(fpItem);
680
+ this.mixedData[mixedStartIdx] = {
681
+ isFixed: true,
682
+ type: fixedSlot.type,
683
+ data: fixedSlot.data
684
+ };
685
+ fpItem = filteredSlots[++fpIdx];
686
+ } else {
687
+ this.mixedData[mixedStartIdx] = {
688
+ isFixed: false,
689
+ type: 'plain',
690
+ data: this.dataList[dataStartIdx]
691
+ };
692
+ ++dataStartIdx;
693
+ }
694
+ this.dispatch('change', {
695
+ mode: isPatchMode ? 'patch' : 'rebuild',
696
+ mixedData: this.mixedData.slice()
697
+ });
698
+ }
699
+ sliceSlots(startIdx, endIdx = 1 / 0) {
700
+ let prevItem = -2;
701
+ let count = 0;
702
+ return Array.from(this.fixedSlots.keys()).sort((ai, bi)=>ai - bi).filter((item)=>{
703
+ if (item >= startIdx && item < endIdx + count || item - 1 === prevItem) {
704
+ ++count;
705
+ prevItem = item;
706
+ return true;
707
+ }
708
+ return false;
709
+ });
710
+ }
711
+ insertSlot(config) {
712
+ const realPosition = this.addFixedSlot({
713
+ ...config,
714
+ type: SLOT_TYPE.insert
715
+ });
716
+ if (realPosition > this.mixedData.length) return realPosition;
717
+ this.buildMixedData({
718
+ lazy: false,
719
+ mode: 'rebuild'
720
+ });
721
+ return realPosition;
722
+ }
723
+ insertSlots(configs) {
724
+ if (!configs.length) return [];
725
+ const positions = this.batchUpdate(()=>configs.map((config)=>this.insertSlot(config)));
726
+ this.buildMixedData({
727
+ lazy: false,
728
+ mode: 'rebuild'
729
+ });
730
+ return positions;
731
+ }
732
+ }
733
+ function dataMixedManager(options) {
734
+ return new DataMixedManager(options);
735
+ }
310
736
  Symbol('__PACK__');
311
- export { animation, conditionMerge, createStorageHandler, stepAnimation, withResolvers };
737
+ export { allx, animation, conditionMerge, createStorageHandler, dataMixedManager, isArray, isBoolean, isEmptyArray, isEmptyString, isFalse, isFalsy, isFunction, isNull, isNullOrUndef, isNumber, isObject, isPlainNumber, isPlainObject, isPlainSymbol, isPromiseLike, isPropertyKey, isString, isSymbol, isTrue, isTruthy, isUndef, stepAnimation, verify_isNaN as isNaN, withResolvers };
package/dist/707.js CHANGED
@@ -1,5 +1,8 @@
1
+ function createError(fnName, message, ErrorClass = Error) {
2
+ return new ErrorClass(`[@cmtlyt/lingshu-toolkit#${fnName}]: ${message}`);
3
+ }
1
4
  function throwError(fnName, message, ErrorClass = Error) {
2
- throw new ErrorClass(`[@cmtlyt/lingshu-toolkit#${fnName}]: ${message}`);
5
+ throw createError(fnName, message, ErrorClass);
3
6
  }
4
7
  function throwType(fnName, message) {
5
8
  throwError(fnName, message, TypeError);
@@ -12,6 +15,8 @@ const logger = new Proxy(console, {
12
15
  };
13
16
  }
14
17
  });
18
+ const noop = ()=>void 0;
19
+ const identity = (_v)=>_v;
15
20
  function getType(_v) {
16
21
  return Object.prototype.toString.call(_v).slice(8, -1).toLowerCase();
17
22
  }
@@ -133,4 +138,4 @@ function dataHandler(data, handler, options) {
133
138
  errors: ctx.errors
134
139
  };
135
140
  }
136
- export { $dt, $t, dataHandler, defineTransform, logger, throwError, throwType };
141
+ export { $dt, $t, createError, dataHandler, defineTransform, getType, identity, logger, noop, throwError, throwType };
@@ -138,9 +138,7 @@ function useMount(callback) {
138
138
  callbackRef.current();
139
139
  }, []);
140
140
  }
141
- function clone(_v) {
142
- return structuredClone(_v);
143
- }
141
+ const clone = structuredClone;
144
142
  function useRefState(initialState) {
145
143
  const stateRef = useRef(initialState);
146
144
  const forceUpdate = useForceUpdate();
@@ -1,8 +1,6 @@
1
1
  import { useMemo, useRef } from "react";
2
2
  import { useForceUpdate } from "../use-force-update/index.js";
3
- function clone(_v) {
4
- return structuredClone(_v);
5
- }
3
+ const clone = structuredClone;
6
4
  function useRefState(initialState) {
7
5
  const stateRef = useRef(initialState);
8
6
  const forceUpdate = useForceUpdate();
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import type { AllxContext, AllxOptions, AllxResult } from './types';
2
+ /**
3
+ * 支持自动依赖优化和完整类型推断的 Promise.all, 执行任务时自动解决依赖关系。
4
+ *
5
+ * @platform web, node, webworker
6
+ * @example
7
+ * const { a, b, c } = await allx({
8
+ * a() { return 1 },
9
+ * async b() { return 'hello' },
10
+ * async c() { return (await this.$.a) + 10 }
11
+ * })
12
+ */
13
+ export declare function allx<M extends Record<PropertyKey, any>, O extends AllxOptions>(tasks: M & ThisType<AllxContext<M>>, options?: O): Promise<AllxResult<M, O>>;
@@ -0,0 +1,44 @@
1
+ import { $dt, $t, dataHandler } from "../data-handler/index.js";
2
+ import { isFunction, isPromiseLike } from "../utils/verify.js";
3
+ import { withResolvers } from "../with-resolvers/index.js";
4
+ import { createDepProxy, getValueFormatFunc } from "./utils.js";
5
+ const validInfo = $dt({
6
+ allSettled: $t.boolean(false)
7
+ });
8
+ async function allx(tasks, options) {
9
+ const validOptions = dataHandler(options || {}, validInfo, {
10
+ unwrap: true
11
+ });
12
+ const { allSettled } = validOptions;
13
+ const results = {};
14
+ const depCtrl = createDepProxy(tasks, results, validOptions);
15
+ const valueFormat = getValueFormatFunc(options);
16
+ const promises = [];
17
+ depCtrl.taskNameSet.forEach(async (taskName)=>{
18
+ const taskFn = tasks[taskName];
19
+ const context = {
20
+ $: depCtrl.createContextFor(taskName)
21
+ };
22
+ const taskResolvers = withResolvers();
23
+ taskResolvers.promise.then((value)=>{
24
+ results[taskName] = valueFormat(value, 'fulfilled');
25
+ depCtrl.resolveDepFor(taskName, value);
26
+ return value;
27
+ }, (error)=>{
28
+ if (allSettled) results[taskName] = valueFormat(error, 'rejected');
29
+ depCtrl.rejectDepFor(taskName, error);
30
+ });
31
+ promises.push(taskResolvers.promise);
32
+ if (isPromiseLike(taskFn)) return void await taskFn.then(taskResolvers.resolve, taskResolvers.reject);
33
+ if (!isFunction(taskFn)) return void taskResolvers.resolve(taskFn);
34
+ try {
35
+ const result = await taskFn.call(context);
36
+ taskResolvers.resolve(result);
37
+ } catch (error) {
38
+ taskResolvers.reject(error);
39
+ }
40
+ });
41
+ if (allSettled) return Promise.allSettled(promises).then(()=>results);
42
+ return Promise.all(promises).then(()=>results);
43
+ }
44
+ export { allx };
@@ -0,0 +1,13 @@
1
+ import type { AnyFunc } from '../types/base';
2
+ export interface AllxOptions {
3
+ allSettled?: boolean;
4
+ }
5
+ export type AllxTaskValue<T> = T extends AnyFunc ? Awaited<ReturnType<T>> : Awaited<T>;
6
+ export interface AllxContext<M extends Record<PropertyKey, AnyFunc>> {
7
+ $: {
8
+ [P in keyof M]: Promise<AllxTaskValue<M[P]>>;
9
+ };
10
+ }
11
+ export type AllxResult<M extends Record<PropertyKey, AnyFunc>, O extends AllxOptions = AllxOptions> = {
12
+ [P in keyof M]: O['allSettled'] extends true ? PromiseSettledResult<Awaited<ReturnType<M[P]>>> : AllxTaskValue<M[P]>;
13
+ };
File without changes
@@ -0,0 +1,9 @@
1
+ import type { AnyFunc } from '../types/base';
2
+ import type { AllxOptions } from './types';
3
+ export declare function createDepProxy(tasks: Record<PropertyKey, AnyFunc>, results: Record<PropertyKey, any>, options: Required<AllxOptions>): {
4
+ taskNameSet: Set<PropertyKey>;
5
+ createContextFor: (currentTask: PropertyKey) => {};
6
+ resolveDepFor: (depName: PropertyKey, value: any) => void;
7
+ rejectDepFor: (depName: PropertyKey, error: any) => void;
8
+ };
9
+ export declare function getValueFormatFunc(options?: AllxOptions): (value: any, _type?: PromiseSettledResult<any>["status"]) => any;