@cmtlyt/lingshu-toolkit 0.2.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 (83) hide show
  1. package/dist/607.js +737 -0
  2. package/dist/707.js +13 -3
  3. package/dist/react/index.d.ts +7 -0
  4. package/dist/react/index.js +120 -3
  5. package/dist/react/use-force-update/index.d.ts +1 -0
  6. package/dist/react/use-force-update/index.js +6 -0
  7. package/dist/react/use-force-update/index.test.d.ts +1 -0
  8. package/dist/react/use-ref-state/index.d.ts +8 -0
  9. package/dist/react/use-ref-state/index.js +33 -0
  10. package/dist/react/use-ref-state/index.test.d.ts +1 -0
  11. package/dist/react/use-storage/index.d.ts +2 -0
  12. package/dist/react/use-storage/index.js +15 -0
  13. package/dist/react/use-storage/index.test.d.ts +1 -0
  14. package/dist/react/use-valid-data/index.d.ts +3 -3
  15. package/dist/shared/allx/__test__/allsettled.test.d.ts +1 -0
  16. package/dist/shared/allx/__test__/basic.test.d.ts +1 -0
  17. package/dist/shared/allx/__test__/circular-dependency.test.d.ts +1 -0
  18. package/dist/shared/allx/__test__/dependency.test.d.ts +1 -0
  19. package/dist/shared/allx/__test__/edge-cases.test.d.ts +1 -0
  20. package/dist/shared/allx/__test__/error-handling.test.d.ts +1 -0
  21. package/dist/shared/allx/__test__/execution-order.test.d.ts +1 -0
  22. package/dist/shared/allx/__test__/falsy-values.test.d.ts +1 -0
  23. package/dist/shared/allx/__test__/performance.test.d.ts +1 -0
  24. package/dist/shared/allx/__test__/type-checking.test.d.ts +1 -0
  25. package/dist/shared/allx/__test__/use-cases.test.d.ts +1 -0
  26. package/dist/shared/allx/index.d.ts +13 -0
  27. package/dist/shared/allx/index.js +44 -0
  28. package/dist/shared/allx/types.d.ts +13 -0
  29. package/dist/shared/allx/types.js +0 -0
  30. package/dist/shared/allx/utils.d.ts +9 -0
  31. package/dist/shared/allx/utils.js +94 -0
  32. package/dist/shared/animation/__test__/animation-pause-resume.test.d.ts +1 -0
  33. package/dist/shared/animation/__test__/animation.test.d.ts +1 -0
  34. package/dist/shared/animation/__test__/step-animation.test.d.ts +1 -0
  35. package/dist/shared/animation/__test__/utils.test.d.ts +1 -0
  36. package/dist/shared/animation/index.d.ts +3 -0
  37. package/dist/shared/animation/index.js +77 -0
  38. package/dist/shared/animation/types.d.ts +24 -0
  39. package/dist/shared/animation/types.js +0 -0
  40. package/dist/shared/animation/utils.d.ts +14 -0
  41. package/dist/shared/animation/utils.js +134 -0
  42. package/dist/shared/condition-merge/index.d.ts +1 -5
  43. package/dist/shared/create-storage-handler/index.browser.test.d.ts +1 -0
  44. package/dist/shared/create-storage-handler/index.d.ts +10 -0
  45. package/dist/shared/create-storage-handler/index.js +68 -0
  46. package/dist/shared/create-storage-handler/index.test.d.ts +1 -0
  47. package/dist/shared/data-handler/index.d.ts +7 -2
  48. package/dist/shared/data-handler/tools.d.ts +36 -12
  49. package/dist/shared/data-handler/tools.js +8 -4
  50. package/dist/shared/data-handler/types.d.ts +2 -2
  51. package/dist/shared/data-mixed-manager/__test__/basic.test.d.ts +1 -0
  52. package/dist/shared/data-mixed-manager/__test__/build-options.test.d.ts +1 -0
  53. package/dist/shared/data-mixed-manager/__test__/constructor-options.test.d.ts +1 -0
  54. package/dist/shared/data-mixed-manager/__test__/data-management.test.d.ts +1 -0
  55. package/dist/shared/data-mixed-manager/__test__/edge-cases.test.d.ts +1 -0
  56. package/dist/shared/data-mixed-manager/__test__/events.browser.test.d.ts +1 -0
  57. package/dist/shared/data-mixed-manager/__test__/events.test.d.ts +1 -0
  58. package/dist/shared/data-mixed-manager/__test__/fixed-slots.test.d.ts +1 -0
  59. package/dist/shared/data-mixed-manager/__test__/insert-mode.test.d.ts +1 -0
  60. package/dist/shared/data-mixed-manager/constants.d.ts +8 -0
  61. package/dist/shared/data-mixed-manager/constants.js +9 -0
  62. package/dist/shared/data-mixed-manager/index.d.ts +128 -0
  63. package/dist/shared/data-mixed-manager/index.js +226 -0
  64. package/dist/shared/data-mixed-manager/types.d.ts +90 -0
  65. package/dist/shared/data-mixed-manager/types.js +0 -0
  66. package/dist/shared/index.d.ts +8 -0
  67. package/dist/shared/index.js +2 -1
  68. package/dist/shared/throw-error/index.d.ts +1 -0
  69. package/dist/shared/throw-error/index.js +5 -2
  70. package/dist/shared/types/base.d.ts +6 -0
  71. package/dist/shared/utils/__test__/base.test.d.ts +1 -0
  72. package/dist/shared/utils/__test__/verify.test.d.ts +1 -0
  73. package/dist/shared/utils/base.d.ts +3 -0
  74. package/dist/shared/utils/base.js +6 -0
  75. package/dist/shared/utils/index.d.ts +2 -0
  76. package/dist/shared/utils/index.js +2 -0
  77. package/dist/shared/utils/verify.d.ts +53 -0
  78. package/dist/shared/utils/verify.js +67 -0
  79. package/dist/shared/with-resolvers/index.d.ts +6 -0
  80. package/dist/shared/with-resolvers/index.js +15 -0
  81. package/dist/shared/with-resolvers/index.test.d.ts +1 -0
  82. package/dist/test/utils.d.ts +13 -0
  83. package/package.json +9 -7
