deep6 1.1.3 → 1.2.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 (48) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +44 -38
  3. package/llms-full.txt +371 -0
  4. package/llms.txt +154 -0
  5. package/package.json +31 -109
  6. package/src/env.d.ts +174 -0
  7. package/src/env.js +4 -4
  8. package/src/index.d.ts +86 -0
  9. package/src/index.js +10 -7
  10. package/src/traverse/assemble.d.ts +59 -0
  11. package/src/traverse/assemble.js +4 -3
  12. package/src/traverse/clone.d.ts +57 -0
  13. package/src/traverse/clone.js +4 -2
  14. package/src/traverse/deref.d.ts +59 -0
  15. package/src/traverse/deref.js +3 -2
  16. package/src/traverse/preprocess.d.ts +65 -0
  17. package/src/traverse/preprocess.js +2 -1
  18. package/src/traverse/walk.d.ts +219 -0
  19. package/src/traverse/walk.js +9 -4
  20. package/src/unifiers/matchCondition.d.ts +45 -0
  21. package/src/unifiers/matchCondition.js +1 -0
  22. package/src/unifiers/matchInstanceOf.d.ts +37 -0
  23. package/src/unifiers/matchInstanceOf.js +1 -0
  24. package/src/unifiers/matchString.d.ts +56 -0
  25. package/src/unifiers/matchString.js +1 -0
  26. package/src/unifiers/matchTypeOf.d.ts +37 -0
  27. package/src/unifiers/matchTypeOf.js +1 -0
  28. package/src/unifiers/ref.d.ts +52 -0
  29. package/src/unifiers/ref.js +1 -0
  30. package/src/unify.d.ts +95 -0
  31. package/src/unify.js +130 -66
  32. package/src/utils/replaceVars.d.ts +25 -0
  33. package/src/utils/replaceVars.js +23 -19
  34. package/cjs/env.js +0 -227
  35. package/cjs/index.js +0 -57
  36. package/cjs/package.json +0 -1
  37. package/cjs/traverse/assemble.js +0 -145
  38. package/cjs/traverse/clone.js +0 -94
  39. package/cjs/traverse/deref.js +0 -102
  40. package/cjs/traverse/preprocess.js +0 -96
  41. package/cjs/traverse/walk.js +0 -330
  42. package/cjs/unifiers/matchCondition.js +0 -25
  43. package/cjs/unifiers/matchInstanceOf.js +0 -25
  44. package/cjs/unifiers/matchString.js +0 -49
  45. package/cjs/unifiers/matchTypeOf.js +0 -25
  46. package/cjs/unifiers/ref.js +0 -30
  47. package/cjs/unify.js +0 -549
  48. package/cjs/utils/replaceVars.js +0 -37
