@bcts/envelope-pattern 1.0.0-alpha.16 → 1.0.0-alpha.18

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 (46) hide show
  1. package/README.md +1 -1
  2. package/dist/index.cjs +1992 -1714
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.d.cts +147 -31
  5. package/dist/index.d.cts.map +1 -1
  6. package/dist/index.d.mts +147 -31
  7. package/dist/index.d.mts.map +1 -1
  8. package/dist/index.iife.js +1984 -1707
  9. package/dist/index.iife.js.map +1 -1
  10. package/dist/index.mjs +1966 -1698
  11. package/dist/index.mjs.map +1 -1
  12. package/package.json +9 -9
  13. package/src/format.ts +32 -13
  14. package/src/parse/index.ts +138 -5
  15. package/src/parse/token.ts +59 -58
  16. package/src/pattern/index.ts +110 -2
  17. package/src/pattern/leaf/array-pattern.ts +26 -26
  18. package/src/pattern/leaf/bool-pattern.ts +12 -12
  19. package/src/pattern/leaf/byte-string-pattern.ts +15 -15
  20. package/src/pattern/leaf/cbor-pattern.ts +31 -31
  21. package/src/pattern/leaf/date-pattern.ts +9 -9
  22. package/src/pattern/leaf/index.ts +1 -2
  23. package/src/pattern/leaf/known-value-pattern.ts +21 -20
  24. package/src/pattern/leaf/map-pattern.ts +14 -14
  25. package/src/pattern/leaf/null-pattern.ts +8 -8
  26. package/src/pattern/leaf/number-pattern.ts +20 -20
  27. package/src/pattern/leaf/tagged-pattern.ts +20 -20
  28. package/src/pattern/leaf/text-pattern.ts +14 -14
  29. package/src/pattern/matcher.ts +88 -3
  30. package/src/pattern/meta/and-pattern.ts +19 -18
  31. package/src/pattern/meta/capture-pattern.ts +16 -17
  32. package/src/pattern/meta/group-pattern.ts +20 -17
  33. package/src/pattern/meta/not-pattern.ts +9 -8
  34. package/src/pattern/meta/or-pattern.ts +30 -25
  35. package/src/pattern/meta/search-pattern.ts +17 -17
  36. package/src/pattern/meta/traverse-pattern.ts +42 -18
  37. package/src/pattern/structure/assertions-pattern.ts +31 -32
  38. package/src/pattern/structure/digest-pattern.ts +23 -23
  39. package/src/pattern/structure/index.ts +1 -0
  40. package/src/pattern/structure/node-pattern.ts +17 -17
  41. package/src/pattern/structure/object-pattern.ts +14 -15
  42. package/src/pattern/structure/obscured-pattern.ts +7 -7
  43. package/src/pattern/structure/predicate-pattern.ts +14 -15
  44. package/src/pattern/structure/subject-pattern.ts +16 -17
  45. package/src/pattern/structure/wrapped-pattern.ts +40 -19
  46. package/src/pattern/vm.ts +12 -11