@@ -0,0 +1,226 @@
1
+ import { $dt, $t, dataHandler } from "../data-handler/index.js";
2
+ import { throwError } from "../throw-error/index.js";
3
+ import { SLOT_TYPE } from "./constants.js";
4
+ const validInfo = $dt({
5
+ name: $t.string('default'),
6
+ fixedSlots: $t.array([]),
7
+ dataList: $t.array([]),
8
+ listener: $t.object({})
9
+ });
10
+ class DataMixedManager extends EventTarget {
11
+ addEventListener(...args) {
12
+ return super.addEventListener.apply(this, args);
13
+ }
14
+ removeEventListener(...args) {
15
+ return super.removeEventListener.apply(this, args);
16
+ }
17
+ options;
18
+ fixedSlots = new Map();
19
+ dataList = [];
20
+ mixedData = [];
21
+ lastMixedSlotIdx = -1;
22
+ prevDataLength = 0;
23
+ isBatching = false;
24
+ constructor(options){
25
+ super();
26
+ const validOptions = dataHandler(options || {}, validInfo, {
27
+ unwrap: true
28
+ });
29
+ const { fixedSlots, dataList, listener } = validOptions;
30
+ this.options = validOptions;
31
+ this.addFixedSlots(fixedSlots, {
32
+ lazy: true
33
+ });
34
+ this.appendList(dataList);
35
+ try {
36
+ this.initListener(listener);
37
+ } catch (error) {
38
+ throwError('dataMixedManager', error.message, error.constructor);
39
+ }
40
+ }
41
+ initListener(listener) {
42
+ const listenerNames = Object.keys(listener);
43
+ for(let i = 0, name = listenerNames[i], handler = listener[name]; i < listenerNames.length; name = listenerNames[++i], handler = listener[name])this.addEventListener(name, handler);
44
+ }
45
+ getTypeText(_type) {
46
+ switch(_type){
47
+ case SLOT_TYPE.fixed:
48
+ return 'fixed';
49
+ case SLOT_TYPE.insert:
50
+ return 'insert';
51
+ }
52
+ }
53
+ buildSlotConfig(config, type) {
54
+ const typeText = this.getTypeText(config.type || type);
55
+ return {
56
+ ...config,
57
+ type: typeText,
58
+ inputPosition: config.position,
59
+ insertMode: config.insertMode || 'cover'
60
+ };
61
+ }
62
+ addFixedSlot(config, buildOptions) {
63
+ const realConfig = this.reorderFixedSlots(this.buildSlotConfig(config, SLOT_TYPE.fixed));
64
+ this.fixedSlots.set(realConfig.position, realConfig);
65
+ this.buildMixedData(buildOptions);
66
+ return realConfig.position;
67
+ }
68
+ reorderFixedSlots(config) {
69
+ const { position: oldPosition, insertMode } = config;
70
+ if (null == insertMode || 'cover' === insertMode || !this.fixedSlots.has(oldPosition)) return {
71
+ ...config,
72
+ inputPosition: oldPosition
73
+ };
74
+ const position = 'after' === insertMode ? oldPosition + 1 : oldPosition;
75
+ 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)){
76
+ preItem.position = i;
77
+ this.fixedSlots.set(i, preItem);
78
+ }
79
+ return {
80
+ ...config,
81
+ position,
82
+ inputPosition: oldPosition
83
+ };
84
+ }
85
+ addFixedSlots(configs, buildOptions) {
86
+ if (!configs.length) return [];
87
+ const positions = this.batchUpdate(()=>configs.map((config)=>this.addFixedSlot(config)));
88
+ this.buildMixedData(buildOptions);
89
+ return positions;
90
+ }
91
+ deleteFixedSlot(position, buildOptions) {
92
+ this.fixedSlots.delete(position);
93
+ this.buildMixedData(buildOptions);
94
+ }
95
+ deleteFixedSlots(positions, buildOptions) {
96
+ if (!positions.length) return;
97
+ this.batchUpdate(()=>positions.forEach((position)=>void this.deleteFixedSlot(position)));
98
+ this.buildMixedData(buildOptions);
99
+ }
100
+ batchUpdate(callback) {
101
+ try {
102
+ this.isBatching = true;
103
+ const result = callback();
104
+ return result;
105
+ } finally{
106
+ this.isBatching = false;
107
+ }
108
+ }
109
+ clearFixedSlots(buildOptions) {
110
+ this.fixedSlots.clear();
111
+ this.buildMixedData(buildOptions);
112
+ }
113
+ appendList(list, buildOptions) {
114
+ if (!list.length) return;
115
+ this.dataList.push(...list);
116
+ this.buildMixedData({
117
+ ...buildOptions,
118
+ lazy: true === (buildOptions || {}).lazy
119
+ });
120
+ }
121
+ clearList() {
122
+ this.dataList.length = 0;
123
+ this.mixedData.length = 0;
124
+ this.dispatch('change', {
125
+ mode: 'clear',
126
+ mixedData: this.getMixedData({
127
+ mode: 'rebuild'
128
+ })
129
+ });
130
+ this.dispatch('clear');
131
+ }
132
+ getMixedData(buildOptions) {
133
+ this.buildMixedData({
134
+ ...buildOptions,
135
+ lazy: false
136
+ });
137
+ return this.mixedData.slice();
138
+ }
139
+ dispatch(name, data) {
140
+ const detail = {
141
+ name: this.options.name,
142
+ ...data
143
+ };
144
+ this.dispatchEvent(new CustomEvent(name, {
145
+ detail
146
+ }));
147
+ if ("u" > typeof window) window.dispatchEvent(new CustomEvent(`[DMM]:${name}`, {
148
+ detail
149
+ }));
150
+ }
151
+ buildMixedData(buildOptions) {
152
+ if (this.isBatching) return;
153
+ const { lazy, mode } = buildOptions || {};
154
+ if ('rebuild' === mode) {
155
+ this.prevDataLength = 0;
156
+ this.lastMixedSlotIdx = -1;
157
+ }
158
+ if (false !== lazy || this.dataList.length <= this.prevDataLength) return;
159
+ let dataStartIdx = this.prevDataLength;
160
+ const dataEndIdx = this.dataList.length;
161
+ const newItemCount = dataEndIdx - dataStartIdx;
162
+ this.prevDataLength = dataEndIdx;
163
+ const isPatchMode = dataStartIdx > 0;
164
+ const filteredSlots = this.sliceSlots(isPatchMode ? this.mixedData.length : this.lastMixedSlotIdx, this.mixedData.length + newItemCount);
165
+ this.lastMixedSlotIdx = filteredSlots.at(-1) ?? this.lastMixedSlotIdx;
166
+ let mixedStartIdx = isPatchMode ? this.mixedData.length : 0;
167
+ this.mixedData.length = (isPatchMode ? newItemCount + mixedStartIdx : dataEndIdx) + filteredSlots.length;
168
+ for(let fpIdx = 0, fpItem = filteredSlots[fpIdx]; dataStartIdx < dataEndIdx; ++mixedStartIdx)if (mixedStartIdx === fpItem) {
169
+ const fixedSlot = this.fixedSlots.get(fpItem);
170
+ this.mixedData[mixedStartIdx] = {
171
+ isFixed: true,
172
+ type: fixedSlot.type,
173
+ data: fixedSlot.data
174
+ };
175
+ fpItem = filteredSlots[++fpIdx];
176
+ } else {
177
+ this.mixedData[mixedStartIdx] = {
178
+ isFixed: false,
179
+ type: 'plain',
180
+ data: this.dataList[dataStartIdx]
181
+ };
182
+ ++dataStartIdx;
183
+ }
184
+ this.dispatch('change', {
185
+ mode: isPatchMode ? 'patch' : 'rebuild',
186
+ mixedData: this.mixedData.slice()
187
+ });
188
+ }
189
+ sliceSlots(startIdx, endIdx = 1 / 0) {
190
+ let prevItem = -2;
191
+ let count = 0;
192
+ return Array.from(this.fixedSlots.keys()).sort((ai, bi)=>ai - bi).filter((item)=>{
193
+ if (item >= startIdx && item < endIdx + count || item - 1 === prevItem) {
194
+ ++count;
195
+ prevItem = item;
196
+ return true;
197
+ }
198
+ return false;
199
+ });
200
+ }
201
+ insertSlot(config) {
202
+ const realPosition = this.addFixedSlot({
203
+ ...config,
204
+ type: SLOT_TYPE.insert
205
+ });
206
+ if (realPosition > this.mixedData.length) return realPosition;
207
+ this.buildMixedData({
208
+ lazy: false,
209
+ mode: 'rebuild'
210
+ });
211
+ return realPosition;
212
+ }
213
+ insertSlots(configs) {
214
+ if (!configs.length) return [];
215
+ const positions = this.batchUpdate(()=>configs.map((config)=>this.insertSlot(config)));
216
+ this.buildMixedData({
217
+ lazy: false,
218
+ mode: 'rebuild'
219
+ });
220
+ return positions;
221
+ }
222
+ }
223
+ function dataMixedManager(options) {
224
+ return new DataMixedManager(options);
225
+ }
226
+ export { dataMixedManager };
@@ -0,0 +1,90 @@
1
+ import type { SLOT_TYPE } from './constants';
2
+ export type SlotType = (typeof SLOT_TYPE)[keyof typeof SLOT_TYPE];
3
+ export interface InputSlotConfig<T> {
4
+ /** 坑位位置(从1开始) */
5
+ position: number;
6
+ /** 定坑数据 */
7
+ data: T;
8
+ /** 插入模式:cover-覆盖,before-在指定位置前插入,after-在指定位置后插入 */
9
+ insertMode?: 'cover' | 'before' | 'after';
10
+ }
11
+ /**
12
+ * 定坑配置接口
13
+ */
14
+ export interface SlotConfig<T> {
15
+ /** 坑位位置(从1开始) */
16
+ position: number;
17
+ /** 定坑数据 */
18
+ data: T;
19
+ /** 定坑类型 */
20
+ type: 'fixed' | 'insert';
21
+ /** 插入模式:cover-覆盖,before-在指定位置前插入,after-在指定位置后插入 */
22
+ insertMode: 'cover' | 'before' | 'after';
23
+ /** 输入位置(用于记录原始输入的位置) */
24
+ inputPosition: number;
25
+ }
26
+ export interface BaseDataItem<T> {
27
+ /** 数据内容 */
28
+ data: T;
29
+ }
30
+ /**
31
+ * 普通数据项接口
32
+ */
33
+ export interface PlainDataItem<T> extends BaseDataItem<T> {
34
+ /** 是否为定坑数据 */
35
+ isFixed: false;
36
+ /** 数据类型 */
37
+ type: 'plain';
38
+ }
39
+ /**
40
+ * 定坑数据项接口
41
+ */
42
+ export interface FixedDataItem<T> extends BaseDataItem<T> {
43
+ /** 是否为定坑数据 */
44
+ isFixed: true;
45
+ /** 定坑类型 */
46
+ type: SlotConfig<T>['type'];
47
+ }
48
+ /**
49
+ * 混合数据项类型
50
+ * 可以是定坑数据项或普通数据项
51
+ */
52
+ export type MixedDataItem<T> = FixedDataItem<T> | PlainDataItem<T>;
53
+ /**
54
+ * 构建选项接口
55
+ */
56
+ export interface BuildOptions {
57
+ /** 是否延迟构建,为 true 时不立即构建混合数据 */
58
+ lazy?: boolean;
59
+ /** 构建模式:rebuild-全量重建,patch-增量更新 */
60
+ mode?: 'rebuild' | 'patch';
61
+ }
62
+ interface DiffEventDetailMap<T> {
63
+ change: {
64
+ mode: NonNullable<BuildOptions['mode']> | 'clear';
65
+ mixedData: MixedDataItem<T>[];
66
+ };
67
+ clear: Record<PropertyKey, never>;
68
+ }
69
+ export interface BaseEventDetail {
70
+ name: string;
71
+ }
72
+ export type EventDetailMap<T> = {
73
+ [K in keyof DiffEventDetailMap<T>]: BaseEventDetail & DiffEventDetailMap<T>[K];
74
+ };
75
+ export type DMMEventHandler<T, K extends keyof EventDetailMap<T>> = ((event: CustomEvent<EventDetailMap<T>[K]>) => void) | {
76
+ handleEvent: (event: CustomEvent<EventDetailMap<T>[K]>) => void;
77
+ };
78
+ export interface DataMixedManagerOptions<T> {
79
+ /** 实例名称 */
80
+ name?: string;
81
+ /** 定坑配置数组 */
82
+ fixedSlots?: InputSlotConfig<T>[];
83
+ /** 普通数据列表 */
84
+ dataList?: T[];
85
+ /** 事件监听 */
86
+ listener?: {
87
+ [K in keyof EventDetailMap<T>]?: DMMEventHandler<T, K>;
88
+ };
89
+ }
90
+ export {};
File without changes
@@ -1,2 +1,10 @@
1
+ export * from './allx';
2
+ export * from './animation';
3
+ export * from './condition-merge';
4
+ export * from './create-storage-handler';
1
5
  export * from './data-handler';