package/package.json CHANGED
@@ -1,100 +1,22 @@
1
1
  {
2
2
  "name": "deep6",
3
- "version": "1.1.3",
4
- "description": "No dependency mini-library: unification, deep equivalence, deep cloning.",
3
+ "version": "1.2.0",
4
+ "description": "deep6 is a no-dependency ES6 mini-library for advanced deep equivalence, unification, and cloning of JavaScript structures. Supports extensible pattern matching, circular reference handling, Map, Set, URL, typed arrays, symbols, and property descriptors.",
5
5
  "type": "module",
6
- "module": "src/index.js",
7
- "main": "cjs/index.js",
6
+ "main": "src/index.js",
8
7
  "exports": {
9
- ".": {
10
- "require": "./cjs/index.js",
11
- "default": "./src/index.js"
12
- },
13
- "./*": {
14
- "require": "./cjs/*",
15
- "default": "./src/*"
16
- },
17
- "./env.js": {
18
- "require": "./cjs/env.js",
19
- "default": "./src/env.js"
20
- },
21
- "./index.js": {
22
- "require": "./cjs/index.js",
23
- "default": "./src/index.js"
24
- },
25
- "./unify.js": {
26
- "require": "./cjs/unify.js",
27
- "default": "./src/unify.js"
28
- },
29
- "./unifiers/matchConditions.js": {
30
- "require": "./cjs/unifiers/matchConditions.js",
31
- "default": "./src/unifiers/matchConditions.js"
32
- },
33
- "./unifiers/matchInstanceOf.js": {
34
- "require": "./cjs/unifiers/matchInstanceOf.js",
35
- "default": "./src/unifiers/matchInstanceOf.js"
36
- },
37
- "./unifiers/matchString.js": {
38
- "require": "./cjs/unifiers/matchString.js",
39
- "default": "./src/unifiers/matchString.js"
40
- },
41
- "./unifiers/matchTypeOf.js": {
42
- "require": "./cjs/unifiers/matchTypeOf.js",
43
- "default": "./src/unifiers/matchTypeOf.js"
44
- },
45
- "./unifiers/ref.js": {
46
- "require": "./cjs/unifiers/ref.js",
47
- "default": "./src/unifiers/ref.js"
48
- },
49
- "./traverse/assemble.js": {
50
- "require": "./cjs/traverse/assemble.js",
51
- "default": "./src/traverse/assemble.js"
52
- },
53
- "./traverse/clone.js": {
54
- "require": "./cjs/traverse/clone.js",
55
- "default": "./src/traverse/clone.js"
56
- },
57
- "./traverse/deref.js": {
58
- "require": "./cjs/traverse/deref.js",
59
- "default": "./src/traverse/deref.js"
60
- },
61
- "./traverse/preprocess.js": {
62
- "require": "./cjs/traverse/preprocess.js",
63
- "default": "./src/traverse/preprocess.js"
64
- },
65
- "./traverse/walk.js": {
66
- "require": "./cjs/traverse/walk.js",
67
- "default": "./src/traverse/walk.js"
68
- },
69
- "./utils/replaceVars.js": {
70
- "require": "./cjs/utils/replaceVars.js",
71
- "default": "./src/utils/replaceVars.js"
72
- },
73
- "./cjs": "./cjs/index.js",
74
- "./cjs/*": "./cjs/*",
75
- "./cjs/env.js": "./cjs/env.js",
76
- "./cjs/index.js": "./cjs/index.js",
77
- "./cjs/unify.js": "./cjs/unify.js",
78
- "./cjs/unifiers/matchConditions.js": "./cjs/unifiers/matchConditions.js",
79
- "./cjs/unifiers/matchInstanceOf.js": "./cjs/unifiers/matchInstanceOf.js",
80
- "./cjs/unifiers/matchString.js": "./cjs/unifiers/matchString.js",
81
- "./cjs/unifiers/matchTypeOf.js": "./cjs/unifiers/matchTypeOf.js",
82
- "./cjs/unifiers/ref.js": "./cjs/unifiers/ref.js",
83
- "./cjs/traverse/assemble.js": "./cjs/traverse/assemble.js",
84
- "./cjs/traverse/clone.js": "./cjs/traverse/clone.js",
85
- "./cjs/traverse/deref.js": "./cjs/traverse/deref.js",
86
- "./cjs/traverse/preprocess.js": "./cjs/traverse/preprocess.js",
87
- "./cjs/traverse/walk.js": "./cjs/traverse/walk.js",
88
- "./cjs/utils/replaceVars.js": "./cjs/utils/replaceVars.js"
8
+ ".": "./src/index.js",
9
+ "./*": "./src/*"
89
10
  },
90
11
  "scripts": {
91
12
  "start": "node tests/server.js --trace",
92
13
  "test": "node tests/tests.js",
14
+ "test:bun": "bun run tests/tests.js",
15
+ "test:deno": "deno run --allow-read tests/tests.js",
93
16
  "debug": "node --inspect-brk tests/tests.js",
94
- "prepareDist": "node scripts/prepareDist.js",
95
- "babel": "babel src --out-dir cjs",
96
- "build": "npm run prepareDist && npm run babel",
97
- "prepublishOnly": "npm run build"
17
+ "ts-check": "tsc --noEmit",
18
+ "lint": "prettier --check .",
19
+ "lint:fix": "prettier --write ."
98
20
  },
99
21
  "repository": {
100
22
  "type": "git",
@@ -102,36 +24,36 @@
102
24
  },
103
25
  "keywords": [
104
26
  "deep",
105
- "unification",
106
- "equivalence",
107
- "comparison",
108
27
  "deep equivalence",
28
+ "deep equality",
29
+ "deep compare",
30
+ "unification",
31
+ "unify",
32
+ "pattern matching",
33
+ "pattern match",
34
+ "wildcard",
109
35
  "clone",
110
36
  "deep clone",
111
37
  "deep cloning",
112
- "traversing"
38
+ "copy",
39
+ "deep copy",
40
+ "traversing",
41
+ "traverse",
42
+ "walk",
43
+ "logical variables",
44
+ "es6",
45
+ "no dependencies"
113
46
  ],
114
47
  "author": "Eugene Lazutkin <eugene.lazutkin@gmail.com> (https://www.lazutkin.com/)",
48
+ "funding": "https://github.com/sponsors/uhop",
115
49
  "license": "BSD-3-Clause",
116
- "devDependencies": {
117
- "@babel/cli": "^7.14.5",
118
- "@babel/core": "^7.14.6",
119
- "@babel/preset-env": "^7.14.7"
120
- },
121
50
  "files": [
122
51
  "/src",
123
- "/cjs"
52
+ "llms.txt",
53
+ "llms-full.txt"
124
54
  ],
125
- "babel": {
126
- "presets": [
127
- [
128
- "@babel/preset-env",
129
- {
130
- "targets": {
131
- "node": "current"
132
- }
133
- }
134
- ]
135
- ]
55
+ "devDependencies": {
56
+ "prettier": "^3.8.1",
57
+ "typescript": "^6.0.2"
136
58
  }
137
59
  }
package/src/env.d.ts ADDED
@@ -0,0 +1,174 @@
1
+ // Type definitions for deep6 environment
2
+ // Generated from src/env.js
3
+
4
+ /**
5
+ * Unification environment managing variable bindings and stack frames
6
+ *
7
+ * Maintains two parallel prototype-chain structures:
8
+ * - `variables`: maps variable names to their alias groups
9
+ * - `values`: maps variable names/aliases to their bound values
10
+ *
11
+ * Stack frames enable scoped bindings that can be reverted.
12
+ */
13
+ export declare class Env {
14
+ /** Map of variable names to their alias groups */
15
+ variables: Record<string | symbol, unknown>;
16
+ /** Map of variable names/aliases to their bound values */
17
+ values: Record<string | symbol, unknown>;
18
+ /** Current stack frame depth */
19
+ depth: number;
20
+
21
+ constructor();
22
+
23
+ /** Pushes a new stack frame for nested scoping */
24
+ push(): void;
25
+
26
+ /**
27
+ * Pops the current stack frame, reverting bindings
28
+ * @throws {Error} If stack is empty
29
+ */
30
+ pop(): void;
31
+
32
+ /**
33
+ * Reverts to a specific stack frame depth
34
+ * @param depth - Target depth to revert to
35
+ * @throws {Error} If depth is higher than current depth
36
+ */
37
+ revert(depth: number): void;
38
+
39
+ /**
40
+ * Creates an alias between two variable names
41
+ * @param name1 - First variable name
42
+ * @param name2 - Second variable name
43
+ */
44
+ bindVar(name1: string | symbol, name2: string | symbol): void;
45
+
46
+ /**
47
+ * Binds a variable name (and its aliases) to a value
48
+ * @param name - Variable name to bind
49
+ * @param val - Value to bind
50
+ */
51
+ bindVal(name: string | symbol, val: unknown): void;
52
+
53
+ /**
54
+ * Checks if a variable is bound to a value
55
+ * @param name - Variable name to check
56
+ * @returns True if variable has a bound value
57
+ */
58
+ isBound(name: string | symbol): boolean;
59
+
60
+ /**
61
+ * Checks if two variable names are aliases
62
+ * @param name1 - First variable name
63
+ * @param name2 - Second variable name
64
+ * @returns True if variables are aliases
65
+ */
66
+ isAlias(name1: string | symbol, name2: string | symbol): boolean;
67
+
68
+ /**
69
+ * Gets the value bound to a variable
70
+ * @param name - Variable name
71
+ * @returns The bound value, or undefined if unbound
72
+ */
73
+ get(name: string | symbol): unknown;
74
+
75
+ /**
76
+ * Returns all variable bindings (for debugging)
77
+ * @returns Array of name/value pairs
78
+ */
79
+ getAllValues(): Array<{name: string | symbol; value: unknown}>;
80
+ }
81
+
82
+ /**
83
+ * Base class for custom unification behavior
84
+ *
85
+ * Subclasses must implement the `unify` method.
86
+ */
87
+ export declare class Unifier {
88
+ /**
89
+ * Unifies this unifier with a value
90
+ * @param val - Value to unify with
91
+ * @param ls - Left argument stack
92
+ * @param rs - Right argument stack
93
+ * @param env - Unification environment
94
+ * @returns True if unification succeeds
95
+ */
96
+ unify(val: unknown, ls: unknown[], rs: unknown[], env: Env): boolean;
97
+ }
98
+
99
+ /**
100
+ * Type guard for Unifier instances
101
+ * @param x - Value to check
102
+ * @returns True if x is a Unifier
103
+ */
104
+ export declare const isUnifier: (x: unknown) => x is Unifier;
105
+
106
+ /**
107
+ * Wildcard symbol that matches any value during unification
108
+ */
109
+ export declare const any: unique symbol;
110
+
111
+ /** Alias for `any` */
112
+ export declare const _: typeof any;
113
+
114
+ /**
115
+ * Logical variable for capturing values during unification
116
+ *
117
+ * Variables can be bound to values, aliased to other variables,
118
+ * and dereferenced through an Env.
119
+ */
120
+ export declare class Variable extends Unifier {
121
+ /** Variable identifier */
122
+ name: string | symbol;
123
+
124
+ /**
125
+ * @param name - Optional identifier (defaults to a unique Symbol)
126
+ */
127
+ constructor(name?: string | symbol);
128
+
129
+ /**
130
+ * Checks if this variable is bound in the given environment
131
+ * @param env - Unification environment
132
+ * @returns True if bound
133
+ */
134
+ isBound(env: Env): boolean;
135
+
136
+ /**
137
+ * Checks if this variable is aliased to another
138
+ * @param name - Variable name, symbol, or Variable instance
139
+ * @param env - Unification environment
140
+ * @returns True if aliased
141
+ */
142
+ isAlias(name: Variable | string | symbol, env: Env): boolean;
143
+
144
+ /**
145
+ * Gets the bound value of this variable
146
+ * @param env - Unification environment
147
+ * @returns The bound value, or undefined if unbound
148
+ */
149
+ get(env: Env): unknown;
150
+
151
+ /**
152
+ * Unifies this variable with a value
153
+ * @param val - Value to unify with
154
+ * @param ls - Left argument stack
155
+ * @param rs - Right argument stack
156
+ * @param env - Unification environment
157
+ * @returns True if unification succeeds
158
+ */
159
+ unify(val: unknown, ls: unknown[], rs: unknown[], env: Env): boolean;
160
+ }
161
+
162
+ /**
163
+ * Type guard for Variable instances
164
+ * @param x - Value to check
165
+ * @returns True if x is a Variable
166
+ */
167
+ export declare const isVariable: (x: unknown) => x is Variable;
168
+
169
+ /**
170
+ * Creates a new Variable
171
+ * @param name - Optional identifier (defaults to a unique Symbol)
172
+ * @returns A new Variable instance
173
+ */
174
+ export declare const variable: (name?: string | symbol) => Variable;
package/src/env.js CHANGED
@@ -13,7 +13,7 @@ const collectSymbols = object => {
13
13
  };
14
14
 
15
15
  const ensure = (object, depth) => {
16
- while (object[keyDepth] > depth) object = object.getPrototypeOf(object);
16
+ while (object[keyDepth] > depth) object = Object.getPrototypeOf(object);
17
17
  if (object[keyDepth] < depth) {
18
18
  object = Object.create(object);
19
19
  object[keyDepth] = depth;
@@ -90,14 +90,14 @@ class Env {
90
90
  }
91
91
  // helpers
92
92
  isBound(name) {
93
- return name in env.values;
93
+ return name in this.values;
94
94
  }
95
95
  isAlias(name1, name2) {
96
- const u = env.variables[name2];
96
+ const u = this.variables[name2];
97
97
  return u && u[name1] === 1;
98
98
  }
99
99
  get(name) {
100
- return env.values[name];
100
+ return this.values[name];
101
101
  }
102
102
  // debugging
103
103
  getAllValues() {
package/src/index.d.ts ADDED
@@ -0,0 +1,86 @@
1
+ // Type definitions for deep6
2
+ // Generated from src/index.js
3
+
4
+ /**
5
+ * Options for deep equality comparison
6
+ */
7
+ export interface EqualOptions {
8
+ /** Handle circular references (default: true) */
9
+ circular?: boolean;
10
+ /** Include symbol properties (default: false) */
11
+ symbols?: boolean;
12
+ /** Use loose equality for primitives (default: false) */
13
+ loose?: boolean;
14
+ /** Ignore function properties (default: false) */
15
+ ignoreFunctions?: boolean;
16
+ /** Distinguish +0 from -0 (default: false) */
17
+ signedZero?: boolean;
18
+ }
19
+
20
+ /**
21
+ * Options for pattern matching
22
+ */
23
+ export interface MatchOptions {
24
+ /** Allow extra keys on target objects (default: true) */
25
+ openObjects?: boolean;
26
+ /** Allow extra entries in target Maps (default: true) */
27
+ openMaps?: boolean;
28
+ /** Allow extra entries in target Sets (default: true) */
29
+ openSets?: boolean;
30
+ /** Allow extra elements in target arrays (default: false) */
31
+ openArrays?: boolean;
32
+ /** Handle circular references (default: true) */
33
+ circular?: boolean;
34
+ /** Include symbol properties (default: false) */
35
+ symbols?: boolean;
36
+ /** Use loose equality for primitives (default: false) */
37
+ loose?: boolean;
38
+ /** Ignore function properties (default: false) */
39
+ ignoreFunctions?: boolean;
40
+ }
41
+
42
+ /**
43
+ * Options for deep cloning via the main API
44
+ */
45
+ export interface CloneOptions {
46
+ /** Handle circular references (default: true) */
47
+ circular?: boolean;
48
+ /** Clone symbol properties (default: false) */
49
+ symbols?: boolean;
50
+ /** Clone non-enumerable properties (default: false) */
51
+ allProps?: boolean;
52
+ }
53
+
54
+ /**
55
+ * Deep equality check using unification
56
+ * @param a - First value
57
+ * @param b - Second value
58
+ * @param options - Comparison options
59
+ * @returns True if values are deeply equal
60
+ */
61
+ export declare const equal: (a: unknown, b: unknown, options?: EqualOptions) => boolean;
62
+
63
+ /**
64
+ * Deep clone of a value
65
+ * @param a - Value to clone
66
+ * @param options - Cloning options
67
+ * @returns Deep copy of the value
68
+ */
69
+ export declare const clone: <T>(a: T, options?: CloneOptions) => T;
70
+
71
+ /**
72
+ * Pattern matching with wildcards
73
+ * @param object - Value to test
74
+ * @param pattern - Pattern to match against
75
+ * @param options - Matching options
76
+ * @returns True if object matches the pattern
77
+ */
78
+ export declare const match: (object: unknown, pattern: unknown, options?: MatchOptions) => boolean;
79
+
80
+ /** Alias for `match` */
81
+ export declare const isShape: typeof match;
82
+
83
+ export {any, _} from './env.js';
84
+
85
+ /** Default export — deep equality function */
86
+ export default equal;
package/src/index.js CHANGED
@@ -7,13 +7,16 @@ const defaultOptions = {circular: true};
7
7
  const equal = (a, b, options = defaultOptions) => !!unify(a, b, null, options);
8
8
 
9
9
  const defaultMatchOptions = {openObjects: true, openMaps: true, openSets: true, circular: true};
10
- const match = (object, pattern, options = defaultMatchOptions) =>
11
- !!unify(object, preprocess(pattern, options), null, {
12
- circular: options.circular,
13
- symbols: options.symbols,
14
- loose: options.loose,
15
- ignoreFunctions: options.ignoreFunctions
16
- });
10
+ const match = (object, pattern, options = defaultMatchOptions) => {
11
+ const processedPattern = preprocess(pattern, options),
12
+ unifyOptions = {
13
+ circular: options.circular,
14
+ symbols: options.symbols,
15
+ loose: options.loose,
16
+ ignoreFunctions: options.ignoreFunctions
17
+ };
18
+ return !!unify(object, processedPattern, null, unifyOptions);
19
+ };
17
20
 
18
21
  const clone = (a, options = defaultOptions) => originalClone(a, null, options);
19
22
 
@@ -0,0 +1,59 @@
1
+ // Type definitions for deep6 assemble
2
+ // Generated from src/traverse/assemble.js
3
+
4
+ import type {Env} from '../env.js';
5
+ import type {WalkContext} from './walk.js';
6
+
7
+ /**
8
+ * Options for assembly
9
+ */
10
+ export interface AssembleOptions {
11
+ /** Handle circular references (default: false) */
12
+ circular?: boolean;
13
+ /** Include symbol properties (default: false) */
14
+ symbols?: boolean;
15
+ /** Include non-enumerable properties (default: false) */
16
+ allProps?: boolean;
17
+ /** Custom context object */
18
+ context?: Record<string, unknown>;
19
+ /** Custom object processor */
20
+ processObject?: (object: unknown, context: WalkContext) => void;
21
+ /** Custom non-object value processor */
22
+ processOther?: (value: unknown, context: WalkContext) => void;
23
+ /** Custom circular reference processor */
24
+ processCircular?: (value: unknown, context: WalkContext) => void;
25
+ /** Custom type handler registry (flat array of [Constructor, handler] pairs) */
26
+ registry?: unknown[];
27
+ /** Custom filter functions */
28
+ filters?: Array<(val: unknown, context: WalkContext) => boolean>;
29
+ }
30
+
31
+ /**
32
+ * Flat array of type-specific assembler pairs: [Constructor, handler, ...]
33
+ *
34
+ * Use `registry.push(Type, handler)` to register a custom assembler.
35
+ */
36
+ export declare const registry: unknown[];
37
+
38
+ /**
39
+ * Filter functions for custom assembly processing
40
+ */
41
+ export declare const filters: Array<(val: unknown, context: WalkContext) => boolean>;
42
+
43
+ /**
44
+ * Replaces variables with their bound values from an environment
45
+ *
46
+ * Creates a new structure only when values differ from the source.
47
+ * Unbound variables are kept as-is.
48
+ *
49
+ * @param source - Value containing variables to resolve
50
+ * @param env - Env with bindings, or options object
51
+ * @param options - Assembly options (when env is provided separately)
52
+ * @returns New value with variables replaced, or original if unchanged
53
+ */
54
+ export declare const assemble: ((source: unknown, env?: Env | AssembleOptions | null, options?: AssembleOptions) => unknown) & {
55
+ registry: unknown[];
56
+ filters: Array<(val: unknown, context: WalkContext) => boolean>;
57
+ };
58
+
59
+ export default assemble;
@@ -52,7 +52,7 @@ function postProcessSeen(context) {
52
52
  }
53
53
  }
54
54
 
55
- const postProcessMap = context => {
55
+ function postProcessMap(context) {
56
56
  const stackOut = context.stackOut,
57
57
  s = this.s;
58
58
  let j = stackOut.length - 1;
@@ -65,7 +65,7 @@ const postProcessMap = context => {
65
65
  } else {
66
66
  replaceObject(j, s, stackOut);
67
67
  }
68
- };
68
+ }
69
69
 
70
70
  function postProcessMapSeen(context) {
71
71
  const stackOut = context.stackOut,
@@ -108,6 +108,7 @@ const registry = [
108
108
 
109
109
  const addType = (Type, process) => registry.push(Type, process || processOther);
110
110
 
111
+ typeof URL == 'function' && addType(URL);
111
112
  typeof Int8Array == 'function' && addType(Int8Array);
112
113
  typeof Uint8Array == 'function' && addType(Uint8Array);
113
114
  typeof Uint8ClampedArray == 'function' && addType(Uint8ClampedArray);
@@ -154,5 +155,5 @@ const assemble = (source, env, options) => {
154
155
  assemble.registry = registry;
155
156
  assemble.filters = filters;
156
157
 
157
- export {registry, filters};
158
+ export {registry, filters, assemble};
158
159
  export default assemble;
@@ -0,0 +1,57 @@
1
+ // Type definitions for deep6 clone
2
+ // Generated from src/traverse/clone.js
3
+
4
+ import type {Env} from '../env.js';
5
+ import type {WalkContext} from './walk.js';
6
+
7
+ /**
8
+ * Options for deep cloning
9
+ */
10
+ export interface CloneOptions {
11
+ /** Handle circular references (default: true in main API) */
12
+ circular?: boolean;
13
+ /** Clone symbol properties (default: false) */
14
+ symbols?: boolean;
15
+ /** Clone non-enumerable properties (default: false) */
16
+ allProps?: boolean;
17
+ /** Custom context object */
18
+ context?: Record<string, unknown>;
19
+ /** Custom object processor */
20
+ processObject?: (object: unknown, context: WalkContext) => void;
21
+ /** Custom non-object value processor */
22
+ processOther?: (value: unknown, context: WalkContext) => void;
23
+ /** Custom circular reference processor */
24
+ processCircular?: (value: unknown, context: WalkContext) => void;
25
+ /** Custom type handler registry (flat array of [Constructor, handler] pairs) */
26
+ registry?: unknown[];
27
+ /** Custom filter functions — return true to indicate value was handled */
28
+ filters?: Array<(val: unknown, context: WalkContext) => boolean>;
29
+ }
30
+
31
+ /**
32
+ * Flat array of type-specific cloner pairs: [Constructor, handler, Constructor, handler, ...]
33
+ *
34
+ * Use `registry.push(Type, handler)` to register a custom type cloner.
35
+ * Handler signature: `(val, context) => void` (push result to context.stackOut)
36
+ */
37
+ export declare const registry: unknown[];
38
+
39
+ /**
40
+ * Filter functions for custom clone processing — return true to indicate value was handled
41
+ */
42
+ export declare const filters: Array<(val: unknown, context: WalkContext) => boolean>;
43
+
44
+ /**
45
+ * Deep clones a value with circular reference handling
46
+ *
47
+ * @param source - Value to clone
48
+ * @param env - Optional Env for variable resolution, or options object
49
+ * @param options - Cloning options (when env is provided separately)
50
+ * @returns Deep copy of the value
51
+ */
52
+ export declare const clone: (<T>(source: T, env?: Env | CloneOptions | null, options?: CloneOptions) => T) & {
53
+ registry: unknown[];
54
+ filters: Array<(val: unknown, context: WalkContext) => boolean>;
55
+ };
56
+
57
+ export default clone;
@@ -45,7 +45,7 @@ const registry = [
45
45
  Date,
46
46
  (val, context) => context.stackOut.push(new Date(val.getTime())),
47
47
  RegExp,
48
- (val, context) => context.stackOut.push(new RegExp(val.source, (val.global ? 'g' : '') + (val.multiline ? 'm' : '') + (val.ignoreCase ? 'i' : ''))),
48
+ (val, context) => context.stackOut.push(new RegExp(val.source, val.flags)),
49
49
  Map,
50
50
  processMap(postProcessMap, postProcessMapSeen),
51
51
  Promise,
@@ -53,6 +53,8 @@ const registry = [
53
53
  ],
54
54
  filters = [];
55
55
 
56
+ typeof URL == 'function' && registry.push(URL, (val, context) => context.stackOut.push(new URL(val.href)));
57
+
56
58
  // add more types
57
59
 
58
60
  const addType = (Type, process) => registry.push(Type, process || ((val, context) => context.stackOut.push(new Type(val))));
@@ -105,5 +107,5 @@ const clone = (source, env, options) => {
105
107
  clone.registry = registry;
106
108
  clone.filters = filters;
107
109
 
108
- export {registry, filters};
110
+ export {registry, filters, clone};
109
111
  export default clone;