@@ -19,6 +19,7 @@ import {
19
19
 
20
20
  import type { Path } from "../format";
21
21
  import type { Instr } from "./vm";
22
+ import { compile, run } from "./vm";
22
23
 
23
24
  // Re-export sub-modules
24
25
  export * from "./leaf";
@@ -104,6 +105,7 @@ import {
104
105
  registerNodePatternFactory,
105
106
  registerObscuredPatternFactory,
106
107
  registerWrappedPatternFactory,
108
+ registerWrappedPatternDispatch,
107
109
  } from "./structure";
108
110
 
109
111
  // Import meta patterns
@@ -176,13 +178,57 @@ export function patternMeta(meta: MetaPattern): Pattern {
176
178
  // Pattern Matcher Implementation
177
179
  // ============================================================================
178
180
 
181
+ /**
182
+ * Check if a pattern requires the VM for execution.
183
+ * Patterns containing Group (repeat), Traverse, or Search require compilation.
184
+ */
185
+ function patternNeedsVM(pattern: Pattern): boolean {
186
+ switch (pattern.type) {
187
+ case "Leaf":
188
+ case "Structure":
189
+ return false;
190
+ case "Meta":
191
+ return metaPatternNeedsVM(pattern.pattern);
192
+ }
193
+ }
194
+
195
+ function metaPatternNeedsVM(pattern: MetaPattern): boolean {
196
+ switch (pattern.type) {
197
+ case "Any":
198
+ return false;
199
+ case "And":
200
+ return pattern.pattern.patterns().some(patternNeedsVM);
201
+ case "Or":
202
+ return pattern.pattern.patterns().some(patternNeedsVM);
203
+ case "Not":
204
+ return patternNeedsVM(pattern.pattern.pattern());
205
+ case "Capture":
206
+ return patternNeedsVM(pattern.pattern.pattern());
207
+ case "Search":
208
+ case "Traverse":
209
+ return true;
210
+ case "Group": {
211
+ // Group with exactly(1) is simple pass-through, doesn't need VM
212
+ const q = pattern.pattern.quantifier();
213
+ if (q.min() === 1 && q.max() === 1) {
214
+ return patternNeedsVM(pattern.pattern.pattern());
215
+ }
216
+ return true;
217
+ }
218
+ }
219
+ }
220
+
179
221
  /**
180
222
  * Gets paths with captures for a pattern.
223
+ * Routes through the VM for complex patterns that require compilation.
181
224
  */
182
225
  export function patternPathsWithCaptures(
183
226
  pattern: Pattern,
184
227
  haystack: Envelope,
185
228
  ): [Path[], Map<string, Path[]>] {
229
+ if (patternNeedsVM(pattern)) {
230
+ return patternPathsWithCapturesViaVM(pattern, haystack);
231
+ }
186
232
  switch (pattern.type) {
187
233
  case "Leaf":
188
234
  return leafPatternPathsWithCaptures(pattern.pattern, haystack);
@@ -193,6 +239,31 @@ export function patternPathsWithCaptures(
193
239
  }
194
240
  }
195
241
 
242
+ /**
243
+ * Execute a pattern through the VM, merging results.
244
+ */
245
+ function patternPathsWithCapturesViaVM(
246
+ pattern: Pattern,
247
+ haystack: Envelope,
248
+ ): [Path[], Map<string, Path[]>] {
249
+ const prog = compile(pattern);
250
+ const results = run(prog, haystack);
251
+
252
+ const allPaths: Path[] = [];
253
+ const mergedCaptures = new Map<string, Path[]>();
254
+
255
+ for (const [path, captures] of results) {
256
+ allPaths.push(path);
257
+ for (const [name, paths] of captures) {
258
+ const existing = mergedCaptures.get(name) ?? [];
259
+ existing.push(...paths);
260
+ mergedCaptures.set(name, existing);
261
+ }
262
+ }
263
+
264
+ return [allPaths, mergedCaptures];
265
+ }
266
+
196
267
  /**
197
268
  * Gets paths for a pattern.
198
269
  */
@@ -347,6 +418,27 @@ export function dateRange(earliest: CborDate, latest: CborDate): Pattern {
347
418
  return patternLeaf(leafDate(DatePattern.range(earliest, latest)));
348
419
  }
349
420
 
421
+ /**
422
+ * Creates a new Pattern that matches Date values on or after the specified date.
423
+ */
424
+ export function dateEarliest(d: CborDate): Pattern {
425
+ return patternLeaf(leafDate(DatePattern.earliest(d)));
426
+ }
427
+
428
+ /**
429
+ * Creates a new Pattern that matches Date values on or before the specified date.
430
+ */
431
+ export function dateLatest(d: CborDate): Pattern {
432
+ return patternLeaf(leafDate(DatePattern.latest(d)));
433
+ }
434
+
435
+ /**
436
+ * Creates a new Pattern that matches Date values whose ISO-8601 string matches the regex.
437
+ */
438
+ export function dateRegex(pattern: RegExp): Pattern {
439
+ return patternLeaf(leafDate(DatePattern.regex(pattern)));
440
+ }
441
+
350
442
  /**
351
443
  * Creates a new Pattern that matches any number value.
352
444
  */
@@ -700,6 +792,11 @@ function registerAllFactories(): void {
700
792
  registerNodePatternFactory((p) => patternStructure(structureNode(p)));
701
793
  registerObscuredPatternFactory((p) => patternStructure(structureObscured(p)));
702
794
  registerWrappedPatternFactory((p) => patternStructure(structureWrapped(p)));
795
+ registerWrappedPatternDispatch({
796
+ pathsWithCaptures: patternPathsWithCaptures,
797
+ compile: patternCompile,
798
+ toString: patternToString,
799
+ });
703
800
 
704
801
  // Meta pattern factories
705
802
  registerAnyPatternFactory((p) => patternMeta(metaAny(p)));
@@ -719,6 +816,17 @@ registerAllFactories();
719
816
  import { registerVMPatternFunctions } from "./vm";
720
817
  registerVMPatternFunctions(patternPathsWithCaptures, patternMatches, patternPaths);
721
818
 
722
- // Register pattern match function for meta patterns
723
- import { registerPatternMatchFn } from "./matcher";
819
+ // Register pattern dispatch functions for meta patterns
820
+ import { registerPatternMatchFn, registerPatternDispatchFns } from "./matcher";
724
821
  registerPatternMatchFn(patternMatches);
822
+ registerPatternDispatchFns({
823
+ pathsWithCaptures: patternPathsWithCaptures,
824
+ paths: patternPaths,
825
+ compile: patternCompile,
826
+ isComplex: patternIsComplex,
827
+ toString: patternToString,
828
+ });
829
+
830
+ // Register traverse dispatch functions to resolve circular dependencies
831
+ import { registerTraverseDispatchFunctions } from "./meta/traverse-pattern";
832
+ registerTraverseDispatchFunctions(patternPathsWithCaptures, patternCompile, patternIsComplex);
@@ -44,10 +44,10 @@ export type ArrayPatternType =
44
44
  * Corresponds to the Rust `ArrayPattern` struct in array_pattern.rs
45
45
  */
46
46
  export class ArrayPattern implements Matcher {
47
- readonly #pattern: ArrayPatternType;
47
+ private readonly _pattern: ArrayPatternType;
48
48
 
49
49
  private constructor(pattern: ArrayPatternType) {
50
- this.#pattern = pattern;
50
+ this._pattern = pattern;
51
51
  }
52
52
 
53
53
  /**
@@ -93,12 +93,12 @@ export class ArrayPattern implements Matcher {
93
93
  * Gets the pattern type.
94
94
  */
95
95
  get pattern(): ArrayPatternType {
96
- return this.#pattern;
96
+ return this._pattern;
97
97
  }
98
98
 
99
99
  pathsWithCaptures(haystack: Envelope): [Path[], Map<string, Path[]>] {
100
100
  // Try to extract CBOR from the envelope
101
- const cbor = haystack.asLeaf();
101
+ const cbor = haystack.subject().asLeaf();
102
102
  if (cbor === undefined) {
103
103
  return [[], new Map<string, Path[]>()];
104
104
  }
@@ -109,13 +109,13 @@ export class ArrayPattern implements Matcher {
109
109
  return [[], new Map<string, Path[]>()];
110
110
  }
111
111
 
112
- switch (this.#pattern.type) {
112
+ switch (this._pattern.type) {
113
113
  case "Any":
114
114
  return [[[haystack]], new Map<string, Path[]>()];
115
115
 
116
116
  case "Interval": {
117
117
  const length = array.length;
118
- if (this.#pattern.interval.contains(length)) {
118
+ if (this._pattern.interval.contains(length)) {
119
119
  return [[[haystack]], new Map<string, Path[]>()];
120
120
  }
121
121
  return [[], new Map<string, Path[]>()];
@@ -124,7 +124,7 @@ export class ArrayPattern implements Matcher {
124
124
  case "DCBORPattern": {
125
125
  // Delegate to dcbor-pattern for matching
126
126
  const { paths: dcborPaths, captures: dcborCaptures } = dcborPatternPathsWithCaptures(
127
- this.#pattern.pattern,
127
+ this._pattern.pattern,
128
128
  cbor,
129
129
  );
130
130
 
@@ -167,7 +167,7 @@ export class ArrayPattern implements Matcher {
167
167
  case "WithPatterns":
168
168
  // For envelope patterns, match if array length equals patterns count
169
169
  // Full element-by-element matching would require additional implementation
170
- if (array.length === this.#pattern.patterns.length) {
170
+ if (array.length === this._pattern.patterns.length) {
171
171
  return [[[haystack]], new Map<string, Path[]>()];
172
172
  }
173
173
  return [[], new Map<string, Path[]>()];
@@ -194,15 +194,15 @@ export class ArrayPattern implements Matcher {
194
194
  }
195
195
 
196
196
  toString(): string {
197
- switch (this.#pattern.type) {
197
+ switch (this._pattern.type) {
198
198
  case "Any":
199
199
  return "[*]";
200
200
  case "Interval":
201
- return `[{${this.#pattern.interval.toString()}}]`;
201
+ return `[{${this._pattern.interval.toString()}}]`;
202
202
  case "DCBORPattern":
203
- return dcborPatternDisplay(this.#pattern.pattern);
203
+ return dcborPatternDisplay(this._pattern.pattern);
204
204
  case "WithPatterns":
205
- return `[${this.#pattern.patterns.map(String).join(", ")}]`;
205
+ return `[${this._pattern.patterns.map(String).join(", ")}]`;
206
206
  }
207
207
  }
208
208
 
@@ -210,30 +210,30 @@ export class ArrayPattern implements Matcher {
210
210
  * Equality comparison.
211
211
  */
212
212
  equals(other: ArrayPattern): boolean {
213
- if (this.#pattern.type !== other.#pattern.type) {
213
+ if (this._pattern.type !== other._pattern.type) {
214
214
  return false;
215
215
  }
216
- switch (this.#pattern.type) {
216
+ switch (this._pattern.type) {
217
217
  case "Any":
218
218
  return true;
219
219
  case "Interval":
220
- return this.#pattern.interval.equals(
221
- (other.#pattern as { type: "Interval"; interval: Interval }).interval,
220
+ return this._pattern.interval.equals(
221
+ (other._pattern as { type: "Interval"; interval: Interval }).interval,
222
222
  );
223
223
  case "DCBORPattern":
224
224
  // Compare using display representation
225
225
  return (
226
- dcborPatternDisplay(this.#pattern.pattern) ===
226
+ dcborPatternDisplay(this._pattern.pattern) ===
227
227
  dcborPatternDisplay(
228
- (other.#pattern as { type: "DCBORPattern"; pattern: DCBORPattern }).pattern,
228
+ (other._pattern as { type: "DCBORPattern"; pattern: DCBORPattern }).pattern,
229
229
  )
230
230
  );
231
231
  case "WithPatterns": {
232
- const otherPatterns = (other.#pattern as { type: "WithPatterns"; patterns: Pattern[] })
232
+ const otherPatterns = (other._pattern as { type: "WithPatterns"; patterns: Pattern[] })
233
233
  .patterns;
234
- if (this.#pattern.patterns.length !== otherPatterns.length) return false;
235
- for (let i = 0; i < this.#pattern.patterns.length; i++) {
236
- if (this.#pattern.patterns[i] !== otherPatterns[i]) return false;
234
+ if (this._pattern.patterns.length !== otherPatterns.length) return false;
235
+ for (let i = 0; i < this._pattern.patterns.length; i++) {
236
+ if (this._pattern.patterns[i] !== otherPatterns[i]) return false;
237
237
  }
238
238
  return true;
239
239
  }
@@ -244,17 +244,17 @@ export class ArrayPattern implements Matcher {
244
244
  * Hash code for use in Maps/Sets.
245
245
  */
246
246
  hashCode(): number {
247
- switch (this.#pattern.type) {
247
+ switch (this._pattern.type) {
248
248
  case "Any":
249
249
  return 0;
250
250
  case "Interval":
251
251
  // Simple hash based on min/max
252
- return this.#pattern.interval.min() * 31 + (this.#pattern.interval.max() ?? 0);
252
+ return this._pattern.interval.min() * 31 + (this._pattern.interval.max() ?? 0);
253
253
  case "DCBORPattern":
254
254
  // Simple hash based on display string
255
- return simpleStringHash(dcborPatternDisplay(this.#pattern.pattern));
255
+ return simpleStringHash(dcborPatternDisplay(this._pattern.pattern));
256
256
  case "WithPatterns":
257
- return this.#pattern.patterns.length;
257
+ return this._pattern.patterns.length;
258
258
  }
259
259
  }
260
260
  }
@@ -36,10 +36,10 @@ export function registerBoolPatternFactory(factory: (pattern: BoolPattern) => Pa
36
36
  * Corresponds to the Rust `BoolPattern` struct in bool_pattern.rs
37
37
  */
38
38
  export class BoolPattern implements Matcher {
39
- readonly #inner: DCBORBoolPattern;
39
+ private readonly _inner: DCBORBoolPattern;
40
40
 
41
41
  private constructor(inner: DCBORBoolPattern) {
42
- this.#inner = inner;
42
+ this._inner = inner;
43
43
  }
44
44
 
45
45
  /**
@@ -67,15 +67,15 @@ export class BoolPattern implements Matcher {
67
67
  * Gets the underlying dcbor-pattern BoolPattern.
68
68
  */
69
69
  get inner(): DCBORBoolPattern {
70
- return this.#inner;
70
+ return this._inner;
71
71
  }
72
72
 
73
73
  pathsWithCaptures(haystack: Envelope): [Path[], Map<string, Path[]>] {
74
74
  // For leaf envelopes, extract the CBOR and delegate to dcbor-pattern
75
- const cbor = haystack.asLeaf();
75
+ const cbor = haystack.subject().asLeaf();
76
76
  if (cbor !== undefined) {
77
77
  // Delegate to dcbor-pattern for CBOR matching
78
- const dcborPaths = dcborBoolPatternPaths(this.#inner, cbor);
78
+ const dcborPaths = dcborBoolPatternPaths(this._inner, cbor);
79
79
 
80
80
  // For simple leaf patterns, if dcbor-pattern found matches, return the envelope
81
81
  if (dcborPaths.length > 0) {
@@ -109,7 +109,7 @@ export class BoolPattern implements Matcher {
109
109
  }
110
110
 
111
111
  toString(): string {
112
- return boolPatternDisplay(this.#inner);
112
+ return boolPatternDisplay(this._inner);
113
113
  }
114
114
 
115
115
  /**
@@ -117,11 +117,11 @@ export class BoolPattern implements Matcher {
117
117
  */
118
118
  equals(other: BoolPattern): boolean {
119
119
  // Compare by variant and value
120
- if (this.#inner.variant !== other.#inner.variant) {
120
+ if (this._inner.variant !== other._inner.variant) {
121
121
  return false;
122
122
  }
123
- if (this.#inner.variant === "Value" && other.#inner.variant === "Value") {
124
- return this.#inner.value === other.#inner.value;
123
+ if (this._inner.variant === "Value" && other._inner.variant === "Value") {
124
+ return this._inner.value === other._inner.value;
125
125
  }
126
126
  return true;
127
127
  }
@@ -131,9 +131,9 @@ export class BoolPattern implements Matcher {
131
131
  */
132
132
  hashCode(): number {
133
133
  // Simple hash based on variant and value
134
- let hash = this.#inner.variant === "Any" ? 0 : 1;
135
- if (this.#inner.variant === "Value") {
136
- hash = hash * 31 + (this.#inner.value ? 1 : 0);
134
+ let hash = this._inner.variant === "Any" ? 0 : 1;
135
+ if (this._inner.variant === "Value") {
136
+ hash = hash * 31 + (this._inner.value ? 1 : 0);
137
137
  }
138
138
  return hash;
139
139
  }
@@ -39,10 +39,10 @@ export function registerByteStringPatternFactory(
39
39
  * Corresponds to the Rust `ByteStringPattern` struct in byte_string_pattern.rs
40
40
  */
41
41
  export class ByteStringPattern implements Matcher {
42
- readonly #inner: DCBORByteStringPattern;
42
+ private readonly _inner: DCBORByteStringPattern;
43
43
 
44
44
  private constructor(inner: DCBORByteStringPattern) {
45
- this.#inner = inner;
45
+ this._inner = inner;
46
46
  }
47
47
 
48
48
  /**
@@ -77,15 +77,15 @@ export class ByteStringPattern implements Matcher {
77
77
  * Gets the underlying dcbor-pattern ByteStringPattern.
78
78
  */
79
79
  get inner(): DCBORByteStringPattern {
80
- return this.#inner;
80
+ return this._inner;
81
81
  }
82
82
 
83
83
  pathsWithCaptures(haystack: Envelope): [Path[], Map<string, Path[]>] {
84
84
  // For leaf envelopes, extract the CBOR and delegate to dcbor-pattern
85
- const cbor = haystack.asLeaf();
85
+ const cbor = haystack.subject().asLeaf();
86
86
  if (cbor !== undefined) {
87
87
  // Delegate to dcbor-pattern for CBOR matching
88
- const dcborPaths = dcborByteStringPatternPaths(this.#inner, cbor);
88
+ const dcborPaths = dcborByteStringPatternPaths(this._inner, cbor);
89
89
 
90
90
  // For simple leaf patterns, if dcbor-pattern found matches, return the envelope
91
91
  if (dcborPaths.length > 0) {
@@ -117,22 +117,22 @@ export class ByteStringPattern implements Matcher {
117
117
  }
118
118
 
119
119
  toString(): string {
120
- return byteStringPatternDisplay(this.#inner);
120
+ return byteStringPatternDisplay(this._inner);
121
121
  }
122
122
 
123
123
  /**
124
124
  * Equality comparison.
125
125
  */
126
126
  equals(other: ByteStringPattern): boolean {
127
- if (this.#inner.variant !== other.#inner.variant) {
127
+ if (this._inner.variant !== other._inner.variant) {
128
128
  return false;
129
129
  }
130
- switch (this.#inner.variant) {
130
+ switch (this._inner.variant) {
131
131
  case "Any":
132
132
  return true;
133
133
  case "Value": {
134
- const a = (this.#inner as { value: Uint8Array }).value;
135
- const b = (other.#inner as { value: Uint8Array }).value;
134
+ const a = (this._inner as { value: Uint8Array }).value;
135
+ const b = (other._inner as { value: Uint8Array }).value;
136
136
  if (a.length !== b.length) return false;
137
137
  for (let i = 0; i < a.length; i++) {
138
138
  if (a[i] !== b[i]) return false;
@@ -141,8 +141,8 @@ export class ByteStringPattern implements Matcher {
141
141
  }
142
142
  case "BinaryRegex":
143
143
  return (
144
- (this.#inner as { pattern: RegExp }).pattern.source ===
145
- (other.#inner as { pattern: RegExp }).pattern.source
144
+ (this._inner as { pattern: RegExp }).pattern.source ===
145
+ (other._inner as { pattern: RegExp }).pattern.source
146
146
  );
147
147
  }
148
148
  }
@@ -152,19 +152,19 @@ export class ByteStringPattern implements Matcher {
152
152
  */
153
153
  hashCode(): number {
154
154
  let hash = 0;
155
- switch (this.#inner.variant) {
155
+ switch (this._inner.variant) {
156
156
  case "Any":
157
157
  hash = 1;
158
158
  break;
159
159
  case "Value": {
160
- const val = (this.#inner as { value: Uint8Array }).value;
160
+ const val = (this._inner as { value: Uint8Array }).value;
161
161
  for (const byte of val) {
162
162
  hash = hash * 31 + byte;
163
163
  }
164
164
  break;
165
165
  }
166
166
  case "BinaryRegex":
167
- hash = 3 * 31 + (this.#inner as { pattern: RegExp }).pattern.source.length;
167
+ hash = 3 * 31 + (this._inner as { pattern: RegExp }).pattern.source.length;
168
168
  break;
169
169
  }
170
170
  return hash;
@@ -43,10 +43,10 @@ export type CBORPatternType =
43
43
  * Corresponds to the Rust `CBORPattern` enum in cbor_pattern.rs
44
44
  */
45
45
  export class CBORPattern implements Matcher {
46
- readonly #pattern: CBORPatternType;
46
+ private readonly _pattern: CBORPatternType;
47
47
 
48
48
  private constructor(pattern: CBORPatternType) {
49
- this.#pattern = pattern;
49
+ this._pattern = pattern;
50
50
  }
51
51
 
52
52
  /**
@@ -81,13 +81,13 @@ export class CBORPattern implements Matcher {
81
81
  * Gets the pattern type.
82
82
  */
83
83
  get pattern(): CBORPatternType {
84
- return this.#pattern;
84
+ return this._pattern;
85
85
  }
86
86
 
87
87
  /**
88
88
  * Convert dcbor captures to envelope captures.
89
89
  */
90
- #convertDcborCapturesToEnvelopeCaptures(
90
+ private _convertDcborCapturesToEnvelopeCaptures(
91
91
  dcborCaptures: Map<string, Cbor[][]>,
92
92
  baseEnvelope: Envelope,
93
93
  baseCbor: Cbor,
@@ -96,7 +96,7 @@ export class CBORPattern implements Matcher {
96
96
 
97
97
  for (const [captureName, dcborCapturePaths] of dcborCaptures) {
98
98
  const envelopeCapturePaths: Path[] = dcborCapturePaths.map((dcborPath) =>
99
- this.#convertDcborPathToEnvelopePath(dcborPath, baseEnvelope, baseCbor),
99
+ this._convertDcborPathToEnvelopePath(dcborPath, baseEnvelope, baseCbor),
100
100
  );
101
101
  envelopeCaptures.set(captureName, envelopeCapturePaths);
102
102
  }
@@ -107,7 +107,7 @@ export class CBORPattern implements Matcher {
107
107
  /**
108
108
  * Convert a single dcbor path to an envelope path.
109
109
  */
110
- #convertDcborPathToEnvelopePath(
110
+ private _convertDcborPathToEnvelopePath(
111
111
  dcborPath: Cbor[],
112
112
  baseEnvelope: Envelope,
113
113
  baseCbor: Cbor,
@@ -131,7 +131,7 @@ export class CBORPattern implements Matcher {
131
131
  /**
132
132
  * Collect capture names from a dcbor pattern.
133
133
  */
134
- #collectDcborCaptureNames(dcborPattern: DCBORPattern, names: string[]): void {
134
+ private _collectDcborCaptureNames(dcborPattern: DCBORPattern, names: string[]): void {
135
135
  // Parse the pattern string to extract capture names
136
136
  const patternStr = dcborPatternDisplay(dcborPattern);
137
137
 
@@ -156,26 +156,26 @@ export class CBORPattern implements Matcher {
156
156
  }
157
157
 
158
158
  pathsWithCaptures(haystack: Envelope): [Path[], Map<string, Path[]>] {
159
- const envCase = haystack.case();
159
+ const envCase = haystack.subject().case();
160
160
 
161
161
  // Special case for KnownValue envelope
162
162
  if (envCase.type === "knownValue") {
163
163
  const knownValue = envCase.value;
164
164
  const knownValueCbor = knownValue.taggedCbor();
165
165
 
166
- switch (this.#pattern.type) {
166
+ switch (this._pattern.type) {
167
167
  case "Any":
168
168
  return [[[haystack]], new Map<string, Path[]>()];
169
169
  case "Value": {
170
170
  // Compare using diagnostic representation
171
- if (knownValueCbor.toDiagnostic() === this.#pattern.cbor.toDiagnostic()) {
171
+ if (knownValueCbor.toDiagnostic() === this._pattern.cbor.toDiagnostic()) {
172
172
  return [[[haystack]], new Map<string, Path[]>()];
173
173
  }
174
174
  return [[], new Map<string, Path[]>()];
175
175
  }
176
176
  case "Pattern": {
177
177
  const { paths: dcborPaths, captures: dcborCaptures } = dcborPatternPathsWithCaptures(
178
- this.#pattern.pattern,
178
+ this._pattern.pattern,
179
179
  knownValueCbor,
180
180
  );
181
181
 
@@ -193,7 +193,7 @@ export class CBORPattern implements Matcher {
193
193
  return extendedPath;
194
194
  });
195
195
 
196
- const envelopeCaptures = this.#convertDcborCapturesToEnvelopeCaptures(
196
+ const envelopeCaptures = this._convertDcborCapturesToEnvelopeCaptures(
197
197
  dcborCaptures,
198
198
  haystack,
199
199
  knownValueCbor,
@@ -206,25 +206,25 @@ export class CBORPattern implements Matcher {
206
206
  }
207
207
 
208
208
  // Standard case for CBOR leaf
209
- const leafCbor = haystack.asLeaf();
209
+ const leafCbor = haystack.subject().asLeaf();
210
210
  if (leafCbor === undefined) {
211
211
  return [[], new Map<string, Path[]>()];
212
212
  }
213
213
 
214
- switch (this.#pattern.type) {
214
+ switch (this._pattern.type) {
215
215
  case "Any":
216
216
  return [[[haystack]], new Map<string, Path[]>()];
217
217
 
218
218
  case "Value":
219
219
  // Compare using diagnostic representation
220
- if (leafCbor.toDiagnostic() === this.#pattern.cbor.toDiagnostic()) {
220
+ if (leafCbor.toDiagnostic() === this._pattern.cbor.toDiagnostic()) {
221
221
  return [[[haystack]], new Map<string, Path[]>()];
222
222
  }
223
223
  return [[], new Map<string, Path[]>()];
224
224
 
225
225
  case "Pattern": {
226
226
  const { paths: dcborPaths, captures: dcborCaptures } = dcborPatternPathsWithCaptures(
227
- this.#pattern.pattern,
227
+ this._pattern.pattern,
228
228
  leafCbor,
229
229
  );
230
230
 
@@ -245,7 +245,7 @@ export class CBORPattern implements Matcher {
245
245
  return extendedPath;
246
246
  });
247
247
 
248
- const envelopeCaptures = this.#convertDcborCapturesToEnvelopeCaptures(
248
+ const envelopeCaptures = this._convertDcborCapturesToEnvelopeCaptures(
249
249
  dcborCaptures,
250
250
  haystack,
251
251
  leafCbor,
@@ -267,9 +267,9 @@ export class CBORPattern implements Matcher {
267
267
 
268
268
  compile(code: Instr[], literals: Pattern[], captures: string[]): void {
269
269
  // Register any capture names from this CBOR pattern
270
- if (this.#pattern.type === "Pattern") {
270
+ if (this._pattern.type === "Pattern") {
271
271
  const captureNames: string[] = [];
272
- this.#collectDcborCaptureNames(this.#pattern.pattern, captureNames);
272
+ this._collectDcborCaptureNames(this._pattern.pattern, captureNames);
273
273
  for (const name of captureNames) {
274
274
  if (!captures.includes(name)) {
275
275
  captures.push(name);
@@ -288,13 +288,13 @@ export class CBORPattern implements Matcher {
288
288
  }
289
289
 
290
290
  toString(): string {
291
- switch (this.#pattern.type) {
291
+ switch (this._pattern.type) {
292
292
  case "Any":
293
293
  return "cbor";
294
294
  case "Value":
295
- return `cbor(${this.#pattern.cbor.toDiagnostic()})`;
295
+ return `cbor(${this._pattern.cbor.toDiagnostic()})`;
296
296
  case "Pattern":
297
- return `cbor(/${dcborPatternDisplay(this.#pattern.pattern)}/)`;
297
+ return `cbor(/${dcborPatternDisplay(this._pattern.pattern)}/)`;
298
298
  }
299
299
  }
300
300
 
@@ -302,24 +302,24 @@ export class CBORPattern implements Matcher {
302
302
  * Equality comparison.
303
303
  */
304
304
  equals(other: CBORPattern): boolean {
305
- if (this.#pattern.type !== other.#pattern.type) {
305
+ if (this._pattern.type !== other._pattern.type) {
306
306
  return false;
307
307
  }
308
- switch (this.#pattern.type) {
308
+ switch (this._pattern.type) {
309
309
  case "Any":
310
310
  return true;
311
311
  case "Value":
312
312
  // Compare using diagnostic representation
313
313
  return (
314
- this.#pattern.cbor.toDiagnostic() ===
315
- (other.#pattern as { type: "Value"; cbor: Cbor }).cbor.toDiagnostic()
314
+ this._pattern.cbor.toDiagnostic() ===
315
+ (other._pattern as { type: "Value"; cbor: Cbor }).cbor.toDiagnostic()
316
316
  );
317
317
  case "Pattern":
318
318
  // Compare using display representation
319
319
  return (
320
- dcborPatternDisplay(this.#pattern.pattern) ===
320
+ dcborPatternDisplay(this._pattern.pattern) ===
321
321
  dcborPatternDisplay(
322
- (other.#pattern as { type: "Pattern"; pattern: DCBORPattern }).pattern,
322
+ (other._pattern as { type: "Pattern"; pattern: DCBORPattern }).pattern,
323
323
  )
324
324
  );
325
325
  }
@@ -329,15 +329,15 @@ export class CBORPattern implements Matcher {
329
329
  * Hash code for use in Maps/Sets.
330
330
  */
331
331
  hashCode(): number {
332
- switch (this.#pattern.type) {
332
+ switch (this._pattern.type) {
333
333
  case "Any":
334
334
  return 0;
335
335
  case "Value":
336
336
  // Simple hash based on diagnostic string
337
- return simpleStringHash(this.#pattern.cbor.toDiagnostic());
337
+ return simpleStringHash(this._pattern.cbor.toDiagnostic());
338
338
  case "Pattern":
339
339
  // Simple hash based on display string
340
- return simpleStringHash(dcborPatternDisplay(this.#pattern.pattern));
340
+ return simpleStringHash(dcborPatternDisplay(this._pattern.pattern));
341
341
  }
342
342
  }
343
343
  }