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.
- package/LICENSE +1 -1
- package/README.md +44 -38
- package/llms-full.txt +371 -0
- package/llms.txt +154 -0
- package/package.json +31 -109
- package/src/env.d.ts +174 -0
- package/src/env.js +4 -4
- package/src/index.d.ts +86 -0
- package/src/index.js +10 -7
- package/src/traverse/assemble.d.ts +59 -0
- package/src/traverse/assemble.js +4 -3
- package/src/traverse/clone.d.ts +57 -0
- package/src/traverse/clone.js +4 -2
- package/src/traverse/deref.d.ts +59 -0
- package/src/traverse/deref.js +3 -2
- package/src/traverse/preprocess.d.ts +65 -0
- package/src/traverse/preprocess.js +2 -1
- package/src/traverse/walk.d.ts +219 -0
- package/src/traverse/walk.js +9 -4
- package/src/unifiers/matchCondition.d.ts +45 -0
- package/src/unifiers/matchCondition.js +1 -0
- package/src/unifiers/matchInstanceOf.d.ts +37 -0
- package/src/unifiers/matchInstanceOf.js +1 -0
- package/src/unifiers/matchString.d.ts +56 -0
- package/src/unifiers/matchString.js +1 -0
- package/src/unifiers/matchTypeOf.d.ts +37 -0
- package/src/unifiers/matchTypeOf.js +1 -0
- package/src/unifiers/ref.d.ts +52 -0
- package/src/unifiers/ref.js +1 -0
- package/src/unify.d.ts +95 -0
- package/src/unify.js +130 -66
- package/src/utils/replaceVars.d.ts +25 -0
- package/src/utils/replaceVars.js +23 -19
- package/cjs/env.js +0 -227
- package/cjs/index.js +0 -57
- package/cjs/package.json +0 -1
- package/cjs/traverse/assemble.js +0 -145
- package/cjs/traverse/clone.js +0 -94
- package/cjs/traverse/deref.js +0 -102
- package/cjs/traverse/preprocess.js +0 -96
- package/cjs/traverse/walk.js +0 -330
- package/cjs/unifiers/matchCondition.js +0 -25
- package/cjs/unifiers/matchInstanceOf.js +0 -25
- package/cjs/unifiers/matchString.js +0 -49
- package/cjs/unifiers/matchTypeOf.js +0 -25
- package/cjs/unifiers/ref.js +0 -30
- package/cjs/unify.js +0 -549
- package/cjs/utils/replaceVars.js +0 -37
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
# deep6 [![NPM version][npm-image]][npm-url]
|
|
2
2
|
|
|
3
3
|
[npm-image]: https://img.shields.io/npm/v/deep6.svg
|
|
4
|
-
[npm-url]:
|
|
4
|
+
[npm-url]: https://npmjs.org/package/deep6
|
|
5
5
|
|
|
6
6
|
`deep6` is a no-dependency ES6 mini-library:
|
|
7
7
|
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
8
|
+
- Advanced deep equivalency for JavaScript structures.
|
|
9
|
+
- Extensible to accommodate custom objects.
|
|
10
|
+
- Traversing objects.
|
|
11
|
+
- Extensible deep cloning.
|
|
12
|
+
- Written in ES6:
|
|
13
|
+
- Use it in Node or browsers without transpiling.
|
|
14
|
+
- Natively supports `Map`, `Set`, typed arrays.
|
|
15
|
+
- Natively supports symbols and property descriptors.
|
|
16
|
+
- Presented as ES6 modules.
|
|
17
|
+
- Efficient non-recursive algorithms.
|
|
18
|
+
- ~550 tests to ensure correctness.
|
|
19
|
+
- Support for circular dependencies.
|
|
20
|
+
- Support for "loose" comparisons.
|
|
21
|
+
- Unification.
|
|
22
|
+
- Identifying and capturing object fragments.
|
|
23
23
|
|
|
24
24
|
## Intro
|
|
25
25
|
|
|
@@ -29,19 +29,19 @@ import equal, {match, clone, any} from 'deep6';
|
|
|
29
29
|
const x = {a: 1, b: 2, c: ['hi!', 42, null, {}]};
|
|
30
30
|
|
|
31
31
|
// deep equality
|
|
32
|
-
equal(x, {b: 2, a: 1, c: ['hi!', 42, null, {}]});
|
|
32
|
+
equal(x, {b: 2, a: 1, c: ['hi!', 42, null, {}]}); // true
|
|
33
33
|
equal(x, {b: 2, a: 1, c: ['hi!', 42, null, {z: 1}]}); // false
|
|
34
34
|
|
|
35
35
|
// pattern matching
|
|
36
|
-
match(x, {a: 1});
|
|
37
|
-
match(x, {z: 1});
|
|
36
|
+
match(x, {a: 1}); // true
|
|
37
|
+
match(x, {z: 1}); // false
|
|
38
38
|
match(x, {a: 1, c: any}); // true
|
|
39
|
-
match(x, {a: 1, c: []});
|
|
39
|
+
match(x, {a: 1, c: []}); // false
|
|
40
40
|
match(x, {a: 1, d: any}); // false
|
|
41
41
|
|
|
42
42
|
// deep cloning
|
|
43
43
|
const y = clone(x);
|
|
44
|
-
equal(x, y);
|
|
44
|
+
equal(x, y); // true
|
|
45
45
|
|
|
46
46
|
// circular dependencies are fine
|
|
47
47
|
const z = {},
|
|
@@ -49,15 +49,15 @@ const z = {},
|
|
|
49
49
|
z.z = z;
|
|
50
50
|
w.z = w;
|
|
51
51
|
const p = clone(w);
|
|
52
|
-
equal(z, w);
|
|
53
|
-
equal(z, p);
|
|
52
|
+
equal(z, w); // true
|
|
53
|
+
equal(z, p); // true
|
|
54
54
|
|
|
55
55
|
// more standard types
|
|
56
56
|
const m = {a: new Map(), b: Buffer.from([99, 98, 97])};
|
|
57
57
|
m.a.set('a', [Symbol(), new Set([1, 2, 3])]);
|
|
58
58
|
m.a.set('b', [/^abc/i, new Date()]);
|
|
59
59
|
const n = clone(m);
|
|
60
|
-
equal(m, n);
|
|
60
|
+
equal(m, n); // true
|
|
61
61
|
|
|
62
62
|
// advanced: symbols
|
|
63
63
|
const s = Symbol(),
|
|
@@ -71,11 +71,11 @@ equal(t, v, {symbols: true}); // true
|
|
|
71
71
|
const r = {a: 1};
|
|
72
72
|
Object.defineProperty(r, 'b', {value: 2, enumerable: false});
|
|
73
73
|
const q = clone(r, {allProps: true});
|
|
74
|
-
r === q;
|
|
75
|
-
equal(r, {a: 1});
|
|
76
|
-
equal(r, {a: 1, b: 2});
|
|
77
|
-
r.a === q.a;
|
|
78
|
-
r.b === q.b;
|
|
74
|
+
r === q; // false
|
|
75
|
+
equal(r, {a: 1}); // true
|
|
76
|
+
equal(r, {a: 1, b: 2}); // false
|
|
77
|
+
r.a === q.a; // true
|
|
78
|
+
r.b === q.b; // true
|
|
79
79
|
```
|
|
80
80
|
|
|
81
81
|
## Docs
|
|
@@ -95,16 +95,22 @@ import matchString from 'deep6/unifiers/matchString';
|
|
|
95
95
|
```
|
|
96
96
|
|
|
97
97
|
```js
|
|
98
|
-
// CommonJS
|
|
99
|
-
const {equal, clone} = require('deep6
|
|
100
|
-
const matchString = require('deep6/
|
|
98
|
+
// CommonJS module
|
|
99
|
+
const {equal, clone} = require('deep6');
|
|
100
|
+
const matchString = require('deep6/unifiers/matchString');
|
|
101
101
|
```
|
|
102
102
|
|
|
103
|
+
## License
|
|
104
|
+
|
|
105
|
+
BSD-3-Clause
|
|
106
|
+
|
|
103
107
|
## Release History
|
|
104
108
|
|
|
105
|
-
- 1.
|
|
106
|
-
- 1.1.
|
|
107
|
-
- 1.1.
|
|
108
|
-
- 1.1.
|
|
109
|
-
- 1.
|
|
110
|
-
- 1.
|
|
109
|
+
- 1.2.0 _added `URL` support, bug fixes (RegExp flag comparison, Map assembly/deref, `env.ensure()`), performance optimizations, improved TypeScript typings, expanded tests (~573)._
|
|
110
|
+
- 1.1.4 _updated dev deps._
|
|
111
|
+
- 1.1.3 _updated dev deps._
|
|
112
|
+
- 1.1.2 _updated dev deps._
|
|
113
|
+
- 1.1.1 _reformulated `any` as a well-known symbol._
|
|
114
|
+
- 1.1.0 _separated from [yopl](https://npmjs.org/package/yopl), extensive refactoring._
|
|
115
|
+
- 1.0.1 _added the exports statement._
|
|
116
|
+
- 1.0.0 _the first 1.0 release._
|
package/llms-full.txt
ADDED
|
@@ -0,0 +1,371 @@
|
|
|
1
|
+
# deep6 — Full LLM Reference
|
|
2
|
+
|
|
3
|
+
> No-dependency ES6 mini-library for advanced deep equivalence, unification, and cloning of JavaScript structures. Supports extensible pattern matching, circular reference handling, and complex objects including Map, Set, typed arrays, symbols, and property descriptors.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i deep6
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
// ESM
|
|
15
|
+
import equal, {clone, match, any} from 'deep6';
|
|
16
|
+
|
|
17
|
+
// CommonJS
|
|
18
|
+
const {equal, clone, match, any} = require('deep6');
|
|
19
|
+
|
|
20
|
+
const x = {a: 1, b: 2, c: ['hi!', 42, null, {}]};
|
|
21
|
+
|
|
22
|
+
// deep equality
|
|
23
|
+
equal(x, {b: 2, a: 1, c: ['hi!', 42, null, {}]}); // true
|
|
24
|
+
|
|
25
|
+
// pattern matching
|
|
26
|
+
match(x, {a: 1}); // true
|
|
27
|
+
match(x, {a: 1, c: any}); // true
|
|
28
|
+
|
|
29
|
+
// deep cloning
|
|
30
|
+
const y = clone(x);
|
|
31
|
+
equal(x, y); // true
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
## API Reference
|
|
35
|
+
|
|
36
|
+
### equal(a, b, options)
|
|
37
|
+
|
|
38
|
+
Deep equivalence check using unification. Returns `true` if structures can be unified.
|
|
39
|
+
|
|
40
|
+
```js
|
|
41
|
+
equal({a: 1}, {a: 1}); // true
|
|
42
|
+
equal({a: 1, b: 2}, {b: 2, a: 1}); // true (order independent)
|
|
43
|
+
equal(new Date('2020-01-01'), new Date('2020-01-01')); // true
|
|
44
|
+
equal(/abc/gi, /abc/gi); // true
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
Options:
|
|
48
|
+
- `circular: true` — handle circular references (default: true)
|
|
49
|
+
- `symbols: true` — compare symbol properties
|
|
50
|
+
- `loose: true` — use loose equality (`==`) for primitives
|
|
51
|
+
- `ignoreFunctions: true` — ignore function properties
|
|
52
|
+
- `signedZero: true` — distinguish +0 from -0
|
|
53
|
+
|
|
54
|
+
### clone(object, options)
|
|
55
|
+
|
|
56
|
+
Deep cloning with circular reference support.
|
|
57
|
+
|
|
58
|
+
```js
|
|
59
|
+
const x = {a: new Map(), b: Buffer.from([1, 2, 3])};
|
|
60
|
+
const y = clone(x);
|
|
61
|
+
equal(x, y); // true
|
|
62
|
+
```
|
|
63
|
+
|
|
64
|
+
Options:
|
|
65
|
+
- `circular: true` — handle circular references (default: true)
|
|
66
|
+
- `symbols: true` — clone symbol properties
|
|
67
|
+
- `allProps: true` — clone non-enumerable properties
|
|
68
|
+
|
|
69
|
+
### match(object, pattern)
|
|
70
|
+
|
|
71
|
+
Pattern matching with wildcards. Returns `true` if object matches pattern.
|
|
72
|
+
|
|
73
|
+
```js
|
|
74
|
+
match({a: 1, b: 2}, {a: 1}); // true (open match)
|
|
75
|
+
match({a: 1, b: 2}, {a: 1, c: any}); // false (c missing)
|
|
76
|
+
match({a: 1, b: 2}, {a: 1, b: any}); // true
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
Default options: `openObjects: true`, `openMaps: true`, `openSets: true`, `circular: true`
|
|
80
|
+
|
|
81
|
+
### unify(a, b, env, options)
|
|
82
|
+
|
|
83
|
+
Core unification algorithm. Returns `Env` on success, `null` on failure.
|
|
84
|
+
|
|
85
|
+
```js
|
|
86
|
+
import unify, {Variable, variable, any, _} from 'deep6/unify.js';
|
|
87
|
+
|
|
88
|
+
const v = variable();
|
|
89
|
+
const env = unify({a: 1, b: v}, {a: 1, b: 2});
|
|
90
|
+
// env.get(v) === 2
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
Options:
|
|
94
|
+
- `openObjects: true` — target can have extra keys
|
|
95
|
+
- `openMaps: true` — maps can have extra entries
|
|
96
|
+
- `openSets: true` — sets can have extra entries
|
|
97
|
+
- `openArrays: true` — arrays can have extra elements
|
|
98
|
+
- `circular: true` — handle circular references
|
|
99
|
+
- `loose: true` — use loose equality
|
|
100
|
+
- `ignoreFunctions: true` — ignore functions
|
|
101
|
+
- `symbols: true` — process symbol properties
|
|
102
|
+
|
|
103
|
+
### Wildcards
|
|
104
|
+
|
|
105
|
+
`any` (or `_`) matches any value:
|
|
106
|
+
|
|
107
|
+
```js
|
|
108
|
+
import {match, any, _} from 'deep6';
|
|
109
|
+
|
|
110
|
+
match({a: 1, b: 2}, {a: any}); // true
|
|
111
|
+
match({a: 1, b: 2}, {a: 1, b: _}); // true
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
### Wrap types
|
|
115
|
+
|
|
116
|
+
`open()` and `soft()` control matching strictness:
|
|
117
|
+
|
|
118
|
+
```js
|
|
119
|
+
import {match, open, soft} from 'deep6';
|
|
120
|
+
|
|
121
|
+
// open: pattern keys must exist, target can have extras
|
|
122
|
+
match({a: 1, b: 2}, open({a: 1})); // true
|
|
123
|
+
|
|
124
|
+
// soft: bidirectional open matching
|
|
125
|
+
match(soft({a: 1}), {a: 1, b: 2}); // true
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
### Variable
|
|
129
|
+
|
|
130
|
+
Logical variable for capturing values during unification:
|
|
131
|
+
|
|
132
|
+
```js
|
|
133
|
+
import {Variable, variable} from 'deep6/unify.js';
|
|
134
|
+
|
|
135
|
+
const v = variable();
|
|
136
|
+
const env = unify({a: 1, b: v}, {a: 1, b: 2});
|
|
137
|
+
|
|
138
|
+
v.isBound(env); // true
|
|
139
|
+
v.get(env); // 2
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
### Env
|
|
143
|
+
|
|
144
|
+
Unification environment managing variable bindings:
|
|
145
|
+
|
|
146
|
+
```js
|
|
147
|
+
import {Env} from 'deep6/env.js';
|
|
148
|
+
|
|
149
|
+
const env = new Env();
|
|
150
|
+
// env.depth, env.variables, env.values
|
|
151
|
+
// env.push(), env.pop(), env.revert(depth)
|
|
152
|
+
// env.bindVar(name1, name2), env.bindVal(name, val)
|
|
153
|
+
// env.get(name), env.isBound(name), env.isAlias(name1, name2)
|
|
154
|
+
```
|
|
155
|
+
|
|
156
|
+
### Unifier
|
|
157
|
+
|
|
158
|
+
Base class for custom unification behavior:
|
|
159
|
+
|
|
160
|
+
```js
|
|
161
|
+
import {Unifier} from 'deep6/env.js';
|
|
162
|
+
|
|
163
|
+
class MyMatcher extends Unifier {
|
|
164
|
+
unify(val, ls, rs, env) {
|
|
165
|
+
// return true for match, false for failure
|
|
166
|
+
// push to ls/rs to continue unification
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Unifiers
|
|
172
|
+
|
|
173
|
+
### matchString(regexp, matches, props)
|
|
174
|
+
|
|
175
|
+
Regex-based string matching:
|
|
176
|
+
|
|
177
|
+
```js
|
|
178
|
+
import matchString from 'deep6/unifiers/matchString.js';
|
|
179
|
+
|
|
180
|
+
const m = matchString(/^hello (\w+)$/, ['name'], {index: true, input: true});
|
|
181
|
+
match({greeting: 'hello world'}, {greeting: m}); // captures name
|
|
182
|
+
```
|
|
183
|
+
|
|
184
|
+
### matchTypeOf(type)
|
|
185
|
+
|
|
186
|
+
Match by `typeof`:
|
|
187
|
+
|
|
188
|
+
```js
|
|
189
|
+
import matchTypeOf from 'deep6/unifiers/matchTypeOf.js';
|
|
190
|
+
|
|
191
|
+
match({x: 42}, {x: matchTypeOf('number')}); // true
|
|
192
|
+
match({x: 'hi'}, {x: matchTypeOf('string')}); // true
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### matchInstanceOf(constructor)
|
|
196
|
+
|
|
197
|
+
Match by `instanceof`:
|
|
198
|
+
|
|
199
|
+
```js
|
|
200
|
+
import matchInstanceOf from 'deep6/unifiers/matchInstanceOf.js';
|
|
201
|
+
|
|
202
|
+
match({d: new Date()}, {d: matchInstanceOf(Date)}); // true
|
|
203
|
+
match({r: /abc/}, {r: matchInstanceOf(RegExp)}); // true
|
|
204
|
+
```
|
|
205
|
+
|
|
206
|
+
### matchCondition(predicate)
|
|
207
|
+
|
|
208
|
+
Match by custom predicate:
|
|
209
|
+
|
|
210
|
+
```js
|
|
211
|
+
import matchCondition from 'deep6/unifiers/matchCondition.js';
|
|
212
|
+
|
|
213
|
+
const isPositive = matchCondition(x => typeof x === 'number' && x > 0);
|
|
214
|
+
match({n: 5}, {n: isPositive}); // true
|
|
215
|
+
match({n: -1}, {n: isPositive}); // false
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
### ref()
|
|
219
|
+
|
|
220
|
+
Reference variable for cross-pattern matching:
|
|
221
|
+
|
|
222
|
+
```js
|
|
223
|
+
import ref from 'deep6/unifiers/ref.js';
|
|
224
|
+
|
|
225
|
+
const r = ref();
|
|
226
|
+
match({a: 1, b: 1}, {a: r, b: r}); // true (a and b are equal)
|
|
227
|
+
```
|
|
228
|
+
|
|
229
|
+
## Walker and Cloning
|
|
230
|
+
|
|
231
|
+
### walk(object, options)
|
|
232
|
+
|
|
233
|
+
Generic non-recursive object walker:
|
|
234
|
+
|
|
235
|
+
```js
|
|
236
|
+
import walk from 'deep6/traverse/walk.js';
|
|
237
|
+
|
|
238
|
+
walk(myObject, {
|
|
239
|
+
processObject: (obj, context) => { /* handle object */ },
|
|
240
|
+
processOther: (val, context) => { /* handle primitive */ },
|
|
241
|
+
registry: [[Date, (d, ctx) => ctx.stackOut.push(d)]],
|
|
242
|
+
circular: true
|
|
243
|
+
});
|
|
244
|
+
```
|
|
245
|
+
|
|
246
|
+
### clone.registry and unify.registry
|
|
247
|
+
|
|
248
|
+
Extensible registries for custom types:
|
|
249
|
+
|
|
250
|
+
```js
|
|
251
|
+
import unify from 'deep6/unify.js';
|
|
252
|
+
import clone from 'deep6/traverse/clone.js';
|
|
253
|
+
|
|
254
|
+
// Add unifier for custom type
|
|
255
|
+
unify.registry.push(MyClass, (l, r, ls, rs, env) => {
|
|
256
|
+
// return true for match, false for failure
|
|
257
|
+
});
|
|
258
|
+
|
|
259
|
+
// Add cloner for custom type
|
|
260
|
+
clone.registry.push(MyClass, (val, context) => {
|
|
261
|
+
context.stackOut.push(new MyClass(val));
|
|
262
|
+
});
|
|
263
|
+
```
|
|
264
|
+
|
|
265
|
+
### preprocess(pattern, options)
|
|
266
|
+
|
|
267
|
+
Pattern preprocessing for matching:
|
|
268
|
+
|
|
269
|
+
```js
|
|
270
|
+
import preprocess from 'deep6/traverse/preprocess.js';
|
|
271
|
+
|
|
272
|
+
const processed = preprocess({a: 1}, {openObjects: true});
|
|
273
|
+
// Returns Wrap instance with type metadata
|
|
274
|
+
```
|
|
275
|
+
|
|
276
|
+
## Project Structure
|
|
277
|
+
|
|
278
|
+
```
|
|
279
|
+
src/
|
|
280
|
+
├── index.js # Main entry: equal, clone, match, any, _
|
|
281
|
+
├── env.js # Env, Variable, Unifier, any, _
|
|
282
|
+
├── unify.js # Core unification algorithm
|
|
283
|
+
├── traverse/
|
|
284
|
+
│ ├── walk.js # Generic walker
|
|
285
|
+
│ ├── clone.js # Deep cloning
|
|
286
|
+
│ ├── preprocess.js # Pattern preprocessing
|
|
287
|
+
│ ├── assemble.js # Object assembly
|
|
288
|
+
│ └── deref.js # Dereferencing
|
|
289
|
+
├── unifiers/
|
|
290
|
+
│ ├── matchString.js
|
|
291
|
+
│ ├── matchTypeOf.js
|
|
292
|
+
│ ├── matchInstanceOf.js
|
|
293
|
+
│ ├── matchCondition.js
|
|
294
|
+
│ └── ref.js
|
|
295
|
+
└── utils/
|
|
296
|
+
└── replaceVars.js
|
|
297
|
+
```
|
|
298
|
+
|
|
299
|
+
## Commands
|
|
300
|
+
|
|
301
|
+
- `npm test` — run tests
|
|
302
|
+
- `npm run debug` — debug with Node inspector
|
|
303
|
+
|
|
304
|
+
## Code Style
|
|
305
|
+
|
|
306
|
+
- ES6 modules (`"type": "module"`)
|
|
307
|
+
- 2-space indentation
|
|
308
|
+
- Single quotes
|
|
309
|
+
- Semicolons required (Prettier)
|
|
310
|
+
- Zero runtime dependencies
|
|
311
|
+
|
|
312
|
+
## Supported Types
|
|
313
|
+
|
|
314
|
+
Built-in support for:
|
|
315
|
+
- Primitives (including NaN, +0/-0 handling)
|
|
316
|
+
- Objects and Arrays
|
|
317
|
+
- Map and Set
|
|
318
|
+
- Date and RegExp
|
|
319
|
+
- All typed arrays (Int8Array, Uint8Array, etc.)
|
|
320
|
+
- DataView and ArrayBuffer
|
|
321
|
+
- URL
|
|
322
|
+
- Symbols (optional)
|
|
323
|
+
- Property descriptors
|
|
324
|
+
- Circular references
|
|
325
|
+
- Functions (configurable)
|
|
326
|
+
|
|
327
|
+
## Common Patterns
|
|
328
|
+
|
|
329
|
+
### Capturing values
|
|
330
|
+
|
|
331
|
+
```js
|
|
332
|
+
import {unify, variable} from 'deep6/unify.js';
|
|
333
|
+
|
|
334
|
+
const name = variable();
|
|
335
|
+
const env = unify({user: {name: 'Alice', age: 30}}, {user: {name, age: 30}});
|
|
336
|
+
// name.get(env) === 'Alice'
|
|
337
|
+
```
|
|
338
|
+
|
|
339
|
+
### Nested pattern matching
|
|
340
|
+
|
|
341
|
+
```js
|
|
342
|
+
match(
|
|
343
|
+
{users: [{name: 'Alice'}, {name: 'Bob'}]},
|
|
344
|
+
{users: [{name: any}, {name: any}]}
|
|
345
|
+
); // true
|
|
346
|
+
```
|
|
347
|
+
|
|
348
|
+
### Custom unifier
|
|
349
|
+
|
|
350
|
+
```js
|
|
351
|
+
import {Unifier} from 'deep6/env.js';
|
|
352
|
+
|
|
353
|
+
class Range extends Unifier {
|
|
354
|
+
constructor(min, max) {
|
|
355
|
+
super();
|
|
356
|
+
this.min = min;
|
|
357
|
+
this.max = max;
|
|
358
|
+
}
|
|
359
|
+
unify(val, ls, rs) {
|
|
360
|
+
return typeof val === 'number' && val >= this.min && val <= this.max;
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
|
|
364
|
+
match({age: 25}, {age: new Range(18, 65)}); // true
|
|
365
|
+
```
|
|
366
|
+
|
|
367
|
+
## Links
|
|
368
|
+
|
|
369
|
+
- GitHub: https://github.com/uhop/deep6
|
|
370
|
+
- npm: https://www.npmjs.com/package/deep6
|
|
371
|
+
- Wiki: https://github.com/uhop/deep6/wiki
|
package/llms.txt
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# deep6
|
|
2
|
+
|
|
3
|
+
> No-dependency ES6 mini-library for advanced deep equivalence, unification, and cloning of JavaScript structures. Supports extensible pattern matching, circular reference handling, and complex objects including Map, Set, typed arrays, symbols, and property descriptors.
|
|
4
|
+
|
|
5
|
+
## Install
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm i deep6
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
## Quick start
|
|
12
|
+
|
|
13
|
+
```js
|
|
14
|
+
import equal, {clone, match, any} from 'deep6';
|
|
15
|
+
|
|
16
|
+
const x = {a: 1, b: 2, c: ['hi!', 42, null, {}]};
|
|
17
|
+
|
|
18
|
+
// deep equality
|
|
19
|
+
equal(x, {b: 2, a: 1, c: ['hi!', 42, null, {}]}); // true
|
|
20
|
+
|
|
21
|
+
// pattern matching
|
|
22
|
+
match(x, {a: 1}); // true
|
|
23
|
+
match(x, {a: 1, c: any}); // true
|
|
24
|
+
|
|
25
|
+
// deep cloning
|
|
26
|
+
const y = clone(x);
|
|
27
|
+
equal(x, y); // true
|
|
28
|
+
|
|
29
|
+
// circular dependencies are fine
|
|
30
|
+
const z = {}, w = {};
|
|
31
|
+
z.z = z;
|
|
32
|
+
w.z = w;
|
|
33
|
+
const p = clone(w);
|
|
34
|
+
equal(z, w); // true
|
|
35
|
+
equal(z, p); // true
|
|
36
|
+
|
|
37
|
+
// advanced: symbols and non-enumerable properties
|
|
38
|
+
const r = {a: 1};
|
|
39
|
+
Object.defineProperty(r, 'b', {value: 2, enumerable: false});
|
|
40
|
+
const q = clone(r, {allProps: true});
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
## API
|
|
44
|
+
|
|
45
|
+
### equal(a, b, options)
|
|
46
|
+
|
|
47
|
+
Deep equivalence check. Returns `true` if structures are deeply equal.
|
|
48
|
+
|
|
49
|
+
Options:
|
|
50
|
+
- `circular: true` — handle circular references (default: true)
|
|
51
|
+
- `symbols: true` — compare symbol properties
|
|
52
|
+
- `loose: true` — use loose equality for primitives (`==`)
|
|
53
|
+
- `ignoreFunctions: true` — ignore function properties
|
|
54
|
+
- `signedZero: true` — distinguish +0 from -0
|
|
55
|
+
|
|
56
|
+
### clone(object, options)
|
|
57
|
+
|
|
58
|
+
Deep cloning. Returns a deep copy of the object.
|
|
59
|
+
|
|
60
|
+
Options:
|
|
61
|
+
- `circular: true` — handle circular references (default: true)
|
|
62
|
+
- `symbols: true` — clone symbol properties
|
|
63
|
+
- `allProps: true` — clone non-enumerable properties
|
|
64
|
+
|
|
65
|
+
### match(object, pattern)
|
|
66
|
+
|
|
67
|
+
Pattern matching. Returns `true` if object matches pattern (open match by default).
|
|
68
|
+
|
|
69
|
+
Pattern features:
|
|
70
|
+
- `any` or `_` — wildcard that matches any value
|
|
71
|
+
- Object keys can be missing in target (open matching)
|
|
72
|
+
- Use `open()` for explicit open matching
|
|
73
|
+
- Use `soft()` for bidirectional open matching
|
|
74
|
+
|
|
75
|
+
### unify(a, b, env, options)
|
|
76
|
+
|
|
77
|
+
Core unification algorithm. Returns `Env` on success, `null` on failure.
|
|
78
|
+
|
|
79
|
+
```js
|
|
80
|
+
import unify, {Variable, variable} from 'deep6/unify.js';
|
|
81
|
+
|
|
82
|
+
const v = variable();
|
|
83
|
+
const env = unify({a: 1, b: v}, {a: 1, b: 2});
|
|
84
|
+
// env.get(v) === 2
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
### Unifiers
|
|
88
|
+
|
|
89
|
+
Extensible pattern matching components:
|
|
90
|
+
|
|
91
|
+
- `matchString(regexp, matches, props)` — regex-based string matching
|
|
92
|
+
- `matchTypeOf(type)` — match by `typeof` value
|
|
93
|
+
- `matchInstanceOf(constructor)` — match by `instanceof` check
|
|
94
|
+
- `matchCondition(predicate)` — match by custom predicate
|
|
95
|
+
- `ref()` — reference variable for cross-pattern matching
|
|
96
|
+
|
|
97
|
+
```js
|
|
98
|
+
// ESM
|
|
99
|
+
import matchString from 'deep6/unifiers/matchString.js';
|
|
100
|
+
import matchTypeOf from 'deep6/unifiers/matchTypeOf.js';
|
|
101
|
+
import matchInstanceOf from 'deep6/unifiers/matchInstanceOf.js';
|
|
102
|
+
import matchCondition from 'deep6/unifiers/matchCondition.js';
|
|
103
|
+
import ref from 'deep6/unifiers/ref.js';
|
|
104
|
+
|
|
105
|
+
// CommonJS
|
|
106
|
+
const {equal, clone, match, any} = require('deep6');
|
|
107
|
+
const matchString = require('deep6/unifiers/matchString.js');
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
## Registry and filters
|
|
111
|
+
|
|
112
|
+
Both `unify` and `clone` support extensible registries:
|
|
113
|
+
|
|
114
|
+
```js
|
|
115
|
+
import unify from 'deep6/unify.js';
|
|
116
|
+
import clone from 'deep6/traverse/clone.js';
|
|
117
|
+
|
|
118
|
+
// Add custom type unifier
|
|
119
|
+
unify.registry.push(MyClass, (l, r) => /* compare */);
|
|
120
|
+
|
|
121
|
+
// Add custom type cloner
|
|
122
|
+
clone.registry.push(MyClass, (val, context) => /* clone */);
|
|
123
|
+
```
|
|
124
|
+
|
|
125
|
+
## Common patterns
|
|
126
|
+
|
|
127
|
+
### Deep equality with special types
|
|
128
|
+
|
|
129
|
+
```js
|
|
130
|
+
equal(new Date('2020-01-01'), new Date('2020-01-01')); // true
|
|
131
|
+
equal(/abc/gi, /abc/gi); // true
|
|
132
|
+
equal(new Map([['a', 1]]), new Map([['a', 1]])); // true
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
### Pattern matching with wildcards
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
match({a: 1, b: {c: 2}}, {a: 1}); // true (open match)
|
|
139
|
+
match({a: 1, b: {c: 2}}, {a: 1, b: any}); // true
|
|
140
|
+
match({a: 'hello'}, {a: matchString(/^h/i)}); // true
|
|
141
|
+
```
|
|
142
|
+
|
|
143
|
+
### Cloning with options
|
|
144
|
+
|
|
145
|
+
```js
|
|
146
|
+
const x = {a: 1, [Symbol('s')]: 2};
|
|
147
|
+
const y = clone(x, {symbols: true});
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Links
|
|
151
|
+
|
|
152
|
+
- Docs: https://github.com/uhop/deep6/wiki
|
|
153
|
+
- npm: https://www.npmjs.com/package/deep6
|
|
154
|
+
- Full LLM reference: https://github.com/uhop/deep6/blob/master/llms-full.txt
|