@avstantso/core 1.2.2 → 1.3.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.
- package/CHANGELOG.md +24 -0
- package/README.md +124 -1
- package/dist/_global/_register.d.ts +2 -1
- package/dist/_global/deep-ops.d.ts +505 -0
- package/dist/_global/func.d.ts +15 -2
- package/dist/_global/index.d.ts +2 -0
- package/dist/_global/low-level.d.ts +116 -0
- package/dist/export.d.ts +2 -1
- package/dist/index.js +575 -53
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -12,11 +12,9 @@ require('@avstantso/std-ext');
|
|
|
12
12
|
* ⚠ All exported namespace `AVStantso` constants and functions\
|
|
13
13
|
* must be expressed through `avstantso` global variable
|
|
14
14
|
*/
|
|
15
|
-
|
|
16
|
-
(
|
|
15
|
+
const avstantso$1 = (() => {
|
|
16
|
+
const symbolFreeze = Symbol('freeze');
|
|
17
17
|
const RegisterGlobalNamespace = ((namespaceName, statics) => {
|
|
18
|
-
const structs = ['object', 'function'];
|
|
19
|
-
const symbolFreeze = Symbol('freeze');
|
|
20
18
|
const singleton = { ...statics };
|
|
21
19
|
/**
|
|
22
20
|
* @summary Register `field`. ⚠ Override not supported now
|
|
@@ -44,7 +42,7 @@ require('@avstantso/std-ext');
|
|
|
44
42
|
get(target, p) {
|
|
45
43
|
return p in target
|
|
46
44
|
? Reflect.get(target, p)
|
|
47
|
-
: p in level
|
|
45
|
+
: p in level && Object.isExtensible(level[p])
|
|
48
46
|
? RegLevel(level[p])
|
|
49
47
|
: regField.bind(level, p);
|
|
50
48
|
}
|
|
@@ -54,29 +52,7 @@ require('@avstantso/std-ext');
|
|
|
54
52
|
delete this._reg;
|
|
55
53
|
delete this.debugState;
|
|
56
54
|
delete this.freeze;
|
|
57
|
-
|
|
58
|
-
const hasCustomFreeze = Symbol.Has(symbolFreeze, () => { });
|
|
59
|
-
function deepFreeze(obj, path = []) {
|
|
60
|
-
try {
|
|
61
|
-
const ti = structs.indexOf(typeof obj);
|
|
62
|
-
if (!obj || ti < 0 || walked.has(obj))
|
|
63
|
-
return obj;
|
|
64
|
-
walked.add(obj);
|
|
65
|
-
if (hasCustomFreeze(obj))
|
|
66
|
-
return obj[symbolFreeze].call(obj);
|
|
67
|
-
const entries = Object.entries(Object.getOwnPropertyDescriptors(obj));
|
|
68
|
-
for (const [key, dsc] of entries)
|
|
69
|
-
if (ti
|
|
70
|
-
? !(key in deepFreeze) // Except standard function properties
|
|
71
|
-
: !Array.isArray(dsc.value))
|
|
72
|
-
deepFreeze(dsc.value, [...path, key]);
|
|
73
|
-
return Object.freeze(obj);
|
|
74
|
-
}
|
|
75
|
-
catch (e) {
|
|
76
|
-
throw ('path' in e) ? e : Object.assign(e, { path });
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
deepFreeze(this);
|
|
55
|
+
avstantso$1.DeepOps.freeze(this, { ownProps: true });
|
|
80
56
|
}
|
|
81
57
|
Object.definePropertiesOnce(singleton, {
|
|
82
58
|
_reg: {
|
|
@@ -118,10 +94,10 @@ require('@avstantso/std-ext');
|
|
|
118
94
|
return avs_singleton;
|
|
119
95
|
})();
|
|
120
96
|
|
|
121
|
-
var AVStantso$
|
|
97
|
+
var AVStantso$7;
|
|
122
98
|
(function (AVStantso) {
|
|
123
99
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
124
|
-
AVStantso.Generic = avstantso._reg.Generic(() => {
|
|
100
|
+
AVStantso.Generic = avstantso._reg.Generic(({ symbolFreeze }) => {
|
|
125
101
|
function Validator() {
|
|
126
102
|
function validate(value) {
|
|
127
103
|
return value;
|
|
@@ -134,18 +110,51 @@ var AVStantso$5;
|
|
|
134
110
|
function Cast(from) {
|
|
135
111
|
return from;
|
|
136
112
|
}
|
|
137
|
-
|
|
113
|
+
const Generic = {
|
|
138
114
|
Validator,
|
|
139
115
|
validate: Validator(),
|
|
140
|
-
Cast: Object.assign(Cast, { To: Cast })
|
|
116
|
+
Cast: Object.assign(Cast, { To: Cast }),
|
|
117
|
+
[symbolFreeze]() {
|
|
118
|
+
Object.freeze(Generic);
|
|
119
|
+
}
|
|
141
120
|
};
|
|
121
|
+
return Generic;
|
|
142
122
|
});
|
|
143
|
-
})(AVStantso$
|
|
123
|
+
})(AVStantso$7 || (AVStantso$7 = {}));
|
|
144
124
|
|
|
145
|
-
var AVStantso$
|
|
125
|
+
var AVStantso$6;
|
|
146
126
|
(function (AVStantso) {
|
|
127
|
+
/* eslint-disable @typescript-eslint/no-unsafe-function-type */
|
|
147
128
|
const fpd = Object.assign({}, Object.getOwnPropertyDescriptors(Function.prototype), Object.getOwnPropertyDescriptors(function () { }));
|
|
148
|
-
|
|
129
|
+
const runtimeFuncTypes = [
|
|
130
|
+
'plain',
|
|
131
|
+
'async', // adds if generators/async needed
|
|
132
|
+
'generator', // can't be `new`-called — distinct from plain
|
|
133
|
+
'class',
|
|
134
|
+
'arrow',
|
|
135
|
+
'bound'
|
|
136
|
+
];
|
|
137
|
+
const generatorClasses = [
|
|
138
|
+
'GeneratorFunction',
|
|
139
|
+
'AsyncGeneratorFunction'
|
|
140
|
+
];
|
|
141
|
+
AVStantso.Func = avstantso._reg.Func(({ symbolFreeze }) => Object.assign({
|
|
142
|
+
Types: Object.freeze(Object.fromEntries(runtimeFuncTypes.map((k) => [k, k]))),
|
|
143
|
+
determineType(func) {
|
|
144
|
+
const protoDsc = Object.getOwnPropertyDescriptor(func, 'prototype');
|
|
145
|
+
const ctorName = func.constructor.name;
|
|
146
|
+
if (!protoDsc)
|
|
147
|
+
return func.name?.startsWith('bound ')
|
|
148
|
+
? 'bound'
|
|
149
|
+
: 'AsyncFunction' === ctorName
|
|
150
|
+
? 'async'
|
|
151
|
+
: 'arrow';
|
|
152
|
+
if (!protoDsc.writable)
|
|
153
|
+
return 'class';
|
|
154
|
+
if (generatorClasses.includes(ctorName))
|
|
155
|
+
return 'generator';
|
|
156
|
+
return 'plain';
|
|
157
|
+
},
|
|
149
158
|
OwnPropertyDescriptors: fpd,
|
|
150
159
|
isPropAllowed: Object.assign(function isPropAllowed(propName) {
|
|
151
160
|
return !(propName in fpd);
|
|
@@ -163,16 +172,20 @@ var AVStantso$4;
|
|
|
163
172
|
return true;
|
|
164
173
|
return false;
|
|
165
174
|
},
|
|
166
|
-
// eslint-disable-next-line @typescript-eslint/no-unsafe-function-type
|
|
167
175
|
Dynamic(name, func) {
|
|
168
176
|
return !process.env.IS_DEV
|
|
169
177
|
? func
|
|
170
178
|
: new Function('func', `return function ${name}(...params){ return func(...params); };`)(func);
|
|
171
179
|
}
|
|
172
|
-
}
|
|
173
|
-
|
|
180
|
+
}, {
|
|
181
|
+
[symbolFreeze]() {
|
|
182
|
+
for (const field of Object.values(this))
|
|
183
|
+
Object.freeze(field);
|
|
184
|
+
}
|
|
185
|
+
}));
|
|
186
|
+
})(AVStantso$6 || (AVStantso$6 = {}));
|
|
174
187
|
|
|
175
|
-
var AVStantso$
|
|
188
|
+
var AVStantso$5;
|
|
176
189
|
(function (AVStantso) {
|
|
177
190
|
AVStantso.Catch = avstantso._reg.Catch(() => {
|
|
178
191
|
const catchFilters = [];
|
|
@@ -192,28 +205,46 @@ var AVStantso$3;
|
|
|
192
205
|
};
|
|
193
206
|
return DoCatch;
|
|
194
207
|
});
|
|
195
|
-
})(AVStantso$
|
|
208
|
+
})(AVStantso$5 || (AVStantso$5 = {}));
|
|
196
209
|
|
|
197
|
-
var AVStantso$
|
|
210
|
+
var AVStantso$4;
|
|
198
211
|
(function (AVStantso) {
|
|
199
|
-
AVStantso.AtomicObjects = avstantso._reg.AtomicObjects(() => {
|
|
212
|
+
AVStantso.AtomicObjects = avstantso._reg.AtomicObjects(({ symbolFreeze }) => {
|
|
200
213
|
const classes = new Map();
|
|
214
|
+
const derivedCache = new Map();
|
|
201
215
|
function register(atomicObjectClass, options) {
|
|
202
216
|
classes.set(atomicObjectClass, options);
|
|
217
|
+
derivedCache.clear();
|
|
218
|
+
}
|
|
219
|
+
function resolve(obj) {
|
|
220
|
+
const ctor = Object.getPrototypeOf(obj)?.constructor;
|
|
221
|
+
if (!ctor)
|
|
222
|
+
return null;
|
|
223
|
+
if (derivedCache.has(ctor))
|
|
224
|
+
return derivedCache.get(ctor);
|
|
225
|
+
for (const [Class, options] of classes.entries())
|
|
226
|
+
if (obj instanceof Class) {
|
|
227
|
+
const d = { Class, ...options };
|
|
228
|
+
derivedCache.set(ctor, d);
|
|
229
|
+
return d;
|
|
230
|
+
}
|
|
231
|
+
derivedCache.set(ctor, null);
|
|
232
|
+
return null;
|
|
203
233
|
}
|
|
204
234
|
function is(testObject) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
return true;
|
|
209
|
-
return false;
|
|
235
|
+
return 'object' === typeof testObject
|
|
236
|
+
&& null !== testObject
|
|
237
|
+
&& null !== resolve(testObject);
|
|
210
238
|
}
|
|
211
239
|
function descriptor(param) {
|
|
212
|
-
|
|
213
|
-
if (i >= 0)
|
|
240
|
+
if ('string' === typeof param) {
|
|
214
241
|
for (const [Class, options] of classes.entries())
|
|
215
|
-
if (
|
|
242
|
+
if (param === Class.name)
|
|
216
243
|
return { Class, ...options };
|
|
244
|
+
return;
|
|
245
|
+
}
|
|
246
|
+
if ('object' === typeof param && null !== param)
|
|
247
|
+
return resolve(param) ?? undefined;
|
|
217
248
|
}
|
|
218
249
|
register(Date, {
|
|
219
250
|
empty: () => new Date(0),
|
|
@@ -225,11 +256,14 @@ var AVStantso$2;
|
|
|
225
256
|
empty: () => Buffer.from(''),
|
|
226
257
|
clone: (instance) => Buffer.from(instance)
|
|
227
258
|
});
|
|
228
|
-
return { classes, register, is, descriptor }
|
|
259
|
+
return Object.assign({ classes, register, is, descriptor }, { [symbolFreeze]() {
|
|
260
|
+
for (const field of Object.values(this))
|
|
261
|
+
Object.freeze(field);
|
|
262
|
+
} });
|
|
229
263
|
});
|
|
230
|
-
})(AVStantso$
|
|
264
|
+
})(AVStantso$4 || (AVStantso$4 = {}));
|
|
231
265
|
|
|
232
|
-
var AVStantso$
|
|
266
|
+
var AVStantso$3;
|
|
233
267
|
(function (AVStantso) {
|
|
234
268
|
/* eslint-disable @typescript-eslint/no-explicit-any */
|
|
235
269
|
/**
|
|
@@ -237,12 +271,500 @@ var AVStantso$1;
|
|
|
237
271
|
* @returns `undefined`
|
|
238
272
|
*/
|
|
239
273
|
AVStantso.X = avstantso._reg.X(() => function X() { });
|
|
274
|
+
})(AVStantso$3 || (AVStantso$3 = {}));
|
|
275
|
+
|
|
276
|
+
var AVStantso$2;
|
|
277
|
+
(function (AVStantso) {
|
|
278
|
+
const JSStucturalTypes = Object.freeze(['object', 'function']);
|
|
279
|
+
let TypeGroupEnum;
|
|
280
|
+
(function (TypeGroupEnum) {
|
|
281
|
+
/**
|
|
282
|
+
* `foo === null || !JSStucturalTypes.includes(typeof foo)`
|
|
283
|
+
*/
|
|
284
|
+
TypeGroupEnum[TypeGroupEnum["scalar"] = 0] = "scalar";
|
|
285
|
+
/**
|
|
286
|
+
* `AVStantso.AtomicObjects.is(foo)`
|
|
287
|
+
*/
|
|
288
|
+
TypeGroupEnum[TypeGroupEnum["atomic"] = 1] = "atomic";
|
|
289
|
+
/**
|
|
290
|
+
* `typeof foo === 'object' && Object.isPlainObject(foo)`
|
|
291
|
+
*/
|
|
292
|
+
TypeGroupEnum[TypeGroupEnum["plain"] = 2] = "plain";
|
|
293
|
+
/**
|
|
294
|
+
* `typeof foo === 'object' && !Object.isPlainObject(foo)`
|
|
295
|
+
*/
|
|
296
|
+
TypeGroupEnum[TypeGroupEnum["rich"] = 3] = "rich";
|
|
297
|
+
/**
|
|
298
|
+
* `typeof foo === 'function'`
|
|
299
|
+
*/
|
|
300
|
+
TypeGroupEnum[TypeGroupEnum["func"] = 4] = "func";
|
|
301
|
+
})(TypeGroupEnum || (TypeGroupEnum = {}));
|
|
302
|
+
Object.freeze(TypeGroupEnum);
|
|
303
|
+
const TypeGroups = Object.freeze([
|
|
304
|
+
'scalar',
|
|
305
|
+
'atomic',
|
|
306
|
+
'plain',
|
|
307
|
+
'rich',
|
|
308
|
+
'func'
|
|
309
|
+
]);
|
|
310
|
+
AVStantso.LowLevel = avstantso._reg.LowLevel(({ AtomicObjects }) => {
|
|
311
|
+
function typeGroupOf(a) {
|
|
312
|
+
if (null === a)
|
|
313
|
+
return TypeGroupEnum.scalar;
|
|
314
|
+
const t = typeof a;
|
|
315
|
+
const i = JSStucturalTypes.indexOf(t);
|
|
316
|
+
if (i < 0)
|
|
317
|
+
return TypeGroupEnum.scalar;
|
|
318
|
+
if (i)
|
|
319
|
+
return TypeGroupEnum.func;
|
|
320
|
+
if (AtomicObjects.is(a))
|
|
321
|
+
return TypeGroupEnum.atomic;
|
|
322
|
+
return Object.isPlainObject(a) ? TypeGroupEnum.plain : TypeGroupEnum.rich;
|
|
323
|
+
}
|
|
324
|
+
return {
|
|
325
|
+
JSStucturalTypes,
|
|
326
|
+
TypeGroup: TypeGroupEnum,
|
|
327
|
+
TypeGroups,
|
|
328
|
+
typeGroupOf
|
|
329
|
+
};
|
|
330
|
+
});
|
|
331
|
+
})(AVStantso$2 || (AVStantso$2 = {}));
|
|
332
|
+
|
|
333
|
+
var AVStantso$1;
|
|
334
|
+
(function (AVStantso) {
|
|
335
|
+
/* eslint-disable @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-function-type */
|
|
336
|
+
const symbolClone = Symbol('clone');
|
|
337
|
+
const symbolMerge = Symbol('merge');
|
|
338
|
+
AVStantso.DeepOps = avstantso._reg.DeepOps(({ symbolFreeze, Func, AtomicObjects, LowLevel }) => {
|
|
339
|
+
function nodeTypePrefix(nodeType) {
|
|
340
|
+
return `walk${nodeType.toCapitalized()}`;
|
|
341
|
+
}
|
|
342
|
+
function AllowsClassMap(...classes) {
|
|
343
|
+
return new Map(classes.map((c) => [c, true]));
|
|
344
|
+
}
|
|
345
|
+
//#region shared node helpers
|
|
346
|
+
function nodeTypeOf(value) {
|
|
347
|
+
return LowLevel.TypeGroups[LowLevel.typeGroupOf(value)];
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* @summary Resolve a single `walk{NodeType}Inc`/`walk{NodeType}Exc` rule against `value`
|
|
351
|
+
*/
|
|
352
|
+
function resolveWalkRule(_options, nodeType, value) {
|
|
353
|
+
function resolve(behavior, fallback) {
|
|
354
|
+
if (null == behavior)
|
|
355
|
+
return { walk: fallback };
|
|
356
|
+
if ('boolean' === typeof behavior)
|
|
357
|
+
return { walk: behavior };
|
|
358
|
+
if ('function' === typeof behavior)
|
|
359
|
+
return { walk: true, custom: behavior };
|
|
360
|
+
return { walk: fallback };
|
|
361
|
+
}
|
|
362
|
+
const p = nodeTypePrefix(nodeType);
|
|
363
|
+
const isInc = `${p}Inc` in _options;
|
|
364
|
+
const raw = isInc ? _options[`${p}Inc`] : _options[`${p}Exc`];
|
|
365
|
+
const fallback = isInc;
|
|
366
|
+
if (null == raw || 'boolean' === typeof raw || 'function' === typeof raw)
|
|
367
|
+
return resolve(raw, fallback);
|
|
368
|
+
if (raw instanceof Map) {
|
|
369
|
+
const ctor = value?.constructor;
|
|
370
|
+
return resolve(ctor && raw.has(ctor) ? raw.get(ctor) : undefined, fallback);
|
|
371
|
+
}
|
|
372
|
+
const subKey = 'scalar' === nodeType
|
|
373
|
+
? (null === value ? 'null' : typeof value)
|
|
374
|
+
: Func.determineType(value);
|
|
375
|
+
return resolve(subKey in raw ? raw[subKey] : undefined, fallback);
|
|
376
|
+
}
|
|
377
|
+
/**
|
|
378
|
+
* @summary Iterate `[key, value, descriptor?]` entries of a `plain`/`func` node
|
|
379
|
+
*/
|
|
380
|
+
function* plainEntries(value, ownProps, isFunc) {
|
|
381
|
+
if (!ownProps) {
|
|
382
|
+
for (const kv of Object.entries(value))
|
|
383
|
+
yield kv;
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
for (const [key, dsc] of Object.entries(Object.getOwnPropertyDescriptors(value))) {
|
|
387
|
+
if (isFunc && !Func.isPropAllowed(key))
|
|
388
|
+
continue;
|
|
389
|
+
if ('value' in dsc)
|
|
390
|
+
yield [key, dsc.value, dsc];
|
|
391
|
+
else if (dsc.get)
|
|
392
|
+
yield [key, dsc.get.call(value), dsc];
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
/**
|
|
396
|
+
* @summary Iterate `[key, value]` entries of an `Array`/`Set`/`Map` node
|
|
397
|
+
*/
|
|
398
|
+
function* richIterate(value) {
|
|
399
|
+
if (value instanceof Map) {
|
|
400
|
+
for (const [k, v] of value)
|
|
401
|
+
yield [k, v];
|
|
402
|
+
return;
|
|
403
|
+
}
|
|
404
|
+
let i = 0;
|
|
405
|
+
for (const v of value)
|
|
406
|
+
yield [i++, v];
|
|
407
|
+
}
|
|
408
|
+
function resolveOption(opt, node, key) {
|
|
409
|
+
return ('function' === typeof opt ? opt(node, key) : opt);
|
|
410
|
+
}
|
|
411
|
+
//#endregion
|
|
412
|
+
//#region WalkDef
|
|
413
|
+
function WalkDef(options) {
|
|
414
|
+
function walkDef(nodeType, defaults) {
|
|
415
|
+
const p = nodeTypePrefix(nodeType);
|
|
416
|
+
if (options && (`${p}Inc` in options || `${p}Exc` in options))
|
|
417
|
+
return {};
|
|
418
|
+
return defaults;
|
|
419
|
+
}
|
|
420
|
+
for (const nt of LowLevel.TypeGroups)
|
|
421
|
+
Object.defineProperty(walkDef, nt.toCapitalized(), {
|
|
422
|
+
value(defaults) {
|
|
423
|
+
return walkDef(nt, defaults);
|
|
424
|
+
}
|
|
425
|
+
});
|
|
426
|
+
return walkDef;
|
|
427
|
+
}
|
|
428
|
+
//#endregion
|
|
429
|
+
//#region Is
|
|
430
|
+
const deepOpsIs = (() => {
|
|
431
|
+
const walkFieldNames = LowLevel.TypeGroups.flatMap((nt) => {
|
|
432
|
+
const p = `walk${nt.toCapitalized()}`;
|
|
433
|
+
return [`${p}Inc`, `${p}Exc`];
|
|
434
|
+
});
|
|
435
|
+
function isObj(candidate) {
|
|
436
|
+
return candidate != null
|
|
437
|
+
&& 'object' === typeof candidate;
|
|
438
|
+
}
|
|
439
|
+
function isOptBool(v) {
|
|
440
|
+
return v === undefined || 'boolean' === typeof v;
|
|
441
|
+
}
|
|
442
|
+
function isOptBoolOrFunc(v) {
|
|
443
|
+
return isOptBool || 'function' === typeof v;
|
|
444
|
+
}
|
|
445
|
+
function isCommonOptions(candidate) {
|
|
446
|
+
if (!isObj(candidate))
|
|
447
|
+
return false;
|
|
448
|
+
if (isOptBool(candidate.ownProps))
|
|
449
|
+
return true;
|
|
450
|
+
for (const f of walkFieldNames)
|
|
451
|
+
if (f in candidate && candidate[f] !== undefined)
|
|
452
|
+
return true;
|
|
453
|
+
return false;
|
|
454
|
+
}
|
|
455
|
+
function isCopyOpsOptions(candidate) {
|
|
456
|
+
if (!isObj(candidate))
|
|
457
|
+
return false;
|
|
458
|
+
return isOptBool(candidate.copyFuncs);
|
|
459
|
+
}
|
|
460
|
+
function isMergeOptions(candidate) {
|
|
461
|
+
if (!isObj(candidate))
|
|
462
|
+
return false;
|
|
463
|
+
const obj = candidate;
|
|
464
|
+
return !isCopyOpsOptions(candidate)
|
|
465
|
+
|| isOptBoolOrFunc(obj.onlyExists)
|
|
466
|
+
|| isOptBoolOrFunc(obj.isUniqueArrItems)
|
|
467
|
+
|| isOptBoolOrFunc(obj.nullAsDelete);
|
|
468
|
+
}
|
|
469
|
+
return {
|
|
470
|
+
options: {
|
|
471
|
+
common: isCommonOptions,
|
|
472
|
+
clone: isCopyOpsOptions,
|
|
473
|
+
merge: isMergeOptions
|
|
474
|
+
}
|
|
475
|
+
};
|
|
476
|
+
})();
|
|
477
|
+
//#endregion
|
|
478
|
+
//#region deepFreeze
|
|
479
|
+
function deepFreeze(obj, options) {
|
|
480
|
+
const WD = WalkDef(options);
|
|
481
|
+
const _options = {
|
|
482
|
+
...options,
|
|
483
|
+
symbol: symbolFreeze,
|
|
484
|
+
...WD.Scalar({ walkScalarExc: false }),
|
|
485
|
+
...WD.Atomic({ walkAtomicExc: false }),
|
|
486
|
+
...WD.Plain({ walkPlainInc: true }),
|
|
487
|
+
...WD.Rich({ walkRichInc: true }),
|
|
488
|
+
...WD.Func({
|
|
489
|
+
walkFuncInc: {
|
|
490
|
+
class: false,
|
|
491
|
+
generator: false
|
|
492
|
+
}
|
|
493
|
+
})
|
|
494
|
+
};
|
|
495
|
+
const seen = new Set();
|
|
496
|
+
const hasCustomFreeze = Symbol.Has(symbolFreeze);
|
|
497
|
+
function walk(value) {
|
|
498
|
+
const nt = nodeTypeOf(value);
|
|
499
|
+
const isContainer = 'plain' === nt || 'rich' === nt || 'func' === nt;
|
|
500
|
+
if (isContainer && seen.has(value))
|
|
501
|
+
return value;
|
|
502
|
+
if (isContainer && hasCustomFreeze(value)) {
|
|
503
|
+
seen.add(value);
|
|
504
|
+
value[symbolFreeze]();
|
|
505
|
+
return value;
|
|
506
|
+
}
|
|
507
|
+
const rule = resolveWalkRule(_options, nt, value);
|
|
508
|
+
if (!rule.walk)
|
|
509
|
+
return undefined;
|
|
510
|
+
if (isContainer)
|
|
511
|
+
seen.add(value);
|
|
512
|
+
if (rule.custom) {
|
|
513
|
+
rule.custom(value);
|
|
514
|
+
return value;
|
|
515
|
+
}
|
|
516
|
+
if ('plain' === nt || 'func' === nt)
|
|
517
|
+
for (const [, child] of plainEntries(value, _options.ownProps, 'func' === nt))
|
|
518
|
+
walk(child);
|
|
519
|
+
else if ('rich' === nt) {
|
|
520
|
+
const v = value;
|
|
521
|
+
if (Array.isArray(v) || v instanceof Set || v instanceof Map)
|
|
522
|
+
for (const [, child] of richIterate(v))
|
|
523
|
+
walk(child);
|
|
524
|
+
else
|
|
525
|
+
for (const [, child] of plainEntries(v, _options.ownProps, false))
|
|
526
|
+
walk(child);
|
|
527
|
+
}
|
|
528
|
+
if (isContainer)
|
|
529
|
+
Object.freeze(value);
|
|
530
|
+
return value;
|
|
531
|
+
}
|
|
532
|
+
return walk(obj);
|
|
533
|
+
}
|
|
534
|
+
deepFreeze.symbol = symbolFreeze;
|
|
535
|
+
//#endregion
|
|
536
|
+
//#region deepClone
|
|
537
|
+
const deepCloneRich = AllowsClassMap(Array, Set, Map);
|
|
538
|
+
const SKIP = Symbol('deep-clone-skip');
|
|
539
|
+
function deepClone(obj, options) {
|
|
540
|
+
const WD = WalkDef(options);
|
|
541
|
+
const _options = {
|
|
542
|
+
...options,
|
|
543
|
+
symbol: symbolClone,
|
|
544
|
+
parentFirst: true,
|
|
545
|
+
...WD.Scalar({ walkScalarInc: true }),
|
|
546
|
+
...WD.Atomic({ walkAtomicInc: true }),
|
|
547
|
+
...WD.Plain({ walkPlainInc: true }),
|
|
548
|
+
...WD.Rich({ walkRichExc: deepCloneRich }),
|
|
549
|
+
...WD.Func({
|
|
550
|
+
walkFuncInc: {
|
|
551
|
+
class: false,
|
|
552
|
+
generator: false
|
|
553
|
+
}
|
|
554
|
+
})
|
|
555
|
+
};
|
|
556
|
+
const hasCustomClone = Symbol.Has(symbolClone);
|
|
557
|
+
const cloned = new Map();
|
|
558
|
+
function clone(value) {
|
|
559
|
+
const nt = nodeTypeOf(value);
|
|
560
|
+
const isContainer = 'plain' === nt || 'rich' === nt || 'func' === nt;
|
|
561
|
+
if (isContainer && cloned.has(value))
|
|
562
|
+
return cloned.get(value);
|
|
563
|
+
if (isContainer && hasCustomClone(value)) {
|
|
564
|
+
const r = value[symbolClone]();
|
|
565
|
+
cloned.set(value, r);
|
|
566
|
+
return r;
|
|
567
|
+
}
|
|
568
|
+
const rule = resolveWalkRule(_options, nt, value);
|
|
569
|
+
if (!rule.walk)
|
|
570
|
+
return SKIP;
|
|
571
|
+
if (rule.custom) {
|
|
572
|
+
const r = rule.custom(value);
|
|
573
|
+
if (isContainer)
|
|
574
|
+
cloned.set(value, r);
|
|
575
|
+
return r;
|
|
576
|
+
}
|
|
577
|
+
switch (nt) {
|
|
578
|
+
case 'scalar':
|
|
579
|
+
return value;
|
|
580
|
+
case 'atomic':
|
|
581
|
+
return AtomicObjects.descriptor(value).clone(value);
|
|
582
|
+
case 'plain': {
|
|
583
|
+
const r = {};
|
|
584
|
+
cloned.set(value, r);
|
|
585
|
+
const entries = plainEntries(value, _options.ownProps, false);
|
|
586
|
+
for (const [key, child, dsc] of entries) {
|
|
587
|
+
const c = clone(child);
|
|
588
|
+
if (c === SKIP)
|
|
589
|
+
continue;
|
|
590
|
+
if (dsc)
|
|
591
|
+
Object.defineProperty(r, key, { ...dsc, value: c });
|
|
592
|
+
else
|
|
593
|
+
r[key] = c;
|
|
594
|
+
}
|
|
595
|
+
return r;
|
|
596
|
+
}
|
|
597
|
+
case 'rich': {
|
|
598
|
+
const v = value;
|
|
599
|
+
if (Array.isArray(v)) {
|
|
600
|
+
const r = [];
|
|
601
|
+
cloned.set(value, r);
|
|
602
|
+
for (const item of v) {
|
|
603
|
+
const c = clone(item);
|
|
604
|
+
if (c !== SKIP)
|
|
605
|
+
r.push(c);
|
|
606
|
+
}
|
|
607
|
+
return r;
|
|
608
|
+
}
|
|
609
|
+
if (v instanceof Set) {
|
|
610
|
+
const r = new Set();
|
|
611
|
+
cloned.set(value, r);
|
|
612
|
+
for (const item of v) {
|
|
613
|
+
const c = clone(item);
|
|
614
|
+
if (c !== SKIP)
|
|
615
|
+
r.add(c);
|
|
616
|
+
}
|
|
617
|
+
return r;
|
|
618
|
+
}
|
|
619
|
+
if (v instanceof Map) {
|
|
620
|
+
const r = new Map();
|
|
621
|
+
cloned.set(value, r);
|
|
622
|
+
for (const [k, item] of v) {
|
|
623
|
+
const c = clone(item);
|
|
624
|
+
if (c !== SKIP)
|
|
625
|
+
r.set(clone(k), c);
|
|
626
|
+
}
|
|
627
|
+
return r;
|
|
628
|
+
}
|
|
629
|
+
throw Error(`Cannot clone rich object "${v?.constructor?.name}"`);
|
|
630
|
+
}
|
|
631
|
+
case 'func': {
|
|
632
|
+
const fn = value;
|
|
633
|
+
if (_options.copyFuncs) {
|
|
634
|
+
cloned.set(value, fn);
|
|
635
|
+
return fn;
|
|
636
|
+
}
|
|
637
|
+
const wrapper = 'async' === Func.determineType(fn)
|
|
638
|
+
? async (...params) => fn(...params)
|
|
639
|
+
: (...params) => fn(...params);
|
|
640
|
+
cloned.set(value, wrapper);
|
|
641
|
+
return wrapper;
|
|
642
|
+
}
|
|
643
|
+
}
|
|
644
|
+
}
|
|
645
|
+
const r = clone(obj);
|
|
646
|
+
return (r === SKIP ? undefined : r);
|
|
647
|
+
}
|
|
648
|
+
deepClone.symbol = symbolClone;
|
|
649
|
+
//#endregion
|
|
650
|
+
//#region deepMerge
|
|
651
|
+
function deepMerge(target, ...params) {
|
|
652
|
+
const { onlyExists, nullAsDelete, isUniqueArrItems, concatArrays, ...options } = params.pop();
|
|
653
|
+
if (params.length <= 0)
|
|
654
|
+
return target;
|
|
655
|
+
const WD = WalkDef(options);
|
|
656
|
+
const _options = {
|
|
657
|
+
...options,
|
|
658
|
+
symbol: symbolMerge,
|
|
659
|
+
...WD.Scalar({ walkScalarInc: true }),
|
|
660
|
+
...WD.Atomic({ walkAtomicInc: true }),
|
|
661
|
+
...WD.Plain({ walkPlainInc: true }),
|
|
662
|
+
...WD.Rich({ walkRichExc: deepCloneRich }),
|
|
663
|
+
...WD.Func({
|
|
664
|
+
walkFuncInc: {
|
|
665
|
+
class: false,
|
|
666
|
+
generator: false
|
|
667
|
+
}
|
|
668
|
+
})
|
|
669
|
+
};
|
|
670
|
+
const hasCustomMerge = Symbol.Has(symbolMerge);
|
|
671
|
+
function mergeValue(t, s, ownKey) {
|
|
672
|
+
if (hasCustomMerge(t))
|
|
673
|
+
return t[symbolMerge](s);
|
|
674
|
+
const nt = nodeTypeOf(t);
|
|
675
|
+
const ns = nodeTypeOf(s);
|
|
676
|
+
if (nt !== ns || 'scalar' === nt || 'atomic' === nt)
|
|
677
|
+
return deepClone(s, options);
|
|
678
|
+
if ('plain' === nt || 'func' === nt) {
|
|
679
|
+
const entries = plainEntries(s, options.ownProps, 'func' === nt);
|
|
680
|
+
for (const [key, sChild] of entries) {
|
|
681
|
+
if (!resolveWalkRule(_options, nodeTypeOf(sChild), sChild).walk)
|
|
682
|
+
continue;
|
|
683
|
+
if (resolveOption(nullAsDelete, sChild, key) && null === sChild) {
|
|
684
|
+
delete t[key];
|
|
685
|
+
continue;
|
|
686
|
+
}
|
|
687
|
+
if (resolveOption(onlyExists, sChild, key) && !(key in t))
|
|
688
|
+
continue;
|
|
689
|
+
t[key] = mergeValue(t[key], sChild, key);
|
|
690
|
+
}
|
|
691
|
+
return t;
|
|
692
|
+
}
|
|
693
|
+
const tv = t;
|
|
694
|
+
const sv = s;
|
|
695
|
+
if (Array.isArray(tv)) {
|
|
696
|
+
const arr = tv;
|
|
697
|
+
const src = sv;
|
|
698
|
+
if (resolveOption(concatArrays, arr, ownKey))
|
|
699
|
+
for (const sChild of src)
|
|
700
|
+
arr.push(deepClone(sChild, options));
|
|
701
|
+
else
|
|
702
|
+
for (let i = 0; i < src.length; i++) {
|
|
703
|
+
const sChild = src[i];
|
|
704
|
+
if (!resolveWalkRule(_options, nodeTypeOf(sChild), sChild).walk)
|
|
705
|
+
continue;
|
|
706
|
+
if (resolveOption(nullAsDelete, sChild, i) && null === sChild) {
|
|
707
|
+
if (i < arr.length)
|
|
708
|
+
arr.splice(i, 1);
|
|
709
|
+
continue;
|
|
710
|
+
}
|
|
711
|
+
if (i >= arr.length) {
|
|
712
|
+
if (!resolveOption(onlyExists, sChild, i))
|
|
713
|
+
arr.push(deepClone(sChild, options));
|
|
714
|
+
}
|
|
715
|
+
else
|
|
716
|
+
arr[i] = mergeValue(arr[i], sChild, i);
|
|
717
|
+
}
|
|
718
|
+
if (resolveOption(isUniqueArrItems, arr, ownKey))
|
|
719
|
+
arr.splice(0, arr.length, ...new Set(arr));
|
|
720
|
+
return arr;
|
|
721
|
+
}
|
|
722
|
+
if (tv instanceof Set) {
|
|
723
|
+
for (const sChild of sv) {
|
|
724
|
+
if (resolveOption(onlyExists, sChild, ownKey) && !tv.has(sChild))
|
|
725
|
+
continue;
|
|
726
|
+
tv.add('scalar' === nodeTypeOf(sChild) ? sChild : deepClone(sChild, options));
|
|
727
|
+
}
|
|
728
|
+
return tv;
|
|
729
|
+
}
|
|
730
|
+
if (tv instanceof Map) {
|
|
731
|
+
for (const [mapKey, sChild] of sv) {
|
|
732
|
+
const k = mapKey;
|
|
733
|
+
if (resolveOption(nullAsDelete, sChild, k) && null === sChild) {
|
|
734
|
+
tv.delete(mapKey);
|
|
735
|
+
continue;
|
|
736
|
+
}
|
|
737
|
+
if (resolveOption(onlyExists, sChild, k) && !tv.has(mapKey))
|
|
738
|
+
continue;
|
|
739
|
+
tv.set(mapKey, tv.has(mapKey) ? mergeValue(tv.get(mapKey), sChild, k) : deepClone(sChild, options));
|
|
740
|
+
}
|
|
741
|
+
return tv;
|
|
742
|
+
}
|
|
743
|
+
throw Error(`Cannot merge rich object "${tv?.constructor?.name}"`);
|
|
744
|
+
}
|
|
745
|
+
let result = deepClone(target, options);
|
|
746
|
+
for (const source of params)
|
|
747
|
+
result = mergeValue(result, source);
|
|
748
|
+
return result;
|
|
749
|
+
}
|
|
750
|
+
deepMerge.symbol = symbolMerge;
|
|
751
|
+
//#endregion
|
|
752
|
+
return {
|
|
753
|
+
NodeTypes: LowLevel.TypeGroups,
|
|
754
|
+
is: deepOpsIs,
|
|
755
|
+
freeze: deepFreeze,
|
|
756
|
+
clone: deepClone,
|
|
757
|
+
merge: deepMerge
|
|
758
|
+
};
|
|
759
|
+
});
|
|
240
760
|
})(AVStantso$1 || (AVStantso$1 = {}));
|
|
241
761
|
|
|
242
762
|
var Func = AVStantso.Func;
|
|
243
763
|
var X = AVStantso.X;
|
|
244
764
|
var Generic = AVStantso.Generic;
|
|
765
|
+
var DeepOps = AVStantso.DeepOps;
|
|
245
766
|
|
|
767
|
+
exports.DeepOps = DeepOps;
|
|
246
768
|
exports.Func = Func;
|
|
247
769
|
exports.Generic = Generic;
|
|
248
770
|
exports.X = X;
|