@codady/utils 0.0.8 → 0.0.10
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/CHANGELOG.md +21 -0
- package/dist/utils.cjs.js +247 -23
- package/dist/utils.cjs.min.js +3 -3
- package/dist/utils.esm.js +247 -23
- package/dist/utils.esm.min.js +3 -3
- package/dist/utils.umd.js +247 -23
- package/dist/utils.umd.min.js +3 -3
- package/dist.zip +0 -0
- package/modules.js +13 -3
- package/modules.ts +13 -3
- package/package.json +1 -1
- package/src/arrayMutableMethods - /345/211/257/346/234/254.js" +5 -0
- package/src/arrayMutableMethods.js +5 -0
- package/src/{mutableMethods.ts → arrayMutableMethods.ts} +3 -3
- package/src/deepClone.js +151 -26
- package/src/deepClone.ts +194 -35
- package/src/deepCloneToJSON - /345/211/257/346/234/254.js" +47 -0
- package/src/getUniqueId.js +39 -0
- package/src/getUniqueId.ts +47 -0
- package/src/mapMutableMethods.js +5 -0
- package/src/mapMutableMethods.ts +15 -0
- package/src/mutableMethods.js +2 -2
- package/src/setMutableMethods - /345/211/257/346/234/254.js" +5 -0
- package/src/setMutableMethods.js +5 -0
- package/src/setMutableMethods.ts +14 -0
- package/src/wrapArrayMethods.js +5 -5
- package/src/wrapArrayMethods.ts +7 -7
- package/src/wrapMap - /345/211/257/346/234/254.js" +119 -0
- package/src/wrapMapMethods.js +118 -0
- package/src/wrapMapMethods.ts +226 -0
- package/src/wrapSetMethods.js +112 -0
- package/src/wrapSetMethods.ts +215 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @since Last modified: 2025/12/22 17:19:21
|
|
3
|
+
* Wraps Set objects with mutation tracking capabilities.
|
|
4
|
+
* Provides hooks for before/after mutation events and captures detailed context
|
|
5
|
+
* for undo/redo or change tracking purposes.
|
|
6
|
+
*
|
|
7
|
+
* @template T - Set element type
|
|
8
|
+
* @param {SetMutationOptions<T>} options - Configuration object containing target Set and callbacks
|
|
9
|
+
* @returns {SetMutationMethods<T>} - Object containing wrapped Set mutation methods
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* // Basic usage with tracking
|
|
13
|
+
* const set = new Set([1, 2, 3]);
|
|
14
|
+
* const methods = wrapSet({
|
|
15
|
+
* target: set,
|
|
16
|
+
* onAfterMutate: (patch) => {
|
|
17
|
+
* console.log(`Set ${patch.method} called`, patch.context);
|
|
18
|
+
* }
|
|
19
|
+
* });
|
|
20
|
+
*
|
|
21
|
+
* methods.add(4); // Tracked
|
|
22
|
+
* methods.delete(2); // Tracked
|
|
23
|
+
* methods.clear(); // Tracked
|
|
24
|
+
*
|
|
25
|
+
* @example
|
|
26
|
+
* // With change detection for UI updates
|
|
27
|
+
* const set = new Set<string>();
|
|
28
|
+
* const methods = wrapSet({
|
|
29
|
+
* target: set,
|
|
30
|
+
* onAfterMutate: (patch) => {
|
|
31
|
+
* // Trigger UI update when Set changes
|
|
32
|
+
* if (patch.method === 'add' || patch.method === 'delete') {
|
|
33
|
+
* updateUI(Array.from(patch.target));
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
* });
|
|
37
|
+
*/
|
|
38
|
+
'use strict';
|
|
39
|
+
|
|
40
|
+
import setMutableMethods, { SetMutationNames } from "./setMutableMethods";
|
|
41
|
+
|
|
42
|
+
/**
|
|
43
|
+
* Context captured before Set mutation for tracking purposes
|
|
44
|
+
*/
|
|
45
|
+
export interface SetMutationContext<T = any> {
|
|
46
|
+
/** For add method: the value being added */
|
|
47
|
+
addedItem?: T;
|
|
48
|
+
/** For add / delete method: whether the value already existed */
|
|
49
|
+
existed?: boolean;
|
|
50
|
+
/** For delete method: the value being deleted */
|
|
51
|
+
deletedItem?: T;
|
|
52
|
+
/** For clear method: snapshot of all values before clearing */
|
|
53
|
+
clearedItems?: T[];
|
|
54
|
+
/** For clear method: size of the Set before clearing */
|
|
55
|
+
previousSize?: number;
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/**
|
|
59
|
+
* Data object passed to callback after Set mutation
|
|
60
|
+
*/
|
|
61
|
+
export interface SetMutationPatch<T = any> {
|
|
62
|
+
/** The mutation method called */
|
|
63
|
+
method: SetMutationNames;
|
|
64
|
+
/** The result returned by the mutation method */
|
|
65
|
+
result: any;
|
|
66
|
+
/** Arguments passed to the mutation method */
|
|
67
|
+
args: any[];
|
|
68
|
+
/** Context captured before mutation */
|
|
69
|
+
context: SetMutationContext<T>;
|
|
70
|
+
/** Reference to the mutated Set */
|
|
71
|
+
target: Set<T>;
|
|
72
|
+
/** Additional custom properties */
|
|
73
|
+
[key: string]: any;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Configuration options for wrapSet function
|
|
78
|
+
*/
|
|
79
|
+
export interface SetMutationOptions<T = any> {
|
|
80
|
+
/** The Set to wrap with mutation tracking */
|
|
81
|
+
target: Set<T>;
|
|
82
|
+
/** Callback triggered before mutation */
|
|
83
|
+
onBeforeMutate?: (context: SetMutationContext<T>) => void;
|
|
84
|
+
/** Callback triggered after mutation */
|
|
85
|
+
onAfterMutate?: (patch: SetMutationPatch<T>) => void;
|
|
86
|
+
/** Optional list of allowed mutation methods (default: all Set methods) */
|
|
87
|
+
allowList?: SetMutationNames[];
|
|
88
|
+
/** Additional properties to attach to the patch */
|
|
89
|
+
props?: Record<string, any>;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
/**
|
|
93
|
+
* Wrapped mutation methods for Set
|
|
94
|
+
*/
|
|
95
|
+
export interface SetMutationMethods<T = any> {
|
|
96
|
+
/**
|
|
97
|
+
* Adds a value to the Set.
|
|
98
|
+
* @param value The value to add
|
|
99
|
+
* @returns The Set object
|
|
100
|
+
*/
|
|
101
|
+
add: (value: T) => Set<T>;
|
|
102
|
+
|
|
103
|
+
/**
|
|
104
|
+
* Deletes a value from the Set.
|
|
105
|
+
* @param value The value to delete
|
|
106
|
+
* @returns true if the value existed and has been removed, false otherwise
|
|
107
|
+
*/
|
|
108
|
+
delete: (value: T) => boolean;
|
|
109
|
+
|
|
110
|
+
/**
|
|
111
|
+
* Clears all values from the Set.
|
|
112
|
+
* @returns void
|
|
113
|
+
*/
|
|
114
|
+
clear: () => void;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Gets the original Set instance for direct access
|
|
118
|
+
*/
|
|
119
|
+
readonly target: Set<T>;
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
/**
|
|
123
|
+
* Creates wrapped mutation methods for Set with tracking capabilities
|
|
124
|
+
*
|
|
125
|
+
* @param options Configuration options
|
|
126
|
+
* @returns Object containing wrapped Set mutation methods
|
|
127
|
+
* @throws TypeError if target is not a Set
|
|
128
|
+
*/
|
|
129
|
+
const wrapSetMethods = <T = any>({
|
|
130
|
+
target,
|
|
131
|
+
onBeforeMutate = () => { },
|
|
132
|
+
onAfterMutate = () => { },
|
|
133
|
+
allowList = setMutableMethods,
|
|
134
|
+
props = {},
|
|
135
|
+
}: SetMutationOptions<T>): SetMutationMethods<T> => {
|
|
136
|
+
|
|
137
|
+
// Validation: Ensure target is a Set
|
|
138
|
+
if (!(target instanceof Set)) {
|
|
139
|
+
throw new TypeError("The 'target' parameter must be a Set.");
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
// Create method wrappers
|
|
143
|
+
const methods: Partial<SetMutationMethods<T>> = {};
|
|
144
|
+
|
|
145
|
+
// Helper to create wrapped method
|
|
146
|
+
const createWrappedMethod = (method: SetMutationNames) => {
|
|
147
|
+
return function (...args: any[]) {
|
|
148
|
+
const context: SetMutationContext<T> = {};
|
|
149
|
+
|
|
150
|
+
// Capture pre-mutation context based on method
|
|
151
|
+
switch (method) {
|
|
152
|
+
case 'add': {
|
|
153
|
+
const [value] = args as [T];
|
|
154
|
+
context.addedItem = value;
|
|
155
|
+
//context.existed=true,说明值重复
|
|
156
|
+
context.existed = target.has(value);
|
|
157
|
+
break;
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
case 'delete': {
|
|
161
|
+
const [value] = args as [T];
|
|
162
|
+
context.existed = target.has(value);
|
|
163
|
+
context.deletedItem = context.existed ? value : undefined;
|
|
164
|
+
break;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
case 'clear': {
|
|
168
|
+
context.clearedItems = Array.from(target);
|
|
169
|
+
//用来做验证
|
|
170
|
+
context.previousSize = target.size;
|
|
171
|
+
break;
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
// Execute before mutation callback
|
|
176
|
+
onBeforeMutate(context);
|
|
177
|
+
|
|
178
|
+
// Execute the native Set method
|
|
179
|
+
const result = (target as any)[method].apply(target, args);
|
|
180
|
+
|
|
181
|
+
// Construct patch object
|
|
182
|
+
const patch: SetMutationPatch<T> = {
|
|
183
|
+
method,
|
|
184
|
+
result,
|
|
185
|
+
args,
|
|
186
|
+
context,
|
|
187
|
+
target,
|
|
188
|
+
...props
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
// Execute after mutation callback
|
|
192
|
+
onAfterMutate(patch);
|
|
193
|
+
|
|
194
|
+
return result;
|
|
195
|
+
};
|
|
196
|
+
};
|
|
197
|
+
|
|
198
|
+
// Wrap allowed methods
|
|
199
|
+
for (const method of allowList) {
|
|
200
|
+
if (setMutableMethods.includes(method)) {
|
|
201
|
+
(methods as any)[method] = createWrappedMethod(method);
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
// Add target reference
|
|
206
|
+
Object.defineProperty(methods, 'target', {
|
|
207
|
+
get: () => target,
|
|
208
|
+
enumerable: false,
|
|
209
|
+
configurable: false
|
|
210
|
+
});
|
|
211
|
+
|
|
212
|
+
return methods as SetMutationMethods<T>;
|
|
213
|
+
};
|
|
214
|
+
|
|
215
|
+
export default wrapSetMethods;
|