6
+ export * from './data-mixed-manager';
2
7
  export * from './throw-error';
8
+ export * from './types';
9
+ export * from './utils';
10
+ export * from './with-resolvers';
@@ -1 +1,2 @@
1
- export { $dt, $t, dataHandler, defineTransform, throwError, throwType } from "../707.js";
1
+ export { $dt, $t, createError, dataHandler, defineTransform, getType, identity, noop, throwError, throwType } from "../707.js";
2
+ export { allx, animation, conditionMerge, createStorageHandler, dataMixedManager, isArray, isBoolean, isEmptyArray, isEmptyString, isFalse, isFalsy, isFunction, isNaN, isNull, isNullOrUndef, isNumber, isObject, isPlainNumber, isPlainObject, isPlainSymbol, isPromiseLike, isPropertyKey, isString, isSymbol, isTrue, isTruthy, isUndef, stepAnimation, withResolvers } from "../607.js";
@@ -1,2 +1,3 @@
1
+ export declare function createError(fnName: string, message: string, ErrorClass?: ErrorConstructor): Error;
1
2
  export declare function throwError(fnName: string, message: string, ErrorClass?: ErrorConstructor): never;
2
3
  export declare function throwType(fnName: string, message: string): never;
@@ -1,7 +1,10 @@
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);
6
9
  }
