@bcts/envelope-pattern 1.0.0-alpha.23 → 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/dist/index.cjs +1302 -766
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +101 -59
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +102 -60
- package/dist/index.d.mts.map +1 -1
- package/dist/index.iife.js +1299 -763
- package/dist/index.iife.js.map +1 -1
- package/dist/index.mjs +1299 -766
- package/dist/index.mjs.map +1 -1
- package/package.json +8 -6
- package/src/format.ts +19 -31
- package/src/parse/index.ts +16 -1009
- package/src/parse/leaf/array-parser.ts +36 -0
- package/src/parse/leaf/cbor-parser.ts +43 -0
- package/src/parse/leaf/date-parser.ts +81 -0
- package/src/parse/leaf/known-value-parser.ts +73 -0
- package/src/parse/leaf/null-parser.ts +16 -0
- package/src/parse/leaf/number-parser.ts +90 -0
- package/src/parse/leaf/tag-parser.ts +160 -0
- package/src/parse/meta/and-parser.ts +40 -0
- package/src/parse/meta/capture-parser.ts +50 -0
- package/src/parse/meta/group-parser.ts +77 -0
- package/src/parse/meta/not-parser.ts +30 -0
- package/src/parse/meta/or-parser.ts +36 -0
- package/src/parse/meta/primary-parser.ts +234 -0
- package/src/parse/meta/search-parser.ts +41 -0
- package/src/parse/meta/traverse-parser.ts +42 -0
- package/src/parse/structure/assertion-obj-parser.ts +44 -0
- package/src/parse/structure/assertion-parser.ts +22 -0
- package/src/parse/structure/assertion-pred-parser.ts +45 -0
- package/src/parse/structure/compressed-parser.ts +17 -0
- package/src/parse/structure/digest-parser.ts +132 -0
- package/src/parse/structure/elided-parser.ts +17 -0
- package/src/parse/structure/encrypted-parser.ts +17 -0
- package/src/parse/structure/node-parser.ts +54 -0
- package/src/parse/structure/object-parser.ts +32 -0
- package/src/parse/structure/obscured-parser.ts +17 -0
- package/src/parse/structure/predicate-parser.ts +32 -0
- package/src/parse/structure/subject-parser.ts +32 -0
- package/src/parse/structure/wrapped-parser.ts +36 -0
- package/src/pattern/dcbor-integration.ts +40 -8
- package/src/pattern/index.ts +29 -0
- package/src/pattern/leaf/array-pattern.ts +67 -169
- package/src/pattern/leaf/cbor-pattern.ts +37 -23
- package/src/pattern/leaf/index.ts +1 -1
- package/src/pattern/leaf/map-pattern.ts +21 -2
- package/src/pattern/leaf/tagged-pattern.ts +6 -1
- package/src/pattern/meta/search-pattern.ts +13 -38
- package/src/pattern/meta/traverse-pattern.ts +2 -2
- package/src/pattern/structure/assertions-pattern.ts +19 -53
- package/src/pattern/structure/digest-pattern.ts +18 -22
- package/src/pattern/structure/index.ts +3 -0
- package/src/pattern/structure/node-pattern.ts +10 -29
- package/src/pattern/structure/object-pattern.ts +2 -2
- package/src/pattern/structure/predicate-pattern.ts +2 -2
- package/src/pattern/structure/subject-pattern.ts +31 -4
- package/src/pattern/structure/wrapped-pattern.ts +28 -9
- package/src/pattern/vm.ts +4 -4
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { Interval, Interval as Interval$1, Quantifier, Quantifier as Quantifier$1, Reluctance, Reluctance as Reluctance$1, boolPatternAny, boolPatternDisplay, boolPatternPaths, boolPatternValue, byteStringPatternAny, byteStringPatternBinaryRegex, byteStringPatternDisplay, byteStringPatternPaths, byteStringPatternValue, datePatternAny, datePatternDisplay, datePatternEarliest, datePatternLatest, datePatternPaths, datePatternRange, datePatternRegex, datePatternStringValue, datePatternValue, knownValuePatternAny, knownValuePatternDisplay, knownValuePatternMatches, knownValuePatternNamed, knownValuePatternRegex, knownValuePatternValue, nullPatternDisplay, nullPatternPaths, numberPatternAny, numberPatternDisplay, numberPatternGreaterThan, numberPatternGreaterThanOrEqual, numberPatternInfinity, numberPatternLessThan, numberPatternLessThanOrEqual, numberPatternNaN, numberPatternNegInfinity, numberPatternPaths, numberPatternRange, numberPatternValue, parse as parse$1, patternDisplay, patternPathsWithCaptures as patternPathsWithCaptures$1, taggedPatternAny, taggedPatternDisplay, taggedPatternPathsWithCaptures, taggedPatternWithName, taggedPatternWithRegex, taggedPatternWithTag, textPatternAny, textPatternDisplay, textPatternPaths, textPatternRegex, textPatternValue } from "@bcts/dcbor-pattern";
|
|
2
|
-
import { UNIT } from "@bcts/known-values";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
1
|
+
import { Interval, Interval as Interval$1, Quantifier, Quantifier as Quantifier$1, Reluctance, Reluctance as Reluctance$1, arrayPatternAny, arrayPatternDisplay, arrayPatternEquals, arrayPatternMatches, arrayPatternWithElements, arrayPatternWithLength, arrayPatternWithLengthInterval, arrayPatternWithLengthRange, boolPatternAny, boolPatternDisplay, boolPatternPaths, boolPatternValue, byteStringPatternAny, byteStringPatternBinaryRegex, byteStringPatternDisplay, byteStringPatternPaths, byteStringPatternValue, datePatternAny, datePatternDisplay, datePatternEarliest, datePatternLatest, datePatternPaths, datePatternRange, datePatternRegex, datePatternStringValue, datePatternValue, knownValuePatternAny, knownValuePatternDisplay, knownValuePatternMatches, knownValuePatternNamed, knownValuePatternRegex, knownValuePatternValue, nullPatternDisplay, nullPatternPaths, numberPatternAny, numberPatternDisplay, numberPatternGreaterThan, numberPatternGreaterThanOrEqual, numberPatternInfinity, numberPatternLessThan, numberPatternLessThanOrEqual, numberPatternNaN, numberPatternNegInfinity, numberPatternPaths, numberPatternRange, numberPatternValue, parse as parse$1, patternDisplay, patternPathsWithCaptures as patternPathsWithCaptures$1, taggedPatternAny, taggedPatternDisplay, taggedPatternPathsWithCaptures, taggedPatternWithName, taggedPatternWithRegex, taggedPatternWithTag, textPatternAny, textPatternDisplay, textPatternPaths, textPatternRegex, textPatternValue } from "@bcts/dcbor-pattern";
|
|
2
|
+
import { KnownValue, UNIT } from "@bcts/known-values";
|
|
3
|
+
import { CborDate, asCborMap, bytesToHex, cbor, cborData, cborEquals } from "@bcts/dcbor";
|
|
4
|
+
import { Digest, Envelope } from "@bcts/envelope";
|
|
5
5
|
import { parseDcborItemPartial } from "@bcts/dcbor-parse";
|
|
6
6
|
//#region src/error.ts
|
|
7
7
|
/**
|
|
@@ -305,6 +305,14 @@ function formatPathsOpts() {
|
|
|
305
305
|
/**
|
|
306
306
|
* Gets a summary of an envelope for display.
|
|
307
307
|
*
|
|
308
|
+
* Mirrors Rust `envelope_summary` in `format.rs`: defers to
|
|
309
|
+
* `Envelope::format_flat()` for nodes / wrapped / assertions and to
|
|
310
|
+
* `cbor.envelope_summary(usize::MAX, ...)` for raw CBOR leaves. The
|
|
311
|
+
* obscured cases (`elided` / `encrypted` / `compressed`) emit just the
|
|
312
|
+
* keyword. KnownValue envelopes look up the canonical name via
|
|
313
|
+
* `KnownValue.name()`, matching the Rust call to
|
|
314
|
+
* `KnownValuesStore::known_value_for_raw_value(value, …)`.
|
|
315
|
+
*
|
|
308
316
|
* @param env - The envelope to summarize
|
|
309
317
|
* @returns A string summary of the envelope
|
|
310
318
|
*/
|
|
@@ -313,25 +321,17 @@ function envelopeSummary(env) {
|
|
|
313
321
|
const c = env.case();
|
|
314
322
|
let summary;
|
|
315
323
|
switch (c.type) {
|
|
316
|
-
case "node":
|
|
317
|
-
|
|
318
|
-
const assertions = env.assertions();
|
|
319
|
-
if (assertions.length > 0) summary = `NODE ${subjectSummary} [ ${assertions.map((a) => {
|
|
320
|
-
const ac = a.case();
|
|
321
|
-
if (ac.type === "assertion") return `${ac.assertion.predicate().summary(Number.MAX_SAFE_INTEGER)}: ${ac.assertion.object().summary(Number.MAX_SAFE_INTEGER)}`;
|
|
322
|
-
return a.summary(Number.MAX_SAFE_INTEGER);
|
|
323
|
-
}).join(", ")} ]`;
|
|
324
|
-
else summary = `NODE ${subjectSummary}`;
|
|
324
|
+
case "node":
|
|
325
|
+
summary = `NODE ${env.formatFlat()}`;
|
|
325
326
|
break;
|
|
326
|
-
}
|
|
327
327
|
case "leaf":
|
|
328
328
|
summary = `LEAF ${env.summary(Number.MAX_SAFE_INTEGER)}`;
|
|
329
329
|
break;
|
|
330
330
|
case "wrapped":
|
|
331
|
-
summary = `WRAPPED ${env.
|
|
331
|
+
summary = `WRAPPED ${env.formatFlat()}`;
|
|
332
332
|
break;
|
|
333
333
|
case "assertion":
|
|
334
|
-
summary = `ASSERTION ${
|
|
334
|
+
summary = `ASSERTION ${env.formatFlat()}`;
|
|
335
335
|
break;
|
|
336
336
|
case "elided":
|
|
337
337
|
summary = "ELIDED";
|
|
@@ -377,8 +377,8 @@ function formatPathOpt(path, opts = defaultFormatPathsOpts()) {
|
|
|
377
377
|
if (element === void 0) return "";
|
|
378
378
|
switch (opts.elementFormat.type) {
|
|
379
379
|
case "Summary": return truncateWithEllipsis(envelopeSummary(element), opts.elementFormat.maxLength);
|
|
380
|
-
case "EnvelopeUR": return element.
|
|
381
|
-
case "DigestUR": return element.digest().
|
|
380
|
+
case "EnvelopeUR": return element.urString();
|
|
381
|
+
case "DigestUR": return element.digest().urString();
|
|
382
382
|
}
|
|
383
383
|
}
|
|
384
384
|
switch (opts.elementFormat.type) {
|
|
@@ -393,8 +393,8 @@ function formatPathOpt(path, opts = defaultFormatPathsOpts()) {
|
|
|
393
393
|
}
|
|
394
394
|
return lines.join("\n");
|
|
395
395
|
}
|
|
396
|
-
case "EnvelopeUR": return path.map((element) => element.
|
|
397
|
-
case "DigestUR": return path.map((element) => element.digest().
|
|
396
|
+
case "EnvelopeUR": return path.map((element) => element.urString()).join(" ");
|
|
397
|
+
case "DigestUR": return path.map((element) => element.digest().urString()).join(" ");
|
|
398
398
|
}
|
|
399
399
|
}
|
|
400
400
|
/**
|
|
@@ -1236,25 +1236,16 @@ var DatePattern = class DatePattern {
|
|
|
1236
1236
|
};
|
|
1237
1237
|
//#endregion
|
|
1238
1238
|
//#region src/pattern/leaf/array-pattern.ts
|
|
1239
|
-
/**
|
|
1240
|
-
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
1241
|
-
* Copyright © 2025-2026 Parity Technologies
|
|
1242
|
-
*
|
|
1243
|
-
*
|
|
1244
|
-
* @bcts/envelope-pattern - Array pattern matching
|
|
1245
|
-
*
|
|
1246
|
-
* This is a 1:1 TypeScript port of bc-envelope-pattern-rust array_pattern.rs
|
|
1247
|
-
*
|
|
1248
|
-
* @module envelope-pattern/pattern/leaf/array-pattern
|
|
1249
|
-
*/
|
|
1250
1239
|
let createLeafArrayPattern;
|
|
1251
1240
|
function registerArrayPatternFactory(factory) {
|
|
1252
1241
|
createLeafArrayPattern = factory;
|
|
1253
1242
|
}
|
|
1254
1243
|
/**
|
|
1255
|
-
* Pattern for matching
|
|
1244
|
+
* Pattern for matching arrays.
|
|
1256
1245
|
*
|
|
1257
|
-
*
|
|
1246
|
+
* Mirrors Rust `ArrayPattern(dcbor_pattern::ArrayPattern)` from
|
|
1247
|
+
* `bc-envelope-pattern-rust/src/pattern/leaf/array_pattern.rs`. All
|
|
1248
|
+
* matching, display, and equality is delegated to dcbor-pattern.
|
|
1258
1249
|
*/
|
|
1259
1250
|
var ArrayPattern = class ArrayPattern {
|
|
1260
1251
|
_pattern;
|
|
@@ -1265,93 +1256,54 @@ var ArrayPattern = class ArrayPattern {
|
|
|
1265
1256
|
* Creates a new ArrayPattern that matches any array.
|
|
1266
1257
|
*/
|
|
1267
1258
|
static any() {
|
|
1268
|
-
return new ArrayPattern(
|
|
1259
|
+
return new ArrayPattern(arrayPatternAny());
|
|
1269
1260
|
}
|
|
1270
1261
|
/**
|
|
1271
1262
|
* Creates a new ArrayPattern that matches arrays with a specific length.
|
|
1272
1263
|
*/
|
|
1273
1264
|
static count(count) {
|
|
1274
|
-
return new ArrayPattern(
|
|
1275
|
-
type: "Interval",
|
|
1276
|
-
interval: Interval$1.exactly(count)
|
|
1277
|
-
});
|
|
1265
|
+
return new ArrayPattern(arrayPatternWithLength(count));
|
|
1278
1266
|
}
|
|
1279
1267
|
/**
|
|
1280
1268
|
* Creates a new ArrayPattern that matches arrays within a length range.
|
|
1281
1269
|
*/
|
|
1282
1270
|
static interval(min, max) {
|
|
1283
|
-
return new ArrayPattern(
|
|
1284
|
-
type: "Interval",
|
|
1285
|
-
interval: max !== void 0 ? Interval$1.from(min, max) : Interval$1.atLeast(min)
|
|
1286
|
-
});
|
|
1271
|
+
return new ArrayPattern(arrayPatternWithLengthRange(min, max));
|
|
1287
1272
|
}
|
|
1288
1273
|
/**
|
|
1289
|
-
* Creates a new ArrayPattern from a
|
|
1274
|
+
* Creates a new ArrayPattern from a length Interval.
|
|
1290
1275
|
*/
|
|
1291
|
-
static
|
|
1292
|
-
return new ArrayPattern(
|
|
1293
|
-
type: "DCBORPattern",
|
|
1294
|
-
pattern: dcborPattern
|
|
1295
|
-
});
|
|
1276
|
+
static fromInterval(interval) {
|
|
1277
|
+
return new ArrayPattern(arrayPatternWithLengthInterval(interval));
|
|
1296
1278
|
}
|
|
1297
1279
|
/**
|
|
1298
|
-
* Creates a new ArrayPattern
|
|
1280
|
+
* Creates a new ArrayPattern from a top-level dcbor-pattern.
|
|
1281
|
+
*
|
|
1282
|
+
* Mirrors Rust `ArrayPattern::from_dcbor_pattern`, which constructs an
|
|
1283
|
+
* `ArrayPattern::Elements`-style dcbor array pattern.
|
|
1299
1284
|
*/
|
|
1300
|
-
static
|
|
1301
|
-
return new ArrayPattern(
|
|
1302
|
-
type: "WithPatterns",
|
|
1303
|
-
patterns
|
|
1304
|
-
});
|
|
1285
|
+
static fromDcborPattern(pattern) {
|
|
1286
|
+
return new ArrayPattern(arrayPatternWithElements(pattern));
|
|
1305
1287
|
}
|
|
1306
1288
|
/**
|
|
1307
|
-
*
|
|
1289
|
+
* Creates a new ArrayPattern from an existing dcbor-pattern ArrayPattern.
|
|
1290
|
+
*
|
|
1291
|
+
* Mirrors Rust `ArrayPattern::from_dcbor_array_pattern`.
|
|
1308
1292
|
*/
|
|
1309
|
-
|
|
1293
|
+
static fromDcborArrayPattern(arrayPattern) {
|
|
1294
|
+
return new ArrayPattern(arrayPattern);
|
|
1295
|
+
}
|
|
1296
|
+
/**
|
|
1297
|
+
* Returns the underlying dcbor-pattern ArrayPattern.
|
|
1298
|
+
*/
|
|
1299
|
+
inner() {
|
|
1310
1300
|
return this._pattern;
|
|
1311
1301
|
}
|
|
1312
1302
|
pathsWithCaptures(haystack) {
|
|
1313
1303
|
const cbor = haystack.subject().asLeaf();
|
|
1314
1304
|
if (cbor === void 0) return [[], /* @__PURE__ */ new Map()];
|
|
1315
|
-
|
|
1316
|
-
|
|
1317
|
-
switch (this._pattern.type) {
|
|
1318
|
-
case "Any": return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1319
|
-
case "Interval": {
|
|
1320
|
-
const length = array.length;
|
|
1321
|
-
if (this._pattern.interval.contains(length)) return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1322
|
-
return [[], /* @__PURE__ */ new Map()];
|
|
1323
|
-
}
|
|
1324
|
-
case "DCBORPattern": {
|
|
1325
|
-
const { paths: dcborPaths, captures: dcborCaptures } = patternPathsWithCaptures$1(this._pattern.pattern, cbor);
|
|
1326
|
-
if (dcborPaths.length > 0) {
|
|
1327
|
-
const envelopePaths = dcborPaths.map((dcborPath) => {
|
|
1328
|
-
const envPath = [haystack];
|
|
1329
|
-
for (let i = 1; i < dcborPath.length; i++) {
|
|
1330
|
-
const elem = dcborPath[i];
|
|
1331
|
-
if (elem !== void 0) envPath.push(Envelope.newLeaf(elem));
|
|
1332
|
-
}
|
|
1333
|
-
return envPath;
|
|
1334
|
-
});
|
|
1335
|
-
const envelopeCaptures = /* @__PURE__ */ new Map();
|
|
1336
|
-
for (const [name, capturePaths] of dcborCaptures) {
|
|
1337
|
-
const envCapturePaths = capturePaths.map((dcborPath) => {
|
|
1338
|
-
const envPath = [haystack];
|
|
1339
|
-
for (let i = 1; i < dcborPath.length; i++) {
|
|
1340
|
-
const elem = dcborPath[i];
|
|
1341
|
-
if (elem !== void 0) envPath.push(Envelope.newLeaf(elem));
|
|
1342
|
-
}
|
|
1343
|
-
return envPath;
|
|
1344
|
-
});
|
|
1345
|
-
envelopeCaptures.set(name, envCapturePaths);
|
|
1346
|
-
}
|
|
1347
|
-
return [envelopePaths, envelopeCaptures];
|
|
1348
|
-
}
|
|
1349
|
-
return [[], /* @__PURE__ */ new Map()];
|
|
1350
|
-
}
|
|
1351
|
-
case "WithPatterns":
|
|
1352
|
-
if (array.length === this._pattern.patterns.length) return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1353
|
-
return [[], /* @__PURE__ */ new Map()];
|
|
1354
|
-
}
|
|
1305
|
+
if (arrayPatternMatches(this._pattern, cbor)) return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1306
|
+
return [[], /* @__PURE__ */ new Map()];
|
|
1355
1307
|
}
|
|
1356
1308
|
paths(haystack) {
|
|
1357
1309
|
return this.pathsWithCaptures(haystack)[0];
|
|
@@ -1367,54 +1319,31 @@ var ArrayPattern = class ArrayPattern {
|
|
|
1367
1319
|
return false;
|
|
1368
1320
|
}
|
|
1369
1321
|
toString() {
|
|
1370
|
-
|
|
1371
|
-
case "Any": return "[*]";
|
|
1372
|
-
case "Interval": return `[{${this._pattern.interval.toString()}}]`;
|
|
1373
|
-
case "DCBORPattern": return patternDisplay(this._pattern.pattern);
|
|
1374
|
-
case "WithPatterns": return `[${this._pattern.patterns.map(String).join(", ")}]`;
|
|
1375
|
-
}
|
|
1322
|
+
return arrayPatternDisplay(this._pattern, patternDisplay);
|
|
1376
1323
|
}
|
|
1377
1324
|
/**
|
|
1378
|
-
* Equality comparison.
|
|
1325
|
+
* Equality comparison. Delegates to dcbor-pattern's structural equality
|
|
1326
|
+
* with a display-string fallback for pattern-equality (mirrors Rust's
|
|
1327
|
+
* `Hash` impl that hashes the display, since dcbor `ArrayPattern`
|
|
1328
|
+
* itself does not derive `Hash`).
|
|
1379
1329
|
*/
|
|
1380
1330
|
equals(other) {
|
|
1381
|
-
|
|
1382
|
-
switch (this._pattern.type) {
|
|
1383
|
-
case "Any": return true;
|
|
1384
|
-
case "Interval": return this._pattern.interval.equals(other._pattern.interval);
|
|
1385
|
-
case "DCBORPattern": return patternDisplay(this._pattern.pattern) === patternDisplay(other._pattern.pattern);
|
|
1386
|
-
case "WithPatterns": {
|
|
1387
|
-
const otherPatterns = other._pattern.patterns;
|
|
1388
|
-
if (this._pattern.patterns.length !== otherPatterns.length) return false;
|
|
1389
|
-
for (let i = 0; i < this._pattern.patterns.length; i++) if (this._pattern.patterns[i] !== otherPatterns[i]) return false;
|
|
1390
|
-
return true;
|
|
1391
|
-
}
|
|
1392
|
-
}
|
|
1331
|
+
return arrayPatternEquals(this._pattern, other._pattern, (a, b) => patternDisplay(a) === patternDisplay(b));
|
|
1393
1332
|
}
|
|
1394
1333
|
/**
|
|
1395
|
-
* Hash code for use in Maps/Sets.
|
|
1334
|
+
* Hash code for use in Maps/Sets. Mirrors Rust's
|
|
1335
|
+
* "hash the string representation" approach.
|
|
1396
1336
|
*/
|
|
1397
1337
|
hashCode() {
|
|
1398
|
-
|
|
1399
|
-
|
|
1400
|
-
|
|
1401
|
-
|
|
1402
|
-
|
|
1338
|
+
let hash = 0;
|
|
1339
|
+
const str = this.toString();
|
|
1340
|
+
for (let i = 0; i < str.length; i++) {
|
|
1341
|
+
hash = (hash << 5) - hash + str.charCodeAt(i);
|
|
1342
|
+
hash = hash & hash;
|
|
1403
1343
|
}
|
|
1344
|
+
return hash;
|
|
1404
1345
|
}
|
|
1405
1346
|
};
|
|
1406
|
-
/**
|
|
1407
|
-
* Simple string hash function for hashCode implementations.
|
|
1408
|
-
*/
|
|
1409
|
-
function simpleStringHash$3(str) {
|
|
1410
|
-
let hash = 0;
|
|
1411
|
-
for (let i = 0; i < str.length; i++) {
|
|
1412
|
-
const char = str.charCodeAt(i);
|
|
1413
|
-
hash = (hash << 5) - hash + char;
|
|
1414
|
-
hash = hash & hash;
|
|
1415
|
-
}
|
|
1416
|
-
return hash;
|
|
1417
|
-
}
|
|
1418
1347
|
//#endregion
|
|
1419
1348
|
//#region src/pattern/leaf/map-pattern.ts
|
|
1420
1349
|
let createLeafMapPattern;
|
|
@@ -1447,6 +1376,19 @@ var MapPattern = class MapPattern {
|
|
|
1447
1376
|
});
|
|
1448
1377
|
}
|
|
1449
1378
|
/**
|
|
1379
|
+
* Creates a new MapPattern from a length Interval.
|
|
1380
|
+
*
|
|
1381
|
+
* Mirrors Rust `MapPattern::from_interval`. Used by the
|
|
1382
|
+
* dcbor-pattern → envelope-pattern bridge to preserve `{{n,m}}`
|
|
1383
|
+
* length info.
|
|
1384
|
+
*/
|
|
1385
|
+
static fromInterval(interval) {
|
|
1386
|
+
return new MapPattern({
|
|
1387
|
+
type: "Interval",
|
|
1388
|
+
interval
|
|
1389
|
+
});
|
|
1390
|
+
}
|
|
1391
|
+
/**
|
|
1450
1392
|
* Gets the pattern type.
|
|
1451
1393
|
*/
|
|
1452
1394
|
get pattern() {
|
|
@@ -1481,8 +1423,8 @@ var MapPattern = class MapPattern {
|
|
|
1481
1423
|
}
|
|
1482
1424
|
toString() {
|
|
1483
1425
|
switch (this._pattern.type) {
|
|
1484
|
-
case "Any": return "
|
|
1485
|
-
case "Interval": return `{
|
|
1426
|
+
case "Any": return "map";
|
|
1427
|
+
case "Interval": return `{${this._pattern.interval.toString()}}`;
|
|
1486
1428
|
}
|
|
1487
1429
|
}
|
|
1488
1430
|
/**
|
|
@@ -1735,7 +1677,7 @@ var TaggedPattern = class TaggedPattern {
|
|
|
1735
1677
|
return false;
|
|
1736
1678
|
}
|
|
1737
1679
|
toString() {
|
|
1738
|
-
return taggedPatternDisplay(this._inner, patternDisplay);
|
|
1680
|
+
return taggedPatternDisplay(this._inner, patternDisplay).replace(", ", ", ");
|
|
1739
1681
|
}
|
|
1740
1682
|
/**
|
|
1741
1683
|
* Equality comparison.
|
|
@@ -1861,10 +1803,18 @@ var CBORPattern = class CBORPattern {
|
|
|
1861
1803
|
}
|
|
1862
1804
|
/**
|
|
1863
1805
|
* Convert a single dcbor path to an envelope path.
|
|
1806
|
+
*
|
|
1807
|
+
* Uses canonical CBOR-byte equality (`cborEquals`) for the "skip the
|
|
1808
|
+
* dcbor root if it duplicates our base envelope" check, mirroring
|
|
1809
|
+
* Rust's `dcbor_path.first().map(|first| first == &base_cbor)`. The
|
|
1810
|
+
* earlier port compared diagnostic strings, which collapses values
|
|
1811
|
+
* that share a textual representation but differ structurally
|
|
1812
|
+
* (e.g. NaN payloads).
|
|
1864
1813
|
*/
|
|
1865
1814
|
_convertDcborPathToEnvelopePath(dcborPath, baseEnvelope, baseCbor) {
|
|
1866
1815
|
const envelopePath = [baseEnvelope];
|
|
1867
|
-
const
|
|
1816
|
+
const first = dcborPath[0];
|
|
1817
|
+
const elementsToAdd = first !== void 0 && cborEquals(first, baseCbor) ? dcborPath.slice(1) : dcborPath;
|
|
1868
1818
|
for (const cborElement of elementsToAdd) envelopePath.push(Envelope.newLeaf(cborElement));
|
|
1869
1819
|
return envelopePath;
|
|
1870
1820
|
}
|
|
@@ -1891,7 +1841,7 @@ var CBORPattern = class CBORPattern {
|
|
|
1891
1841
|
switch (this._pattern.type) {
|
|
1892
1842
|
case "Any": return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1893
1843
|
case "Value":
|
|
1894
|
-
if (knownValueCbor
|
|
1844
|
+
if (cborEquals(knownValueCbor, this._pattern.cbor)) return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1895
1845
|
return [[], /* @__PURE__ */ new Map()];
|
|
1896
1846
|
case "Pattern": {
|
|
1897
1847
|
const { paths: dcborPaths, captures: dcborCaptures } = patternPathsWithCaptures$1(this._pattern.pattern, knownValueCbor);
|
|
@@ -1915,7 +1865,7 @@ var CBORPattern = class CBORPattern {
|
|
|
1915
1865
|
switch (this._pattern.type) {
|
|
1916
1866
|
case "Any": return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1917
1867
|
case "Value":
|
|
1918
|
-
if (leafCbor
|
|
1868
|
+
if (cborEquals(leafCbor, this._pattern.cbor)) return [[[haystack]], /* @__PURE__ */ new Map()];
|
|
1919
1869
|
return [[], /* @__PURE__ */ new Map()];
|
|
1920
1870
|
case "Pattern": {
|
|
1921
1871
|
const { paths: dcborPaths, captures: dcborCaptures } = patternPathsWithCaptures$1(this._pattern.pattern, leafCbor);
|
|
@@ -1923,7 +1873,8 @@ var CBORPattern = class CBORPattern {
|
|
|
1923
1873
|
const basePath = [haystack];
|
|
1924
1874
|
return [dcborPaths.map((dcborPath) => {
|
|
1925
1875
|
const extendedPath = [...basePath];
|
|
1926
|
-
const
|
|
1876
|
+
const first = dcborPath[0];
|
|
1877
|
+
const elementsToAdd = first !== void 0 && cborEquals(first, leafCbor) ? dcborPath.slice(1) : dcborPath;
|
|
1927
1878
|
for (const cborElement of elementsToAdd) extendedPath.push(Envelope.newLeaf(cborElement));
|
|
1928
1879
|
return extendedPath;
|
|
1929
1880
|
}), this._convertDcborCapturesToEnvelopeCaptures(dcborCaptures, haystack, leafCbor)];
|
|
@@ -1958,13 +1909,16 @@ var CBORPattern = class CBORPattern {
|
|
|
1958
1909
|
}
|
|
1959
1910
|
}
|
|
1960
1911
|
/**
|
|
1961
|
-
* Equality comparison.
|
|
1912
|
+
* Equality comparison. `Value` variants compare by canonical CBOR
|
|
1913
|
+
* byte sequence (mirrors Rust `==` on `CBOR`); `Pattern` variants fall
|
|
1914
|
+
* back to display-string compare since `DCBORPattern` doesn't expose
|
|
1915
|
+
* structural equality outside the crate.
|
|
1962
1916
|
*/
|
|
1963
1917
|
equals(other) {
|
|
1964
1918
|
if (this._pattern.type !== other._pattern.type) return false;
|
|
1965
1919
|
switch (this._pattern.type) {
|
|
1966
1920
|
case "Any": return true;
|
|
1967
|
-
case "Value": return this._pattern.cbor
|
|
1921
|
+
case "Value": return cborEquals(this._pattern.cbor, other._pattern.cbor);
|
|
1968
1922
|
case "Pattern": return patternDisplay(this._pattern.pattern) === patternDisplay(other._pattern.pattern);
|
|
1969
1923
|
}
|
|
1970
1924
|
}
|
|
@@ -1974,7 +1928,12 @@ var CBORPattern = class CBORPattern {
|
|
|
1974
1928
|
hashCode() {
|
|
1975
1929
|
switch (this._pattern.type) {
|
|
1976
1930
|
case "Any": return 0;
|
|
1977
|
-
case "Value":
|
|
1931
|
+
case "Value": {
|
|
1932
|
+
const bytes = cborData(this._pattern.cbor);
|
|
1933
|
+
let hash = 0;
|
|
1934
|
+
for (const byte of bytes) hash = hash * 31 + byte | 0;
|
|
1935
|
+
return hash;
|
|
1936
|
+
}
|
|
1978
1937
|
case "Pattern": return simpleStringHash(patternDisplay(this._pattern.pattern));
|
|
1979
1938
|
}
|
|
1980
1939
|
}
|
|
@@ -2243,7 +2202,13 @@ var LeafStructurePattern = class LeafStructurePattern {
|
|
|
2243
2202
|
return 0;
|
|
2244
2203
|
}
|
|
2245
2204
|
};
|
|
2205
|
+
let dispatchPatternCompile$1;
|
|
2206
|
+
let dispatchPatternToString$3;
|
|
2246
2207
|
function registerSubjectPatternFactory(factory) {}
|
|
2208
|
+
function registerSubjectPatternDispatch(dispatch) {
|
|
2209
|
+
dispatchPatternCompile$1 = dispatch.compile;
|
|
2210
|
+
dispatchPatternToString$3 = dispatch.toString;
|
|
2211
|
+
}
|
|
2247
2212
|
/**
|
|
2248
2213
|
* Pattern for matching subjects in envelopes.
|
|
2249
2214
|
*
|
|
@@ -2307,9 +2272,10 @@ var SubjectPattern = class SubjectPattern {
|
|
|
2307
2272
|
code.push({ type: "NavigateSubject" });
|
|
2308
2273
|
break;
|
|
2309
2274
|
case "Pattern":
|
|
2275
|
+
if (dispatchPatternCompile$1 === void 0) throw new Error("SubjectPattern.compile requires the top-level Pattern compile dispatch; not registered");
|
|
2310
2276
|
code.push({ type: "NavigateSubject" });
|
|
2311
2277
|
code.push({ type: "ExtendTraversal" });
|
|
2312
|
-
this._pattern.pattern
|
|
2278
|
+
dispatchPatternCompile$1(this._pattern.pattern, code, literals, captures);
|
|
2313
2279
|
code.push({ type: "CombineTraversal" });
|
|
2314
2280
|
break;
|
|
2315
2281
|
}
|
|
@@ -2320,7 +2286,10 @@ var SubjectPattern = class SubjectPattern {
|
|
|
2320
2286
|
toString() {
|
|
2321
2287
|
switch (this._pattern.type) {
|
|
2322
2288
|
case "Any": return "subj";
|
|
2323
|
-
case "Pattern":
|
|
2289
|
+
case "Pattern": {
|
|
2290
|
+
const fmt = dispatchPatternToString$3;
|
|
2291
|
+
return `subj(${fmt !== void 0 ? fmt(this._pattern.pattern) : "?"})`;
|
|
2292
|
+
}
|
|
2324
2293
|
}
|
|
2325
2294
|
}
|
|
2326
2295
|
/**
|
|
@@ -2417,7 +2386,7 @@ var PredicatePattern = class PredicatePattern {
|
|
|
2417
2386
|
toString() {
|
|
2418
2387
|
switch (this._pattern.type) {
|
|
2419
2388
|
case "Any": return "pred";
|
|
2420
|
-
case "Pattern": return `pred(${this._pattern.pattern
|
|
2389
|
+
case "Pattern": return `pred(${dispatchPatternToString(this._pattern.pattern)})`;
|
|
2421
2390
|
}
|
|
2422
2391
|
}
|
|
2423
2392
|
/**
|
|
@@ -2514,7 +2483,7 @@ var ObjectPattern = class ObjectPattern {
|
|
|
2514
2483
|
toString() {
|
|
2515
2484
|
switch (this._pattern.type) {
|
|
2516
2485
|
case "Any": return "obj";
|
|
2517
|
-
case "Pattern": return `obj(${this._pattern.pattern
|
|
2486
|
+
case "Pattern": return `obj(${dispatchPatternToString(this._pattern.pattern)})`;
|
|
2518
2487
|
}
|
|
2519
2488
|
}
|
|
2520
2489
|
/**
|
|
@@ -2535,9 +2504,13 @@ var ObjectPattern = class ObjectPattern {
|
|
|
2535
2504
|
//#endregion
|
|
2536
2505
|
//#region src/pattern/structure/assertions-pattern.ts
|
|
2537
2506
|
let createStructureAssertionsPattern;
|
|
2507
|
+
let dispatchPatternToString$2;
|
|
2538
2508
|
function registerAssertionsPatternFactory(factory) {
|
|
2539
2509
|
createStructureAssertionsPattern = factory;
|
|
2540
2510
|
}
|
|
2511
|
+
function registerAssertionsPatternToStringDispatch(fn) {
|
|
2512
|
+
dispatchPatternToString$2 = fn;
|
|
2513
|
+
}
|
|
2541
2514
|
/**
|
|
2542
2515
|
* Pattern for matching assertions in envelopes.
|
|
2543
2516
|
*
|
|
@@ -2575,17 +2548,6 @@ var AssertionsPattern = class AssertionsPattern {
|
|
|
2575
2548
|
});
|
|
2576
2549
|
}
|
|
2577
2550
|
/**
|
|
2578
|
-
* Creates a new AssertionsPattern that matches assertions with both
|
|
2579
|
-
* predicate and object patterns.
|
|
2580
|
-
*/
|
|
2581
|
-
static withBoth(predicatePattern, objectPattern) {
|
|
2582
|
-
return new AssertionsPattern({
|
|
2583
|
-
type: "WithBoth",
|
|
2584
|
-
predicatePattern,
|
|
2585
|
-
objectPattern
|
|
2586
|
-
});
|
|
2587
|
-
}
|
|
2588
|
-
/**
|
|
2589
2551
|
* Gets the pattern type.
|
|
2590
2552
|
*/
|
|
2591
2553
|
get patternType() {
|
|
@@ -2596,14 +2558,12 @@ var AssertionsPattern = class AssertionsPattern {
|
|
|
2596
2558
|
*/
|
|
2597
2559
|
predicatePattern() {
|
|
2598
2560
|
if (this._pattern.type === "WithPredicate") return this._pattern.pattern;
|
|
2599
|
-
if (this._pattern.type === "WithBoth") return this._pattern.predicatePattern;
|
|
2600
2561
|
}
|
|
2601
2562
|
/**
|
|
2602
2563
|
* Gets the object pattern if this has one, undefined otherwise.
|
|
2603
2564
|
*/
|
|
2604
2565
|
objectPattern() {
|
|
2605
2566
|
if (this._pattern.type === "WithObject") return this._pattern.pattern;
|
|
2606
|
-
if (this._pattern.type === "WithBoth") return this._pattern.objectPattern;
|
|
2607
2567
|
}
|
|
2608
2568
|
pathsWithCaptures(haystack) {
|
|
2609
2569
|
const paths = [];
|
|
@@ -2625,14 +2585,6 @@ var AssertionsPattern = class AssertionsPattern {
|
|
|
2625
2585
|
}
|
|
2626
2586
|
break;
|
|
2627
2587
|
}
|
|
2628
|
-
case "WithBoth": {
|
|
2629
|
-
const predicate = assertion.asPredicate?.();
|
|
2630
|
-
const object = assertion.asObject?.();
|
|
2631
|
-
if (predicate !== void 0 && object !== void 0) {
|
|
2632
|
-
if (matchPattern(this._pattern.predicatePattern, predicate) && matchPattern(this._pattern.objectPattern, object)) paths.push([assertion]);
|
|
2633
|
-
}
|
|
2634
|
-
break;
|
|
2635
|
-
}
|
|
2636
2588
|
}
|
|
2637
2589
|
return [paths, /* @__PURE__ */ new Map()];
|
|
2638
2590
|
}
|
|
@@ -2655,11 +2607,11 @@ var AssertionsPattern = class AssertionsPattern {
|
|
|
2655
2607
|
return false;
|
|
2656
2608
|
}
|
|
2657
2609
|
toString() {
|
|
2610
|
+
const fmt = dispatchPatternToString$2;
|
|
2658
2611
|
switch (this._pattern.type) {
|
|
2659
2612
|
case "Any": return "assert";
|
|
2660
|
-
case "WithPredicate": return `assertpred(${this._pattern.pattern
|
|
2661
|
-
case "WithObject": return `assertobj(${this._pattern.pattern
|
|
2662
|
-
case "WithBoth": return `assert(${this._pattern.predicatePattern.toString()}, ${this._pattern.objectPattern.toString()})`;
|
|
2613
|
+
case "WithPredicate": return `assertpred(${fmt !== void 0 ? fmt(this._pattern.pattern) : "?"})`;
|
|
2614
|
+
case "WithObject": return `assertobj(${fmt !== void 0 ? fmt(this._pattern.pattern) : "?"})`;
|
|
2663
2615
|
}
|
|
2664
2616
|
}
|
|
2665
2617
|
/**
|
|
@@ -2671,10 +2623,6 @@ var AssertionsPattern = class AssertionsPattern {
|
|
|
2671
2623
|
case "Any": return true;
|
|
2672
2624
|
case "WithPredicate":
|
|
2673
2625
|
case "WithObject": return this._pattern.pattern === other._pattern.pattern;
|
|
2674
|
-
case "WithBoth": {
|
|
2675
|
-
const otherBoth = other._pattern;
|
|
2676
|
-
return this._pattern.predicatePattern === otherBoth.predicatePattern && this._pattern.objectPattern === otherBoth.objectPattern;
|
|
2677
|
-
}
|
|
2678
2626
|
}
|
|
2679
2627
|
}
|
|
2680
2628
|
/**
|
|
@@ -2685,7 +2633,6 @@ var AssertionsPattern = class AssertionsPattern {
|
|
|
2685
2633
|
case "Any": return 0;
|
|
2686
2634
|
case "WithPredicate": return 1;
|
|
2687
2635
|
case "WithObject": return 2;
|
|
2688
|
-
case "WithBoth": return 3;
|
|
2689
2636
|
}
|
|
2690
2637
|
}
|
|
2691
2638
|
};
|
|
@@ -2714,12 +2661,6 @@ var DigestPattern = class DigestPattern {
|
|
|
2714
2661
|
this._pattern = pattern;
|
|
2715
2662
|
}
|
|
2716
2663
|
/**
|
|
2717
|
-
* Creates a new DigestPattern that matches any digest.
|
|
2718
|
-
*/
|
|
2719
|
-
static any() {
|
|
2720
|
-
return new DigestPattern({ type: "Any" });
|
|
2721
|
-
}
|
|
2722
|
-
/**
|
|
2723
2664
|
* Creates a new DigestPattern that matches the exact digest.
|
|
2724
2665
|
*/
|
|
2725
2666
|
static digest(digest) {
|
|
@@ -2757,9 +2698,6 @@ var DigestPattern = class DigestPattern {
|
|
|
2757
2698
|
const digestData = digest.data();
|
|
2758
2699
|
let isHit = false;
|
|
2759
2700
|
switch (this._pattern.type) {
|
|
2760
|
-
case "Any":
|
|
2761
|
-
isHit = true;
|
|
2762
|
-
break;
|
|
2763
2701
|
case "Digest":
|
|
2764
2702
|
isHit = digest.equals(this._pattern.digest);
|
|
2765
2703
|
break;
|
|
@@ -2797,7 +2735,6 @@ var DigestPattern = class DigestPattern {
|
|
|
2797
2735
|
}
|
|
2798
2736
|
toString() {
|
|
2799
2737
|
switch (this._pattern.type) {
|
|
2800
|
-
case "Any": return "digest";
|
|
2801
2738
|
case "Digest": return `digest(${this._pattern.digest.hex()})`;
|
|
2802
2739
|
case "Prefix": return `digest(${bytesToHex(this._pattern.prefix)})`;
|
|
2803
2740
|
case "BinaryRegex": return `digest(/${this._pattern.regex.source}/)`;
|
|
@@ -2805,17 +2742,26 @@ var DigestPattern = class DigestPattern {
|
|
|
2805
2742
|
}
|
|
2806
2743
|
/**
|
|
2807
2744
|
* Equality comparison.
|
|
2745
|
+
*
|
|
2746
|
+
* `Prefix` comparison is case-insensitive on the *hex representation* to
|
|
2747
|
+
* mirror Rust's `eq_ignore_ascii_case` (which compares the underlying
|
|
2748
|
+
* `Vec<u8>` of hex bytes byte-for-byte modulo ASCII case). For raw byte
|
|
2749
|
+
* prefixes that happen to be ASCII, this is an ordinary byte compare.
|
|
2808
2750
|
*/
|
|
2809
2751
|
equals(other) {
|
|
2810
2752
|
if (this._pattern.type !== other._pattern.type) return false;
|
|
2811
2753
|
switch (this._pattern.type) {
|
|
2812
|
-
case "Any": return true;
|
|
2813
2754
|
case "Digest": return this._pattern.digest.equals(other._pattern.digest);
|
|
2814
2755
|
case "Prefix": {
|
|
2815
2756
|
const thisPrefix = this._pattern.prefix;
|
|
2816
2757
|
const otherPrefix = other._pattern.prefix;
|
|
2817
2758
|
if (thisPrefix.length !== otherPrefix.length) return false;
|
|
2818
|
-
for (let i = 0; i < thisPrefix.length; i++)
|
|
2759
|
+
for (let i = 0; i < thisPrefix.length; i++) {
|
|
2760
|
+
const a = thisPrefix[i];
|
|
2761
|
+
const b = otherPrefix[i];
|
|
2762
|
+
if (a === b) continue;
|
|
2763
|
+
if ((a >= 65 && a <= 90 ? a + 32 : a) !== (b >= 65 && b <= 90 ? b + 32 : b)) return false;
|
|
2764
|
+
}
|
|
2819
2765
|
return true;
|
|
2820
2766
|
}
|
|
2821
2767
|
case "BinaryRegex": return this._pattern.regex.source === other._pattern.regex.source;
|
|
@@ -2826,7 +2772,6 @@ var DigestPattern = class DigestPattern {
|
|
|
2826
2772
|
*/
|
|
2827
2773
|
hashCode() {
|
|
2828
2774
|
switch (this._pattern.type) {
|
|
2829
|
-
case "Any": return 0;
|
|
2830
2775
|
case "Digest": {
|
|
2831
2776
|
const data = this._pattern.digest.data().slice(0, 8);
|
|
2832
2777
|
let hash = 0;
|
|
@@ -2835,7 +2780,10 @@ var DigestPattern = class DigestPattern {
|
|
|
2835
2780
|
}
|
|
2836
2781
|
case "Prefix": {
|
|
2837
2782
|
let hash = 0;
|
|
2838
|
-
for (const byte of this._pattern.prefix)
|
|
2783
|
+
for (const byte of this._pattern.prefix) {
|
|
2784
|
+
const folded = byte >= 65 && byte <= 90 ? byte + 32 : byte;
|
|
2785
|
+
hash = hash * 31 + folded | 0;
|
|
2786
|
+
}
|
|
2839
2787
|
return hash;
|
|
2840
2788
|
}
|
|
2841
2789
|
case "BinaryRegex": {
|
|
@@ -2887,28 +2835,19 @@ var NodePattern = class NodePattern {
|
|
|
2887
2835
|
});
|
|
2888
2836
|
}
|
|
2889
2837
|
/**
|
|
2890
|
-
* Creates a new NodePattern with a subject pattern constraint.
|
|
2891
|
-
*/
|
|
2892
|
-
static withSubject(subjectPattern) {
|
|
2893
|
-
return new NodePattern({
|
|
2894
|
-
type: "WithSubject",
|
|
2895
|
-
subjectPattern
|
|
2896
|
-
});
|
|
2897
|
-
}
|
|
2898
|
-
/**
|
|
2899
2838
|
* Gets the pattern type.
|
|
2900
2839
|
*/
|
|
2901
2840
|
get patternType() {
|
|
2902
2841
|
return this._pattern;
|
|
2903
2842
|
}
|
|
2904
2843
|
/**
|
|
2905
|
-
*
|
|
2844
|
+
* Returns the subject pattern, if any. Rust's `NodePattern` does not carry
|
|
2845
|
+
* subject patterns, so this always returns `undefined`.
|
|
2906
2846
|
*/
|
|
2907
|
-
subjectPattern() {
|
|
2908
|
-
return this._pattern.type === "WithSubject" ? this._pattern.subjectPattern : void 0;
|
|
2909
|
-
}
|
|
2847
|
+
subjectPattern() {}
|
|
2910
2848
|
/**
|
|
2911
|
-
*
|
|
2849
|
+
* Returns the assertion patterns. Rust's `NodePattern` does not carry
|
|
2850
|
+
* assertion sub-patterns, so this always returns an empty array.
|
|
2912
2851
|
*/
|
|
2913
2852
|
assertionPatterns() {
|
|
2914
2853
|
return [];
|
|
@@ -2923,9 +2862,6 @@ var NodePattern = class NodePattern {
|
|
|
2923
2862
|
case "AssertionsInterval":
|
|
2924
2863
|
isHit = this._pattern.interval.contains(haystack.assertions().length);
|
|
2925
2864
|
break;
|
|
2926
|
-
case "WithSubject":
|
|
2927
|
-
isHit = true;
|
|
2928
|
-
break;
|
|
2929
2865
|
}
|
|
2930
2866
|
return [isHit ? [[haystack]] : [], /* @__PURE__ */ new Map()];
|
|
2931
2867
|
}
|
|
@@ -2946,7 +2882,6 @@ var NodePattern = class NodePattern {
|
|
|
2946
2882
|
switch (this._pattern.type) {
|
|
2947
2883
|
case "Any": return "node";
|
|
2948
2884
|
case "AssertionsInterval": return `node(${this._pattern.interval.toString()})`;
|
|
2949
|
-
case "WithSubject": return `node(${this._pattern.subjectPattern.toString()})`;
|
|
2950
2885
|
}
|
|
2951
2886
|
}
|
|
2952
2887
|
/**
|
|
@@ -2957,7 +2892,6 @@ var NodePattern = class NodePattern {
|
|
|
2957
2892
|
switch (this._pattern.type) {
|
|
2958
2893
|
case "Any": return true;
|
|
2959
2894
|
case "AssertionsInterval": return this._pattern.interval.equals(other._pattern.interval);
|
|
2960
|
-
case "WithSubject": return this._pattern.subjectPattern === other._pattern.subjectPattern;
|
|
2961
2895
|
}
|
|
2962
2896
|
}
|
|
2963
2897
|
/**
|
|
@@ -2967,7 +2901,6 @@ var NodePattern = class NodePattern {
|
|
|
2967
2901
|
switch (this._pattern.type) {
|
|
2968
2902
|
case "Any": return 0;
|
|
2969
2903
|
case "AssertionsInterval": return this._pattern.interval.min() * 31 + (this._pattern.interval.max() ?? 0);
|
|
2970
|
-
case "WithSubject": return 1;
|
|
2971
2904
|
}
|
|
2972
2905
|
}
|
|
2973
2906
|
};
|
|
@@ -3077,12 +3010,16 @@ var ObscuredPattern = class ObscuredPattern {
|
|
|
3077
3010
|
//#endregion
|
|
3078
3011
|
//#region src/pattern/structure/wrapped-pattern.ts
|
|
3079
3012
|
let createStructureWrappedPattern;
|
|
3013
|
+
let createAnyPattern;
|
|
3080
3014
|
let dispatchPatternPathsWithCaptures;
|
|
3081
3015
|
let dispatchPatternCompile;
|
|
3082
3016
|
let dispatchPatternToString$1;
|
|
3083
3017
|
function registerWrappedPatternFactory(factory) {
|
|
3084
3018
|
createStructureWrappedPattern = factory;
|
|
3085
3019
|
}
|
|
3020
|
+
function registerWrappedPatternAny(factory) {
|
|
3021
|
+
createAnyPattern = factory;
|
|
3022
|
+
}
|
|
3086
3023
|
function registerWrappedPatternDispatch(dispatch) {
|
|
3087
3024
|
dispatchPatternPathsWithCaptures = dispatch.pathsWithCaptures;
|
|
3088
3025
|
dispatchPatternCompile = dispatch.compile;
|
|
@@ -3116,10 +3053,15 @@ var WrappedPattern = class WrappedPattern {
|
|
|
3116
3053
|
}
|
|
3117
3054
|
/**
|
|
3118
3055
|
* Creates a new WrappedPattern that matches any wrapped envelope and descends into it.
|
|
3119
|
-
*
|
|
3056
|
+
*
|
|
3057
|
+
* Mirrors Rust `WrappedPattern::unwrap()` which delegates to
|
|
3058
|
+
* `Self::unwrap_matching(Pattern::any())`. The `any` factory is wired in
|
|
3059
|
+
* during module-load registration to break the circular import on the
|
|
3060
|
+
* top-level `Pattern` type.
|
|
3120
3061
|
*/
|
|
3121
3062
|
static unwrap() {
|
|
3122
|
-
|
|
3063
|
+
if (createAnyPattern === void 0) throw new Error("WrappedPattern.unwrap() requires Pattern.any factory; not registered");
|
|
3064
|
+
return WrappedPattern.unwrapMatching(createAnyPattern());
|
|
3123
3065
|
}
|
|
3124
3066
|
/**
|
|
3125
3067
|
* Gets the pattern type.
|
|
@@ -3195,9 +3137,9 @@ var WrappedPattern = class WrappedPattern {
|
|
|
3195
3137
|
switch (this._pattern.type) {
|
|
3196
3138
|
case "Any": return "wrapped";
|
|
3197
3139
|
case "Unwrap": {
|
|
3198
|
-
const
|
|
3199
|
-
if (
|
|
3200
|
-
return `unwrap(${
|
|
3140
|
+
const inner = this._pattern.pattern;
|
|
3141
|
+
if (inner.type === "Meta" && inner.pattern.type === "Any") return "unwrap";
|
|
3142
|
+
return `unwrap(${dispatchPatternToString$1 !== void 0 ? dispatchPatternToString$1(inner) : "?"})`;
|
|
3201
3143
|
}
|
|
3202
3144
|
}
|
|
3203
3145
|
}
|
|
@@ -3421,10 +3363,7 @@ function axisChildren(axis, env) {
|
|
|
3421
3363
|
case "Wrapped":
|
|
3422
3364
|
if (envCase.type === "node") {
|
|
3423
3365
|
const subject = envCase.subject;
|
|
3424
|
-
if (subject.isWrapped())
|
|
3425
|
-
const unwrapped = subject.unwrap();
|
|
3426
|
-
if (unwrapped !== void 0) return [[unwrapped, "Content"]];
|
|
3427
|
-
}
|
|
3366
|
+
if (subject.isWrapped()) return [[subject.tryUnwrap(), "Content"]];
|
|
3428
3367
|
} else if (envCase.type === "wrapped") return [[envCase.envelope, "Content"]];
|
|
3429
3368
|
return [];
|
|
3430
3369
|
}
|
|
@@ -4422,30 +4361,20 @@ var SearchPattern = class SearchPattern {
|
|
|
4422
4361
|
return [uniquePaths, /* @__PURE__ */ new Map()];
|
|
4423
4362
|
}
|
|
4424
4363
|
/**
|
|
4425
|
-
* Walk the envelope tree
|
|
4364
|
+
* Walk the envelope tree using the canonical `Envelope.walk` traversal.
|
|
4365
|
+
*
|
|
4366
|
+
* Mirrors Rust `bc_envelope::Envelope::walk(false, vec![], visitor)`
|
|
4367
|
+
* which is what `SearchPattern::paths_with_captures` uses. The earlier
|
|
4368
|
+
* port hand-rolled a recursion that double-recursed assertions and
|
|
4369
|
+
* stepped through wrapped subjects manually, producing a different
|
|
4370
|
+
* path order (and extra duplicates that the digest-set deduplication
|
|
4371
|
+
* would partially mask).
|
|
4426
4372
|
*/
|
|
4427
4373
|
_walkEnvelope(envelope, pathToCurrent, visitor) {
|
|
4428
|
-
|
|
4429
|
-
|
|
4430
|
-
|
|
4431
|
-
|
|
4432
|
-
for (const assertion of envelope.assertions()) {
|
|
4433
|
-
this._walkEnvelope(assertion, newPath, visitor);
|
|
4434
|
-
const predicate = assertion.asPredicate?.();
|
|
4435
|
-
if (predicate !== void 0) {
|
|
4436
|
-
const assertionPath = [...newPath, assertion];
|
|
4437
|
-
this._walkEnvelope(predicate, assertionPath, visitor);
|
|
4438
|
-
}
|
|
4439
|
-
const object = assertion.asObject?.();
|
|
4440
|
-
if (object !== void 0) {
|
|
4441
|
-
const assertionPath = [...newPath, assertion];
|
|
4442
|
-
this._walkEnvelope(object, assertionPath, visitor);
|
|
4443
|
-
}
|
|
4444
|
-
}
|
|
4445
|
-
if (subject.isWrapped()) {
|
|
4446
|
-
const unwrapped = subject.tryUnwrap?.();
|
|
4447
|
-
if (unwrapped !== void 0) this._walkEnvelope(unwrapped, newPath, visitor);
|
|
4448
|
-
}
|
|
4374
|
+
envelope.walk(false, pathToCurrent, (current, _level, _edge, state) => {
|
|
4375
|
+
visitor(current, state);
|
|
4376
|
+
return [[...state, current], false];
|
|
4377
|
+
});
|
|
4449
4378
|
}
|
|
4450
4379
|
paths(haystack) {
|
|
4451
4380
|
return this.pathsWithCaptures(haystack)[0];
|
|
@@ -4574,7 +4503,7 @@ var TraversePattern = class TraversePattern {
|
|
|
4574
4503
|
return _patternIsComplex(this._first) || this._rest !== void 0;
|
|
4575
4504
|
}
|
|
4576
4505
|
toString() {
|
|
4577
|
-
return this.patterns().map((p) => p
|
|
4506
|
+
return this.patterns().map((p) => dispatchPatternToString(p)).join(" -> ");
|
|
4578
4507
|
}
|
|
4579
4508
|
/**
|
|
4580
4509
|
* Equality comparison.
|
|
@@ -4923,17 +4852,44 @@ function convertValuePatternToEnvelopePattern(valuePattern) {
|
|
|
4923
4852
|
*/
|
|
4924
4853
|
function convertStructurePatternToEnvelopePattern(structurePattern) {
|
|
4925
4854
|
switch (structurePattern.type) {
|
|
4926
|
-
case "Array":
|
|
4927
|
-
|
|
4928
|
-
|
|
4929
|
-
|
|
4930
|
-
|
|
4931
|
-
|
|
4932
|
-
|
|
4933
|
-
|
|
4934
|
-
|
|
4935
|
-
|
|
4936
|
-
|
|
4855
|
+
case "Array": {
|
|
4856
|
+
const inner = structurePattern.pattern;
|
|
4857
|
+
let arrayPattern;
|
|
4858
|
+
switch (inner.variant) {
|
|
4859
|
+
case "Any":
|
|
4860
|
+
arrayPattern = ArrayPattern.any();
|
|
4861
|
+
break;
|
|
4862
|
+
case "Length":
|
|
4863
|
+
arrayPattern = ArrayPattern.fromInterval(inner.length);
|
|
4864
|
+
break;
|
|
4865
|
+
case "Elements":
|
|
4866
|
+
arrayPattern = ArrayPattern.fromDcborArrayPattern(inner);
|
|
4867
|
+
break;
|
|
4868
|
+
}
|
|
4869
|
+
return ok({
|
|
4870
|
+
type: "Leaf",
|
|
4871
|
+
pattern: leafArray(arrayPattern)
|
|
4872
|
+
});
|
|
4873
|
+
}
|
|
4874
|
+
case "Map": {
|
|
4875
|
+
const inner = structurePattern.pattern;
|
|
4876
|
+
let mapPattern;
|
|
4877
|
+
switch (inner.variant) {
|
|
4878
|
+
case "Any":
|
|
4879
|
+
mapPattern = MapPattern.any();
|
|
4880
|
+
break;
|
|
4881
|
+
case "Length":
|
|
4882
|
+
mapPattern = MapPattern.fromInterval(inner.length);
|
|
4883
|
+
break;
|
|
4884
|
+
case "Constraints":
|
|
4885
|
+
mapPattern = MapPattern.any();
|
|
4886
|
+
break;
|
|
4887
|
+
}
|
|
4888
|
+
return ok({
|
|
4889
|
+
type: "Leaf",
|
|
4890
|
+
pattern: leafMap(mapPattern)
|
|
4891
|
+
});
|
|
4892
|
+
}
|
|
4937
4893
|
case "Tagged": return ok({
|
|
4938
4894
|
type: "Leaf",
|
|
4939
4895
|
pattern: leafTag(TaggedPattern.fromDcborPattern(structurePattern.pattern))
|
|
@@ -4991,6 +4947,169 @@ function convertMetaPatternToEnvelopePattern(metaPattern, originalPattern) {
|
|
|
4991
4947
|
}
|
|
4992
4948
|
}
|
|
4993
4949
|
//#endregion
|
|
4950
|
+
//#region src/parse/utils.ts
|
|
4951
|
+
let createCborPattern;
|
|
4952
|
+
let createCborPatternFromDcbor;
|
|
4953
|
+
let createAnyArray;
|
|
4954
|
+
let createArrayWithCount;
|
|
4955
|
+
let createArrayWithRange;
|
|
4956
|
+
let createArrayFromDcborPattern;
|
|
4957
|
+
/**
|
|
4958
|
+
* Register pattern factory functions.
|
|
4959
|
+
* This is called by the pattern module to avoid circular dependencies.
|
|
4960
|
+
*/
|
|
4961
|
+
function registerPatternFactories(factories) {
|
|
4962
|
+
createCborPattern = factories.cborPattern;
|
|
4963
|
+
createCborPatternFromDcbor = factories.cborPatternFromDcbor;
|
|
4964
|
+
createAnyArray = factories.anyArray;
|
|
4965
|
+
createArrayWithCount = factories.arrayWithCount;
|
|
4966
|
+
createArrayWithRange = factories.arrayWithRange;
|
|
4967
|
+
createArrayFromDcborPattern = factories.arrayFromDcborPattern;
|
|
4968
|
+
}
|
|
4969
|
+
/**
|
|
4970
|
+
* Skips whitespace in the source string.
|
|
4971
|
+
*
|
|
4972
|
+
* @param src - The source string
|
|
4973
|
+
* @param pos - The current position (modified in place)
|
|
4974
|
+
*/
|
|
4975
|
+
function skipWs$1(src, pos) {
|
|
4976
|
+
while (pos.value < src.length) {
|
|
4977
|
+
const ch = src[pos.value];
|
|
4978
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f") pos.value++;
|
|
4979
|
+
else break;
|
|
4980
|
+
}
|
|
4981
|
+
}
|
|
4982
|
+
/**
|
|
4983
|
+
* Parses a CBOR value or dcbor-pattern expression.
|
|
4984
|
+
*
|
|
4985
|
+
* @param src - The source string
|
|
4986
|
+
* @returns The parsed pattern and consumed character count, or an error
|
|
4987
|
+
*/
|
|
4988
|
+
function parseCborInner(src) {
|
|
4989
|
+
if (createCborPattern === void 0 || createCborPatternFromDcbor === void 0) return err(unknown());
|
|
4990
|
+
const pos = { value: 0 };
|
|
4991
|
+
skipWs$1(src, pos);
|
|
4992
|
+
if (src[pos.value] === "/") {
|
|
4993
|
+
pos.value++;
|
|
4994
|
+
const start = pos.value;
|
|
4995
|
+
let escape = false;
|
|
4996
|
+
while (pos.value < src.length) {
|
|
4997
|
+
const b = src[pos.value];
|
|
4998
|
+
pos.value++;
|
|
4999
|
+
if (escape) {
|
|
5000
|
+
escape = false;
|
|
5001
|
+
continue;
|
|
5002
|
+
}
|
|
5003
|
+
if (b === "\\") {
|
|
5004
|
+
escape = true;
|
|
5005
|
+
continue;
|
|
5006
|
+
}
|
|
5007
|
+
if (b === "/") {
|
|
5008
|
+
const parseResult = parse$1(src.slice(start, pos.value - 1));
|
|
5009
|
+
if (!parseResult.ok) return err(invalidPattern({
|
|
5010
|
+
start,
|
|
5011
|
+
end: pos.value - 1
|
|
5012
|
+
}));
|
|
5013
|
+
skipWs$1(src, pos);
|
|
5014
|
+
return ok([createCborPatternFromDcbor(parseResult.value), pos.value]);
|
|
5015
|
+
}
|
|
5016
|
+
}
|
|
5017
|
+
return err(unterminatedRegex({
|
|
5018
|
+
start: start - 1,
|
|
5019
|
+
end: pos.value
|
|
5020
|
+
}));
|
|
5021
|
+
}
|
|
5022
|
+
if (src.slice(pos.value, pos.value + 3) === "ur:") {
|
|
5023
|
+
const parseResult = parseDcborItemPartial(src.slice(pos.value));
|
|
5024
|
+
if (!parseResult.ok) return err(unknown());
|
|
5025
|
+
const [cborValue, consumed] = parseResult.value;
|
|
5026
|
+
return ok([createCborPattern(cborValue), pos.value + consumed]);
|
|
5027
|
+
}
|
|
5028
|
+
const parseResult = parseDcborItemPartial(src.slice(pos.value));
|
|
5029
|
+
if (!parseResult.ok) return err(unknown());
|
|
5030
|
+
const [cborValue, consumed] = parseResult.value;
|
|
5031
|
+
return ok([createCborPattern(cborValue), pos.value + consumed]);
|
|
5032
|
+
}
|
|
5033
|
+
/**
|
|
5034
|
+
* Parses an array pattern inner content.
|
|
5035
|
+
*
|
|
5036
|
+
* @param src - The source string (content between [ and ])
|
|
5037
|
+
* @returns The parsed pattern and consumed character count, or an error
|
|
5038
|
+
*/
|
|
5039
|
+
function parseArrayInner(src) {
|
|
5040
|
+
if (createAnyArray === void 0 || createArrayWithCount === void 0 || createArrayWithRange === void 0 || createArrayFromDcborPattern === void 0) return err(unknown());
|
|
5041
|
+
const pos = { value: 0 };
|
|
5042
|
+
skipWs$1(src, pos);
|
|
5043
|
+
if (src[pos.value] === "*") {
|
|
5044
|
+
pos.value++;
|
|
5045
|
+
skipWs$1(src, pos);
|
|
5046
|
+
return ok([createAnyArray(), pos.value]);
|
|
5047
|
+
}
|
|
5048
|
+
if (src[pos.value] === "{") {
|
|
5049
|
+
pos.value++;
|
|
5050
|
+
skipWs$1(src, pos);
|
|
5051
|
+
const startPos = pos.value;
|
|
5052
|
+
while (pos.value < src.length && src[pos.value] !== void 0 && /\d/.test(src[pos.value])) pos.value++;
|
|
5053
|
+
if (startPos === pos.value) return err(invalidRange({
|
|
5054
|
+
start: pos.value,
|
|
5055
|
+
end: pos.value
|
|
5056
|
+
}));
|
|
5057
|
+
const firstNum = parseInt(src.slice(startPos, pos.value), 10);
|
|
5058
|
+
if (Number.isNaN(firstNum)) return err(invalidNumberFormat({
|
|
5059
|
+
start: startPos,
|
|
5060
|
+
end: pos.value
|
|
5061
|
+
}));
|
|
5062
|
+
skipWs$1(src, pos);
|
|
5063
|
+
if (pos.value >= src.length) return err(unexpectedEndOfInput());
|
|
5064
|
+
const ch = src[pos.value];
|
|
5065
|
+
if (ch === "}") {
|
|
5066
|
+
pos.value++;
|
|
5067
|
+
skipWs$1(src, pos);
|
|
5068
|
+
return ok([createArrayWithCount(firstNum), pos.value]);
|
|
5069
|
+
}
|
|
5070
|
+
if (ch === ",") {
|
|
5071
|
+
pos.value++;
|
|
5072
|
+
skipWs$1(src, pos);
|
|
5073
|
+
if (pos.value >= src.length) return err(unexpectedEndOfInput());
|
|
5074
|
+
const nextCh = src[pos.value];
|
|
5075
|
+
if (nextCh === "}") {
|
|
5076
|
+
pos.value++;
|
|
5077
|
+
skipWs$1(src, pos);
|
|
5078
|
+
return ok([createArrayWithRange(firstNum, void 0), pos.value]);
|
|
5079
|
+
}
|
|
5080
|
+
if (nextCh !== void 0 && /\d/.test(nextCh)) {
|
|
5081
|
+
const secondStart = pos.value;
|
|
5082
|
+
while (pos.value < src.length && src[pos.value] !== void 0 && /\d/.test(src[pos.value])) pos.value++;
|
|
5083
|
+
const secondNum = parseInt(src.slice(secondStart, pos.value), 10);
|
|
5084
|
+
if (Number.isNaN(secondNum)) return err(invalidNumberFormat({
|
|
5085
|
+
start: secondStart,
|
|
5086
|
+
end: pos.value
|
|
5087
|
+
}));
|
|
5088
|
+
skipWs$1(src, pos);
|
|
5089
|
+
if (pos.value >= src.length || src[pos.value] !== "}") return err(unexpectedEndOfInput());
|
|
5090
|
+
pos.value++;
|
|
5091
|
+
skipWs$1(src, pos);
|
|
5092
|
+
return ok([createArrayWithRange(firstNum, secondNum), pos.value]);
|
|
5093
|
+
}
|
|
5094
|
+
return err(invalidRange({
|
|
5095
|
+
start: pos.value,
|
|
5096
|
+
end: pos.value
|
|
5097
|
+
}));
|
|
5098
|
+
}
|
|
5099
|
+
return err(invalidRange({
|
|
5100
|
+
start: pos.value,
|
|
5101
|
+
end: pos.value
|
|
5102
|
+
}));
|
|
5103
|
+
}
|
|
5104
|
+
const parseResult = parse$1(`[${src.slice(pos.value)}]`);
|
|
5105
|
+
if (!parseResult.ok) return err(invalidPattern({
|
|
5106
|
+
start: pos.value,
|
|
5107
|
+
end: src.length
|
|
5108
|
+
}));
|
|
5109
|
+
const consumed = src.length - pos.value;
|
|
5110
|
+
return ok([createArrayFromDcborPattern(parseResult.value), consumed]);
|
|
5111
|
+
}
|
|
5112
|
+
//#endregion
|
|
4994
5113
|
//#region src/pattern/index.ts
|
|
4995
5114
|
/**
|
|
4996
5115
|
* Creates a Leaf pattern.
|
|
@@ -5505,6 +5624,12 @@ function registerAllFactories() {
|
|
|
5505
5624
|
compile: patternCompile,
|
|
5506
5625
|
toString: patternToString
|
|
5507
5626
|
});
|
|
5627
|
+
registerWrappedPatternAny(any);
|
|
5628
|
+
registerAssertionsPatternToStringDispatch(patternToString);
|
|
5629
|
+
registerSubjectPatternDispatch({
|
|
5630
|
+
compile: patternCompile,
|
|
5631
|
+
toString: patternToString
|
|
5632
|
+
});
|
|
5508
5633
|
registerAnyPatternFactory((p) => patternMeta(metaAny(p)));
|
|
5509
5634
|
registerAndPatternFactory((p) => patternMeta(metaAnd(p)));
|
|
5510
5635
|
registerOrPatternFactory((p) => patternMeta(metaOr(p)));
|
|
@@ -5516,6 +5641,14 @@ function registerAllFactories() {
|
|
|
5516
5641
|
}
|
|
5517
5642
|
registerAllFactories();
|
|
5518
5643
|
registerVMPatternFunctions(patternPathsWithCaptures, patternMatches, patternPaths);
|
|
5644
|
+
registerPatternFactories({
|
|
5645
|
+
cborPattern: (value) => cborValue(value),
|
|
5646
|
+
cborPatternFromDcbor: (pattern) => cborPattern(pattern),
|
|
5647
|
+
anyArray,
|
|
5648
|
+
arrayWithCount: (count) => patternLeaf(leafArray(ArrayPattern.count(count))),
|
|
5649
|
+
arrayWithRange: (min, max) => patternLeaf(leafArray(ArrayPattern.interval(min, max))),
|
|
5650
|
+
arrayFromDcborPattern: (pattern) => patternLeaf(leafArray(ArrayPattern.fromDcborPattern(pattern)))
|
|
5651
|
+
});
|
|
5519
5652
|
registerPatternMatchFn(patternMatches);
|
|
5520
5653
|
registerPatternDispatchFns({
|
|
5521
5654
|
pathsWithCaptures: patternPathsWithCaptures,
|
|
@@ -6269,305 +6402,198 @@ var Lexer = class {
|
|
|
6269
6402
|
}
|
|
6270
6403
|
};
|
|
6271
6404
|
//#endregion
|
|
6272
|
-
//#region src/parse/
|
|
6405
|
+
//#region src/parse/leaf/array-parser.ts
|
|
6273
6406
|
/**
|
|
6274
6407
|
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6275
6408
|
* Copyright © 2025-2026 Parity Technologies
|
|
6276
6409
|
*
|
|
6410
|
+
* Array parser — port of `bc-envelope-pattern-rust`
|
|
6411
|
+
* `parse/leaf/array_parser.rs`.
|
|
6277
6412
|
*
|
|
6278
|
-
*
|
|
6279
|
-
*
|
|
6280
|
-
*
|
|
6281
|
-
*
|
|
6413
|
+
* Mirrors Rust's flow exactly: after the `[` token has been consumed,
|
|
6414
|
+
* delegate to `utils::parseArrayInner` (which handles `*`, `{n}`, `{n,m}`,
|
|
6415
|
+
* `{n,}` directly and otherwise wraps the body in `[...]` and re-parses
|
|
6416
|
+
* via dcbor-pattern), then expect a closing `]`.
|
|
6282
6417
|
*
|
|
6283
|
-
* @module envelope-pattern/parse
|
|
6284
|
-
*/
|
|
6285
|
-
/**
|
|
6286
|
-
* Parse a pattern expression string into a Pattern.
|
|
6418
|
+
* @module envelope-pattern/parse/leaf/array-parser
|
|
6287
6419
|
*/
|
|
6288
|
-
function
|
|
6289
|
-
const
|
|
6290
|
-
|
|
6291
|
-
|
|
6292
|
-
|
|
6293
|
-
|
|
6294
|
-
|
|
6295
|
-
|
|
6296
|
-
|
|
6297
|
-
if (next !== void 0) return err(extraData(next.span));
|
|
6298
|
-
return result;
|
|
6420
|
+
function parseArray(lexer) {
|
|
6421
|
+
const inner = parseArrayInner(lexer.remainder());
|
|
6422
|
+
if (!inner.ok) return inner;
|
|
6423
|
+
const [pattern, consumed] = inner.value;
|
|
6424
|
+
lexer.bump(consumed);
|
|
6425
|
+
const close = lexer.next();
|
|
6426
|
+
if (close === void 0) return err(expectedCloseBracket(lexer.span()));
|
|
6427
|
+
if (close.token.type !== "BracketClose") return err(unexpectedToken(close.token, close.span));
|
|
6428
|
+
return ok(pattern);
|
|
6299
6429
|
}
|
|
6430
|
+
//#endregion
|
|
6431
|
+
//#region src/parse/leaf/cbor-parser.ts
|
|
6300
6432
|
/**
|
|
6301
|
-
*
|
|
6433
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6434
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6435
|
+
*
|
|
6436
|
+
* CBOR pattern parser — port of `bc-envelope-pattern-rust`
|
|
6437
|
+
* `parse/leaf/cbor_parser.rs`.
|
|
6438
|
+
*
|
|
6439
|
+
* Mirrors Rust's flow: lookahead for `(`. If absent, return `any_cbor()`.
|
|
6440
|
+
* Otherwise consume the `(`, delegate to `parseCborInner` (handles
|
|
6441
|
+
* `/regex/`, `ur:…`, and CBOR diagnostic notation), and expect a closing
|
|
6442
|
+
* `)`.
|
|
6443
|
+
*
|
|
6444
|
+
* @module envelope-pattern/parse/leaf/cbor-parser
|
|
6302
6445
|
*/
|
|
6303
|
-
function
|
|
6304
|
-
|
|
6305
|
-
|
|
6306
|
-
|
|
6307
|
-
|
|
6446
|
+
function parseCbor(lexer) {
|
|
6447
|
+
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anyCbor());
|
|
6448
|
+
lexer.next();
|
|
6449
|
+
const innerResult = parseCborInner(lexer.remainder());
|
|
6450
|
+
if (!innerResult.ok) return innerResult;
|
|
6451
|
+
const [pattern, consumed] = innerResult.value;
|
|
6452
|
+
lexer.bump(consumed);
|
|
6453
|
+
const close = lexer.next();
|
|
6454
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6455
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6456
|
+
return ok(pattern);
|
|
6308
6457
|
}
|
|
6458
|
+
//#endregion
|
|
6459
|
+
//#region src/parse/leaf/date-parser.ts
|
|
6309
6460
|
/**
|
|
6310
|
-
*
|
|
6461
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6462
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6463
|
+
*
|
|
6464
|
+
* Date content parser — port of `bc-envelope-pattern-rust`
|
|
6465
|
+
* `parse/leaf/date_parser.rs`.
|
|
6466
|
+
*
|
|
6467
|
+
* Mirrors Rust's `Date::from_string`, which accepts a strict ISO-8601
|
|
6468
|
+
* subset, by deferring to dcbor's `CborDate.fromString`. Falls back to JS
|
|
6469
|
+
* `Date.parse` only as a defensive shim — that branch is unreachable for
|
|
6470
|
+
* conformant inputs.
|
|
6471
|
+
*
|
|
6472
|
+
* @module envelope-pattern/parse/leaf/date-parser
|
|
6311
6473
|
*/
|
|
6312
|
-
function convertDcborPatternToEnvelopePattern$1(_dcborPattern) {
|
|
6313
|
-
return ok(any());
|
|
6314
|
-
}
|
|
6315
6474
|
/**
|
|
6316
|
-
* Parse
|
|
6475
|
+
* Parse a date pattern of one of the forms accepted by Rust:
|
|
6476
|
+
*
|
|
6477
|
+
* - `/regex/` (regex match against ISO-8601 string)
|
|
6478
|
+
* - `start...end` (inclusive range)
|
|
6479
|
+
* - `start...` (earliest)
|
|
6480
|
+
* - `...end` (latest)
|
|
6481
|
+
* - `iso-8601` (exact)
|
|
6482
|
+
*
|
|
6483
|
+
* Mirrors `parse_date_content` in Rust; uses `CborDate.fromString` so the
|
|
6484
|
+
* accepted formats match Rust's `bc_envelope::prelude::Date::from_string`
|
|
6485
|
+
* exactly rather than the looser JS `Date.parse`.
|
|
6317
6486
|
*/
|
|
6318
|
-
function
|
|
6319
|
-
|
|
6320
|
-
|
|
6321
|
-
|
|
6322
|
-
|
|
6323
|
-
|
|
6324
|
-
|
|
6325
|
-
|
|
6326
|
-
const nextExpr = parseTraverse(lexer);
|
|
6327
|
-
if (!nextExpr.ok) return nextExpr;
|
|
6328
|
-
patterns.push(nextExpr.value);
|
|
6487
|
+
function parseDateContent(content, span) {
|
|
6488
|
+
if (content.startsWith("/") && content.endsWith("/") && content.length >= 2) {
|
|
6489
|
+
const regexStr = content.slice(1, -1);
|
|
6490
|
+
try {
|
|
6491
|
+
return ok(dateRegex(new RegExp(regexStr)));
|
|
6492
|
+
} catch {
|
|
6493
|
+
return err(invalidRegex(span));
|
|
6494
|
+
}
|
|
6329
6495
|
}
|
|
6330
|
-
|
|
6331
|
-
|
|
6496
|
+
const ellipsisIdx = content.indexOf("...");
|
|
6497
|
+
if (ellipsisIdx !== -1) {
|
|
6498
|
+
const left = content.slice(0, ellipsisIdx);
|
|
6499
|
+
const right = content.slice(ellipsisIdx + 3);
|
|
6500
|
+
if (left.length === 0 && right.length > 0) {
|
|
6501
|
+
const parsed = parseIsoDateStrict(right);
|
|
6502
|
+
if (parsed === void 0) return err(invalidDateFormat(span));
|
|
6503
|
+
return ok(dateLatest(parsed));
|
|
6504
|
+
}
|
|
6505
|
+
if (left.length > 0 && right.length === 0) {
|
|
6506
|
+
const parsed = parseIsoDateStrict(left);
|
|
6507
|
+
if (parsed === void 0) return err(invalidDateFormat(span));
|
|
6508
|
+
return ok(dateEarliest(parsed));
|
|
6509
|
+
}
|
|
6510
|
+
if (left.length > 0 && right.length > 0) {
|
|
6511
|
+
const start = parseIsoDateStrict(left);
|
|
6512
|
+
const end = parseIsoDateStrict(right);
|
|
6513
|
+
if (start === void 0 || end === void 0) return err(invalidDateFormat(span));
|
|
6514
|
+
return ok(dateRange(start, end));
|
|
6515
|
+
}
|
|
6516
|
+
return err(invalidDateFormat(span));
|
|
6517
|
+
}
|
|
6518
|
+
const parsed = parseIsoDateStrict(content);
|
|
6519
|
+
if (parsed === void 0) return err(invalidDateFormat(span));
|
|
6520
|
+
return ok(date(parsed));
|
|
6332
6521
|
}
|
|
6522
|
+
function parseIsoDateStrict(value) {
|
|
6523
|
+
try {
|
|
6524
|
+
return CborDate.fromString(value);
|
|
6525
|
+
} catch {
|
|
6526
|
+
return;
|
|
6527
|
+
}
|
|
6528
|
+
}
|
|
6529
|
+
//#endregion
|
|
6530
|
+
//#region src/parse/leaf/known-value-parser.ts
|
|
6333
6531
|
/**
|
|
6334
|
-
*
|
|
6335
|
-
|
|
6336
|
-
|
|
6337
|
-
|
|
6338
|
-
|
|
6339
|
-
|
|
6340
|
-
|
|
6341
|
-
|
|
6342
|
-
|
|
6343
|
-
|
|
6344
|
-
|
|
6345
|
-
|
|
6346
|
-
|
|
6347
|
-
|
|
6348
|
-
|
|
6349
|
-
return ok(traverse(patterns));
|
|
6350
|
-
}
|
|
6351
|
-
/**
|
|
6352
|
-
* Parse an And expression: expr (& expr)*
|
|
6532
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6533
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6534
|
+
*
|
|
6535
|
+
* Helpers for parsing the body of a `'…'` (single-quoted) known-value
|
|
6536
|
+
* literal. Mirrors the inline body of Rust's `Token::SingleQuotedPattern`
|
|
6537
|
+
* branch in `parse_primary`:
|
|
6538
|
+
*
|
|
6539
|
+
* - If the contents are a valid `u64`, build `Pattern::known_value(...)`.
|
|
6540
|
+
* - Otherwise, build `Pattern::known_value_named(...)`.
|
|
6541
|
+
*
|
|
6542
|
+
* The earlier port duck-typed a fake `KnownValue`; this version uses the
|
|
6543
|
+
* real `KnownValue` constructor so all subsequent KnownValue methods work
|
|
6544
|
+
* (e.g., `taggedCbor()`, `name()`, etc.).
|
|
6545
|
+
*
|
|
6546
|
+
* @module envelope-pattern/parse/leaf/known-value-parser
|
|
6353
6547
|
*/
|
|
6354
|
-
function parseAnd(lexer) {
|
|
6355
|
-
const patterns = [];
|
|
6356
|
-
const first = parseNot(lexer);
|
|
6357
|
-
if (!first.ok) return first;
|
|
6358
|
-
patterns.push(first.value);
|
|
6359
|
-
while (true) {
|
|
6360
|
-
if (lexer.peekToken()?.token.type !== "And") break;
|
|
6361
|
-
lexer.next();
|
|
6362
|
-
const nextExpr = parseNot(lexer);
|
|
6363
|
-
if (!nextExpr.ok) return nextExpr;
|
|
6364
|
-
patterns.push(nextExpr.value);
|
|
6365
|
-
}
|
|
6366
|
-
if (patterns.length === 1) return ok(patterns[0]);
|
|
6367
|
-
return ok(and(patterns));
|
|
6368
|
-
}
|
|
6369
6548
|
/**
|
|
6370
|
-
*
|
|
6549
|
+
* Maximum value of a Rust `u64`. Used to reject literals that would
|
|
6550
|
+
* silently wrap or lose precision when constructing a `KnownValue`.
|
|
6371
6551
|
*/
|
|
6372
|
-
|
|
6373
|
-
if (lexer.peekToken()?.token.type === "Not") {
|
|
6374
|
-
lexer.next();
|
|
6375
|
-
const inner = parseGroup(lexer);
|
|
6376
|
-
if (!inner.ok) return inner;
|
|
6377
|
-
return ok(notMatching(inner.value));
|
|
6378
|
-
}
|
|
6379
|
-
return parseGroup(lexer);
|
|
6380
|
-
}
|
|
6552
|
+
const U64_MAX = 18446744073709551615n;
|
|
6381
6553
|
/**
|
|
6382
|
-
* Parse a
|
|
6554
|
+
* Parse the inner contents of a `'…'` known-value pattern token.
|
|
6555
|
+
*
|
|
6556
|
+
* Mirrors the Rust dispatch
|
|
6557
|
+
* ```ignore
|
|
6558
|
+
* if let Ok(value) = content.parse::<u64>() {
|
|
6559
|
+
* Pattern::known_value(KnownValue::new(value))
|
|
6560
|
+
* } else {
|
|
6561
|
+
* Pattern::known_value_named(content)
|
|
6562
|
+
* }
|
|
6563
|
+
* ```
|
|
6564
|
+
* but uses BigInt parsing to preserve full `u64` range — the previous
|
|
6565
|
+
* `parseInt(...)` path silently truncated above `2^53-1`.
|
|
6383
6566
|
*/
|
|
6384
|
-
function
|
|
6385
|
-
|
|
6386
|
-
|
|
6387
|
-
const next = lexer.peekToken();
|
|
6388
|
-
if (next === void 0) return primary;
|
|
6389
|
-
const tokenType = next.token.type;
|
|
6390
|
-
let quantifier;
|
|
6391
|
-
if (tokenType === "RepeatZeroOrMore") {
|
|
6392
|
-
lexer.next();
|
|
6393
|
-
quantifier = Quantifier$1.zeroOrMore(Reluctance$1.Greedy);
|
|
6394
|
-
} else if (tokenType === "RepeatZeroOrMoreLazy") {
|
|
6395
|
-
lexer.next();
|
|
6396
|
-
quantifier = Quantifier$1.zeroOrMore(Reluctance$1.Lazy);
|
|
6397
|
-
} else if (tokenType === "RepeatZeroOrMorePossessive") {
|
|
6398
|
-
lexer.next();
|
|
6399
|
-
quantifier = Quantifier$1.zeroOrMore(Reluctance$1.Possessive);
|
|
6400
|
-
} else if (tokenType === "RepeatOneOrMore") {
|
|
6401
|
-
lexer.next();
|
|
6402
|
-
quantifier = Quantifier$1.oneOrMore(Reluctance$1.Greedy);
|
|
6403
|
-
} else if (tokenType === "RepeatOneOrMoreLazy") {
|
|
6404
|
-
lexer.next();
|
|
6405
|
-
quantifier = Quantifier$1.oneOrMore(Reluctance$1.Lazy);
|
|
6406
|
-
} else if (tokenType === "RepeatOneOrMorePossessive") {
|
|
6407
|
-
lexer.next();
|
|
6408
|
-
quantifier = Quantifier$1.oneOrMore(Reluctance$1.Possessive);
|
|
6409
|
-
} else if (tokenType === "RepeatZeroOrOne") {
|
|
6410
|
-
lexer.next();
|
|
6411
|
-
quantifier = Quantifier$1.zeroOrOne(Reluctance$1.Greedy);
|
|
6412
|
-
} else if (tokenType === "RepeatZeroOrOneLazy") {
|
|
6413
|
-
lexer.next();
|
|
6414
|
-
quantifier = Quantifier$1.zeroOrOne(Reluctance$1.Lazy);
|
|
6415
|
-
} else if (tokenType === "RepeatZeroOrOnePossessive") {
|
|
6416
|
-
lexer.next();
|
|
6417
|
-
quantifier = Quantifier$1.zeroOrOne(Reluctance$1.Possessive);
|
|
6418
|
-
} else if (tokenType === "Range") {
|
|
6419
|
-
lexer.next();
|
|
6420
|
-
if (!next.token.value.ok) return err(next.token.value.error);
|
|
6421
|
-
quantifier = next.token.value.value;
|
|
6422
|
-
} else return primary;
|
|
6423
|
-
return ok(repeat(primary.value, quantifier.min(), quantifier.max(), quantifier.reluctance()));
|
|
6567
|
+
function parseKnownValueContent(content) {
|
|
6568
|
+
if (isU64Literal(content)) return ok(knownValue(new KnownValue(BigInt(content))));
|
|
6569
|
+
return ok(patternLeaf(leafKnownValue(KnownValuePattern.named(content))));
|
|
6424
6570
|
}
|
|
6425
|
-
|
|
6426
|
-
|
|
6427
|
-
|
|
6428
|
-
|
|
6429
|
-
|
|
6430
|
-
|
|
6431
|
-
|
|
6432
|
-
|
|
6433
|
-
|
|
6434
|
-
|
|
6435
|
-
|
|
6436
|
-
case "AssertionPred": return parseAssertionPred(lexer);
|
|
6437
|
-
case "AssertionObj": return parseAssertionObj(lexer);
|
|
6438
|
-
case "Digest": return parseDigest(lexer);
|
|
6439
|
-
case "Obj": return parseObject(lexer);
|
|
6440
|
-
case "Obscured": return ok(obscured());
|
|
6441
|
-
case "Elided": return ok(elided());
|
|
6442
|
-
case "Encrypted": return ok(encrypted());
|
|
6443
|
-
case "Compressed": return ok(compressed());
|
|
6444
|
-
case "Pred": return parsePredicate(lexer);
|
|
6445
|
-
case "Subject": return parseSubject(lexer);
|
|
6446
|
-
case "Wrapped": return ok(wrapped());
|
|
6447
|
-
case "Unwrap": return parseUnwrap(lexer);
|
|
6448
|
-
case "Leaf": return ok(leaf());
|
|
6449
|
-
case "GroupName": return parseCapture(lexer, token.name);
|
|
6450
|
-
case "ParenOpen": return parseParenGroup(lexer);
|
|
6451
|
-
case "Cbor": return parseCbor(lexer);
|
|
6452
|
-
case "RepeatZeroOrMore": return ok(any());
|
|
6453
|
-
case "BoolKeyword": return ok(anyBool());
|
|
6454
|
-
case "BoolTrue": return ok(bool(true));
|
|
6455
|
-
case "BoolFalse": return ok(bool(false));
|
|
6456
|
-
case "NumberKeyword": return ok(anyNumber());
|
|
6457
|
-
case "TextKeyword": return ok(anyText());
|
|
6458
|
-
case "StringLiteral":
|
|
6459
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6460
|
-
return ok(text(token.value.value));
|
|
6461
|
-
case "UnsignedInteger":
|
|
6462
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6463
|
-
return parseNumberRangeOrComparison(lexer, token.value.value);
|
|
6464
|
-
case "Integer":
|
|
6465
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6466
|
-
return parseNumberRangeOrComparison(lexer, token.value.value);
|
|
6467
|
-
case "Float":
|
|
6468
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6469
|
-
return parseNumberRangeOrComparison(lexer, token.value.value);
|
|
6470
|
-
case "GreaterThanOrEqual": return parseComparisonNumber(lexer, ">=");
|
|
6471
|
-
case "LessThanOrEqual": return parseComparisonNumber(lexer, "<=");
|
|
6472
|
-
case "GreaterThan": return parseComparisonNumber(lexer, ">");
|
|
6473
|
-
case "LessThan": return parseComparisonNumber(lexer, "<");
|
|
6474
|
-
case "NaN": return ok(patternLeaf(leafNumber(NumberPattern.nan())));
|
|
6475
|
-
case "Infinity": return ok(number(Infinity));
|
|
6476
|
-
case "NegativeInfinity": return ok(number(-Infinity));
|
|
6477
|
-
case "Regex":
|
|
6478
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6479
|
-
try {
|
|
6480
|
-
return ok(textRegex(new RegExp(token.value.value)));
|
|
6481
|
-
} catch {
|
|
6482
|
-
return err(invalidRegex(span));
|
|
6483
|
-
}
|
|
6484
|
-
case "BracketOpen": return parseArray(lexer);
|
|
6485
|
-
case "ByteString": return ok(anyByteString());
|
|
6486
|
-
case "HexPattern":
|
|
6487
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6488
|
-
return ok(byteString(token.value.value));
|
|
6489
|
-
case "HexBinaryRegex":
|
|
6490
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6491
|
-
try {
|
|
6492
|
-
return ok(patternLeaf(leafByteString(ByteStringPattern.regex(new RegExp(token.value.value)))));
|
|
6493
|
-
} catch {
|
|
6494
|
-
return err(invalidRegex(span));
|
|
6495
|
-
}
|
|
6496
|
-
case "DateKeyword": return ok(anyDate());
|
|
6497
|
-
case "DatePattern":
|
|
6498
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6499
|
-
return parseDateContent(token.value.value, span);
|
|
6500
|
-
case "Tagged": return parseTag(lexer);
|
|
6501
|
-
case "Known": return ok(anyKnownValue());
|
|
6502
|
-
case "SingleQuotedPattern":
|
|
6503
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6504
|
-
return parseKnownValueContent(token.value.value);
|
|
6505
|
-
case "SingleQuotedRegex":
|
|
6506
|
-
if (!token.value.ok) return err(token.value.error);
|
|
6507
|
-
try {
|
|
6508
|
-
return ok(patternLeaf(leafKnownValue(KnownValuePattern.regex(new RegExp(token.value.value)))));
|
|
6509
|
-
} catch {
|
|
6510
|
-
return err(invalidRegex(span));
|
|
6511
|
-
}
|
|
6512
|
-
case "Null": return ok(nullPattern());
|
|
6513
|
-
case "And":
|
|
6514
|
-
case "Or":
|
|
6515
|
-
case "Not":
|
|
6516
|
-
case "Traverse":
|
|
6517
|
-
case "RepeatZeroOrMoreLazy":
|
|
6518
|
-
case "RepeatZeroOrMorePossessive":
|
|
6519
|
-
case "RepeatOneOrMore":
|
|
6520
|
-
case "RepeatOneOrMoreLazy":
|
|
6521
|
-
case "RepeatOneOrMorePossessive":
|
|
6522
|
-
case "RepeatZeroOrOne":
|
|
6523
|
-
case "RepeatZeroOrOneLazy":
|
|
6524
|
-
case "RepeatZeroOrOnePossessive":
|
|
6525
|
-
case "ParenClose":
|
|
6526
|
-
case "BracketClose":
|
|
6527
|
-
case "Comma":
|
|
6528
|
-
case "Ellipsis":
|
|
6529
|
-
case "Range":
|
|
6530
|
-
case "Identifier": return err(unexpectedToken(token, span));
|
|
6571
|
+
function isU64Literal(content) {
|
|
6572
|
+
if (content.length === 0) return false;
|
|
6573
|
+
for (let i = 0; i < content.length; i++) {
|
|
6574
|
+
const c = content.charCodeAt(i);
|
|
6575
|
+
if (c < 48 || c > 57) return false;
|
|
6576
|
+
}
|
|
6577
|
+
try {
|
|
6578
|
+
const value = BigInt(content);
|
|
6579
|
+
return value >= 0n && value <= U64_MAX;
|
|
6580
|
+
} catch {
|
|
6581
|
+
return false;
|
|
6531
6582
|
}
|
|
6532
6583
|
}
|
|
6584
|
+
//#endregion
|
|
6585
|
+
//#region src/parse/leaf/number-parser.ts
|
|
6533
6586
|
/**
|
|
6534
|
-
*
|
|
6535
|
-
|
|
6536
|
-
|
|
6537
|
-
|
|
6538
|
-
|
|
6539
|
-
|
|
6540
|
-
type: "ExpectedCloseParen",
|
|
6541
|
-
span: lexer.span()
|
|
6542
|
-
});
|
|
6543
|
-
return ok(group(inner.value));
|
|
6544
|
-
}
|
|
6545
|
-
/**
|
|
6546
|
-
* Parse a capture group: @name pattern
|
|
6547
|
-
*/
|
|
6548
|
-
function parseCapture(lexer, name) {
|
|
6549
|
-
const inner = parseGroup(lexer);
|
|
6550
|
-
if (!inner.ok) return inner;
|
|
6551
|
-
return ok(capture(name, inner.value));
|
|
6552
|
-
}
|
|
6553
|
-
/**
|
|
6554
|
-
* Parse a search pattern: search(pattern)
|
|
6587
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6588
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6589
|
+
*
|
|
6590
|
+
* Number parsers — port of `bc-envelope-pattern-rust` `parse/leaf/number_parser.rs`.
|
|
6591
|
+
*
|
|
6592
|
+
* @module envelope-pattern/parse/leaf/number-parser
|
|
6555
6593
|
*/
|
|
6556
|
-
function parseSearch(lexer) {
|
|
6557
|
-
if (lexer.next()?.token.type !== "ParenOpen") return err({
|
|
6558
|
-
type: "ExpectedOpenParen",
|
|
6559
|
-
span: lexer.span()
|
|
6560
|
-
});
|
|
6561
|
-
const inner = parseOr(lexer);
|
|
6562
|
-
if (!inner.ok) return inner;
|
|
6563
|
-
if (lexer.next()?.token.type !== "ParenClose") return err({
|
|
6564
|
-
type: "ExpectedCloseParen",
|
|
6565
|
-
span: lexer.span()
|
|
6566
|
-
});
|
|
6567
|
-
return ok(search(inner.value));
|
|
6568
|
-
}
|
|
6569
6594
|
/**
|
|
6570
|
-
*
|
|
6595
|
+
* Parses an optional `...end` suffix following an already-consumed number,
|
|
6596
|
+
* mirroring Rust `parse_number_range_or_comparison`.
|
|
6571
6597
|
*/
|
|
6572
6598
|
function parseNumberRangeOrComparison(lexer, firstValue) {
|
|
6573
6599
|
const next = lexer.peekToken();
|
|
@@ -6577,10 +6603,7 @@ function parseNumberRangeOrComparison(lexer, firstValue) {
|
|
|
6577
6603
|
const endToken = lexer.next();
|
|
6578
6604
|
if (endToken === void 0) return err(unexpectedEndOfInput());
|
|
6579
6605
|
let endValue;
|
|
6580
|
-
if (endToken.token.type === "UnsignedInteger" || endToken.token.type === "Integer") {
|
|
6581
|
-
if (!endToken.token.value.ok) return err(endToken.token.value.error);
|
|
6582
|
-
endValue = endToken.token.value.value;
|
|
6583
|
-
} else if (endToken.token.type === "Float") {
|
|
6606
|
+
if (endToken.token.type === "UnsignedInteger" || endToken.token.type === "Integer" || endToken.token.type === "Float") {
|
|
6584
6607
|
if (!endToken.token.value.ok) return err(endToken.token.value.error);
|
|
6585
6608
|
endValue = endToken.token.value.value;
|
|
6586
6609
|
} else return err(unexpectedToken(endToken.token, endToken.span));
|
|
@@ -6589,16 +6612,14 @@ function parseNumberRangeOrComparison(lexer, firstValue) {
|
|
|
6589
6612
|
return ok(number(firstValue));
|
|
6590
6613
|
}
|
|
6591
6614
|
/**
|
|
6592
|
-
*
|
|
6615
|
+
* Parses a number following a comparison operator, mirroring Rust
|
|
6616
|
+
* `parse_comparison_number`.
|
|
6593
6617
|
*/
|
|
6594
6618
|
function parseComparisonNumber(lexer, op) {
|
|
6595
6619
|
const numToken = lexer.next();
|
|
6596
6620
|
if (numToken === void 0) return err(unexpectedEndOfInput());
|
|
6597
6621
|
let value;
|
|
6598
|
-
if (numToken.token.type === "UnsignedInteger" || numToken.token.type === "Integer") {
|
|
6599
|
-
if (!numToken.token.value.ok) return err(numToken.token.value.error);
|
|
6600
|
-
value = numToken.token.value.value;
|
|
6601
|
-
} else if (numToken.token.type === "Float") {
|
|
6622
|
+
if (numToken.token.type === "UnsignedInteger" || numToken.token.type === "Integer" || numToken.token.type === "Float") {
|
|
6602
6623
|
if (!numToken.token.value.ok) return err(numToken.token.value.error);
|
|
6603
6624
|
value = numToken.token.value.value;
|
|
6604
6625
|
} else return err(unexpectedToken(numToken.token, numToken.span));
|
|
@@ -6607,306 +6628,818 @@ function parseComparisonNumber(lexer, op) {
|
|
|
6607
6628
|
case "<=": return ok(patternLeaf(leafNumber(NumberPattern.lessThanOrEqual(value))));
|
|
6608
6629
|
case ">": return ok(numberGreaterThan(value));
|
|
6609
6630
|
case "<": return ok(numberLessThan(value));
|
|
6610
|
-
default: return ok(number(value));
|
|
6611
6631
|
}
|
|
6612
6632
|
}
|
|
6633
|
+
//#endregion
|
|
6634
|
+
//#region src/parse/leaf/tag-parser.ts
|
|
6613
6635
|
/**
|
|
6614
|
-
*
|
|
6636
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6637
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6638
|
+
*
|
|
6639
|
+
* Tag parser — port of `bc-envelope-pattern-rust`
|
|
6640
|
+
* `parse/leaf/tag_parser.rs`.
|
|
6641
|
+
*
|
|
6642
|
+
* Mirrors the Rust dispatch exactly: lookahead for `(`; if absent, return
|
|
6643
|
+
* the bare `any_tag()`. Otherwise build a synthetic dcbor-pattern
|
|
6644
|
+
* expression `tagged(<inner>)`, parse it via `@bcts/dcbor-pattern`, and
|
|
6645
|
+
* extract the resulting `TaggedPattern` to wrap as an envelope-pattern
|
|
6646
|
+
* leaf. This keeps the **full** tag selector (number, name, regex)
|
|
6647
|
+
* intact — the previous port discarded the tag value entirely.
|
|
6648
|
+
*
|
|
6649
|
+
* @module envelope-pattern/parse/leaf/tag-parser
|
|
6615
6650
|
*/
|
|
6616
|
-
function parseArray(lexer) {
|
|
6617
|
-
const first = lexer.peekToken();
|
|
6618
|
-
if (first === void 0) return err(unexpectedEndOfInput());
|
|
6619
|
-
if (first.token.type === "BracketClose") {
|
|
6620
|
-
lexer.next();
|
|
6621
|
-
return ok(patternLeaf(leafArray(ArrayPattern.count(0))));
|
|
6622
|
-
}
|
|
6623
|
-
if (first.token.type === "RepeatZeroOrMore") {
|
|
6624
|
-
lexer.next();
|
|
6625
|
-
if (lexer.next()?.token.type !== "BracketClose") return err({
|
|
6626
|
-
type: "ExpectedCloseBracket",
|
|
6627
|
-
span: lexer.span()
|
|
6628
|
-
});
|
|
6629
|
-
return ok(anyArray());
|
|
6630
|
-
}
|
|
6631
|
-
const patterns = [];
|
|
6632
|
-
while (true) {
|
|
6633
|
-
const next = lexer.peekToken();
|
|
6634
|
-
if (next === void 0) return err(unexpectedEndOfInput());
|
|
6635
|
-
if (next.token.type === "BracketClose") {
|
|
6636
|
-
lexer.next();
|
|
6637
|
-
break;
|
|
6638
|
-
}
|
|
6639
|
-
const pattern = parseOr(lexer);
|
|
6640
|
-
if (!pattern.ok) return pattern;
|
|
6641
|
-
patterns.push(pattern.value);
|
|
6642
|
-
const afterPattern = lexer.peekToken();
|
|
6643
|
-
if (afterPattern === void 0) return err(unexpectedEndOfInput());
|
|
6644
|
-
if (afterPattern.token.type === "Comma") lexer.next();
|
|
6645
|
-
else if (afterPattern.token.type !== "BracketClose") return err(unexpectedToken(afterPattern.token, afterPattern.span));
|
|
6646
|
-
}
|
|
6647
|
-
if (patterns.length === 0) return ok(patternLeaf(leafArray(ArrayPattern.count(0))));
|
|
6648
|
-
return ok(patternLeaf(leafArray(ArrayPattern.withPatterns(patterns))));
|
|
6649
|
-
}
|
|
6650
6651
|
/**
|
|
6651
|
-
* Parse
|
|
6652
|
+
* Parse `tagged` and `tagged(...)` patterns.
|
|
6652
6653
|
*/
|
|
6653
6654
|
function parseTag(lexer) {
|
|
6654
|
-
if (lexer.
|
|
6655
|
-
|
|
6656
|
-
|
|
6657
|
-
|
|
6658
|
-
if (
|
|
6659
|
-
|
|
6660
|
-
|
|
6661
|
-
|
|
6662
|
-
|
|
6663
|
-
|
|
6664
|
-
|
|
6665
|
-
|
|
6666
|
-
|
|
6667
|
-
|
|
6668
|
-
|
|
6669
|
-
if (content.startsWith("/") && content.endsWith("/")) {
|
|
6670
|
-
const regexStr = content.slice(1, -1);
|
|
6671
|
-
try {
|
|
6672
|
-
return ok(dateRegex(new RegExp(regexStr)));
|
|
6673
|
-
} catch {
|
|
6674
|
-
return err(invalidRegex(span));
|
|
6655
|
+
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anyTag());
|
|
6656
|
+
lexer.next();
|
|
6657
|
+
const remainder = lexer.remainder();
|
|
6658
|
+
const closeIdx = findMatchingCloseParen(remainder);
|
|
6659
|
+
if (closeIdx === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6660
|
+
const innerContent = remainder.slice(0, closeIdx);
|
|
6661
|
+
const dcborResult = parse$1(`tagged(${innerContent})`);
|
|
6662
|
+
if (dcborResult.ok) {
|
|
6663
|
+
const dcborPattern = dcborResult.value;
|
|
6664
|
+
if (dcborPattern.kind === "Structure" && dcborPattern.pattern.type === "Tagged") {
|
|
6665
|
+
lexer.bump(closeIdx);
|
|
6666
|
+
const close = lexer.next();
|
|
6667
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6668
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6669
|
+
return ok(patternLeaf(leafTag(TaggedPattern.fromDcborPattern(dcborPattern.pattern.pattern))));
|
|
6675
6670
|
}
|
|
6676
6671
|
}
|
|
6677
|
-
const
|
|
6678
|
-
if (
|
|
6679
|
-
|
|
6680
|
-
|
|
6681
|
-
|
|
6682
|
-
|
|
6683
|
-
|
|
6684
|
-
|
|
6685
|
-
|
|
6686
|
-
|
|
6687
|
-
|
|
6688
|
-
|
|
6689
|
-
|
|
6690
|
-
|
|
6691
|
-
|
|
6692
|
-
|
|
6693
|
-
|
|
6694
|
-
|
|
6695
|
-
|
|
6696
|
-
|
|
6697
|
-
if (left.length > 0 && right.length > 0) {
|
|
6698
|
-
const parsedStart = Date.parse(left);
|
|
6699
|
-
const parsedEnd = Date.parse(right);
|
|
6700
|
-
if (isNaN(parsedStart) || isNaN(parsedEnd)) return err({
|
|
6701
|
-
type: "InvalidDateFormat",
|
|
6702
|
-
span
|
|
6703
|
-
});
|
|
6704
|
-
return ok(dateRange(CborDate.fromDatetime(new Date(parsedStart)), CborDate.fromDatetime(new Date(parsedEnd))));
|
|
6672
|
+
const fallback = parseTagInner(innerContent);
|
|
6673
|
+
if (!fallback.ok) return fallback;
|
|
6674
|
+
lexer.bump(closeIdx);
|
|
6675
|
+
const close = lexer.next();
|
|
6676
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6677
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6678
|
+
return ok(fallback.value);
|
|
6679
|
+
}
|
|
6680
|
+
/**
|
|
6681
|
+
* Locate the index of the closing `)` matching the `(` that has already
|
|
6682
|
+
* been consumed by `parseTag`. Mirrors Rust `find_matching_paren`.
|
|
6683
|
+
*/
|
|
6684
|
+
function findMatchingCloseParen(src) {
|
|
6685
|
+
let depth = 0;
|
|
6686
|
+
for (let i = 0; i < src.length; i++) {
|
|
6687
|
+
const ch = src.charCodeAt(i);
|
|
6688
|
+
if (ch === 40) depth += 1;
|
|
6689
|
+
else if (ch === 41) {
|
|
6690
|
+
if (depth === 0) return i;
|
|
6691
|
+
depth -= 1;
|
|
6705
6692
|
}
|
|
6706
|
-
return err({
|
|
6707
|
-
type: "InvalidDateFormat",
|
|
6708
|
-
span
|
|
6709
|
-
});
|
|
6710
6693
|
}
|
|
6711
|
-
const parsed = Date.parse(content);
|
|
6712
|
-
if (isNaN(parsed)) return err({
|
|
6713
|
-
type: "InvalidDateFormat",
|
|
6714
|
-
span
|
|
6715
|
-
});
|
|
6716
|
-
return ok(date(CborDate.fromDatetime(new Date(parsed))));
|
|
6717
6694
|
}
|
|
6718
6695
|
/**
|
|
6719
|
-
*
|
|
6696
|
+
* Fallback for `tagged(N)` and `tagged(name)` when the full delegation
|
|
6697
|
+
* to dcbor-pattern fails. Mirrors Rust `parse_tag_inner`.
|
|
6720
6698
|
*/
|
|
6721
|
-
function
|
|
6722
|
-
const
|
|
6723
|
-
if (
|
|
6724
|
-
|
|
6699
|
+
function parseTagInner(src) {
|
|
6700
|
+
const trimmed = src.trim();
|
|
6701
|
+
if (trimmed.length === 0) return err(unexpectedEndOfInput());
|
|
6702
|
+
if (trimmed.startsWith("/")) return err(unexpectedEndOfInput());
|
|
6703
|
+
if (/^\d+$/.test(trimmed)) try {
|
|
6704
|
+
const dcborResult = parse$1(`tagged(${trimmed})`);
|
|
6705
|
+
if (dcborResult.ok && dcborResult.value.kind === "Structure" && dcborResult.value.pattern.type === "Tagged") return ok(patternLeaf(leafTag(TaggedPattern.fromDcborPattern(dcborResult.value.pattern.pattern))));
|
|
6706
|
+
} catch {}
|
|
6707
|
+
const dcborResult = parse$1(`tagged(${trimmed})`);
|
|
6708
|
+
if (dcborResult.ok && dcborResult.value.kind === "Structure" && dcborResult.value.pattern.type === "Tagged") return ok(patternLeaf(leafTag(TaggedPattern.fromDcborPattern(dcborResult.value.pattern.pattern))));
|
|
6709
|
+
return err(unexpectedEndOfInput());
|
|
6725
6710
|
}
|
|
6711
|
+
//#endregion
|
|
6712
|
+
//#region src/parse/structure/assertion-parser.ts
|
|
6726
6713
|
/**
|
|
6727
|
-
*
|
|
6714
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6715
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6716
|
+
*
|
|
6717
|
+
* Assertion parser — port of `bc-envelope-pattern-rust`
|
|
6718
|
+
* `parse/structure/assertion_parser.rs`.
|
|
6719
|
+
*
|
|
6720
|
+
* Note: Rust's `parse_assertion` ignores its lexer entirely and always
|
|
6721
|
+
* returns `Pattern::any_assertion()`. There is intentionally **no**
|
|
6722
|
+
* `assert(pred, obj)` syntax — predicate/object filters are written via
|
|
6723
|
+
* the dedicated `assertpred(...)` / `assertobj(...)` keywords.
|
|
6728
6724
|
*
|
|
6729
|
-
*
|
|
6730
|
-
* then CBOR diagnostic notation via parseDcborItemPartial, then falls
|
|
6731
|
-
* back to parseOr for envelope pattern expressions.
|
|
6725
|
+
* @module envelope-pattern/parse/structure/assertion-parser
|
|
6732
6726
|
*/
|
|
6733
|
-
function
|
|
6734
|
-
|
|
6735
|
-
lexer.next();
|
|
6736
|
-
if (lexer.peek() === "/") {
|
|
6737
|
-
const regexTokenResult = lexer.next();
|
|
6738
|
-
if (regexTokenResult?.token.type === "Regex") {
|
|
6739
|
-
const regexToken = regexTokenResult.token;
|
|
6740
|
-
if (!regexToken.value.ok) return err(regexToken.value.error);
|
|
6741
|
-
const keyword = regexToken.value.value;
|
|
6742
|
-
const dcborResult = parse$1(keyword);
|
|
6743
|
-
if (!dcborResult.ok) return err(unexpectedToken(regexToken, regexTokenResult.span));
|
|
6744
|
-
if (lexer.next()?.token.type !== "ParenClose") return err({
|
|
6745
|
-
type: "ExpectedCloseParen",
|
|
6746
|
-
span: lexer.span()
|
|
6747
|
-
});
|
|
6748
|
-
return ok(cborPattern(dcborResult.value));
|
|
6749
|
-
}
|
|
6750
|
-
}
|
|
6751
|
-
const cborResult = parseDcborItemPartial(lexer.remainder());
|
|
6752
|
-
if (cborResult.ok) {
|
|
6753
|
-
const [cborData, consumed] = cborResult.value;
|
|
6754
|
-
lexer.bump(consumed);
|
|
6755
|
-
while (lexer.peek() === " " || lexer.peek() === " " || lexer.peek() === "\n") lexer.bump(1);
|
|
6756
|
-
if (lexer.next()?.token.type !== "ParenClose") return err({
|
|
6757
|
-
type: "ExpectedCloseParen",
|
|
6758
|
-
span: lexer.span()
|
|
6759
|
-
});
|
|
6760
|
-
return ok(cborValue(cborData));
|
|
6761
|
-
}
|
|
6762
|
-
const inner = parseOr(lexer);
|
|
6763
|
-
if (!inner.ok) return inner;
|
|
6764
|
-
if (lexer.next()?.token.type !== "ParenClose") return err({
|
|
6765
|
-
type: "ExpectedCloseParen",
|
|
6766
|
-
span: lexer.span()
|
|
6767
|
-
});
|
|
6768
|
-
return inner;
|
|
6727
|
+
function parseAssertion(_lexer) {
|
|
6728
|
+
return ok(anyAssertion());
|
|
6769
6729
|
}
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
|
|
6773
|
-
|
|
6774
|
-
|
|
6775
|
-
|
|
6776
|
-
|
|
6777
|
-
|
|
6778
|
-
|
|
6779
|
-
|
|
6780
|
-
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6730
|
+
//#endregion
|
|
6731
|
+
//#region src/parse/structure/assertion-obj-parser.ts
|
|
6732
|
+
/**
|
|
6733
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6734
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6735
|
+
*
|
|
6736
|
+
* Assertion-object parser — port of
|
|
6737
|
+
* `bc-envelope-pattern-rust/src/parse/structure/assertion_obj_parser.rs`.
|
|
6738
|
+
*
|
|
6739
|
+
* Requires `assertobj(<pattern>)`. The bare `assertobj` keyword is a
|
|
6740
|
+
* syntax error in Rust; we now mirror that behaviour.
|
|
6741
|
+
*
|
|
6742
|
+
* @module envelope-pattern/parse/structure/assertion-obj-parser
|
|
6743
|
+
*/
|
|
6744
|
+
function parseAssertionObj(lexer) {
|
|
6745
|
+
const open = lexer.next();
|
|
6746
|
+
if (open === void 0) return err(unexpectedEndOfInput());
|
|
6747
|
+
if (open.token.type !== "ParenOpen") return err(unexpectedToken(open.token, open.span));
|
|
6785
6748
|
const inner = parseOr(lexer);
|
|
6786
6749
|
if (!inner.ok) return inner;
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
|
|
6790
|
-
|
|
6791
|
-
return ok(patternStructure(structureNode(NodePattern.withSubject(inner.value))));
|
|
6792
|
-
}
|
|
6793
|
-
function parseAssertion(lexer) {
|
|
6794
|
-
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anyAssertion());
|
|
6795
|
-
lexer.next();
|
|
6796
|
-
const pred = parseOr(lexer);
|
|
6797
|
-
if (!pred.ok) return pred;
|
|
6798
|
-
const comma = lexer.next();
|
|
6799
|
-
if (comma?.token.type !== "Comma") return err(unexpectedToken(comma?.token ?? { type: "Null" }, comma?.span ?? lexer.span()));
|
|
6800
|
-
const obj = parseOr(lexer);
|
|
6801
|
-
if (!obj.ok) return obj;
|
|
6802
|
-
if (lexer.next()?.token.type !== "ParenClose") return err({
|
|
6803
|
-
type: "ExpectedCloseParen",
|
|
6804
|
-
span: lexer.span()
|
|
6805
|
-
});
|
|
6806
|
-
return ok(patternStructure(structureAssertions(AssertionsPattern.withBoth(pred.value, obj.value))));
|
|
6750
|
+
const close = lexer.next();
|
|
6751
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6752
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6753
|
+
return ok(assertionWithObject(inner.value));
|
|
6807
6754
|
}
|
|
6755
|
+
//#endregion
|
|
6756
|
+
//#region src/parse/structure/assertion-pred-parser.ts
|
|
6757
|
+
/**
|
|
6758
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6759
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6760
|
+
*
|
|
6761
|
+
* Assertion-predicate parser — port of
|
|
6762
|
+
* `bc-envelope-pattern-rust/src/parse/structure/assertion_pred_parser.rs`.
|
|
6763
|
+
*
|
|
6764
|
+
* Requires `assertpred(<pattern>)`. The bare `assertpred` keyword is a
|
|
6765
|
+
* syntax error in Rust (it errors on `UnexpectedEndOfInput` /
|
|
6766
|
+
* `UnexpectedToken`); we now mirror that behaviour.
|
|
6767
|
+
*
|
|
6768
|
+
* @module envelope-pattern/parse/structure/assertion-pred-parser
|
|
6769
|
+
*/
|
|
6808
6770
|
function parseAssertionPred(lexer) {
|
|
6809
|
-
|
|
6810
|
-
|
|
6771
|
+
const open = lexer.next();
|
|
6772
|
+
if (open === void 0) return err(unexpectedEndOfInput());
|
|
6773
|
+
if (open.token.type !== "ParenOpen") return err(unexpectedToken(open.token, open.span));
|
|
6811
6774
|
const inner = parseOr(lexer);
|
|
6812
6775
|
if (!inner.ok) return inner;
|
|
6813
|
-
|
|
6814
|
-
|
|
6815
|
-
|
|
6816
|
-
});
|
|
6776
|
+
const close = lexer.next();
|
|
6777
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6778
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6817
6779
|
return ok(assertionWithPredicate(inner.value));
|
|
6818
6780
|
}
|
|
6819
|
-
|
|
6820
|
-
|
|
6821
|
-
|
|
6822
|
-
|
|
6823
|
-
|
|
6824
|
-
|
|
6825
|
-
|
|
6826
|
-
|
|
6827
|
-
|
|
6828
|
-
|
|
6781
|
+
//#endregion
|
|
6782
|
+
//#region src/parse/structure/compressed-parser.ts
|
|
6783
|
+
/**
|
|
6784
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6785
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6786
|
+
*
|
|
6787
|
+
* Compressed parser — port of `bc-envelope-pattern-rust`
|
|
6788
|
+
* `parse/structure/compressed_parser.rs`.
|
|
6789
|
+
*
|
|
6790
|
+
* @module envelope-pattern/parse/structure/compressed-parser
|
|
6791
|
+
*/
|
|
6792
|
+
function parseCompressed(_lexer) {
|
|
6793
|
+
return ok(compressed());
|
|
6829
6794
|
}
|
|
6795
|
+
//#endregion
|
|
6796
|
+
//#region src/parse/structure/digest-parser.ts
|
|
6797
|
+
/**
|
|
6798
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6799
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6800
|
+
*
|
|
6801
|
+
* Digest parser — port of `bc-envelope-pattern-rust`
|
|
6802
|
+
* `parse/structure/digest_parser.rs`.
|
|
6803
|
+
*
|
|
6804
|
+
* Mirrors Rust exactly:
|
|
6805
|
+
*
|
|
6806
|
+
* - Requires `digest(...)` — bare `digest` is an `UnexpectedEndOfInput`
|
|
6807
|
+
* error (the previous TS port silently returned `digest(any)`).
|
|
6808
|
+
* - Inside the parens, accepts either a UR string (`ur:digest/...`,
|
|
6809
|
+
* parsed via `Digest.fromURString`) or a hex byte prefix.
|
|
6810
|
+
* - Hex prefixes must have even length and not exceed `Digest.DIGEST_SIZE`
|
|
6811
|
+
* bytes; otherwise the parser surfaces `InvalidHexString`.
|
|
6812
|
+
*
|
|
6813
|
+
* @module envelope-pattern/parse/structure/digest-parser
|
|
6814
|
+
*/
|
|
6815
|
+
const DIGEST_SIZE = Digest.DIGEST_SIZE;
|
|
6830
6816
|
function parseDigest(lexer) {
|
|
6831
|
-
|
|
6832
|
-
|
|
6833
|
-
|
|
6834
|
-
|
|
6835
|
-
if (
|
|
6836
|
-
|
|
6837
|
-
|
|
6838
|
-
|
|
6839
|
-
|
|
6840
|
-
|
|
6841
|
-
|
|
6817
|
+
const open = lexer.next();
|
|
6818
|
+
if (open === void 0) return err(unexpectedEndOfInput());
|
|
6819
|
+
if (open.token.type !== "ParenOpen") return err(unexpectedToken(open.token, open.span));
|
|
6820
|
+
const innerResult = parseDigestInner(lexer.remainder(), lexer.position);
|
|
6821
|
+
if (!innerResult.ok) return innerResult;
|
|
6822
|
+
const [pattern, consumed] = innerResult.value;
|
|
6823
|
+
lexer.bump(consumed);
|
|
6824
|
+
const close = lexer.next();
|
|
6825
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6826
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6827
|
+
return ok(pattern);
|
|
6828
|
+
}
|
|
6829
|
+
function parseDigestInner(src, basePos) {
|
|
6830
|
+
let pos = 0;
|
|
6831
|
+
pos = skipWs(src, pos);
|
|
6832
|
+
if (src.startsWith("ur:", pos)) {
|
|
6833
|
+
const start = pos;
|
|
6834
|
+
while (pos < src.length && src[pos] !== ")") pos += 1;
|
|
6835
|
+
const ur = src.slice(start, pos).trimEnd();
|
|
6836
|
+
let parsed;
|
|
6837
|
+
try {
|
|
6838
|
+
parsed = Digest.fromURString(ur);
|
|
6839
|
+
} catch {
|
|
6840
|
+
return err(invalidUr(ur, {
|
|
6841
|
+
start: basePos + start,
|
|
6842
|
+
end: basePos + pos
|
|
6843
|
+
}));
|
|
6844
|
+
}
|
|
6845
|
+
pos = skipWs(src, pos);
|
|
6846
|
+
return ok([digest(parsed), pos]);
|
|
6847
|
+
}
|
|
6848
|
+
const start = pos;
|
|
6849
|
+
while (pos < src.length && isAsciiHexDigit(src.charCodeAt(pos))) pos += 1;
|
|
6850
|
+
if (pos === start) return err(invalidHexString({
|
|
6851
|
+
start: basePos + pos,
|
|
6852
|
+
end: basePos + pos
|
|
6853
|
+
}));
|
|
6854
|
+
const hexStr = src.slice(start, pos);
|
|
6855
|
+
if (hexStr.length % 2 !== 0) return err(invalidHexString({
|
|
6856
|
+
start: basePos + pos,
|
|
6857
|
+
end: basePos + pos
|
|
6858
|
+
}));
|
|
6859
|
+
const bytes = decodeHex(hexStr);
|
|
6860
|
+
if (bytes === void 0) return err(invalidHexString({
|
|
6861
|
+
start: basePos + pos,
|
|
6862
|
+
end: basePos + pos
|
|
6863
|
+
}));
|
|
6864
|
+
if (bytes.length > DIGEST_SIZE) return err(invalidHexString({
|
|
6865
|
+
start: basePos + pos,
|
|
6866
|
+
end: basePos + pos
|
|
6867
|
+
}));
|
|
6868
|
+
pos = skipWs(src, pos);
|
|
6869
|
+
return ok([digestPrefix(bytes), pos]);
|
|
6870
|
+
}
|
|
6871
|
+
function skipWs(src, pos) {
|
|
6872
|
+
while (pos < src.length) {
|
|
6873
|
+
const ch = src[pos];
|
|
6874
|
+
if (ch === " " || ch === " " || ch === "\n" || ch === "\r" || ch === "\f") pos += 1;
|
|
6875
|
+
else break;
|
|
6842
6876
|
}
|
|
6843
|
-
|
|
6844
|
-
|
|
6845
|
-
|
|
6846
|
-
|
|
6847
|
-
|
|
6848
|
-
|
|
6849
|
-
|
|
6850
|
-
|
|
6851
|
-
|
|
6852
|
-
|
|
6853
|
-
|
|
6854
|
-
|
|
6855
|
-
return ok(digestPrefix(bytes));
|
|
6877
|
+
return pos;
|
|
6878
|
+
}
|
|
6879
|
+
function isAsciiHexDigit(c) {
|
|
6880
|
+
return c >= 48 && c <= 57 || c >= 65 && c <= 70 || c >= 97 && c <= 102;
|
|
6881
|
+
}
|
|
6882
|
+
function decodeHex(hex) {
|
|
6883
|
+
if (hex.length % 2 !== 0) return void 0;
|
|
6884
|
+
const out = new Uint8Array(hex.length / 2);
|
|
6885
|
+
for (let i = 0; i < hex.length; i += 2) {
|
|
6886
|
+
const value = Number.parseInt(hex.slice(i, i + 2), 16);
|
|
6887
|
+
if (Number.isNaN(value)) return void 0;
|
|
6888
|
+
out[i / 2] = value;
|
|
6856
6889
|
}
|
|
6857
|
-
return
|
|
6890
|
+
return out;
|
|
6891
|
+
}
|
|
6892
|
+
//#endregion
|
|
6893
|
+
//#region src/parse/structure/elided-parser.ts
|
|
6894
|
+
/**
|
|
6895
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6896
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6897
|
+
*
|
|
6898
|
+
* Elided parser — port of `bc-envelope-pattern-rust`
|
|
6899
|
+
* `parse/structure/elided_parser.rs`.
|
|
6900
|
+
*
|
|
6901
|
+
* @module envelope-pattern/parse/structure/elided-parser
|
|
6902
|
+
*/
|
|
6903
|
+
function parseElided(_lexer) {
|
|
6904
|
+
return ok(elided());
|
|
6858
6905
|
}
|
|
6906
|
+
//#endregion
|
|
6907
|
+
//#region src/parse/structure/encrypted-parser.ts
|
|
6908
|
+
/**
|
|
6909
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6910
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6911
|
+
*
|
|
6912
|
+
* Encrypted parser — port of `bc-envelope-pattern-rust`
|
|
6913
|
+
* `parse/structure/encrypted_parser.rs`.
|
|
6914
|
+
*
|
|
6915
|
+
* @module envelope-pattern/parse/structure/encrypted-parser
|
|
6916
|
+
*/
|
|
6917
|
+
function parseEncrypted(_lexer) {
|
|
6918
|
+
return ok(encrypted());
|
|
6919
|
+
}
|
|
6920
|
+
//#endregion
|
|
6921
|
+
//#region src/parse/structure/node-parser.ts
|
|
6922
|
+
/**
|
|
6923
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6924
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6925
|
+
*
|
|
6926
|
+
* Node parser — port of `bc-envelope-pattern-rust`
|
|
6927
|
+
* `parse/structure/node_parser.rs`.
|
|
6928
|
+
*
|
|
6929
|
+
* Mirrors Rust:
|
|
6930
|
+
* - Bare `node` → `any_node()`.
|
|
6931
|
+
* - `node({n})` / `node({n,m})` / `node({n,})` → `node_with_assertions_range`.
|
|
6932
|
+
* - Anything else inside the parens (e.g. `node(text)`) is a syntax error
|
|
6933
|
+
* in Rust; the previous TS port silently produced an always-matching
|
|
6934
|
+
* `WithSubject` node, which we have removed.
|
|
6935
|
+
*
|
|
6936
|
+
* @module envelope-pattern/parse/structure/node-parser
|
|
6937
|
+
*/
|
|
6938
|
+
function parseNode(lexer) {
|
|
6939
|
+
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anyNode());
|
|
6940
|
+
lexer.next();
|
|
6941
|
+
const inner = lexer.next();
|
|
6942
|
+
if (inner === void 0) return err(unexpectedEndOfInput());
|
|
6943
|
+
if (inner.token.type !== "Range") return err(unexpectedToken(inner.token, inner.span));
|
|
6944
|
+
if (!inner.token.value.ok) return err(inner.token.value.error);
|
|
6945
|
+
const interval = inner.token.value.value.interval();
|
|
6946
|
+
const close = lexer.next();
|
|
6947
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6948
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6949
|
+
return ok(patternStructure(structureNode(NodePattern.fromInterval(interval))));
|
|
6950
|
+
}
|
|
6951
|
+
//#endregion
|
|
6952
|
+
//#region src/parse/structure/object-parser.ts
|
|
6953
|
+
/**
|
|
6954
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6955
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6956
|
+
*
|
|
6957
|
+
* Object parser — port of `bc-envelope-pattern-rust`
|
|
6958
|
+
* `parse/structure/object_parser.rs`.
|
|
6959
|
+
*
|
|
6960
|
+
* @module envelope-pattern/parse/structure/object-parser
|
|
6961
|
+
*/
|
|
6859
6962
|
function parseObject(lexer) {
|
|
6860
6963
|
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anyObject());
|
|
6861
6964
|
lexer.next();
|
|
6862
6965
|
const inner = parseOr(lexer);
|
|
6863
6966
|
if (!inner.ok) return inner;
|
|
6864
|
-
|
|
6865
|
-
|
|
6866
|
-
|
|
6867
|
-
});
|
|
6967
|
+
const close = lexer.next();
|
|
6968
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
6969
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6868
6970
|
return ok(object(inner.value));
|
|
6869
6971
|
}
|
|
6972
|
+
//#endregion
|
|
6973
|
+
//#region src/parse/structure/obscured-parser.ts
|
|
6974
|
+
/**
|
|
6975
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6976
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6977
|
+
*
|
|
6978
|
+
* Obscured parser — port of `bc-envelope-pattern-rust`
|
|
6979
|
+
* `parse/structure/obscured_parser.rs`.
|
|
6980
|
+
*
|
|
6981
|
+
* @module envelope-pattern/parse/structure/obscured-parser
|
|
6982
|
+
*/
|
|
6983
|
+
function parseObscured(_lexer) {
|
|
6984
|
+
return ok(obscured());
|
|
6985
|
+
}
|
|
6986
|
+
//#endregion
|
|
6987
|
+
//#region src/parse/structure/predicate-parser.ts
|
|
6988
|
+
/**
|
|
6989
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
6990
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
6991
|
+
*
|
|
6992
|
+
* Predicate parser — port of `bc-envelope-pattern-rust`
|
|
6993
|
+
* `parse/structure/predicate_parser.rs`.
|
|
6994
|
+
*
|
|
6995
|
+
* @module envelope-pattern/parse/structure/predicate-parser
|
|
6996
|
+
*/
|
|
6870
6997
|
function parsePredicate(lexer) {
|
|
6871
6998
|
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anyPredicate());
|
|
6872
6999
|
lexer.next();
|
|
6873
7000
|
const inner = parseOr(lexer);
|
|
6874
7001
|
if (!inner.ok) return inner;
|
|
6875
|
-
|
|
6876
|
-
|
|
6877
|
-
|
|
6878
|
-
});
|
|
7002
|
+
const close = lexer.next();
|
|
7003
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
7004
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6879
7005
|
return ok(predicate(inner.value));
|
|
6880
7006
|
}
|
|
7007
|
+
//#endregion
|
|
7008
|
+
//#region src/parse/structure/subject-parser.ts
|
|
7009
|
+
/**
|
|
7010
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7011
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7012
|
+
*
|
|
7013
|
+
* Subject parser — port of `bc-envelope-pattern-rust`
|
|
7014
|
+
* `parse/structure/subject_parser.rs`.
|
|
7015
|
+
*
|
|
7016
|
+
* @module envelope-pattern/parse/structure/subject-parser
|
|
7017
|
+
*/
|
|
6881
7018
|
function parseSubject(lexer) {
|
|
6882
7019
|
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(anySubject());
|
|
6883
7020
|
lexer.next();
|
|
6884
7021
|
const inner = parseOr(lexer);
|
|
6885
7022
|
if (!inner.ok) return inner;
|
|
6886
|
-
|
|
6887
|
-
|
|
6888
|
-
|
|
6889
|
-
});
|
|
7023
|
+
const close = lexer.next();
|
|
7024
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
7025
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6890
7026
|
return ok(subject(inner.value));
|
|
6891
7027
|
}
|
|
7028
|
+
//#endregion
|
|
7029
|
+
//#region src/parse/structure/wrapped-parser.ts
|
|
7030
|
+
/**
|
|
7031
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7032
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7033
|
+
*
|
|
7034
|
+
* Wrapped/unwrap parser — port of `bc-envelope-pattern-rust`
|
|
7035
|
+
* `parse/structure/wrapped_parser.rs`.
|
|
7036
|
+
*
|
|
7037
|
+
* @module envelope-pattern/parse/structure/wrapped-parser
|
|
7038
|
+
*/
|
|
7039
|
+
function parseWrapped(_lexer) {
|
|
7040
|
+
return ok(wrapped());
|
|
7041
|
+
}
|
|
6892
7042
|
function parseUnwrap(lexer) {
|
|
6893
7043
|
if (lexer.peekToken()?.token.type !== "ParenOpen") return ok(unwrapEnvelope());
|
|
6894
7044
|
lexer.next();
|
|
6895
7045
|
const inner = parseOr(lexer);
|
|
6896
7046
|
if (!inner.ok) return inner;
|
|
6897
|
-
|
|
6898
|
-
|
|
6899
|
-
|
|
6900
|
-
});
|
|
7047
|
+
const close = lexer.next();
|
|
7048
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
7049
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
6901
7050
|
return ok(unwrapMatching(inner.value));
|
|
6902
7051
|
}
|
|
6903
7052
|
//#endregion
|
|
7053
|
+
//#region src/parse/meta/capture-parser.ts
|
|
7054
|
+
/**
|
|
7055
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7056
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7057
|
+
*
|
|
7058
|
+
* Capture parser — port of `bc-envelope-pattern-rust`
|
|
7059
|
+
* `parse/meta/capture_parser.rs`.
|
|
7060
|
+
*
|
|
7061
|
+
* The `@name(...)` form requires explicit parentheses. Mirrors Rust
|
|
7062
|
+
* exactly:
|
|
7063
|
+
* ```ignore
|
|
7064
|
+
* @name ( expr )
|
|
7065
|
+
* ```
|
|
7066
|
+
* The previous TS port called `parse_group` (primary + quantifier), which
|
|
7067
|
+
* wrapped the inner expression in a redundant `GroupPattern` and accepted
|
|
7068
|
+
* the bare `@name p` form that Rust rejects.
|
|
7069
|
+
*
|
|
7070
|
+
* @module envelope-pattern/parse/meta/capture-parser
|
|
7071
|
+
*/
|
|
7072
|
+
function parseCapture(lexer, name) {
|
|
7073
|
+
const open = lexer.next();
|
|
7074
|
+
if (open === void 0) return err(unexpectedEndOfInput());
|
|
7075
|
+
if (open.token.type !== "ParenOpen") return err(unexpectedToken(open.token, open.span));
|
|
7076
|
+
const inner = parseOr(lexer);
|
|
7077
|
+
if (!inner.ok) return inner;
|
|
7078
|
+
const close = lexer.next();
|
|
7079
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
7080
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
7081
|
+
return ok(capture(name, inner.value));
|
|
7082
|
+
}
|
|
7083
|
+
//#endregion
|
|
7084
|
+
//#region src/parse/meta/group-parser.ts
|
|
7085
|
+
/**
|
|
7086
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7087
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7088
|
+
*
|
|
7089
|
+
* Group parser — port of `bc-envelope-pattern-rust`
|
|
7090
|
+
* `parse/meta/group_parser.rs`.
|
|
7091
|
+
*
|
|
7092
|
+
* Called from `parse_primary` after the opening `(` has been consumed.
|
|
7093
|
+
*
|
|
7094
|
+
* Mirrors Rust exactly:
|
|
7095
|
+
*
|
|
7096
|
+
* - Parse the inner expression with `parse_or`.
|
|
7097
|
+
* - Expect `)`. If missing, surface `ExpectedCloseParen`.
|
|
7098
|
+
* - Lookahead **once** for a quantifier suffix. If present, consume it
|
|
7099
|
+
* and wrap as `Pattern::repeat(inner, …)`. Otherwise return the inner
|
|
7100
|
+
* expression unchanged.
|
|
7101
|
+
*
|
|
7102
|
+
* The previous TS port wrapped every parenthesised expression in a
|
|
7103
|
+
* dedicated `GroupPattern` and applied quantifiers to bare primaries —
|
|
7104
|
+
* both broke `format(parse(s)) === s` round-tripping.
|
|
7105
|
+
*
|
|
7106
|
+
* @module envelope-pattern/parse/meta/group-parser
|
|
7107
|
+
*/
|
|
7108
|
+
function parseGroup(lexer) {
|
|
7109
|
+
const inner = parseOr(lexer);
|
|
7110
|
+
if (!inner.ok) return inner;
|
|
7111
|
+
const close = lexer.next();
|
|
7112
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
7113
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
7114
|
+
const next = lexer.peekToken();
|
|
7115
|
+
if (next === void 0) return inner;
|
|
7116
|
+
let quantifier;
|
|
7117
|
+
const tokenType = next.token.type;
|
|
7118
|
+
if (tokenType === "RepeatZeroOrMore") quantifier = Quantifier$1.zeroOrMore(Reluctance$1.Greedy);
|
|
7119
|
+
else if (tokenType === "RepeatZeroOrMoreLazy") quantifier = Quantifier$1.zeroOrMore(Reluctance$1.Lazy);
|
|
7120
|
+
else if (tokenType === "RepeatZeroOrMorePossessive") quantifier = Quantifier$1.zeroOrMore(Reluctance$1.Possessive);
|
|
7121
|
+
else if (tokenType === "RepeatOneOrMore") quantifier = Quantifier$1.oneOrMore(Reluctance$1.Greedy);
|
|
7122
|
+
else if (tokenType === "RepeatOneOrMoreLazy") quantifier = Quantifier$1.oneOrMore(Reluctance$1.Lazy);
|
|
7123
|
+
else if (tokenType === "RepeatOneOrMorePossessive") quantifier = Quantifier$1.oneOrMore(Reluctance$1.Possessive);
|
|
7124
|
+
else if (tokenType === "RepeatZeroOrOne") quantifier = Quantifier$1.zeroOrOne(Reluctance$1.Greedy);
|
|
7125
|
+
else if (tokenType === "RepeatZeroOrOneLazy") quantifier = Quantifier$1.zeroOrOne(Reluctance$1.Lazy);
|
|
7126
|
+
else if (tokenType === "RepeatZeroOrOnePossessive") quantifier = Quantifier$1.zeroOrOne(Reluctance$1.Possessive);
|
|
7127
|
+
else if (tokenType === "Range") {
|
|
7128
|
+
if (!next.token.value.ok) return err(next.token.value.error);
|
|
7129
|
+
quantifier = next.token.value.value;
|
|
7130
|
+
} else return inner;
|
|
7131
|
+
lexer.next();
|
|
7132
|
+
return ok(repeat(inner.value, quantifier.min(), quantifier.max(), quantifier.reluctance()));
|
|
7133
|
+
}
|
|
7134
|
+
//#endregion
|
|
7135
|
+
//#region src/parse/meta/search-parser.ts
|
|
7136
|
+
/**
|
|
7137
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7138
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7139
|
+
*
|
|
7140
|
+
* Search parser — port of `bc-envelope-pattern-rust`
|
|
7141
|
+
* `parse/meta/search_parser.rs`.
|
|
7142
|
+
*
|
|
7143
|
+
* @module envelope-pattern/parse/meta/search-parser
|
|
7144
|
+
*/
|
|
7145
|
+
function parseSearch(lexer) {
|
|
7146
|
+
const open = lexer.next();
|
|
7147
|
+
if (open === void 0) return err(unexpectedEndOfInput());
|
|
7148
|
+
if (open.token.type !== "ParenOpen") return err(unexpectedToken(open.token, open.span));
|
|
7149
|
+
const inner = parseOr(lexer);
|
|
7150
|
+
if (!inner.ok) return inner;
|
|
7151
|
+
const close = lexer.next();
|
|
7152
|
+
if (close === void 0) return err(expectedCloseParen(lexer.span()));
|
|
7153
|
+
if (close.token.type !== "ParenClose") return err(unexpectedToken(close.token, close.span));
|
|
7154
|
+
return ok(search(inner.value));
|
|
7155
|
+
}
|
|
7156
|
+
//#endregion
|
|
7157
|
+
//#region src/parse/meta/primary-parser.ts
|
|
7158
|
+
/**
|
|
7159
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7160
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7161
|
+
*
|
|
7162
|
+
* Primary parser — port of `bc-envelope-pattern-rust`
|
|
7163
|
+
* `parse/meta/primary_parser.rs`.
|
|
7164
|
+
*
|
|
7165
|
+
* Dispatches on the next token to the appropriate leaf/structure/meta
|
|
7166
|
+
* parser. When a `(` is encountered the open paren is consumed here and
|
|
7167
|
+
* `parse_group` handles the rest (paren'd expression + optional
|
|
7168
|
+
* quantifier suffix).
|
|
7169
|
+
*
|
|
7170
|
+
* @module envelope-pattern/parse/meta/primary-parser
|
|
7171
|
+
*/
|
|
7172
|
+
function parsePrimary(lexer) {
|
|
7173
|
+
const tokenResult = lexer.next();
|
|
7174
|
+
if (tokenResult === void 0) return err(unexpectedEndOfInput());
|
|
7175
|
+
const { token, span } = tokenResult;
|
|
7176
|
+
switch (token.type) {
|
|
7177
|
+
case "Search": return parseSearch(lexer);
|
|
7178
|
+
case "Node": return parseNode(lexer);
|
|
7179
|
+
case "Assertion": return parseAssertion(lexer);
|
|
7180
|
+
case "AssertionPred": return parseAssertionPred(lexer);
|
|
7181
|
+
case "AssertionObj": return parseAssertionObj(lexer);
|
|
7182
|
+
case "Digest": return parseDigest(lexer);
|
|
7183
|
+
case "Obj": return parseObject(lexer);
|
|
7184
|
+
case "Obscured": return parseObscured(lexer);
|
|
7185
|
+
case "Elided": return parseElided(lexer);
|
|
7186
|
+
case "Encrypted": return parseEncrypted(lexer);
|
|
7187
|
+
case "Compressed": return parseCompressed(lexer);
|
|
7188
|
+
case "Pred": return parsePredicate(lexer);
|
|
7189
|
+
case "Subject": return parseSubject(lexer);
|
|
7190
|
+
case "Wrapped": return parseWrapped(lexer);
|
|
7191
|
+
case "Unwrap": return parseUnwrap(lexer);
|
|
7192
|
+
case "Leaf": return ok(leaf());
|
|
7193
|
+
case "GroupName": return parseCapture(lexer, token.name);
|
|
7194
|
+
case "ParenOpen": return parseGroup(lexer);
|
|
7195
|
+
case "Cbor": return parseCbor(lexer);
|
|
7196
|
+
case "RepeatZeroOrMore": return ok(any());
|
|
7197
|
+
case "BoolKeyword": return ok(anyBool());
|
|
7198
|
+
case "BoolTrue": return ok(bool(true));
|
|
7199
|
+
case "BoolFalse": return ok(bool(false));
|
|
7200
|
+
case "NumberKeyword": return ok(anyNumber());
|
|
7201
|
+
case "TextKeyword": return ok(anyText());
|
|
7202
|
+
case "StringLiteral":
|
|
7203
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7204
|
+
return ok(text(token.value.value));
|
|
7205
|
+
case "UnsignedInteger":
|
|
7206
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7207
|
+
return parseNumberRangeOrComparison(lexer, token.value.value);
|
|
7208
|
+
case "Integer":
|
|
7209
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7210
|
+
return parseNumberRangeOrComparison(lexer, token.value.value);
|
|
7211
|
+
case "Float":
|
|
7212
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7213
|
+
return parseNumberRangeOrComparison(lexer, token.value.value);
|
|
7214
|
+
case "GreaterThanOrEqual": return parseComparisonNumber(lexer, ">=");
|
|
7215
|
+
case "LessThanOrEqual": return parseComparisonNumber(lexer, "<=");
|
|
7216
|
+
case "GreaterThan": return parseComparisonNumber(lexer, ">");
|
|
7217
|
+
case "LessThan": return parseComparisonNumber(lexer, "<");
|
|
7218
|
+
case "NaN": return ok(patternLeaf(leafNumber(NumberPattern.nan())));
|
|
7219
|
+
case "Infinity": return ok(number(Infinity));
|
|
7220
|
+
case "NegativeInfinity": return ok(number(-Infinity));
|
|
7221
|
+
case "Regex":
|
|
7222
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7223
|
+
try {
|
|
7224
|
+
return ok(textRegex(new RegExp(token.value.value)));
|
|
7225
|
+
} catch {
|
|
7226
|
+
return err(invalidRegex(span));
|
|
7227
|
+
}
|
|
7228
|
+
case "BracketOpen": return parseArray(lexer);
|
|
7229
|
+
case "ByteString": return ok(anyByteString());
|
|
7230
|
+
case "HexPattern":
|
|
7231
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7232
|
+
return ok(byteString(token.value.value));
|
|
7233
|
+
case "HexBinaryRegex":
|
|
7234
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7235
|
+
try {
|
|
7236
|
+
return ok(patternLeaf(leafByteString(ByteStringPattern.regex(new RegExp(token.value.value)))));
|
|
7237
|
+
} catch {
|
|
7238
|
+
return err(invalidRegex(span));
|
|
7239
|
+
}
|
|
7240
|
+
case "DateKeyword": return ok(anyDate());
|
|
7241
|
+
case "DatePattern":
|
|
7242
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7243
|
+
return parseDateContent(token.value.value, span);
|
|
7244
|
+
case "Tagged": return parseTag(lexer);
|
|
7245
|
+
case "Known": return ok(anyKnownValue());
|
|
7246
|
+
case "SingleQuotedPattern":
|
|
7247
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7248
|
+
return parseKnownValueContent(token.value.value);
|
|
7249
|
+
case "SingleQuotedRegex":
|
|
7250
|
+
if (!token.value.ok) return err(token.value.error);
|
|
7251
|
+
try {
|
|
7252
|
+
return ok(patternLeaf(leafKnownValue(KnownValuePattern.regex(new RegExp(token.value.value)))));
|
|
7253
|
+
} catch {
|
|
7254
|
+
return err(invalidRegex(span));
|
|
7255
|
+
}
|
|
7256
|
+
case "Null": return ok(nullPattern());
|
|
7257
|
+
case "Identifier": return err(unrecognizedToken(span));
|
|
7258
|
+
case "And":
|
|
7259
|
+
case "Or":
|
|
7260
|
+
case "Not":
|
|
7261
|
+
case "Traverse":
|
|
7262
|
+
case "RepeatZeroOrMoreLazy":
|
|
7263
|
+
case "RepeatZeroOrMorePossessive":
|
|
7264
|
+
case "RepeatOneOrMore":
|
|
7265
|
+
case "RepeatOneOrMoreLazy":
|
|
7266
|
+
case "RepeatOneOrMorePossessive":
|
|
7267
|
+
case "RepeatZeroOrOne":
|
|
7268
|
+
case "RepeatZeroOrOneLazy":
|
|
7269
|
+
case "RepeatZeroOrOnePossessive":
|
|
7270
|
+
case "ParenClose":
|
|
7271
|
+
case "BracketClose":
|
|
7272
|
+
case "Comma":
|
|
7273
|
+
case "Ellipsis":
|
|
7274
|
+
case "Range": return err(unexpectedToken(token, span));
|
|
7275
|
+
}
|
|
7276
|
+
}
|
|
7277
|
+
//#endregion
|
|
7278
|
+
//#region src/parse/meta/and-parser.ts
|
|
7279
|
+
/**
|
|
7280
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7281
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7282
|
+
*
|
|
7283
|
+
* And parser — port of `bc-envelope-pattern-rust`
|
|
7284
|
+
* `parse/meta/and_parser.rs`.
|
|
7285
|
+
*
|
|
7286
|
+
* Mirrors Rust: `parse_and` calls `parse_primary` (NOT `parse_not`); `!`
|
|
7287
|
+
* is handled at a higher precedence level by `parse_not`.
|
|
7288
|
+
*
|
|
7289
|
+
* @module envelope-pattern/parse/meta/and-parser
|
|
7290
|
+
*/
|
|
7291
|
+
function parseAnd(lexer) {
|
|
7292
|
+
const patterns = [];
|
|
7293
|
+
const first = parsePrimary(lexer);
|
|
7294
|
+
if (!first.ok) return first;
|
|
7295
|
+
patterns.push(first.value);
|
|
7296
|
+
while (true) {
|
|
7297
|
+
if (lexer.peekToken()?.token.type !== "And") break;
|
|
7298
|
+
lexer.next();
|
|
7299
|
+
const nextExpr = parsePrimary(lexer);
|
|
7300
|
+
if (!nextExpr.ok) return nextExpr;
|
|
7301
|
+
patterns.push(nextExpr.value);
|
|
7302
|
+
}
|
|
7303
|
+
if (patterns.length === 1) return ok(patterns[0]);
|
|
7304
|
+
return ok(and(patterns));
|
|
7305
|
+
}
|
|
7306
|
+
//#endregion
|
|
7307
|
+
//#region src/parse/meta/not-parser.ts
|
|
7308
|
+
/**
|
|
7309
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7310
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7311
|
+
*
|
|
7312
|
+
* Not parser — port of `bc-envelope-pattern-rust`
|
|
7313
|
+
* `parse/meta/not_parser.rs`.
|
|
7314
|
+
*
|
|
7315
|
+
* Mirrors Rust:
|
|
7316
|
+
* - On `!`, recurse into `parse_not` so chained negation parses as
|
|
7317
|
+
* `not(not(x))` rather than `not(group(x))`.
|
|
7318
|
+
* - Otherwise descend into `parse_and`.
|
|
7319
|
+
*
|
|
7320
|
+
* @module envelope-pattern/parse/meta/not-parser
|
|
7321
|
+
*/
|
|
7322
|
+
function parseNot(lexer) {
|
|
7323
|
+
if (lexer.peekToken()?.token.type === "Not") {
|
|
7324
|
+
lexer.next();
|
|
7325
|
+
const inner = parseNot(lexer);
|
|
7326
|
+
if (!inner.ok) return inner;
|
|
7327
|
+
return ok(notMatching(inner.value));
|
|
7328
|
+
}
|
|
7329
|
+
return parseAnd(lexer);
|
|
7330
|
+
}
|
|
7331
|
+
//#endregion
|
|
7332
|
+
//#region src/parse/meta/traverse-parser.ts
|
|
7333
|
+
/**
|
|
7334
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7335
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7336
|
+
*
|
|
7337
|
+
* Traverse parser — port of `bc-envelope-pattern-rust`
|
|
7338
|
+
* `parse/meta/traverse_parser.rs`.
|
|
7339
|
+
*
|
|
7340
|
+
* Note the precedence chain: `parse_or → parse_traverse → parse_not →
|
|
7341
|
+
* parse_and → parse_primary`. The earlier TS port had `parse_traverse`
|
|
7342
|
+
* call `parse_and` directly, which pushed `!` below `&` and
|
|
7343
|
+
* miscompiled `!a & b`.
|
|
7344
|
+
*
|
|
7345
|
+
* @module envelope-pattern/parse/meta/traverse-parser
|
|
7346
|
+
*/
|
|
7347
|
+
function parseTraverse(lexer) {
|
|
7348
|
+
const patterns = [];
|
|
7349
|
+
const first = parseNot(lexer);
|
|
7350
|
+
if (!first.ok) return first;
|
|
7351
|
+
patterns.push(first.value);
|
|
7352
|
+
while (true) {
|
|
7353
|
+
if (lexer.peekToken()?.token.type !== "Traverse") break;
|
|
7354
|
+
lexer.next();
|
|
7355
|
+
const nextExpr = parseNot(lexer);
|
|
7356
|
+
if (!nextExpr.ok) return nextExpr;
|
|
7357
|
+
patterns.push(nextExpr.value);
|
|
7358
|
+
}
|
|
7359
|
+
if (patterns.length === 1) return ok(patterns[0]);
|
|
7360
|
+
return ok(traverse(patterns));
|
|
7361
|
+
}
|
|
7362
|
+
//#endregion
|
|
7363
|
+
//#region src/parse/meta/or-parser.ts
|
|
7364
|
+
/**
|
|
7365
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7366
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7367
|
+
*
|
|
7368
|
+
* Or parser — port of `bc-envelope-pattern-rust` `parse/meta/or_parser.rs`.
|
|
7369
|
+
*
|
|
7370
|
+
* @module envelope-pattern/parse/meta/or-parser
|
|
7371
|
+
*/
|
|
7372
|
+
function parseOr(lexer) {
|
|
7373
|
+
const patterns = [];
|
|
7374
|
+
const first = parseTraverse(lexer);
|
|
7375
|
+
if (!first.ok) return first;
|
|
7376
|
+
patterns.push(first.value);
|
|
7377
|
+
while (true) {
|
|
7378
|
+
if (lexer.peekToken()?.token.type !== "Or") break;
|
|
7379
|
+
lexer.next();
|
|
7380
|
+
const nextExpr = parseTraverse(lexer);
|
|
7381
|
+
if (!nextExpr.ok) return nextExpr;
|
|
7382
|
+
patterns.push(nextExpr.value);
|
|
7383
|
+
}
|
|
7384
|
+
if (patterns.length === 1) return ok(patterns[0]);
|
|
7385
|
+
return ok(or(patterns));
|
|
7386
|
+
}
|
|
7387
|
+
//#endregion
|
|
7388
|
+
//#region src/parse/index.ts
|
|
7389
|
+
/**
|
|
7390
|
+
* Copyright © 2023-2026 Blockchain Commons, LLC
|
|
7391
|
+
* Copyright © 2025-2026 Parity Technologies
|
|
7392
|
+
*
|
|
7393
|
+
*
|
|
7394
|
+
* @bcts/envelope-pattern - Parser entry point
|
|
7395
|
+
*
|
|
7396
|
+
* This is a 1:1 TypeScript port of bc-envelope-pattern-rust parse/mod.rs.
|
|
7397
|
+
*
|
|
7398
|
+
* Recursive-descent parser for the Gordian Envelope pattern syntax. The
|
|
7399
|
+
* parsing rules live under `parse/leaf/`, `parse/meta/`, and
|
|
7400
|
+
* `parse/structure/`, mirroring the Rust crate's module layout.
|
|
7401
|
+
*
|
|
7402
|
+
* @module envelope-pattern/parse
|
|
7403
|
+
*/
|
|
7404
|
+
/**
|
|
7405
|
+
* Parse a pattern expression string into a Pattern.
|
|
7406
|
+
*
|
|
7407
|
+
* Mirrors Rust `Pattern::parse`: tries envelope-pattern parsing first;
|
|
7408
|
+
* on failure falls back to dcbor-pattern parsing and converts the
|
|
7409
|
+
* result into an envelope pattern via the
|
|
7410
|
+
* `dcbor_integration::convert_dcbor_pattern_to_envelope_pattern` bridge.
|
|
7411
|
+
*/
|
|
7412
|
+
function parse(input) {
|
|
7413
|
+
const lexer = new Lexer(input);
|
|
7414
|
+
const result = parseOr(lexer);
|
|
7415
|
+
if (!result.ok) {
|
|
7416
|
+
const dcborResult = parse$1(input);
|
|
7417
|
+
if (dcborResult.ok) return convertDcborPatternToEnvelopePattern(dcborResult.value);
|
|
7418
|
+
return result;
|
|
7419
|
+
}
|
|
7420
|
+
const next = lexer.next();
|
|
7421
|
+
if (next !== void 0) return err(extraData(next.span));
|
|
7422
|
+
return result;
|
|
7423
|
+
}
|
|
7424
|
+
/**
|
|
7425
|
+
* Parse a pattern, allowing extra data after the pattern.
|
|
7426
|
+
*
|
|
7427
|
+
* Returns the parsed pattern and the byte offset at which parsing
|
|
7428
|
+
* stopped, mirroring `Pattern::parse_partial` in spirit.
|
|
7429
|
+
*/
|
|
7430
|
+
function parsePartial(input) {
|
|
7431
|
+
const lexer = new Lexer(input);
|
|
7432
|
+
const result = parseOr(lexer);
|
|
7433
|
+
if (!result.ok) return result;
|
|
7434
|
+
return ok([result.value, lexer.position]);
|
|
7435
|
+
}
|
|
7436
|
+
//#endregion
|
|
6904
7437
|
//#region src/index.ts
|
|
6905
7438
|
/**
|
|
6906
7439
|
* Package version.
|
|
6907
7440
|
*/
|
|
6908
7441
|
const VERSION = "1.0.0-alpha.11";
|
|
6909
7442
|
//#endregion
|
|
6910
|
-
export { AndPattern, AnyPattern, ArrayPattern, AssertionsPattern, BoolPattern, ByteStringPattern, CBORPattern, CapturePattern, DatePattern, DigestPattern, FormatPathsOptsBuilder, GroupPattern, Interval, KnownValuePattern, LeafStructurePattern, Lexer, MapPattern, MatcherDefaults, NodePattern, NotPattern, NullPattern, NumberPattern, ObjectPattern, ObscuredPattern, OrPattern, PredicatePattern, Quantifier, Reluctance, SearchPattern, SubjectPattern, TaggedPattern, TextPattern, TraversePattern, VERSION, WrappedPattern, and, any, anyArray, anyAssertion, anyBool, anyByteString, anyCbor, anyDate, anyKnownValue, anyMap, anyNode, anyNumber, anyObject, anyPredicate, anySubject, anyTag, anyText, assertionWithObject, assertionWithPredicate, axisChildren, bool, byteString, capture, cborPattern, cborValue, compile, compileAsAtomic, compressed, convertDcborPatternToEnvelopePattern, date, dateEarliest, dateLatest, dateRange, dateRegex, dcborPatternError, defaultFormatPathsOpts, defaultPathElementFormat, digest, digestPrefix, digestURFormat, dispatchCompile, dispatchIsComplex, dispatchPaths, dispatchPathsWithCaptures, dispatchPatternToString, elided, emptyInput, encrypted, envelopeSummary, envelopeURFormat, err, expectedCloseBracket, expectedCloseParen, expectedOpenBracket, expectedOpenParen, expectedPattern, extraData, formatError, formatPath, formatPathOpt, formatPaths, formatPathsOpt, formatPathsOpts, formatPathsWithCaptures, formatPathsWithCapturesOpt, group, invalidCaptureGroupName, invalidDateFormat, invalidHexString, invalidNumberFormat, invalidPattern, invalidRange, invalidRegex, invalidUr, isErr, isOk, knownValue, leaf, leafArray, leafBool, leafByteString, leafCbor, leafDate, leafKnownValue, leafMap, leafNull, leafNumber, leafPatternCompile, leafPatternIsComplex, leafPatternPaths, leafPatternPathsWithCaptures, leafPatternToString, leafTag, leafText, map, matchPattern, metaAnd, metaAny, metaCapture, metaGroup, metaNot, metaOr, metaPatternCollectCaptureNames, metaPatternCompile, metaPatternIsComplex, metaPatternPathsWithCaptures, metaPatternToString, metaSearch, metaTraverse, notMatching, nullPattern, number, numberGreaterThan, numberLessThan, numberRange, object, obscured, ok, or, parse, parsePartial, patternCollectCaptureNames, patternCompile, patternIsComplex, patternLeaf, patternMatches, patternMeta, patternPaths, patternPathsWithCaptures, patternStructure, patternToString, predicate, registerAndPatternFactory, registerAnyPatternFactory, registerArrayPatternFactory, registerAssertionsPatternFactory, registerBoolPatternFactory, registerByteStringPatternFactory, registerCBORPatternFactory, registerCapturePatternFactory, registerDatePatternFactory, registerDigestPatternFactory, registerGroupPatternFactory, registerKnownValuePatternFactory, registerLeafStructurePatternFactory, registerMapPatternFactory, registerNodePatternFactory, registerNotPatternFactory, registerNullPatternFactory, registerNumberPatternFactory, registerObjectPatternFactory, registerObscuredPatternFactory, registerOrPatternFactory, registerPatternDispatchFns, registerPatternMatchFn, registerPredicatePatternFactory, registerSearchPatternFactory, registerSubjectPatternFactory, registerTaggedPatternFactory, registerTextPatternFactory, registerTraversePatternFactory, registerVMPatternFunctions, registerWrappedPatternDispatch, registerWrappedPatternFactory, repeat, run, search, structureAssertions, structureDigest, structureLeaf, structureNode, structureObject, structureObscured, structurePatternCompile, structurePatternIsComplex, structurePatternPaths, structurePatternPathsWithCaptures, structurePatternToString, structurePredicate, structureSubject, structureWrapped, subject, summaryFormat, tagged, text, textRegex, traverse, unexpectedEndOfInput, unexpectedToken, unit, unknown, unmatchedBraces, unmatchedParentheses, unrecognizedToken, unterminatedRegex, unwrap, unwrapEnvelope, unwrapMatching, unwrapOr, wrapped };
|
|
7443
|
+
export { AndPattern, AnyPattern, ArrayPattern, AssertionsPattern, BoolPattern, ByteStringPattern, CBORPattern, CapturePattern, DatePattern, DigestPattern, FormatPathsOptsBuilder, GroupPattern, Interval, KnownValuePattern, LeafStructurePattern, Lexer, MapPattern, MatcherDefaults, NodePattern, NotPattern, NullPattern, NumberPattern, ObjectPattern, ObscuredPattern, OrPattern, PredicatePattern, Quantifier, Reluctance, SearchPattern, SubjectPattern, TaggedPattern, TextPattern, TraversePattern, VERSION, WrappedPattern, and, any, anyArray, anyAssertion, anyBool, anyByteString, anyCbor, anyDate, anyKnownValue, anyMap, anyNode, anyNumber, anyObject, anyPredicate, anySubject, anyTag, anyText, assertionWithObject, assertionWithPredicate, axisChildren, bool, byteString, capture, cborPattern, cborValue, compile, compileAsAtomic, compressed, convertDcborPatternToEnvelopePattern, date, dateEarliest, dateLatest, dateRange, dateRegex, dcborPatternError, defaultFormatPathsOpts, defaultPathElementFormat, digest, digestPrefix, digestURFormat, dispatchCompile, dispatchIsComplex, dispatchPaths, dispatchPathsWithCaptures, dispatchPatternToString, elided, emptyInput, encrypted, envelopeSummary, envelopeURFormat, err, expectedCloseBracket, expectedCloseParen, expectedOpenBracket, expectedOpenParen, expectedPattern, extraData, formatError, formatPath, formatPathOpt, formatPaths, formatPathsOpt, formatPathsOpts, formatPathsWithCaptures, formatPathsWithCapturesOpt, group, invalidCaptureGroupName, invalidDateFormat, invalidHexString, invalidNumberFormat, invalidPattern, invalidRange, invalidRegex, invalidUr, isErr, isOk, knownValue, leaf, leafArray, leafBool, leafByteString, leafCbor, leafDate, leafKnownValue, leafMap, leafNull, leafNumber, leafPatternCompile, leafPatternIsComplex, leafPatternPaths, leafPatternPathsWithCaptures, leafPatternToString, leafTag, leafText, map, matchPattern, metaAnd, metaAny, metaCapture, metaGroup, metaNot, metaOr, metaPatternCollectCaptureNames, metaPatternCompile, metaPatternIsComplex, metaPatternPathsWithCaptures, metaPatternToString, metaSearch, metaTraverse, notMatching, nullPattern, number, numberGreaterThan, numberLessThan, numberRange, object, obscured, ok, or, parse, parsePartial, patternCollectCaptureNames, patternCompile, patternIsComplex, patternLeaf, patternMatches, patternMeta, patternPaths, patternPathsWithCaptures, patternStructure, patternToString, predicate, registerAndPatternFactory, registerAnyPatternFactory, registerArrayPatternFactory, registerAssertionsPatternFactory, registerAssertionsPatternToStringDispatch, registerBoolPatternFactory, registerByteStringPatternFactory, registerCBORPatternFactory, registerCapturePatternFactory, registerDatePatternFactory, registerDigestPatternFactory, registerGroupPatternFactory, registerKnownValuePatternFactory, registerLeafStructurePatternFactory, registerMapPatternFactory, registerNodePatternFactory, registerNotPatternFactory, registerNullPatternFactory, registerNumberPatternFactory, registerObjectPatternFactory, registerObscuredPatternFactory, registerOrPatternFactory, registerPatternDispatchFns, registerPatternMatchFn, registerPredicatePatternFactory, registerSearchPatternFactory, registerSubjectPatternDispatch, registerSubjectPatternFactory, registerTaggedPatternFactory, registerTextPatternFactory, registerTraversePatternFactory, registerVMPatternFunctions, registerWrappedPatternAny, registerWrappedPatternDispatch, registerWrappedPatternFactory, repeat, run, search, structureAssertions, structureDigest, structureLeaf, structureNode, structureObject, structureObscured, structurePatternCompile, structurePatternIsComplex, structurePatternPaths, structurePatternPathsWithCaptures, structurePatternToString, structurePredicate, structureSubject, structureWrapped, subject, summaryFormat, tagged, text, textRegex, traverse, unexpectedEndOfInput, unexpectedToken, unit, unknown, unmatchedBraces, unmatchedParentheses, unrecognizedToken, unterminatedRegex, unwrap, unwrapEnvelope, unwrapMatching, unwrapOr, wrapped };
|
|
6911
7444
|
|
|
6912
7445
|
//# sourceMappingURL=index.mjs.map
|