prefix-safe-json 0.0.1-alpha.4 → 0.1.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.
Files changed (135) hide show
  1. package/LICENSE +4 -0
  2. package/README.md +2 -2
  3. package/package.json +2 -1
  4. package/dist/coordinator/coordinator.d.ts +0 -53
  5. package/dist/coordinator/coordinator.d.ts.map +0 -1
  6. package/dist/coordinator/coordinator.js +0 -448
  7. package/dist/coordinator/coordinator.js.map +0 -1
  8. package/dist/coordinator/diagnostic-codes.d.ts +0 -11
  9. package/dist/coordinator/diagnostic-codes.d.ts.map +0 -1
  10. package/dist/coordinator/diagnostic-codes.js +0 -22
  11. package/dist/coordinator/diagnostic-codes.js.map +0 -1
  12. package/dist/coordinator/protocol.d.ts +0 -61
  13. package/dist/coordinator/protocol.d.ts.map +0 -1
  14. package/dist/coordinator/protocol.js +0 -2
  15. package/dist/coordinator/protocol.js.map +0 -1
  16. package/dist/coordinator/types.d.ts +0 -104
  17. package/dist/coordinator/types.d.ts.map +0 -1
  18. package/dist/coordinator/types.js +0 -7
  19. package/dist/coordinator/types.js.map +0 -1
  20. package/dist/diagnostics/codes.d.ts +0 -24
  21. package/dist/diagnostics/codes.d.ts.map +0 -1
  22. package/dist/diagnostics/codes.js +0 -28
  23. package/dist/diagnostics/codes.js.map +0 -1
  24. package/dist/diagnostics/factory.d.ts +0 -8
  25. package/dist/diagnostics/factory.d.ts.map +0 -1
  26. package/dist/diagnostics/factory.js +0 -17
  27. package/dist/diagnostics/factory.js.map +0 -1
  28. package/dist/gate/decide.d.ts +0 -27
  29. package/dist/gate/decide.d.ts.map +0 -1
  30. package/dist/gate/decide.js +0 -138
  31. package/dist/gate/decide.js.map +0 -1
  32. package/dist/gate/gate.d.ts +0 -25
  33. package/dist/gate/gate.d.ts.map +0 -1
  34. package/dist/gate/gate.js +0 -96
  35. package/dist/gate/gate.js.map +0 -1
  36. package/dist/gate/types.d.ts +0 -184
  37. package/dist/gate/types.d.ts.map +0 -1
  38. package/dist/gate/types.js +0 -2
  39. package/dist/gate/types.js.map +0 -1
  40. package/dist/grammar/frame.d.ts +0 -58
  41. package/dist/grammar/frame.d.ts.map +0 -1
  42. package/dist/grammar/frame.js +0 -87
  43. package/dist/grammar/frame.js.map +0 -1
  44. package/dist/grammar/pointer.d.ts +0 -10
  45. package/dist/grammar/pointer.d.ts.map +0 -1
  46. package/dist/grammar/pointer.js +0 -20
  47. package/dist/grammar/pointer.js.map +0 -1
  48. package/dist/grammar/stack.d.ts +0 -73
  49. package/dist/grammar/stack.d.ts.map +0 -1
  50. package/dist/grammar/stack.js +0 -168
  51. package/dist/grammar/stack.js.map +0 -1
  52. package/dist/guard/ai-sdk.d.ts +0 -48
  53. package/dist/guard/ai-sdk.d.ts.map +0 -1
  54. package/dist/guard/ai-sdk.js +0 -51
  55. package/dist/guard/ai-sdk.js.map +0 -1
  56. package/dist/guard/provider-guard.d.ts +0 -4
  57. package/dist/guard/provider-guard.d.ts.map +0 -1
  58. package/dist/guard/provider-guard.js +0 -38
  59. package/dist/guard/provider-guard.js.map +0 -1
  60. package/dist/guard/types.d.ts +0 -48
  61. package/dist/guard/types.d.ts.map +0 -1
  62. package/dist/guard/types.js +0 -2
  63. package/dist/guard/types.js.map +0 -1
  64. package/dist/index.d.ts +0 -45
  65. package/dist/index.d.ts.map +0 -1
  66. package/dist/index.js +0 -45
  67. package/dist/index.js.map +0 -1
  68. package/dist/lexer/scanner.d.ts +0 -106
  69. package/dist/lexer/scanner.d.ts.map +0 -1
  70. package/dist/lexer/scanner.js +0 -658
  71. package/dist/lexer/scanner.js.map +0 -1
  72. package/dist/lexer/states.d.ts +0 -31
  73. package/dist/lexer/states.d.ts.map +0 -1
  74. package/dist/lexer/states.js +0 -35
  75. package/dist/lexer/states.js.map +0 -1
  76. package/dist/lexer/tokens.d.ts +0 -22
  77. package/dist/lexer/tokens.d.ts.map +0 -1
  78. package/dist/lexer/tokens.js +0 -22
  79. package/dist/lexer/tokens.js.map +0 -1
  80. package/dist/limits.d.ts +0 -14
  81. package/dist/limits.d.ts.map +0 -1
  82. package/dist/limits.js +0 -23
  83. package/dist/limits.js.map +0 -1
  84. package/dist/parser.d.ts +0 -6
  85. package/dist/parser.d.ts.map +0 -1
  86. package/dist/parser.js +0 -922
  87. package/dist/parser.js.map +0 -1
  88. package/dist/providers/adapter.d.ts +0 -10
  89. package/dist/providers/adapter.d.ts.map +0 -1
  90. package/dist/providers/adapter.js +0 -2
  91. package/dist/providers/adapter.js.map +0 -1
  92. package/dist/providers/ai-sdk.d.ts +0 -58
  93. package/dist/providers/ai-sdk.d.ts.map +0 -1
  94. package/dist/providers/ai-sdk.js +0 -212
  95. package/dist/providers/ai-sdk.js.map +0 -1
  96. package/dist/providers/anthropic.d.ts +0 -45
  97. package/dist/providers/anthropic.d.ts.map +0 -1
  98. package/dist/providers/anthropic.js +0 -112
  99. package/dist/providers/anthropic.js.map +0 -1
  100. package/dist/providers/gemini.d.ts +0 -31
  101. package/dist/providers/gemini.d.ts.map +0 -1
  102. package/dist/providers/gemini.js +0 -94
  103. package/dist/providers/gemini.js.map +0 -1
  104. package/dist/providers/openai-compatible.d.ts +0 -33
  105. package/dist/providers/openai-compatible.d.ts.map +0 -1
  106. package/dist/providers/openai-compatible.js +0 -160
  107. package/dist/providers/openai-compatible.js.map +0 -1
  108. package/dist/providers/openai.d.ts +0 -55
  109. package/dist/providers/openai.d.ts.map +0 -1
  110. package/dist/providers/openai.js +0 -263
  111. package/dist/providers/openai.js.map +0 -1
  112. package/dist/providers/openrouter.d.ts +0 -35
  113. package/dist/providers/openrouter.d.ts.map +0 -1
  114. package/dist/providers/openrouter.js +0 -55
  115. package/dist/providers/openrouter.js.map +0 -1
  116. package/dist/semantic/builder.d.ts +0 -55
  117. package/dist/semantic/builder.d.ts.map +0 -1
  118. package/dist/semantic/builder.js +0 -140
  119. package/dist/semantic/builder.js.map +0 -1
  120. package/dist/semantic/events.d.ts +0 -2
  121. package/dist/semantic/events.d.ts.map +0 -1
  122. package/dist/semantic/events.js +0 -5
  123. package/dist/semantic/events.js.map +0 -1
  124. package/dist/semantic/snapshot.d.ts +0 -56
  125. package/dist/semantic/snapshot.d.ts.map +0 -1
  126. package/dist/semantic/snapshot.js +0 -230
  127. package/dist/semantic/snapshot.js.map +0 -1
  128. package/dist/types.d.ts +0 -156
  129. package/dist/types.d.ts.map +0 -1
  130. package/dist/types.js +0 -5
  131. package/dist/types.js.map +0 -1
  132. package/dist/utf8/decoder.d.ts +0 -53
  133. package/dist/utf8/decoder.d.ts.map +0 -1
  134. package/dist/utf8/decoder.js +0 -323
  135. package/dist/utf8/decoder.js.map +0 -1