7
- export { throwError, throwType };
10
+ export { createError, throwError, throwType };
@@ -3,3 +3,9 @@ export type NonUnion<T> = Equal<[T] extends [never] ? never : T[], T extends any
3
3
  export type UnionToIntersection<U> = [U] extends [never] ? never : (U extends any ? (_v: U) => void : never) extends (_v: infer I) => void ? I : never;
4
4
  export type IsPrimitive<T> = T extends number | string | boolean | symbol | bigint | null | undefined ? true : false;
5
5
  export type IsBasicType<T> = T extends number | string | boolean | symbol | bigint ? true : false;
6
+ export type Printify<T> = T extends any[] ? T : [T] extends [never] ? T : {
7
+ [K in keyof T]: T[K];
8
+ };
9
+ export type PickRequired<T, K extends keyof T> = Printify<Omit<T, K> & Required<Pick<T, K>>>;
10
+ export type AnyFunc = (...args: any[]) => any;
11
+ export type UnULCase<T extends string> = T extends `${infer F}${infer R}` ? `${Uppercase<F> | Lowercase<F>}${UnULCase<R>}` : Uppercase<T> | Lowercase<T>;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare const noop: () => undefined;
2
+ export declare const identity: <T>(_v: T) => T;
3
+ export declare function getType(_v: any): string;
@@ -0,0 +1,6 @@
1
+ const noop = ()=>void 0;
2
+ const identity = (_v)=>_v;
3
+ function getType(_v) {
4
+ return Object.prototype.toString.call(_v).slice(8, -1).toLowerCase();
5
+ }
6
+ export { getType, identity, noop };
@@ -0,0 +1,2 @@
1
+ export * from './base';
2
+ export * from './verify';
@@ -0,0 +1,2 @@
1
+ export * from "./base.js";
2
+ export * from "./verify.js";
@@ -0,0 +1,53 @@
1
+ import type { AnyFunc, UnULCase } from '../types/base';
2
+ /** 判断是一个 symbol */
3
+ export declare function isSymbol(_v: unknown): _v is symbol;
4
+ /** 判断是一个 undefined */
5
+ export declare function isUndef(_v: unknown): _v is undefined;
6
+ /** 判断是一个 null */
7
+ export declare function isNull(_v: unknown): _v is null;
8
+ /** 判断是一个 null 或者 undefined */
9
+ export declare function isNullOrUndef(_v: unknown): _v is null | undefined;
10
+ /** 判断是一个 NaN */
11
+ export declare function isNaN(_v: unknown): _v is number;
12
+ /** 判断是一个 plain symbol */
13
+ export declare function isPlainSymbol(_v: unknown): _v is symbol;
14
+ /** 判断是一个对象 (数组也返回 true) */
15
+ export declare function isObject(_v: unknown): _v is object;
16
+ /** 判断是一个非数组对象 */
17
+ export declare function isPlainObject(_v: unknown): _v is object;
18
+ /** 判断是一个数组 */
19
+ export declare function isArray(_v: unknown): _v is any[];
20
+ /** 判断是否为空数组 */
21
+ export declare function isEmptyArray(_v: unknown): _v is [];
22
+ /** 判断是一个字符串 */
23
+ export declare function isString(_v: unknown): _v is string;
24
+ /** 判断是一个空字符串 */
25
+ export declare function isEmptyString(_v: unknown): _v is '';
26
+ /** 判断是一个数字 */
27
+ export declare function isNumber(_v: unknown): _v is number;
28
+ /** 判断是一个纯数字 (排除 NaN) */
29
+ export declare function isPlainNumber(_v: unknown): _v is number;
30
+ /** 判断是一个合法的对象 key */
31
+ export declare function isPropertyKey(_v: unknown): _v is PropertyKey;
32
+ /** 判断是一个布尔值 */
33
+ export declare function isBoolean(_v: unknown): _v is boolean;
34
+ /** 判断是一个 true 值 */
35
+ export declare function isTrue(_v: unknown): _v is true | UnULCase<'true'>;
36
+ /** 判断是一个 false 值 */
37
+ export declare function isFalse(_v: unknown): _v is false | UnULCase<'false'>;
38
+ /**
39
+ * 判断是一个真值
40
+ *
41
+ * @warn 字符串 'false' 等满足 isFalse 判断的字符串也会被视为真值
42
+ */
43
+ export declare function isTruthy<T>(_v: T): _v is Exclude<T, false | 0 | '' | null | undefined>;
44
+ /**
45
+ * 判断是一个非值
46
+ *
47
+ * @warn 字符串 'false' 等满足 isFalse 判断的字符串不会被视为非值
48
+ */
49
+ export declare function isFalsy(_v: unknown): _v is false | 0 | '' | null | undefined;
50
+ /** 判断是一个函数 */
51
+ export declare function isFunction(_v: unknown): _v is AnyFunc;
52
+ /** 判断是一个 Promise */
53
+ export declare function isPromiseLike(_v: unknown): _v is PromiseLike<any>;
@@ -0,0 +1,67 @@
1
+ function isSymbol(_v) {
2
+ return 'symbol' == typeof _v;
3
+ }
4
+ function isUndef(_v) {
5
+ return void 0 === _v;
6
+ }
7
+ function isNull(_v) {
8
+ return null === _v;
9
+ }
10
+ function isNullOrUndef(_v) {
11
+ return isNull(_v) || isUndef(_v);
12
+ }
13
+ function verify_isNaN(_v) {
14
+ return Number.isNaN(_v);
15
+ }
16
+ function isPlainSymbol(_v) {
17
+ return isSymbol(_v) && isUndef(Symbol.keyFor(_v));
18
+ }
19
+ function isObject(_v) {
20
+ return 'object' == typeof _v && !isNull(_v);
21
+ }
22
+ function isPlainObject(_v) {
23
+ return isObject(_v) && !isArray(_v);
24
+ }
25
+ function isArray(_v) {
26
+ return Array.isArray(_v);
27
+ }
28
+ function isEmptyArray(_v) {
29
+ return isArray(_v) && 0 === _v.length;
30
+ }
31
+ function isString(_v) {
32
+ return 'string' == typeof _v;
33
+ }
34
+ function isEmptyString(_v) {
35
+ return isString(_v) && 0 === _v.length;
36
+ }
37
+ function isNumber(_v) {
38
+ return 'number' == typeof _v;
39
+ }
40
+ function isPlainNumber(_v) {
41
+ return isNumber(_v) && !verify_isNaN(_v);
42
+ }
43
+ function isPropertyKey(_v) {
44
+ return isString(_v) || isNumber(_v) || isSymbol(_v);
45
+ }
46
+ function isBoolean(_v) {
47
+ return 'boolean' == typeof _v;
48
+ }
49
+ function isTrue(_v) {
50
+ return true === _v || isString(_v) && 'true' === _v.toLowerCase();
51
+ }
52
+ function isFalse(_v) {
53
+ return false === _v || isString(_v) && 'false' === _v.toLowerCase();
54
+ }
55
+ function isTruthy(_v) {
56
+ return !!_v;
57
+ }
58
+ function isFalsy(_v) {
59
+ return !(verify_isNaN(_v) || _v);
60
+ }
61
+ function isFunction(_v) {
62
+ return 'function' == typeof _v;
63
+ }
64
+ function isPromiseLike(_v) {
65
+ return isObject(_v) && isFunction(_v.then);
66
+ }
67
+ export { isArray, isBoolean, isEmptyArray, isEmptyString, isFalse, isFalsy, isFunction, verify_isNaN as isNaN, isNull, isNullOrUndef, isNumber, isObject, isPlainNumber, isPlainObject, isPlainSymbol, isPromiseLike, isPropertyKey, isString, isSymbol, isTrue, isTruthy, isUndef };
@@ -0,0 +1,6 @@
1
+ export type Resolver<T> = {
2
+ promise: Promise<T>;
3
+ resolve: (value: T | PromiseLike<T>) => void;
4
+ reject: (reason?: any) => void;
5
+ };
6
+ export declare function withResolvers<T>(): Resolver<T>;
@@ -0,0 +1,15 @@
1
+ function withResolvers() {
2
+ return 'function' == typeof Promise.withResolvers ? Promise.withResolvers() : (()=>{
3
+ const resolver = {
4
+ promise: null,
5
+ resolve: null,
6
+ reject: null
7
+ };
8
+ resolver.promise = new Promise((resolve, reject)=>{
9
+ resolver.resolve = resolve;
10
+ resolver.reject = reject;
11
+ });
12
+ return resolver;
13
+ })();
14
+ }
15
+ export { withResolvers };
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,13 @@
1
+ import { Component, type PropsWithChildren } from 'react';
2
+ export declare class ErrorBoundary extends Component<PropsWithChildren<{
3
+ onError: () => void;
4
+ }>> {
5
+ state: {
6
+ hasError: boolean;
7
+ };
8
+ static getDerivedStateFromError(): {
9
+ hasError: boolean;
10
+ };
11
+ componentDidCatch(): void;
12
+ render(): import("react").ReactNode;
13
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cmtlyt/lingshu-toolkit",
3
- "version": "0.2.0",
3
+ "version": "0.4.0",
4
4
  "type": "module",
5
5
  "main": "./dist/shared.js",
6
6
  "module": "./dist/shared.js",
@@ -41,10 +41,11 @@
41
41
  },
