@ptolemy2002/rgx 6.1.1 → 6.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +9 -2
- package/dist/walker/base.d.ts +1 -0
- package/dist/walker/base.js +7 -1
- package/dist/walker/part.d.ts +7 -0
- package/dist/walker/part.js +5 -2
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -84,9 +84,12 @@ 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;
|
|
87
89
|
};
|
|
88
90
|
|
|
89
91
|
type RGXPartOptions<R, T=string> = {
|
|
92
|
+
id: string;
|
|
90
93
|
transform: (captured: string) => T;
|
|
91
94
|
validate: (captured: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => boolean | string;
|
|
92
95
|
beforeCapture: ((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null;
|
|
@@ -614,12 +617,14 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
|
|
|
614
617
|
```
|
|
615
618
|
- `token` (`RGXToken`): The token to wrap.
|
|
616
619
|
- `options` (`Partial<RGXPartOptions<R, T>>`, optional): Configuration options. Defaults to `{}`.
|
|
620
|
+
- `id` (`string`, optional): An optional identifier for this part. Defaults to `null`, but must be a string if provided.
|
|
617
621
|
- `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
622
|
- `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
623
|
- `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
624
|
- `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
625
|
|
|
622
626
|
#### Properties
|
|
627
|
+
- `id` (`string | null`): An optional identifier for this part.
|
|
623
628
|
- `token` (`RGXToken`): The wrapped token.
|
|
624
629
|
- `transform` (`(captured: string) => T`, readonly): The transform function used to convert captured strings to values of type `T`.
|
|
625
630
|
- `beforeCapture` (`((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null`, readonly): The before-capture callback, or `null`.
|
|
@@ -630,10 +635,11 @@ constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>)
|
|
|
630
635
|
#### Methods
|
|
631
636
|
- `toRgx() => RGXToken`: Returns the wrapped token.
|
|
632
637
|
- `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.
|
|
638
|
+
- `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
639
|
- `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
640
|
|
|
635
641
|
### 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).
|
|
642
|
+
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
643
|
|
|
638
644
|
A function `rgxWalker` is provided with the same parameters as this class' constructor, for easier instantiation without needing to use the `new` keyword.
|
|
639
645
|
|
|
@@ -658,6 +664,7 @@ constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalker
|
|
|
658
664
|
- `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
665
|
- `reduced` (`R`): A user-defined accumulator value, typically updated by `RGXPart` callbacks during walking.
|
|
660
666
|
- `captures` (`RGXCapture[]`): An array of structured capture results recorded during walking. Each entry has a `raw` string and a `value` (the transform result for Parts, or the raw string for plain tokens).
|
|
667
|
+
- `namedCaptures` (`Record<string, RGXCapture>`): An object mapping capture IDs to their corresponding `RGXCapture` results. Only Parts with non-null IDs are included.
|
|
661
668
|
- `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
669
|
|
|
663
670
|
#### Methods
|
|
@@ -670,7 +677,7 @@ constructor(source: string, tokens: RGXTokenCollectionInput, options?: RGXWalker
|
|
|
670
677
|
- `currentToken() => RGXToken | null`: Returns the token at the current token position, or `null` if at the end.
|
|
671
678
|
- `remainingSource() => string | null`: Returns the remaining source string from the current position onward, or `null` if the source is fully consumed.
|
|
672
679
|
- `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.
|
|
680
|
+
- `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
681
|
- `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
682
|
- `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
683
|
- `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 };
|
|
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,9 @@ 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
|
+
this.namedCaptures[token.id] = captureResult;
|
|
111
|
+
}
|
|
106
112
|
}
|
|
107
113
|
// Notify Part after capture
|
|
108
114
|
if (isPart) {
|
package/dist/walker/part.d.ts
CHANGED
|
@@ -5,14 +5,18 @@ 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;
|
|
8
10
|
};
|
|
9
11
|
export type RGXPartOptions<R, T = string> = {
|
|
12
|
+
id: string;
|
|
10
13
|
transform: (captured: string) => T;
|
|
11
14
|
validate: (captured: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => boolean | string;
|
|
12
15
|
beforeCapture: ((part: RGXPart<R, T>, walker: RGXWalker<R>) => RGXPartControl) | null;
|
|
13
16
|
afterCapture: ((capture: RGXCapture<T>, part: RGXPart<R, T>, walker: RGXWalker<R>) => void) | null;
|
|
14
17
|
};
|
|
15
18
|
export declare class RGXPart<R, T = string> implements RGXConvertibleToken {
|
|
19
|
+
id: string | null;
|
|
16
20
|
token: RGXToken;
|
|
17
21
|
readonly transform: RGXPartOptions<R, T>["transform"];
|
|
18
22
|
private readonly _validate;
|
|
@@ -21,6 +25,9 @@ export declare class RGXPart<R, T = string> implements RGXConvertibleToken {
|
|
|
21
25
|
static check: (value: unknown) => value is RGXPart<unknown, unknown>;
|
|
22
26
|
static assert: (value: unknown) => asserts value is RGXPart<unknown, unknown>;
|
|
23
27
|
constructor(token: RGXToken, options?: Partial<RGXPartOptions<R, T>>);
|
|
28
|
+
hasId(): this is RGXPart<R, T> & {
|
|
29
|
+
id: string;
|
|
30
|
+
};
|
|
24
31
|
validate(capture: RGXCapture<T>, walker: RGXWalker<R>): void;
|
|
25
32
|
get rgxIsGroup(): boolean;
|
|
26
33
|
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,
|