@ptolemy2002/rgx 6.1.1 → 7.0.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/README.md +11 -3
- package/dist/walker/base.d.ts +1 -0
- package/dist/walker/base.js +9 -1
- package/dist/walker/part.d.ts +8 -0
- package/dist/walker/part.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,9 +84,13 @@ type RGXPartControl = "skip" | "stop" | "silent" | void;
|
|
|
84
84
|
type RGXCapture<T = unknown> = {
|
|
85
85
|
raw: string;
|
|
86
86
|
value: T;
|
|
87
|
+
start: number;
|
|
88
|
+
end: number;
|
|
89
|
+
ownerId: string | null;
|
|
87
90
|
};
|
|
88
91
|
|
|
89
92
|
type RGXPartOptions<R, T=string> = {
|
|
93
|
+
id: string;
|
|
90
94
|
transform: (captured: string) => T;
|
|
91
95
|
validate: (captured: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => boolean | string;
|
|
92
96
|
beforeCapture: ((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null;
|
|
@@ -614,12 +618,14 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
|
|
|
614
618
|
```
|
|
615
619
|
- `token` (`RGXToken`): The token to wrap.
|
|
616
620
|
- `options` (`Partial<RGXPartOptions<R, T>>`, optional): Configuration options. Defaults to `{}`.
|
|
621
|
+
- `id` (`string`, optional): An optional identifier for this part. Defaults to `null`, but must be a string if provided.
|
|
617
622
|
- `transform` (`(captured: string) => T`, optional): A function that transforms the captured string into the desired type `T`. Defaults to an identity function that casts the string to `T`.
|
|
618
623
|
- `beforeCapture` (`((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null`, optional): A callback invoked before capturing this part during walking. Returns an `RGXPartControl` value to control walker behavior: `"skip"` to skip this token without capturing, `"silent"` to capture but not record in `captures`, `"stop"` to halt immediately without capturing or advancing, or `void`/`undefined` to proceed normally. Defaults to `null`.
|
|
619
624
|
- `afterCapture` (`((capture: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => void) | null`, optional): A callback invoked after capturing this part during walking. Receives the typed `RGXCapture<T>` result. Can call `walker.stop()` to halt walking after this capture. Defaults to `null`.
|
|
620
625
|
- `validate` (`((capture: RGXCapture<T>, walker: RGXWalker<R>) => boolean | string) | null`, optional): A callback invoked during validation after capturing and transforming, but before `afterCapture`. Returns `true` if validation passes, `false` to fail with a generic error, or a string to fail with that string as the error message. Defaults to `null`.
|
|
621
626
|
|
|
622
627
|
#### Properties
|
|
628
|
+
- `id` (`string | null`): An optional identifier for this part.
|
|
623
629
|
- `token` (`RGXToken`): The wrapped token.
|
|
624
630
|
- `transform` (`(captured: string) => T`, readonly): The transform function used to convert captured strings to values of type `T`.
|
|
625
631
|
- `beforeCapture` (`((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null`, readonly): The before-capture callback, or `null`.
|
|
@@ -630,10 +636,11 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
|
|
|
630
636
|
#### Methods
|
|
631
637
|
- `toRgx() => RGXToken`: Returns the wrapped token.
|
|
632
638
|
- `clone(depth: CloneDepth = "max") => RGXPart`: Creates a clone of this part. When `depth` is `0`, returns `this`; otherwise, returns a new `RGXPart` with a cloned token and the same `transform`, `beforeCapture`, and `afterCapture` references.
|
|
639
|
+
- `hasId() => this is RGXPart<R, T> & { id: string }`: A type guard that checks if this part has a non-null `id`. If `true`, narrows the type to indicate that `id` is a string.
|
|
633
640
|
- `validate(capture: RGXCapture<T>, walker: RGXWalker<R>) => void`: A method that calls the inner passed validation logic for this part, if any. If it returns `false`, a generic `RGXPartValidationFailedError` is thrown. If it returns a string, an `RGXPartValidationFailedError` is thrown with that string as the message. If it returns `true`, validation passed. This is called internally by the walker after capturing and transforming a part, before invoking `afterCapture`.
|
|
634
641
|
|
|
635
642
|
### RGXWalker\<R\>
|
|
636
|
-
A class that walks through a sequence of RGX tokens, matching each token against a source string at the current position. It implements `RGXConvertibleToken`, delegating to its internal `RGXTokenCollection`. The walker maintains a source position and a token position, advancing through both as tokens are matched. When an `RGXPart` is encountered, its `beforeCapture` callback can control behavior via return values (`RGXPartControl`), and its `afterCapture` callback is invoked with the typed capture result. All captures are stored as structured `RGXCapture` objects on the walker. The generic type `R` represents a user-defined "reduced" value that can accumulate state during walking (e.g., via `RGXPart` callbacks).
|
|
643
|
+
A class that walks through a sequence of RGX tokens, matching each token against a source string at the current position. It implements `RGXConvertibleToken`, delegating to its internal `RGXTokenCollection`. The walker maintains a source position and a token position, advancing through both as tokens are matched. When an `RGXPart` is encountered, its `beforeCapture` callback can control behavior via return values (`RGXPartControl`), and its `afterCapture` callback is invoked with the typed capture result. All captures are stored as structured `RGXCapture` objects on the walker, and captures with ids are stored in the `namedCaptures` property also. The generic type `R` represents a user-defined "reduced" value that can accumulate state during walking (e.g., via `RGXPart` callbacks).
|
|
637
644
|
|
|
638
645
|
A function `rgxWalker` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
639
646
|
|
|
@@ -657,7 +664,8 @@ constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalker
|
|
|
657
664
|
- `tokens` (`RGXTokenCollection`): The internal collection of tokens in 'concat' mode (readonly).
|
|
658
665
|
- `tokenPosition` (`number`): The current index in the token collection. Setting this validates that the value is >= 0 and <= `tokens.length`, throwing `RGXOutOfBoundsError` if not.
|
|
659
666
|
- `reduced` (`R`): A user-defined accumulator value, typically updated by `RGXPart` callbacks during walking.
|
|
660
|
-
- `captures` (`RGXCapture[]`): An array of structured capture results recorded during walking. Each entry has a `raw` string
|
|
667
|
+
- `captures` (`RGXCapture[]`): An array of structured capture results recorded during walking. Each entry has a `raw` string, a `value` (the transform result for Parts, or the raw string for plain tokens), `start` and `end` indices in the source string, and an `ownerId` that is the `id` of the Part that produced it (or `null` for captures from plain tokens or parts without ids).
|
|
668
|
+
- `namedCaptures` (`Record<string, RGXCapture[]>`): An object mapping capture IDs to their corresponding `RGXCapture` results. Only Parts with non-null IDs are included. The captures occur in the same order as they appear in the `captures` array.
|
|
661
669
|
- `stopped` (`boolean`, readonly): Whether the walker has been stopped, either by a Part's `beforeCapture` returning `"stop"` or by calling `stop()` in an `afterCapture` callback.
|
|
662
670
|
|
|
663
671
|
#### Methods
|
|
@@ -670,7 +678,7 @@ constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalker
|
|
|
670
678
|
- `currentToken() => RGXToken | null`: Returns the token at the current token position, or `null` if at the end.
|
|
671
679
|
- `remainingSource() => string | null`: Returns the remaining source string from the current position onward, or `null` if the source is fully consumed.
|
|
672
680
|
- `capture(token: RGXToken) => string`: Resolves the token to a regex, asserts that it matches at the current source position (throwing `RGXRegexNotMatchedAtPositionError` if not), and advances the source position by the match length. Returns the matched string.
|
|
673
|
-
- `step() => RGXCapture | null`: Steps through the next token in the collection. If the token is an `RGXPart`, calls `beforeCapture` first — if it returns `"stop"`, sets `stopped` and returns `null` without advancing; if `"skip"`, advances the token position and returns `null` without capturing; if `"silent"`, captures but does not add to `captures`. After capturing, validates. After validating, calls `afterCapture` if present. Returns the `RGXCapture` result, or `null` if there are no more tokens, the step was skipped, or the walker was stopped.
|
|
681
|
+
- `step() => RGXCapture | null`: Steps through the next token in the collection. If the token is an `RGXPart`, calls `beforeCapture` first — if it returns `"stop"`, sets `stopped` and returns `null` without advancing; if `"skip"`, advances the token position and returns `null` without capturing; if `"silent"`, captures but does not add to `captures` or `namedCaptures`. After capturing, validates. After validating, calls `afterCapture` if present. Returns the `RGXCapture` result, or `null` if there are no more tokens, the step was skipped, or the walker was stopped.
|
|
674
682
|
- `stepToToken(predicate: (token: RGXToken) => boolean) => void`: Steps through tokens until the predicate returns `true` for the current token or the walker is stopped. The matching token is not consumed.
|
|
675
683
|
- `stepToPart(predicate?: (part: RGXPart<R>) => boolean) => void`: Steps through tokens until the next `RGXPart` satisfying the predicate is reached. If already at a Part, steps once first to move past it. The matching Part is not consumed.
|
|
676
684
|
- `walk() => void`: Steps through all remaining tokens until the end of the token collection or the walker is stopped.
|
package/dist/walker/base.d.ts
CHANGED
|
@@ -13,6 +13,7 @@ export declare class RGXWalker<R> implements RGXConvertibleToken {
|
|
|
13
13
|
_tokenPosition: number;
|
|
14
14
|
reduced: R;
|
|
15
15
|
captures: RGXCapture[];
|
|
16
|
+
namedCaptures: Record<string, RGXCapture[]>;
|
|
16
17
|
private _stopped;
|
|
17
18
|
static check: (value: unknown) => value is RGXWalker<unknown>;
|
|
18
19
|
static assert: (value: unknown) => asserts value is RGXWalker<unknown>;
|
package/dist/walker/base.js
CHANGED
|
@@ -28,6 +28,7 @@ class RGXWalker {
|
|
|
28
28
|
}
|
|
29
29
|
constructor(source, tokens, options = {}) {
|
|
30
30
|
this.captures = [];
|
|
31
|
+
this.namedCaptures = {};
|
|
31
32
|
this._stopped = false;
|
|
32
33
|
this.source = source;
|
|
33
34
|
this.sourcePosition = options.startingSourcePosition ?? 0;
|
|
@@ -93,9 +94,11 @@ class RGXWalker {
|
|
|
93
94
|
}
|
|
94
95
|
}
|
|
95
96
|
// Capture the match
|
|
97
|
+
const start = this.sourcePosition;
|
|
96
98
|
const raw = this.capture(token);
|
|
99
|
+
const end = this.sourcePosition;
|
|
97
100
|
const value = isPart ? token.transform(raw) : raw;
|
|
98
|
-
const captureResult = { raw, value };
|
|
101
|
+
const captureResult = { raw, value, start, end, ownerId: isPart && token.hasId() ? token.id : null };
|
|
99
102
|
// Validate the part. If validation fails, it will throw an error, so nothing below will run.
|
|
100
103
|
if (isPart) {
|
|
101
104
|
token.validate(captureResult, this);
|
|
@@ -103,6 +106,11 @@ class RGXWalker {
|
|
|
103
106
|
// Skip adding the capture if in silent mode.
|
|
104
107
|
if (!silent) {
|
|
105
108
|
this.captures.push(captureResult);
|
|
109
|
+
if (isPart && token.hasId()) {
|
|
110
|
+
if (!(token.id in this.namedCaptures))
|
|
111
|
+
this.namedCaptures[token.id] = [];
|
|
112
|
+
this.namedCaptures[token.id].push(captureResult);
|
|
113
|
+
}
|
|
106
114
|
}
|
|
107
115
|
// Notify Part after capture
|
|
108
116
|
if (isPart) {
|
package/dist/walker/part.d.ts
CHANGED
|
@@ -5,14 +5,19 @@ export type RGXPartControl = "skip" | "stop" | "silent" | void;
|
|
|
5
5
|
export type RGXCapture<T = unknown> = {
|
|
6
6
|
raw: string;
|
|
7
7
|
value: T;
|
|
8
|
+
start: number;
|
|
9
|
+
end: number;
|
|
10
|
+
ownerId: string | null;
|
|
8
11
|
};
|
|
9
12
|
export type RGXPartOptions<R, T = string> = {
|
|
13
|
+
id: string;
|
|
10
14
|
transform: (captured: string) => T;
|
|
11
15
|
validate: (captured: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => boolean | string;
|
|
12
16
|
beforeCapture: ((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null;
|
|
13
17
|
afterCapture: ((capture: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => void) | null;
|
|
14
18
|
};
|
|
15
19
|
export declare class RGXPart<R, T = string> implements RGXConvertibleToken {
|
|
20
|
+
id: string | null;
|
|
16
21
|
token: RGXToken;
|
|
17
22
|
readonly transform: RGXPartOptions<R, T>["transform"];
|
|
18
23
|
private readonly _validate;
|
|
@@ -21,6 +26,9 @@ export declare class RGXPart<R, T = string> implements RGXConvertibleToken {
|
|
|
21
26
|
static check: (value: unknown) => value is RGXPart<unknown, unknown>;
|
|
22
27
|
static assert: (value: unknown) => asserts value is RGXPart<unknown, unknown>;
|
|
23
28
|
constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>);
|
|
29
|
+
hasId(): this is RGXPart<R, T> & {
|
|
30
|
+
id: string;
|
|
31
|
+
};
|
|
24
32
|
validate(capture: RGXCapture<T>, walker: RGXWalker<R>): void;
|
|
25
33
|
get rgxIsGroup(): boolean;
|
|
26
34
|
get rgxIsRepeatable(): boolean;
|
package/dist/walker/part.js
CHANGED
|
@@ -7,16 +7,18 @@ const internal_1 = require("../internal");
|
|
|
7
7
|
const clone_1 = require("../clone");
|
|
8
8
|
const immutability_utils_1 = require("@ptolemy2002/immutability-utils");
|
|
9
9
|
const errors_1 = require("../errors");
|
|
10
|
-
// A Part is purely a definition: a token + optional callbacks.
|
|
11
|
-
// It does NOT store capture state — that lives on the walker.
|
|
12
10
|
class RGXPart {
|
|
13
11
|
constructor(token, options = {}) {
|
|
12
|
+
this.id = options.id ?? null;
|
|
14
13
|
this.token = token;
|
|
15
14
|
this.transform = options.transform ?? ((captured) => captured);
|
|
16
15
|
this._validate = options.validate ?? (() => true);
|
|
17
16
|
this.beforeCapture = options.beforeCapture ?? null;
|
|
18
17
|
this.afterCapture = options.afterCapture ?? null;
|
|
19
18
|
}
|
|
19
|
+
hasId() {
|
|
20
|
+
return this.id !== null;
|
|
21
|
+
}
|
|
20
22
|
validate(capture, walker) {
|
|
21
23
|
const result = this._validate(capture, this, walker);
|
|
22
24
|
if (result === true)
|
|
@@ -42,6 +44,7 @@ class RGXPart {
|
|
|
42
44
|
if (depth === 0)
|
|
43
45
|
return this;
|
|
44
46
|
return new RGXPart((0, clone_1.cloneRGXToken)(this.token, (0, immutability_utils_1.depthDecrement)(depth, 1)), {
|
|
47
|
+
id: this.id ?? undefined,
|
|
45
48
|
transform: this.transform,
|
|
46
49
|
beforeCapture: this.beforeCapture,
|
|
47
50
|
afterCapture: this.afterCapture,
|