42
42
  "devDependencies": {
43
43
  "@biomejs/biome": "2.3.8",
44
- "@cmtlyt/unplugin-shadcn-registry-generate": "^0.1.3",
44
+ "@cmtlyt/unplugin-shadcn-registry-generate": "^0.1.5",
45
45
  "@commitlint/cli": "^20.3.1",
46
46
  "@commitlint/config-conventional": "^20.3.1",
47
47
  "@rslib/core": "^0.19.3",
48
+ "@rspress/core": "^2.0.8",
48
49
  "@types/node": "^24.10.9",
49
50
  "@types/react": "^19.2.9",
50
51
  "@vitejs/plugin-react": "^5.1.2",
@@ -52,13 +53,14 @@
52
53
  "@vitest/browser-playwright": "4.0.18",
53
54
  "@vitest/coverage-v8": "4.0.18",
54
55
  "@vitest/ui": "4.0.18",
56
+ "cross-env": "^10.1.0",
55
57
  "esno": "^4.8.0",
56
58
  "husky": "^9.1.7",
57
59
  "jsdom": "^27.4.0",
58
60
  "lint-staged": "^16.2.7",
61
+ "playwright": "^1.58.1",
59
62
  "react": "^19.2.4",
60
63
  "react-dom": "^19.2.4",
61
- "rspress": "^1.47.1",
62
64
  "typescript": "^5.9.3",
63
65
  "vite-tsconfig-paths": "^6.0.4",
64
66
  "vitest": "4.0.18",
@@ -73,7 +75,7 @@
73
75
  "devEngines": {
74
76
  "runtime": {
75
77
  "name": "node",
76
- "version": ">=18.0.0"
78
+ "version": ">=22.12.0"
77
79
  },
78
80
  "packageManager": {
79
81
  "name": "pnpm"
@@ -115,9 +117,9 @@
115
117
  "dev:registry": "pnpm dlx serve src/public -p 3000",
116
118
  "preview:docs": "rspress preview",
117
119
  "format": "biome format --write",
118
- "test": "vitest --config=vitest.browser.config.ts --coverage.enabled --ui",
119
- "test:ci": "vitest run --config=vitest.browser.config.ts",
120
- "test:lib:ci": "vitest run",
120
+ "test": "vitest --config=vitest.project.config.ts --coverage.enabled --ui",
121
+ "test:ci": "cross-env skip_type_check=true gen_file_disabled=true vitest run --config=vitest.project.config.ts",
122
+ "test:lib:ci": "cross-env skip_type_check=true gen_file_disabled=true vitest run",
121
123
  "test:lib": "vitest --coverage.enabled --ui",
122
124
  "script:gen-file": "esno scripts/gen-file.ts"
123
125
  }