@@ -1,184 +0,0 @@
1
- import { JsonValue, Diagnostic } from "../types.js";
2
- import { CoordinatorDiagnostic, CoordinatorPushResult, ToolCallCoordinatorEvent } from "../coordinator/types.js";
3
- import { NormalizedToolStreamEvent, ProviderName, StreamEndReason } from "../coordinator/protocol.js";
4
- /**
5
- * What to do with a tool call right now.
6
- *
7
- * - `"execute"`: the arguments are complete, unfabricated, and (if a schema
8
- * was registered for this tool) schema-valid. Safe to run.
9
- * - `"retry"`: the provider's output was incomplete or truncated. There is
10
- * nothing wrong with the data received so far - there just isn't a
11
- * trustworthy complete value yet. Re-request/continue generation.
12
- * - `"reject"`: the data itself is the problem (malformed JSON, a schema
13
- * mismatch, a resource limit, a provider-side error, or a content-policy
14
- * termination). Re-sending the exact same partial input will not fix it.
15
- */
16
- export type ExecutionAction = "execute" | "retry" | "reject";
17
- /**
18
- * Machine-readable classification of *why* an `ExecutionAction` was chosen.
19
- * See `docs/EXECUTION_GATE.md` for the full decision table.
20
- */
21
- export type ExecutionReason = "complete" | "truncated" | "stream_incomplete" | "schema_invalid" | "malformed" | "resource_limit" | "provider_error" | "content_filtered" | "unknown";
22
- /**
23
- * Why a decision came out the way it did - observability, not a second
24
- * decision input. Every field here is read-only, derived state already held
25
- * elsewhere (`ToolCallState`, the stream-level `DecisionContext`); nothing
26
- * on this object ever feeds back into `decideExecution()`'s own logic, and
27
- * changing what it reports can never change `action`/`executable`/`reason`.
28
- *
29
- * Deliberately excludes anything that would require new cross-layer
30
- * plumbing to derive reliably (e.g. a received-chunk count - the parser
31
- * only tracks cumulative bytes, not `push()` call counts, and adding that
32
- * tracking purely to populate a metric here was judged not worth the
33
- * coupling for this release).
34
- */
35
- export interface DecisionEvidence {
36
- /** Which provider adapter produced this call (`ToolCallState.provider`). */
37
- readonly provider: ProviderName;
38
- /**
39
- * The provider's own, pre-normalization finish/stop reason string, when
40
- * the stream-ending event carried one (e.g. `"length"`, `"max_output_tokens"`,
41
- * `"content_filter"`). `undefined` when the stream never reported one, or
42
- * reported one without a `providerReason` (e.g. a default `finish()` call
43
- * with no `meta`).
44
- */
45
- readonly providerReason?: string;
46
- /** The normalized, library-level stream-end reason applied to this call. */
47
- readonly streamEndReason: StreamEndReason;
48
- /**
49
- * Whether a real `provider_stream_end` reason was ever observed, as
50
- * opposed to the neutral `"unknown"` default a gate reports before any
51
- * stream-end signal has arrived at all. `true` here does NOT mean the
52
- * reason was safe - a confirmed `"length"` still has `terminalConfirmed:
53
- * true` - only that the stream's end state is genuinely known rather than
54
- * merely unclassified or never observed.
55
- */
56
- readonly terminalConfirmed: boolean;
57
- /**
58
- * Whether the parser's root JSON container actually closed
59
- * (`ToolCallState.parser.rootComplete`) - independent of whether that
60
- * closure was genuine or reached via a safe-close repair, and independent
61
- * of whether the stream-end reason makes it trustworthy. A syntactically
62
- * complete value cut short by `length` has `structurallyComplete: true`
63
- * and `parserExecutable: false` at the same time - that combination *is*
64
- * the scenario this library exists to catch.
65
- */
66
- readonly structurallyComplete: boolean;
67
- /** `ToolCallState.parser.executable`, verbatim - the parser's own fail-closed verdict. */
68
- readonly parserExecutable: boolean;
69
- /**
70
- * `ToolCallState.schemaValid`, verbatim. `undefined` when no schema was
71
- * registered for this tool, or the call never reached a structurally
72
- * complete outcome.
73
- */
74
- readonly schemaValid?: boolean;
75
- /** Total bytes received for this call's argument stream (`ToolCallState.parser.receivedBytes`). */
76
- readonly receivedBytes: number;
77
- }
78
- interface ExecutionDecisionCommon {
79
- /** The coordinator's internal call identifier (see `ToolCallState.internalId`). */
80
- readonly internalId: string;
81
- readonly toolCallId?: string;
82
- readonly toolIndex?: number;
83
- readonly name?: string;
84
- /**
85
- * Whatever was safely committed for this call, complete or not - present
86
- * for both executable and non-executable decisions so a caller can see
87
- * *what part* of a rejected/retried call was genuinely received (e.g. a
88
- * `path` field that arrived before a `content` field got cut off).
89
- * Never the source of truth for whether it's safe to act on - that's
90
- * `action`/`executable`. Absent only when nothing was ever committed.
91
- */
92
- readonly stableValue?: JsonValue;
93
- /** This call's own parser diagnostics, verbatim (`ToolCallState.parser.diagnostics`). */
94
- readonly parserDiagnostics: readonly Diagnostic[];
95
- /** Coordinator-level diagnostics attributable to this call, verbatim. */
96
- readonly coordinatorDiagnostics: readonly CoordinatorDiagnostic[];
97
- /**
98
- * Why this decision came out the way it did. See `DecisionEvidence` -
99
- * always present, purely observational, never a second source of truth
100
- * for `action`/`executable`/`reason`.
101
- */
102
- readonly evidence: DecisionEvidence;
103
- }
104
- /**
105
- * The one and only shape a decision can have when `action === "execute"`.
106
- * `value` is a real, present `JsonValue` here - never `undefined`, never
107
- * optional - because this is the single positive case: everything else in
108
- * the gate exists to rule this out unless it's genuinely earned.
109
- */
110
- export interface ExecuteDecision extends ExecutionDecisionCommon {
111
- readonly action: "execute";
112
- readonly executable: true;
113
- readonly reason: "complete";
114
- readonly value: JsonValue;
115
- /**
116
- * Narrowed to required here (unlike the inherited `name?: string`):
117
- * the coordinator only ever transitions a call to `status: "complete"`
118
- * when `name` is defined (see `DefaultToolCallStreamCoordinator.finishCall`
119
- * - a call with no name is forced to `"invalid"` instead), so every
120
- * `ExecuteDecision` genuinely has one. Encoding that here means
121
- * `tools[decision.name](decision.value)` type-checks directly after
122
- * narrowing on `action === "execute"`, with no non-null assertion needed.
123
- */
124
- readonly name: string;
125
- }
126
- /**
127
- * Every other outcome. `value` does not exist on this type at all (not
128
- * `undefined` - absent) - TypeScript itself refuses code that reads a
129
- * "final executable value" off a call the gate did not clear for execution.
130
- */
131
- export interface NonExecutableDecision extends ExecutionDecisionCommon {
132
- readonly action: "retry" | "reject";
133
- readonly executable: false;
134
- readonly reason: Exclude<ExecutionReason, "complete">;
135
- }
136
- /**
137
- * `ExecuteDecision | NonExecutableDecision` - a discriminated union on
138
- * `action` (and redundantly on `executable`, for callers who prefer that
139
- * check). Narrowing on either field gives you the right shape:
140
- *
141
- * ```ts
142
- * if (decision.action === "execute") {
143
- * await tools[decision.name](decision.value); // JsonValue, not JsonValue|undefined
144
- * }
145
- * ```
146
- */
147
- export type ExecutionDecision = ExecuteDecision | NonExecutableDecision;
148
- export interface ToolCallExecutionGateFinalResult {
149
- /** One decision per tool call the coordinator ever created. */
150
- readonly decisions: readonly ExecutionDecision[];
151
- /**
152
- * The full, unfiltered coordinator diagnostics list (same as
153
- * `coordinator.snapshot().diagnostics`) - includes diagnostics with no
154
- * associated call, e.g. `E_COORDINATOR_LIMIT_CALLS` fires for a call that
155
- * hit the concurrent-call limit before a `ToolCallState` could even be
156
- * created for it, so it can never appear in `decisions`.
157
- */
158
- readonly diagnostics: readonly CoordinatorDiagnostic[];
159
- }
160
- /**
161
- * High-level fail-closed execution decision layer built on top of
162
- * `ToolCallStreamCoordinator`. Answers one question per tool call: is it
163
- * safe to execute right now? Callers never need to touch parser lexical
164
- * state, coordinator event mechanics, or JSON Pointer paths - push provider
165
- * events in, read `ExecutionDecision`s out.
166
- */
167
- export interface ToolCallExecutionGate {
168
- push(event: NormalizedToolStreamEvent): CoordinatorPushResult;
169
- /**
170
- * In-flight view. Every decision here is `"retry"` or `"reject"` -
171
- * `"execute"` is only ever returned once the stream has genuinely
172
- * finished (see `finish()`), since schema validity and prefix-safety are
173
- * both only meaningful once a call has settled.
174
- */
175
- snapshot(): readonly ExecutionDecision[];
176
- /** Drains the underlying coordinator's raw event queue, for advanced/UI consumers. */
177
- drainEvents(): readonly ToolCallCoordinatorEvent[];
178
- finish(meta?: {
179
- reason?: StreamEndReason;
180
- providerReason?: string;
181
- }): ToolCallExecutionGateFinalResult;
182
- }
183
- export {};
184
- //# sourceMappingURL=types.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/gate/types.ts"],"names":[],"mappings":"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"}
@@ -1,2 +0,0 @@
1
- export {};
2
- //# sourceMappingURL=types.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/gate/types.ts"],"names":[],"mappings":""}
@@ -1,58 +0,0 @@
1
- /**
2
- * Expectation states for object parsing.
3
- */
4
- export type ObjectExpectation = "first_key_or_end" | "key_after_comma" | "colon" | "value" | "comma_or_end";
5
- /**
6
- * Expectation states for array parsing.
7
- */
8
- export type ArrayExpectation = "first_value_or_end" | "value_after_comma" | "comma_or_end";
9
- /**
10
- * A frame on the grammar stack representing a JSON container.
11
- */
12
- export interface GrammarFrame {
13
- /** The type of container. */
14
- containerType: "object" | "array";
15
- /**
16
- * The JSON Pointer path up to this container.
17
- * Backed by a lazily-computed, memoized getter (see attachLazyPath) —
18
- * reads exactly like a plain string field everywhere else in the codebase.
19
- */
20
- path: string;
21
- /** Current expectation for object parsing. */
22
- objectExpectation?: ObjectExpectation;
23
- /** Current key being processed. */
24
- currentKey?: string;
25
- /** Set of keys already seen (for duplicate detection). */
26
- seenKeys?: Set<string>;
27
- /** Current expectation for array parsing. */
28
- arrayExpectation?: ArrayExpectation;
29
- /** Index of the next element. */
30
- nextArrayIndex: number;
31
- /** Byte offset where this container started. */
32
- byteStart: number;
33
- /**
34
- * @internal Lazy-path bookkeeping. Do not read directly — use `.path`.
35
- * A frame's own path never changes after creation (only descendants'
36
- * currentKey/nextArrayIndex mutate), so it's safe to resolve on demand.
37
- */
38
- _parent?: GrammarFrame | null;
39
- /** @internal The key/index linking `_parent` to this frame, captured at creation time. */
40
- _segment?: string | number | null;
41
- /** @internal Memoized resolved path, set the first time `.path` is read. */
42
- _cachedPath?: string;
43
- }
44
- /**
45
- * Create a new object frame.
46
- * `parent` is the frame this one is nested inside (or null at the root);
47
- * `segment` is the key/index leading from parent to this frame (or null at
48
- * the root) — the same value `GrammarStack.currentValuePath()` would have
49
- * used, captured eagerly since it reflects the parent's mutable state at
50
- * this exact moment. Only the (expensive, O(depth)) string flattening is
51
- * deferred.
52
- */
53
- export declare function createObjectFrame(parent: GrammarFrame | null, segment: string | number | null, byteStart: number): GrammarFrame;
54
- /**
55
- * Create a new array frame. See createObjectFrame for `parent`/`segment`.
56
- */
57
- export declare function createArrayFrame(parent: GrammarFrame | null, segment: string | number | null, byteStart: number): GrammarFrame;
58
- //# sourceMappingURL=frame.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"frame.d.ts","sourceRoot":"","sources":["../../src/grammar/frame.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,MAAM,iBAAiB,GACzB,kBAAkB,GAClB,iBAAiB,GACjB,OAAO,GACP,OAAO,GACP,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,MAAM,gBAAgB,GACxB,oBAAoB,GACpB,mBAAmB,GACnB,cAAc,CAAC;AAEnB;;GAEG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,aAAa,EAAE,QAAQ,GAAG,OAAO,CAAC;IAElC;;;;OAIG;IACH,IAAI,EAAE,MAAM,CAAC;IAGb,8CAA8C;IAC9C,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IAEtC,mCAAmC;IACnC,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAGvB,6CAA6C;IAC7C,gBAAgB,CAAC,EAAE,gBAAgB,CAAC;IAEpC,iCAAiC;IACjC,cAAc,EAAE,MAAM,CAAC;IAEvB,gDAAgD;IAChD,SAAS,EAAE,MAAM,CAAC;IAElB;;;;OAIG;IACH,OAAO,CAAC,EAAE,YAAY,GAAG,IAAI,CAAC;IAC9B,0FAA0F;IAC1F,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IAClC,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AA0DD;;;;;;;;GAQG;AACH,wBAAgB,iBAAiB,CAC/B,MAAM,EAAE,YAAY,GAAG,IAAI,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC/B,SAAS,EAAE,MAAM,GAChB,YAAY,CAWd;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,MAAM,EAAE,YAAY,GAAG,IAAI,EAC3B,OAAO,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,EAC/B,SAAS,EAAE,MAAM,GAChB,YAAY,CAUd"}
@@ -1,87 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Grammar stack frame — tracks state of a JSON container
3
- // ---------------------------------------------------------------------------
4
- import { appendPointer } from "./pointer.js";
5
- /**
6
- * Resolve (and memoize) a frame's full JSON Pointer path.
7
- *
8
- * Iterative, not recursive: walks up `_parent` references collecting frames
9
- * until it finds one whose path is already cached (or the root), then walks
10
- * back down building and caching each frame's path exactly once. This keeps
11
- * per-frame cost amortized O(1) regardless of nesting depth, and avoids
12
- * both the call-stack growth a recursive walk would have and the O(depth)
13
- * eager string concatenation this replaces (which made opening N nested
14
- * containers cost O(N^2) total, regardless of whether any value inside them
15
- * was ever committed).
16
- */
17
- function resolveFramePath(frame) {
18
- if (frame._cachedPath !== undefined)
19
- return frame._cachedPath;
20
- const chain = [];
21
- let cur = frame;
22
- while (cur !== null && cur._cachedPath === undefined) {
23
- chain.push(cur);
24
- cur = cur._parent === undefined ? null : cur._parent;
25
- }
26
- let basePath = cur !== null ? cur._cachedPath : "";
27
- // chain[0] is always `frame` itself (pushed in the first loop iteration),
28
- // and this loop runs in reverse, so the last iteration (i === 0) sets
29
- // basePath to frame's own resolved path — returning it directly avoids
30
- // re-reading frame._cachedPath, which TS can't prove was set here since
31
- // the mutation happens through the aliased `f` reference.
32
- for (let i = chain.length - 1; i >= 0; i--) {
33
- const f = chain[i];
34
- const seg = f._segment;
35
- basePath =
36
- seg === null || seg === undefined ? basePath : appendPointer(basePath, seg);
37
- f._cachedPath = basePath;
38
- }
39
- return basePath;
40
- }
41
- function attachLazyPath(frame, parent, segment) {
42
- frame._parent = parent;
43
- frame._segment = segment;
44
- Object.defineProperty(frame, "path", {
45
- enumerable: true,
46
- configurable: true,
47
- get() {
48
- return resolveFramePath(frame);
49
- },
50
- });
51
- }
52
- /**
53
- * Create a new object frame.
54
- * `parent` is the frame this one is nested inside (or null at the root);
55
- * `segment` is the key/index leading from parent to this frame (or null at
56
- * the root) — the same value `GrammarStack.currentValuePath()` would have
57
- * used, captured eagerly since it reflects the parent's mutable state at
58
- * this exact moment. Only the (expensive, O(depth)) string flattening is
59
- * deferred.
60
- */
61
- export function createObjectFrame(parent, segment, byteStart) {
62
- const frame = {
63
- containerType: "object",
64
- path: "",
65
- objectExpectation: "first_key_or_end",
66
- seenKeys: new Set(),
67
- nextArrayIndex: 0,
68
- byteStart,
69
- };
70
- attachLazyPath(frame, parent, segment);
71
- return frame;
72
- }
73
- /**
74
- * Create a new array frame. See createObjectFrame for `parent`/`segment`.
75
- */
76
- export function createArrayFrame(parent, segment, byteStart) {
77
- const frame = {
78
- containerType: "array",
79
- path: "",
80
- arrayExpectation: "first_value_or_end",
81
- nextArrayIndex: 0,
82
- byteStart,
83
- };
84
- attachLazyPath(frame, parent, segment);
85
- return frame;
86
- }
87
- //# sourceMappingURL=frame.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"frame.js","sourceRoot":"","sources":["../../src/grammar/frame.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,yDAAyD;AACzD,8EAA8E;AAE9E,OAAO,EAAE,aAAa,EAAE,MAAM,cAAc,CAAC;AAkE7C;;;;;;;;;;;GAWG;AACH,SAAS,gBAAgB,CAAC,KAAmB;IAC3C,IAAI,KAAK,CAAC,WAAW,KAAK,SAAS;QAAE,OAAO,KAAK,CAAC,WAAW,CAAC;IAE9D,MAAM,KAAK,GAAmB,EAAE,CAAC;IACjC,IAAI,GAAG,GAAwB,KAAK,CAAC;IACrC,OAAO,GAAG,KAAK,IAAI,IAAI,GAAG,CAAC,WAAW,KAAK,SAAS,EAAE,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;QAChB,GAAG,GAAG,GAAG,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC;IACvD,CAAC;IAED,IAAI,QAAQ,GAAG,GAAG,KAAK,IAAI,CAAC,CAAC,CAAE,GAAG,CAAC,WAAsB,CAAC,CAAC,CAAC,EAAE,CAAC;IAE/D,0EAA0E;IAC1E,sEAAsE;IACtE,uEAAuE;IACvE,wEAAwE;IACxE,0DAA0D;IAC1D,KAAK,IAAI,CAAC,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QAC3C,MAAM,CAAC,GAAG,KAAK,CAAC,CAAC,CAAiB,CAAC;QACnC,MAAM,GAAG,GAAG,CAAC,CAAC,QAAQ,CAAC;QACvB,QAAQ;YACN,GAAG,KAAK,IAAI,IAAI,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,aAAa,CAAC,QAAQ,EAAE,GAAG,CAAC,CAAC;QAC9E,CAAC,CAAC,WAAW,GAAG,QAAQ,CAAC;IAC3B,CAAC;IAED,OAAO,QAAQ,CAAC;AAClB,CAAC;AAED,SAAS,cAAc,CACrB,KAAmB,EACnB,MAA2B,EAC3B,OAA+B;IAE/B,KAAK,CAAC,OAAO,GAAG,MAAM,CAAC;IACvB,KAAK,CAAC,QAAQ,GAAG,OAAO,CAAC;IACzB,MAAM,CAAC,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE;QACnC,UAAU,EAAE,IAAI;QAChB,YAAY,EAAE,IAAI;QAClB,GAAG;YACD,OAAO,gBAAgB,CAAC,KAAK,CAAC,CAAC;QACjC,CAAC;KACF,CAAC,CAAC;AACL,CAAC;AAED;;;;;;;;GAQG;AACH,MAAM,UAAU,iBAAiB,CAC/B,MAA2B,EAC3B,OAA+B,EAC/B,SAAiB;IAEjB,MAAM,KAAK,GAAiB;QAC1B,aAAa,EAAE,QAAQ;QACvB,IAAI,EAAE,EAAE;QACR,iBAAiB,EAAE,kBAAkB;QACrC,QAAQ,EAAE,IAAI,GAAG,EAAE;QACnB,cAAc,EAAE,CAAC;QACjB,SAAS;KACV,CAAC;IACF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC;AACf,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,gBAAgB,CAC9B,MAA2B,EAC3B,OAA+B,EAC/B,SAAiB;IAEjB,MAAM,KAAK,GAAiB;QAC1B,aAAa,EAAE,OAAO;QACtB,IAAI,EAAE,EAAE;QACR,gBAAgB,EAAE,oBAAoB;QACtC,cAAc,EAAE,CAAC;QACjB,SAAS;KACV,CAAC;IACF,cAAc,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,CAAC,CAAC;IACvC,OAAO,KAAK,CAAC;AACf,CAAC"}
@@ -1,10 +0,0 @@
1
- /**
2
- * Escape a JSON Pointer reference token per RFC 6901.
3
- * ~ → ~0, / → ~1
4
- */
5
- export declare function escapePointerToken(token: string): string;
6
- /**
7
- * Build a JSON Pointer path from parent path and a key or index.
8
- */
9
- export declare function appendPointer(parent: string, token: string | number): string;
10
- //# sourceMappingURL=pointer.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pointer.d.ts","sourceRoot":"","sources":["../../src/grammar/pointer.ts"],"names":[],"mappings":"AAIA;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAExD;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,MAAM,CAK5E"}
@@ -1,20 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // JSON Pointer utilities (RFC 6901)
3
- // ---------------------------------------------------------------------------
4
- /**
5
- * Escape a JSON Pointer reference token per RFC 6901.
6
- * ~ → ~0, / → ~1
7
- */
8
- export function escapePointerToken(token) {
9
- return token.replace(/~/g, "~0").replace(/\//g, "~1");
10
- }
11
- /**
12
- * Build a JSON Pointer path from parent path and a key or index.
13
- */
14
- export function appendPointer(parent, token) {
15
- if (typeof token === "number") {
16
- return `${parent}/${token}`;
17
- }
18
- return `${parent}/${escapePointerToken(token)}`;
19
- }
20
- //# sourceMappingURL=pointer.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"pointer.js","sourceRoot":"","sources":["../../src/grammar/pointer.ts"],"names":[],"mappings":"AAAA,8EAA8E;AAC9E,oCAAoC;AACpC,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,OAAO,KAAK,CAAC,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACxD,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,aAAa,CAAC,MAAc,EAAE,KAAsB;IAClE,IAAI,OAAO,KAAK,KAAK,QAAQ,EAAE,CAAC;QAC9B,OAAO,GAAG,MAAM,IAAI,KAAK,EAAE,CAAC;IAC9B,CAAC;IACD,OAAO,GAAG,MAAM,IAAI,kBAAkB,CAAC,KAAK,CAAC,EAAE,CAAC;AAClD,CAAC"}
@@ -1,73 +0,0 @@
1
- import type { GrammarFrame } from "./frame.js";
2
- import type { Diagnostic } from "../types.js";
3
- /**
4
- * Manages the stack of open JSON containers.
5
- * Handles object/array nesting, expectations, and duplicate key detection.
6
- */
7
- export declare class GrammarStack {
8
- private stack;
9
- private diagnostics;
10
- private hasDuplicateKey;
11
- private maxDepth;
12
- constructor(maxDepth: number);
13
- /** Current depth (number of open containers). */
14
- get depth(): number;
15
- /** Whether any duplicate key has been seen. */
16
- get hasDuplicate(): boolean;
17
- /** Get the current (top) frame, or undefined if empty. */
18
- get current(): GrammarFrame | undefined;
19
- /**
20
- * Push a new object container.
21
- * Returns the frame, or null if depth limit exceeded.
22
- */
23
- pushObject(byteStart: number): GrammarFrame | null;
24
- /**
25
- * Push a new array container.
26
- * Returns the frame, or null if depth limit exceeded.
27
- */
28
- pushArray(byteStart: number): GrammarFrame | null;
29
- /**
30
- * Pop the current container.
31
- * Returns the popped frame.
32
- */
33
- pop(): GrammarFrame | undefined;
34
- /**
35
- * Register an object key. Returns true if the key is new.
36
- * If duplicate, emits diagnostic and returns false.
37
- */
38
- registerObjectKey(key: string, byteOffset: number): boolean;
39
- /**
40
- * Get the JSON Pointer path for where the next value will go.
41
- */
42
- currentValuePath(): string;
43
- /**
44
- * The key/index that would lead from the current frame to its next child,
45
- * without flattening it into a full path string. Same underlying value
46
- * currentValuePath() uses; kept as a raw segment so a newly-pushed child
47
- * frame can capture it in O(1) and defer the expensive path-string join
48
- * (see grammar/frame.ts) until something actually reads `.path`.
49
- */
50
- private currentSegment;
51
- /**
52
- * Advance the array index after an element value is committed.
53
- */
54
- advanceArrayIndex(): void;
55
- /**
56
- * Take accumulated diagnostics and clear.
57
- */
58
- takeDiagnostics(): Diagnostic[];
59
- /**
60
- * Check if the stack is empty (no open containers).
61
- */
62
- isEmpty(): boolean;
63
- /**
64
- * Get all frames (for snapshot/pending info).
65
- */
66
- getFrames(): readonly GrammarFrame[];
67
- /**
68
- * Determine if all open containers can be safely closed by just appending '}' or ']'.
69
- * This is true if no container is waiting for a colon or a value.
70
- */
71
- canSafelyCloseAll(): boolean;
72
- }
73
- //# sourceMappingURL=stack.d.ts.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stack.d.ts","sourceRoot":"","sources":["../../src/grammar/stack.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,YAAY,CAAC;AAG/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AAI9C;;;GAGG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,KAAK,CAAsB;IACnC,OAAO,CAAC,WAAW,CAAoB;IACvC,OAAO,CAAC,eAAe,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAS;gBAEb,QAAQ,EAAE,MAAM;IAI5B,iDAAiD;IACjD,IAAI,KAAK,IAAI,MAAM,CAElB;IAED,+CAA+C;IAC/C,IAAI,YAAY,IAAI,OAAO,CAE1B;IAED,0DAA0D;IAC1D,IAAI,OAAO,IAAI,YAAY,GAAG,SAAS,CAEtC;IAED;;;OAGG;IACH,UAAU,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAmBlD;;;OAGG;IACH,SAAS,CAAC,SAAS,EAAE,MAAM,GAAG,YAAY,GAAG,IAAI;IAmBjD;;;OAGG;IACH,GAAG,IAAI,YAAY,GAAG,SAAS;IAI/B;;;OAGG;IACH,iBAAiB,CAAC,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO;IA0B3D;;OAEG;IACH,gBAAgB,IAAI,MAAM;IAc1B;;;;;;OAMG;IACH,OAAO,CAAC,cAAc;IAUtB;;OAEG;IACH,iBAAiB,IAAI,IAAI;IAOzB;;OAEG;IACH,eAAe,IAAI,UAAU,EAAE;IAM/B;;OAEG;IACH,OAAO,IAAI,OAAO;IAIlB;;OAEG;IACH,SAAS,IAAI,SAAS,YAAY,EAAE;IAIpC;;;OAGG;IACH,iBAAiB,IAAI,OAAO;CAkB7B"}
@@ -1,168 +0,0 @@
1
- // ---------------------------------------------------------------------------
2
- // Grammar Stack — tracks nested JSON container state
3
- // ---------------------------------------------------------------------------
4
- import { createObjectFrame, createArrayFrame } from "./frame.js";
5
- import { appendPointer } from "./pointer.js";
6
- import { DiagnosticCode } from "../diagnostics/codes.js";
7
- import { createDiagnostic } from "../diagnostics/factory.js";
8
- /**
9
- * Manages the stack of open JSON containers.
10
- * Handles object/array nesting, expectations, and duplicate key detection.
11
- */
12
- export class GrammarStack {
13
- stack = [];
14
- diagnostics = [];
15
- hasDuplicateKey = false;
16
- maxDepth;
17
- constructor(maxDepth) {
18
- this.maxDepth = maxDepth;
19
- }
20
- /** Current depth (number of open containers). */
21
- get depth() {
22
- return this.stack.length;
23
- }
24
- /** Whether any duplicate key has been seen. */
25
- get hasDuplicate() {
26
- return this.hasDuplicateKey;
27
- }
28
- /** Get the current (top) frame, or undefined if empty. */
29
- get current() {
30
- return this.stack[this.stack.length - 1];
31
- }
32
- /**
33
- * Push a new object container.
34
- * Returns the frame, or null if depth limit exceeded.
35
- */
36
- pushObject(byteStart) {
37
- if (this.stack.length >= this.maxDepth) {
38
- this.diagnostics.push(createDiagnostic(DiagnosticCode.E_LIMIT_DEPTH, "fatal", byteStart, `Maximum nesting depth ${this.maxDepth} exceeded`, false));
39
- return null;
40
- }
41
- const parent = this.current ?? null;
42
- const frame = createObjectFrame(parent, this.currentSegment(), byteStart);
43
- this.stack.push(frame);
44
- return frame;
45
- }
46
- /**
47
- * Push a new array container.
48
- * Returns the frame, or null if depth limit exceeded.
49
- */
50
- pushArray(byteStart) {
51
- if (this.stack.length >= this.maxDepth) {
52
- this.diagnostics.push(createDiagnostic(DiagnosticCode.E_LIMIT_DEPTH, "fatal", byteStart, `Maximum nesting depth ${this.maxDepth} exceeded`, false));
53
- return null;
54
- }
55
- const parent = this.current ?? null;
56
- const frame = createArrayFrame(parent, this.currentSegment(), byteStart);
57
- this.stack.push(frame);
58
- return frame;
59
- }
60
- /**
61
- * Pop the current container.
62
- * Returns the popped frame.
63
- */
64
- pop() {
65
- return this.stack.pop();
66
- }
67
- /**
68
- * Register an object key. Returns true if the key is new.
69
- * If duplicate, emits diagnostic and returns false.
70
- */
71
- registerObjectKey(key, byteOffset) {
72
- const frame = this.current;
73
- if (!frame || frame.containerType !== "object" || !frame.seenKeys) {
74
- return false;
75
- }
76
- if (frame.seenKeys.has(key)) {
77
- this.hasDuplicateKey = true;
78
- this.diagnostics.push(createDiagnostic(DiagnosticCode.E_DUPLICATE_KEY, "error", byteOffset, `Duplicate object key: ${JSON.stringify(key)}`, false, frame.path));
79
- return false;
80
- }
81
- frame.seenKeys.add(key);
82
- frame.currentKey = key;
83
- return true;
84
- }
85
- /**
86
- * Get the JSON Pointer path for where the next value will go.
87
- */
88
- currentValuePath() {
89
- const frame = this.current;
90
- if (!frame)
91
- return "";
92
- if (frame.containerType === "object") {
93
- if (frame.currentKey !== undefined) {
94
- return appendPointer(frame.path, frame.currentKey);
95
- }
96
- return frame.path;
97
- }
98
- // array
99
- return appendPointer(frame.path, frame.nextArrayIndex);
100
- }
101
- /**
102
- * The key/index that would lead from the current frame to its next child,
103
- * without flattening it into a full path string. Same underlying value
104
- * currentValuePath() uses; kept as a raw segment so a newly-pushed child
105
- * frame can capture it in O(1) and defer the expensive path-string join
106
- * (see grammar/frame.ts) until something actually reads `.path`.
107
- */
108
- currentSegment() {
109
- const frame = this.current;
110
- if (!frame)
111
- return null;
112
- if (frame.containerType === "object") {
113
- return frame.currentKey !== undefined ? frame.currentKey : null;
114
- }
115
- return frame.nextArrayIndex;
116
- }
117
- /**
118
- * Advance the array index after an element value is committed.
119
- */
120
- advanceArrayIndex() {
121
- const frame = this.current;
122
- if (frame && frame.containerType === "array") {
123
- frame.nextArrayIndex++;
124
- }
125
- }
126
- /**
127
- * Take accumulated diagnostics and clear.
128
- */
129
- takeDiagnostics() {
130
- const result = this.diagnostics;
131
- this.diagnostics = [];
132
- return result;
133
- }
134
- /**
135
- * Check if the stack is empty (no open containers).
136
- */
137
- isEmpty() {
138
- return this.stack.length === 0;
139
- }
140
- /**
141
- * Get all frames (for snapshot/pending info).
142
- */
143
- getFrames() {
144
- return this.stack;
145
- }
146
- /**
147
- * Determine if all open containers can be safely closed by just appending '}' or ']'.
148
- * This is true if no container is waiting for a colon or a value.
149
- */
150
- canSafelyCloseAll() {
151
- for (const frame of this.stack) {
152
- if (frame.containerType === "object") {
153
- if (frame.objectExpectation === "colon" ||
154
- frame.objectExpectation === "value" ||
155
- frame.objectExpectation === "key_after_comma") {
156
- return false; // Missing colon or value or key
157
- }
158
- }
159
- else {
160
- if (frame.arrayExpectation === "value_after_comma") {
161
- return false; // Missing value after comma
162
- }
163
- }
164
- }
165
- return true;
166
- }
167
- }
168
- //# sourceMappingURL=stack.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"stack.js","sourceRoot":"","sources":["../../src/grammar/stack.ts"],"names":[],"mappings":"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"}