@bcts/dcbor 1.0.0-alpha.8 → 1.0.0-beta.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/LICENSE +3 -2
- package/README.md +1 -1
- package/dist/index.cjs +1941 -1497
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +613 -327
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +613 -327
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +2149 -1754
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +1932 -1511
- package/dist/index.mjs.map +1 -1
- package/package.json +14 -16
- package/src/bignum.ts +347 -0
- package/src/byte-string.ts +21 -17
- package/src/cbor-codable.ts +4 -0
- package/src/cbor-tagged-codable.ts +4 -0
- package/src/cbor-tagged-decodable.ts +33 -5
- package/src/cbor-tagged-encodable.ts +15 -0
- package/src/cbor-tagged.ts +11 -1
- package/src/cbor.ts +73 -18
- package/src/conveniences.ts +23 -5
- package/src/date.ts +35 -28
- package/src/decode.ts +13 -0
- package/src/diag.ts +233 -196
- package/src/dump.ts +18 -7
- package/src/error.ts +4 -0
- package/src/exact.ts +4 -0
- package/src/float.ts +25 -6
- package/src/global.d.ts +4 -0
- package/src/globals.d.ts +5 -0
- package/src/index.ts +65 -13
- package/src/map.ts +27 -23
- package/src/prelude.ts +12 -2
- package/src/set.ts +37 -10
- package/src/simple.ts +15 -2
- package/src/sortable.ts +70 -0
- package/src/stdlib.ts +4 -0
- package/src/string-util.ts +4 -0
- package/src/tag.ts +51 -2
- package/src/tags-store.ts +53 -68
- package/src/tags.ts +68 -6
- package/src/varint.ts +16 -11
- package/src/walk.ts +77 -281
package/src/walk.ts
CHANGED
|
@@ -1,4 +1,8 @@
|
|
|
1
1
|
/**
|
|
2
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
3
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
4
|
+
*
|
|
5
|
+
*
|
|
2
6
|
* Tree traversal system for CBOR data structures.
|
|
3
7
|
*
|
|
4
8
|
* This module provides a visitor pattern implementation for traversing
|
|
@@ -125,16 +129,18 @@ export const asKeyValue = (element: WalkElement): [Cbor, Cbor] | undefined => {
|
|
|
125
129
|
};
|
|
126
130
|
|
|
127
131
|
/**
|
|
128
|
-
* Visitor function type
|
|
132
|
+
* Visitor function type.
|
|
129
133
|
*
|
|
130
|
-
* @template State - The type of state passed
|
|
134
|
+
* @template State - The type of state passed into each visit
|
|
131
135
|
* @param element - The element being visited
|
|
132
136
|
* @param level - The depth level in the tree (0 = root)
|
|
133
137
|
* @param edge - Information about the edge leading to this element
|
|
134
|
-
* @param state -
|
|
138
|
+
* @param state - The state value cloned from the parent visit
|
|
135
139
|
* @returns Tuple of [newState, stopDescent] where:
|
|
136
|
-
* - newState: The
|
|
137
|
-
*
|
|
140
|
+
* - newState: The state to pass into descendants of this element. Each
|
|
141
|
+
* descendant receives an independent clone of `newState`; sibling
|
|
142
|
+
* subtrees do *not* see each other's mutations.
|
|
143
|
+
* - stopDescent: If true, do not descend into children of this element.
|
|
138
144
|
*/
|
|
139
145
|
export type Visitor<State> = (
|
|
140
146
|
element: WalkElement,
|
|
@@ -143,57 +149,47 @@ export type Visitor<State> = (
|
|
|
143
149
|
state: State,
|
|
144
150
|
) => [State, boolean];
|
|
145
151
|
|
|
152
|
+
/**
|
|
153
|
+
* Clone helper used to give each descendant subtree an independent copy of
|
|
154
|
+
* the post-visit state — mirrors Rust `State: Clone` + `state.clone()` per
|
|
155
|
+
* child in `walk.rs`. Falls back to the value as-is for primitives (which
|
|
156
|
+
* don't need cloning) and uses `structuredClone` for objects.
|
|
157
|
+
*/
|
|
158
|
+
const cloneState = <S>(s: S): S => {
|
|
159
|
+
if (s === null) return s;
|
|
160
|
+
const t = typeof s;
|
|
161
|
+
if (t !== "object" && t !== "function") return s;
|
|
162
|
+
// `structuredClone` is a host-provided global available in modern Node
|
|
163
|
+
// (≥ 17) and every modern browser; declare it inline so eslint's
|
|
164
|
+
// `no-undef` is satisfied without a project-wide globals declaration.
|
|
165
|
+
return (globalThis as { structuredClone(v: unknown): unknown }).structuredClone(s) as S;
|
|
166
|
+
};
|
|
167
|
+
|
|
146
168
|
/**
|
|
147
169
|
* Walk a CBOR tree, visiting each element with a visitor function.
|
|
148
170
|
*
|
|
149
171
|
* The visitor function is called for each element in the tree, in depth-first order.
|
|
150
|
-
* State
|
|
172
|
+
* State semantics mirror Rust's `walk_internal`:
|
|
173
|
+
*
|
|
174
|
+
* - The visitor's returned `newState` propagates **down** to descendants of
|
|
175
|
+
* the just-visited node only.
|
|
176
|
+
* - Sibling subtrees each receive an independent clone of the parent's
|
|
177
|
+
* post-visit state, so accumulating mutations in one subtree never leak
|
|
178
|
+
* into a sibling.
|
|
179
|
+
* - State changes do not propagate **up**: the public `walk` returns `void`.
|
|
151
180
|
*
|
|
152
181
|
* For maps, the visitor is called with:
|
|
153
182
|
* 1. A 'keyvalue' element containing both key and value
|
|
154
183
|
* 2. The key individually (if descent wasn't stopped)
|
|
155
184
|
* 3. The value individually (if descent wasn't stopped)
|
|
156
185
|
*
|
|
157
|
-
* @template State - The type of state to
|
|
186
|
+
* @template State - The type of state to pass into each visit
|
|
158
187
|
* @param cbor - The CBOR value to traverse
|
|
159
188
|
* @param initialState - Initial state value
|
|
160
189
|
* @param visitor - Function to call for each element
|
|
161
|
-
* @returns Final state after traversal
|
|
162
|
-
*
|
|
163
|
-
* @example
|
|
164
|
-
* ```typescript
|
|
165
|
-
* // Count all text strings in a structure
|
|
166
|
-
* interface CountState { count: number }
|
|
167
|
-
*
|
|
168
|
-
* const structure = cbor({ name: 'Alice', tags: ['urgent', 'draft'] });
|
|
169
|
-
* const result = walk(structure, { count: 0 }, (element, level, edge, state) => {
|
|
170
|
-
* if (element.type === 'single' && element.cbor.type === MajorType.Text) {
|
|
171
|
-
* return [{ count: state.count + 1 }, false];
|
|
172
|
-
* }
|
|
173
|
-
* return [state, false];
|
|
174
|
-
* });
|
|
175
|
-
* console.log(result.count); // 3 (name, urgent, draft)
|
|
176
|
-
* ```
|
|
177
|
-
*
|
|
178
|
-
* @example
|
|
179
|
-
* ```typescript
|
|
180
|
-
* // Find first occurrence and stop
|
|
181
|
-
* const structure = cbor([1, 2, 3, 'found', 5, 6]);
|
|
182
|
-
* let found = false;
|
|
183
|
-
*
|
|
184
|
-
* walk(structure, null, (element, level, edge) => {
|
|
185
|
-
* if (element.type === 'single' &&
|
|
186
|
-
* element.cbor.type === MajorType.Text &&
|
|
187
|
-
* element.cbor.value === 'found') {
|
|
188
|
-
* found = true;
|
|
189
|
-
* return [null, true]; // Stop descending
|
|
190
|
-
* }
|
|
191
|
-
* return [null, false];
|
|
192
|
-
* });
|
|
193
|
-
* ```
|
|
194
190
|
*/
|
|
195
|
-
export const walk = <State>(cbor: Cbor, initialState: State, visitor: Visitor<State>):
|
|
196
|
-
|
|
191
|
+
export const walk = <State>(cbor: Cbor, initialState: State, visitor: Visitor<State>): void => {
|
|
192
|
+
walkInternal(cbor, 0, { type: EdgeType.None }, initialState, visitor);
|
|
197
193
|
};
|
|
198
194
|
|
|
199
195
|
/**
|
|
@@ -207,62 +203,43 @@ function walkInternal<State>(
|
|
|
207
203
|
edge: EdgeTypeVariant,
|
|
208
204
|
state: State,
|
|
209
205
|
visitor: Visitor<State>,
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
const [newState, stop] = visitor(element, level, edge, currentState);
|
|
219
|
-
currentState = newState;
|
|
220
|
-
stopDescent = stop;
|
|
221
|
-
|
|
222
|
-
// If visitor says to stop descending, return immediately
|
|
223
|
-
if (stopDescent) {
|
|
224
|
-
return currentState;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
// Recursively visit children based on CBOR type
|
|
229
|
-
// Only container types (Array, Map, Tagged) need special handling; leaf nodes use default
|
|
206
|
+
): void {
|
|
207
|
+
// Visit the current element.
|
|
208
|
+
const element: WalkElement = { type: "single", cbor };
|
|
209
|
+
const [postVisitState, stop] = visitor(element, level, edge, state);
|
|
210
|
+
if (stop) return;
|
|
211
|
+
|
|
212
|
+
// Recursively visit children based on CBOR type. Each child receives an
|
|
213
|
+
// independent clone of `postVisitState`, matching Rust `state.clone()`.
|
|
230
214
|
// eslint-disable-next-line @typescript-eslint/switch-exhaustiveness-check
|
|
231
215
|
switch (cbor.type) {
|
|
232
216
|
case MajorType.Array:
|
|
233
|
-
|
|
217
|
+
walkArray(cbor, level, postVisitState, visitor);
|
|
234
218
|
break;
|
|
235
|
-
|
|
236
219
|
case MajorType.Map:
|
|
237
|
-
|
|
220
|
+
walkMap(cbor, level, postVisitState, visitor);
|
|
238
221
|
break;
|
|
239
|
-
|
|
240
222
|
case MajorType.Tagged:
|
|
241
|
-
|
|
223
|
+
walkTagged(cbor, level, postVisitState, visitor);
|
|
242
224
|
break;
|
|
243
|
-
|
|
244
|
-
// Leaf nodes: Unsigned, Negative, Bytes, Text, Simple
|
|
245
225
|
default:
|
|
246
|
-
//
|
|
226
|
+
// Leaf nodes (Unsigned, Negative, Bytes, Text, Simple) have no children.
|
|
247
227
|
break;
|
|
248
228
|
}
|
|
249
|
-
|
|
250
|
-
return currentState;
|
|
251
229
|
}
|
|
252
230
|
|
|
253
231
|
/**
|
|
254
|
-
* Walk an array's elements.
|
|
232
|
+
* Walk an array's elements. Each element is visited with an independent
|
|
233
|
+
* clone of `parentState`.
|
|
255
234
|
*
|
|
256
235
|
* @internal
|
|
257
236
|
*/
|
|
258
237
|
function walkArray<State>(
|
|
259
238
|
cbor: CborArrayType,
|
|
260
239
|
level: number,
|
|
261
|
-
|
|
240
|
+
parentState: State,
|
|
262
241
|
visitor: Visitor<State>,
|
|
263
|
-
):
|
|
264
|
-
let currentState = state;
|
|
265
|
-
|
|
242
|
+
): void {
|
|
266
243
|
for (let index = 0; index < cbor.value.length; index++) {
|
|
267
244
|
const item = cbor.value[index];
|
|
268
245
|
if (item === undefined) {
|
|
@@ -271,246 +248,65 @@ function walkArray<State>(
|
|
|
271
248
|
message: `Array element at index ${index} is undefined`,
|
|
272
249
|
});
|
|
273
250
|
}
|
|
274
|
-
|
|
251
|
+
walkInternal(
|
|
275
252
|
item,
|
|
276
253
|
level + 1,
|
|
277
254
|
{ type: EdgeType.ArrayElement, index },
|
|
278
|
-
|
|
255
|
+
cloneState(parentState),
|
|
279
256
|
visitor,
|
|
280
257
|
);
|
|
281
258
|
}
|
|
282
|
-
|
|
283
|
-
return currentState;
|
|
284
259
|
}
|
|
285
260
|
|
|
286
261
|
/**
|
|
287
262
|
* Walk a map's key-value pairs.
|
|
288
263
|
*
|
|
289
|
-
*
|
|
290
|
-
*
|
|
291
|
-
*
|
|
292
|
-
* 3. If not stopped, visit the value individually
|
|
264
|
+
* Each kv pair receives a clone of `parentState`. If descent isn't stopped,
|
|
265
|
+
* the key and value subtrees receive independent clones of the kv-visit's
|
|
266
|
+
* post-visit state.
|
|
293
267
|
*
|
|
294
268
|
* @internal
|
|
295
269
|
*/
|
|
296
270
|
function walkMap<State>(
|
|
297
271
|
cbor: CborMapType,
|
|
298
272
|
level: number,
|
|
299
|
-
|
|
273
|
+
parentState: State,
|
|
300
274
|
visitor: Visitor<State>,
|
|
301
|
-
):
|
|
302
|
-
let currentState = state;
|
|
303
|
-
|
|
275
|
+
): void {
|
|
304
276
|
for (const entry of cbor.value.entriesArray) {
|
|
305
277
|
const { key, value } = entry;
|
|
306
278
|
|
|
307
|
-
// First, visit the key-value pair as a semantic unit
|
|
308
279
|
const kvElement: WalkElement = { type: "keyvalue", key, value };
|
|
309
|
-
const [
|
|
280
|
+
const [kvPostState, kvStop] = visitor(
|
|
310
281
|
kvElement,
|
|
311
282
|
level + 1,
|
|
312
283
|
{ type: EdgeType.MapKeyValue },
|
|
313
|
-
|
|
284
|
+
cloneState(parentState),
|
|
314
285
|
);
|
|
315
|
-
|
|
286
|
+
if (kvStop) continue;
|
|
316
287
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
currentState = walkInternal(key, level + 1, { type: EdgeType.MapKey }, currentState, visitor);
|
|
320
|
-
|
|
321
|
-
currentState = walkInternal(
|
|
322
|
-
value,
|
|
323
|
-
level + 1,
|
|
324
|
-
{ type: EdgeType.MapValue },
|
|
325
|
-
currentState,
|
|
326
|
-
visitor,
|
|
327
|
-
);
|
|
328
|
-
}
|
|
288
|
+
walkInternal(key, level + 1, { type: EdgeType.MapKey }, cloneState(kvPostState), visitor);
|
|
289
|
+
walkInternal(value, level + 1, { type: EdgeType.MapValue }, cloneState(kvPostState), visitor);
|
|
329
290
|
}
|
|
330
|
-
|
|
331
|
-
return currentState;
|
|
332
291
|
}
|
|
333
292
|
|
|
334
293
|
/**
|
|
335
|
-
* Walk a tagged value's content.
|
|
294
|
+
* Walk a tagged value's content. The content visit receives a clone of
|
|
295
|
+
* `parentState`.
|
|
336
296
|
*
|
|
337
297
|
* @internal
|
|
338
298
|
*/
|
|
339
299
|
function walkTagged<State>(
|
|
340
300
|
cbor: CborTaggedType,
|
|
341
301
|
level: number,
|
|
342
|
-
|
|
302
|
+
parentState: State,
|
|
343
303
|
visitor: Visitor<State>,
|
|
344
|
-
):
|
|
345
|
-
|
|
304
|
+
): void {
|
|
305
|
+
walkInternal(
|
|
306
|
+
cbor.value,
|
|
307
|
+
level + 1,
|
|
308
|
+
{ type: EdgeType.TaggedContent },
|
|
309
|
+
cloneState(parentState),
|
|
310
|
+
visitor,
|
|
311
|
+
);
|
|
346
312
|
}
|
|
347
|
-
|
|
348
|
-
/**
|
|
349
|
-
* Helper: Count all elements in a CBOR tree.
|
|
350
|
-
*
|
|
351
|
-
* @param cbor - The CBOR value to count
|
|
352
|
-
* @returns Total number of elements visited
|
|
353
|
-
*
|
|
354
|
-
* @example
|
|
355
|
-
* ```typescript
|
|
356
|
-
* const structure = cbor([1, 2, [3, 4]]);
|
|
357
|
-
* const count = countElements(structure);
|
|
358
|
-
* console.log(count); // 6 (array, 1, 2, inner array, 3, 4)
|
|
359
|
-
* ```
|
|
360
|
-
*/
|
|
361
|
-
export const countElements = (cbor: Cbor): number => {
|
|
362
|
-
interface CountState {
|
|
363
|
-
count: number;
|
|
364
|
-
}
|
|
365
|
-
|
|
366
|
-
const result = walk<CountState>(cbor, { count: 0 }, (_element, _level, _edge, state) => {
|
|
367
|
-
return [{ count: state.count + 1 }, false];
|
|
368
|
-
});
|
|
369
|
-
|
|
370
|
-
return result.count;
|
|
371
|
-
};
|
|
372
|
-
|
|
373
|
-
/**
|
|
374
|
-
* Helper: Collect all elements at a specific depth level.
|
|
375
|
-
*
|
|
376
|
-
* @param cbor - The CBOR value to traverse
|
|
377
|
-
* @param targetLevel - The depth level to collect (0 = root)
|
|
378
|
-
* @returns Array of CBOR values at the target level
|
|
379
|
-
*
|
|
380
|
-
* @example
|
|
381
|
-
* ```typescript
|
|
382
|
-
* const structure = cbor([[1, 2], [3, 4]]);
|
|
383
|
-
* const level1 = collectAtLevel(structure, 1);
|
|
384
|
-
* // Returns: [[1, 2], [3, 4]]
|
|
385
|
-
* const level2 = collectAtLevel(structure, 2);
|
|
386
|
-
* // Returns: [1, 2, 3, 4]
|
|
387
|
-
* ```
|
|
388
|
-
*/
|
|
389
|
-
export const collectAtLevel = (cbor: Cbor, targetLevel: number): Cbor[] => {
|
|
390
|
-
interface CollectState {
|
|
391
|
-
items: Cbor[];
|
|
392
|
-
}
|
|
393
|
-
|
|
394
|
-
const result = walk<CollectState>(cbor, { items: [] }, (element, level, _edge, state) => {
|
|
395
|
-
if (level === targetLevel && element.type === "single") {
|
|
396
|
-
return [{ items: [...state.items, element.cbor] }, false];
|
|
397
|
-
}
|
|
398
|
-
return [state, false];
|
|
399
|
-
});
|
|
400
|
-
|
|
401
|
-
return result.items;
|
|
402
|
-
};
|
|
403
|
-
|
|
404
|
-
/**
|
|
405
|
-
* Helper: Find first element matching a predicate.
|
|
406
|
-
*
|
|
407
|
-
* @template T - Type of extracted value
|
|
408
|
-
* @param cbor - The CBOR value to search
|
|
409
|
-
* @param predicate - Function to test each element
|
|
410
|
-
* @returns First matching element, or undefined if not found
|
|
411
|
-
*
|
|
412
|
-
* @example
|
|
413
|
-
* ```typescript
|
|
414
|
-
* const structure = cbor({ users: [
|
|
415
|
-
* { name: 'Alice', age: 30 },
|
|
416
|
-
* { name: 'Bob', age: 25 }
|
|
417
|
-
* ]});
|
|
418
|
-
*
|
|
419
|
-
* const bob = findFirst(structure, (element) => {
|
|
420
|
-
* if (element.type === 'single' &&
|
|
421
|
-
* element.cbor.type === MajorType.Text &&
|
|
422
|
-
* element.cbor.value === 'Bob') {
|
|
423
|
-
* return true;
|
|
424
|
-
* }
|
|
425
|
-
* return false;
|
|
426
|
-
* });
|
|
427
|
-
* ```
|
|
428
|
-
*/
|
|
429
|
-
export const findFirst = (
|
|
430
|
-
cbor: Cbor,
|
|
431
|
-
predicate: (element: WalkElement) => boolean,
|
|
432
|
-
): Cbor | undefined => {
|
|
433
|
-
interface FindState {
|
|
434
|
-
found?: Cbor;
|
|
435
|
-
}
|
|
436
|
-
|
|
437
|
-
const result = walk<FindState>(cbor, {}, (element, _level, _edge, state) => {
|
|
438
|
-
if (state.found !== undefined) {
|
|
439
|
-
// Already found, stop descending
|
|
440
|
-
return [state, true];
|
|
441
|
-
}
|
|
442
|
-
|
|
443
|
-
if (predicate(element)) {
|
|
444
|
-
if (element.type === "single") {
|
|
445
|
-
return [{ found: element.cbor }, true]; // Stop after finding
|
|
446
|
-
}
|
|
447
|
-
// Matched but not a single element, stop anyway
|
|
448
|
-
return [state, true];
|
|
449
|
-
}
|
|
450
|
-
|
|
451
|
-
return [state, false];
|
|
452
|
-
});
|
|
453
|
-
|
|
454
|
-
return result.found;
|
|
455
|
-
};
|
|
456
|
-
|
|
457
|
-
/**
|
|
458
|
-
* Helper: Collect all text strings in a CBOR tree.
|
|
459
|
-
*
|
|
460
|
-
* @param cbor - The CBOR value to traverse
|
|
461
|
-
* @returns Array of all text string values found
|
|
462
|
-
*
|
|
463
|
-
* @example
|
|
464
|
-
* ```typescript
|
|
465
|
-
* const doc = cbor({
|
|
466
|
-
* title: 'Document',
|
|
467
|
-
* tags: ['urgent', 'draft'],
|
|
468
|
-
* author: { name: 'Alice' }
|
|
469
|
-
* });
|
|
470
|
-
*
|
|
471
|
-
* const texts = collectAllText(doc);
|
|
472
|
-
* // Returns: ['Document', 'urgent', 'draft', 'Alice']
|
|
473
|
-
* ```
|
|
474
|
-
*/
|
|
475
|
-
export const collectAllText = (cbor: Cbor): string[] => {
|
|
476
|
-
interface TextState {
|
|
477
|
-
texts: string[];
|
|
478
|
-
}
|
|
479
|
-
|
|
480
|
-
const result = walk<TextState>(cbor, { texts: [] }, (element, _level, _edge, state) => {
|
|
481
|
-
if (element.type === "single" && element.cbor.type === MajorType.Text) {
|
|
482
|
-
return [{ texts: [...state.texts, element.cbor.value] }, false];
|
|
483
|
-
}
|
|
484
|
-
return [state, false];
|
|
485
|
-
});
|
|
486
|
-
|
|
487
|
-
return result.texts;
|
|
488
|
-
};
|
|
489
|
-
|
|
490
|
-
/**
|
|
491
|
-
* Helper: Get the maximum depth of a CBOR tree.
|
|
492
|
-
*
|
|
493
|
-
* @param cbor - The CBOR value to measure
|
|
494
|
-
* @returns Maximum depth (0 for leaf values, 1+ for containers)
|
|
495
|
-
*
|
|
496
|
-
* @example
|
|
497
|
-
* ```typescript
|
|
498
|
-
* const flat = cbor([1, 2, 3]);
|
|
499
|
-
* console.log(maxDepth(flat)); // 1
|
|
500
|
-
*
|
|
501
|
-
* const nested = cbor([[[1]]]);
|
|
502
|
-
* console.log(maxDepth(nested)); // 3
|
|
503
|
-
* ```
|
|
504
|
-
*/
|
|
505
|
-
export const maxDepth = (cbor: Cbor): number => {
|
|
506
|
-
interface DepthState {
|
|
507
|
-
maxDepth: number;
|
|
508
|
-
}
|
|
509
|
-
|
|
510
|
-
const result = walk<DepthState>(cbor, { maxDepth: 0 }, (_element, level, _edge, state) => {
|
|
511
|
-
const newMaxDepth = Math.max(state.maxDepth, level);
|
|
512
|
-
return [{ maxDepth: newMaxDepth }, false];
|
|
513
|
-
});
|
|
514
|
-
|
|
515
|
-
return result.maxDepth;
|
|
516
|
-
};
|