@tabnas/transduce 0.2.9 → 0.2.11

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.
@@ -1,6 +1,10 @@
1
1
  export declare const INCREMENTAL: readonly string[];
2
2
  export declare function isIncremental(grammar: string): boolean;
3
+ export declare const PRUNABLE: readonly string[];
4
+ export declare function isPrunable(grammar: string): boolean;
3
5
  export declare const capability: Readonly<{
4
6
  INCREMENTAL: readonly string[];
5
7
  incremental: typeof isIncremental;
8
+ PRUNABLE: readonly string[];
9
+ prunable: typeof isPrunable;
6
10
  }>;
@@ -1,8 +1,9 @@
1
1
  "use strict";
2
2
  /* Copyright (c) 2026 tabnas, MIT License */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
- exports.capability = exports.INCREMENTAL = void 0;
4
+ exports.capability = exports.PRUNABLE = exports.INCREMENTAL = void 0;
5
5
  exports.isIncremental = isIncremental;
6
+ exports.isPrunable = isPrunable;
6
7
  // Which grammars the incremental source is verified for, in THIS runtime.
7
8
  //
8
9
  // Incremental streaming is a per-grammar VERIFIED capability, never an
@@ -57,8 +58,35 @@ exports.INCREMENTAL = Object.freeze([
57
58
  function isIncremental(grammar) {
58
59
  return exports.INCREMENTAL.includes(grammar);
59
60
  }
61
+ // The grammars whose passes a `ParserEventSource` relays alike whether it
62
+ // prunes or not, on every document `test/prune.test.ts` reads them, by the
63
+ // name of the format each reads, as `INCREMENTAL` names them. The suite
64
+ // asserts the list in both directions; `toml` is not on it, since its
65
+ // message for a key defined twice quotes the value, which pruning empties.
66
+ exports.PRUNABLE = Object.freeze([
67
+ 'csv',
68
+ 'feed',
69
+ 'ini',
70
+ 'json',
71
+ 'json5',
72
+ 'jsonc',
73
+ 'jsonic',
74
+ 'jsonl',
75
+ 'markdown',
76
+ 'pgn',
77
+ 'xml',
78
+ 'yaml',
79
+ 'zon',
80
+ ]);
81
+ // Whether a `ParserEventSource` may empty `grammar`'s arrays behind its
82
+ // stream (`ParserEventSource.prune`).
83
+ function isPrunable(grammar) {
84
+ return exports.PRUNABLE.includes(grammar);
85
+ }
60
86
  exports.capability = Object.freeze({
61
87
  INCREMENTAL: exports.INCREMENTAL,
62
88
  incremental: isIncremental,
89
+ PRUNABLE: exports.PRUNABLE,
90
+ prunable: isPrunable,
63
91
  });
64
92
  //# sourceMappingURL=capability.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;;AAE5C,0EAA0E;AAC1E,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,4EAA4E;AAC5E,6DAA6D;AAC7D,wEAAwE;AACxE,qEAAqE;AACrE,0EAA0E;AAC1E,uEAAuE;AACvE,sEAAsE;AACtE,2EAA2E;AAC3E,wEAAwE;AACxE,yEAAyE;AACzE,mCAAmC;AACnC,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E;AAC1E,UAAU;AAEV,yEAAyE;AACzE,yEAAyE;AACzE,0EAA0E;AAC1E,uEAAuE;AACvE,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AAExE,yEAAyE;AACzE,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,qEAAqE;AACrE,yEAAyE;AACzE,sEAAsE;AACtE,0EAA0E;AAC1E,6EAA6E;AAChE,QAAA,WAAW,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC1D,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;IACV,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;CACN,CAAC,CAAA;AAEF,oDAAoD;AACpD,uBAA8B,OAAe;IAC3C,OAAO,QAAA,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AACtC,CAAC;AAEY,QAAA,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,WAAW,EAAX,QAAA,WAAW;IACX,WAAW,EAAE,aAAa;CAC3B,CAAC,CAAA"}
1
+ {"version":3,"file":"capability.js","sourceRoot":"","sources":["../src/capability.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;;;AAE5C,0EAA0E;AAC1E,EAAE;AACF,uEAAuE;AACvE,0EAA0E;AAC1E,4EAA4E;AAC5E,6DAA6D;AAC7D,wEAAwE;AACxE,qEAAqE;AACrE,0EAA0E;AAC1E,uEAAuE;AACvE,sEAAsE;AACtE,2EAA2E;AAC3E,wEAAwE;AACxE,yEAAyE;AACzE,mCAAmC;AACnC,EAAE;AACF,6EAA6E;AAC7E,2EAA2E;AAC3E,0EAA0E;AAC1E,sEAAsE;AACtE,0EAA0E;AAC1E,UAAU;AAEV,yEAAyE;AACzE,yEAAyE;AACzE,0EAA0E;AAC1E,uEAAuE;AACvE,2EAA2E;AAC3E,4EAA4E;AAC5E,wEAAwE;AAExE,yEAAyE;AACzE,2EAA2E;AAC3E,0EAA0E;AAC1E,uEAAuE;AACvE,qEAAqE;AACrE,yEAAyE;AACzE,sEAAsE;AACtE,0EAA0E;AAC1E,6EAA6E;AAChE,QAAA,WAAW,GAAsB,MAAM,CAAC,MAAM,CAAC;IAC1D,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;IACV,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;CACN,CAAC,CAAA;AAEF,oDAAoD;AACpD,uBAA8B,OAAe;IAC3C,OAAO,QAAA,WAAW,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AACtC,CAAC;AAED,0EAA0E;AAC1E,2EAA2E;AAC3E,wEAAwE;AACxE,sEAAsE;AACtE,2EAA2E;AAC9D,QAAA,QAAQ,GAAsB,MAAM,CAAC,MAAM,CAAC;IACvD,KAAK;IACL,MAAM;IACN,KAAK;IACL,MAAM;IACN,OAAO;IACP,OAAO;IACP,QAAQ;IACR,OAAO;IACP,UAAU;IACV,KAAK;IACL,KAAK;IACL,MAAM;IACN,KAAK;CACN,CAAC,CAAA;AAEF,wEAAwE;AACxE,sCAAsC;AACtC,oBAA2B,OAAe;IACxC,OAAO,QAAA,QAAQ,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAA;AACnC,CAAC;AAEY,QAAA,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,WAAW,EAAX,QAAA,WAAW;IACX,WAAW,EAAE,aAAa;IAC1B,QAAQ,EAAR,QAAA,QAAQ;IACR,QAAQ,EAAE,UAAU;CACrB,CAAC,CAAA"}
@@ -7,11 +7,22 @@ export declare class ParserEventSource {
7
7
  private sourceLimits;
8
8
  private abortFlag;
9
9
  private sourceMetrics;
10
+ private grammarName;
11
+ private pruning;
12
+ private isUnverified;
10
13
  private used;
11
14
  constructor(parser: Tabnas, text: string);
15
+ grammar(name: string): this;
16
+ prune(): this;
17
+ unverified(): this;
18
+ private gate;
12
19
  limits(limits: Limits): this;
13
20
  abort(abort: AbortFlag): this;
14
21
  metrics(metrics: Metrics): this;
15
22
  run(sink: ParserSink): Flow;
23
+ runWithValue(sink: ParserSink): {
24
+ flow: Flow;
25
+ value: unknown;
26
+ };
16
27
  }
17
28
  export declare function scalarOf(value: unknown, lexeme: string | undefined): Datum;
@@ -16,22 +16,21 @@ exports.scalarOf = scalarOf;
16
16
  // What each pass carries is alchemy's `RulePass`:
17
17
  //
18
18
  // - the rule's `name`, its depth `d` and instance `i` (the engine's, which
19
- // counts from 1 here and from 0 in Go and Rust: DIVERGENCE.md 6), the
20
- // alternate that matched (`alt`: `p`, `r`, `b`, and its groups `g`,
21
- // sorted, since they are tags whose order the runtimes' engines keep
22
- // differently), whether recovery forced the close, and its named counters
23
- // `n`, sorted by name;
19
+ // numbers rules from 1, the start rule's, in the order it makes them),
20
+ // the alternate that matched
21
+ // (`alt`: `p`, `r`, `b`, and its groups `g`, sorted, since they are tags
22
+ // whose order the runtimes' engines keep differently), whether recovery
23
+ // forced the close, and its named counters `n`, sorted by name;
24
24
  // - the `tokens` the pass consumed: those its alternate matched (the
25
25
  // engine's `o[:oN]` or `c[:cN]`), less the `b` it gave back from their
26
26
  // end, which are the next rule's to consume, and none when `b` is more
27
27
  // than it recorded, since a close alternate can back up a token it did
28
28
  // not record. A token is its name, its value, its source text and its
29
29
  // 1-based row and column; a token with no value (the end of the source,
30
- // a fixed token such as `[`, which Rust's engine gives its text:
31
- // DIVERGENCE.md 7) has `null`, and a number carries its source text as its lexeme when
32
- // that text is a JSON number spelling the value (RFC 8259), the rule the
33
- // incremental source keeps lexemes by, so a renderer can write it as it
34
- // stands;
30
+ // or a fixed token such as `[`) has `null`, and a number carries
31
+ // its source text as its lexeme when that text is a JSON number spelling
32
+ // the value (RFC 8259), the rule the incremental source keeps lexemes by,
33
+ // so a renderer can write it as it stands;
35
34
  // - on a close pass, the rule's node when that is a scalar (`value`), a
36
35
  // number with the lexeme of the rule's first open token as above;
37
36
  // nothing on an open pass, nor for a container.
@@ -55,21 +54,81 @@ exports.scalarOf = scalarOf;
55
54
  // `AbortFlag` is `ABORTED`; any other engine error is `INPUT_INVALID` with
56
55
  // the engine's code and position. A source runs once, as `ParserSource`
57
56
  // does: its parser carries the run's subscriber and budget.
57
+ //
58
+ // The engine builds its value as it parses, so a long document's tree
59
+ // holds every record, though nothing reads the value the parse returns.
60
+ // `prune()` empties each array behind the stream: once the sink has seen a
61
+ // close pass whose rule's node is an array, the source empties that array
62
+ // in place, so the tree holds the elements of the passes since the last
63
+ // close on it. That alters the value the engine returns, which this source
64
+ // never reads, and it is sound for a grammar whose passes do not depend on
65
+ // what its arrays hold, so it is a verified capability, as the incremental
66
+ // source is: `test/prune.test.ts` runs every document of every grammar in
67
+ // the devDependencies pruned and not, and `capability.prunable` lists the
68
+ // grammars whose passes and outcomes never differed
69
+ // (rs/src/source/parser_events.rs has the contract's one difference, a
70
+ // token whose value is a container of the tree). A run that prunes is
71
+ // gated on the list, by the grammar's name (`grammar`), and without a
72
+ // listed name it fails with `STREAMABILITY_UNKNOWN` before the parse,
73
+ // having sent nothing; `unverified()` lifts the gate for the suite.
58
74
  const shared_1 = require("@tabnas/alchemy/shared");
75
+ const capability_1 = require("./capability");
59
76
  const rule_events_1 = require("./rule-events");
60
77
  const source_1 = require("./source");
61
78
  // A tabnas parser applied to one text, as a source of its rule passes.
62
79
  class ParserEventSource {
63
- // A source with default limits, its own abort flag and fresh metrics; the
64
- // builder methods change each.
80
+ // A source with default limits, its own abort flag and fresh metrics,
81
+ // that prunes nothing; the builder methods change each.
65
82
  constructor(parser, text) {
66
83
  this.sourceLimits = shared_1.Limits.default();
67
84
  this.abortFlag = new shared_1.AbortFlag();
68
85
  this.sourceMetrics = new shared_1.Metrics();
86
+ this.grammarName = null;
87
+ this.pruning = false;
88
+ this.isUnverified = false;
69
89
  this.used = false;
70
90
  this.parser = parser;
71
91
  this.text = text;
72
92
  }
93
+ // The grammar the parser implements, by the name of the format it reads,
94
+ // as `ParserSource.grammar` takes it. A run that prunes needs a name
95
+ // `capability.prunable` lists; one that does not prune needs no name.
96
+ grammar(name) {
97
+ this.grammarName = name;
98
+ return this;
99
+ }
100
+ // Empty each array in the engine's tree once the sink has seen a close
101
+ // pass on it, so the tree does not hold the whole document. The passes
102
+ // are unchanged for a grammar `capability.prunable` lists, and `run`
103
+ // refuses to prune any other, with `STREAMABILITY_UNKNOWN` before the
104
+ // parse.
105
+ prune() {
106
+ this.pruning = true;
107
+ return this;
108
+ }
109
+ // Prune whatever the verified list says. This exists for the
110
+ // differential suite that maintains the list and for nothing else: a
111
+ // grammar that reads its arrays back may make other passes once they are
112
+ // emptied, and the run still returns.
113
+ unverified() {
114
+ this.isUnverified = true;
115
+ return this;
116
+ }
117
+ // Why the run may not prune, when it may not.
118
+ gate() {
119
+ if (!this.pruning || this.isUnverified)
120
+ return null;
121
+ const name = this.grammarName;
122
+ if (null !== name && (0, capability_1.isPrunable)(name))
123
+ return null;
124
+ if (null !== name) {
125
+ return new shared_1.Fail('STREAMABILITY_UNKNOWN', `grammar ${JSON.stringify(name)} is not in capability.prunable: the differential suite ` +
126
+ 'has not verified that its passes are the same when its arrays are emptied behind ' +
127
+ 'the stream; run it without ParserEventSource.prune');
128
+ }
129
+ return new shared_1.Fail('STREAMABILITY_UNKNOWN', "ParserEventSource.prune needs the grammar's name (ParserEventSource.grammar) to check " +
130
+ 'capability.prunable; without one, run it without pruning');
131
+ }
73
132
  limits(limits) {
74
133
  this.sourceLimits = limits;
75
134
  return this;
@@ -84,19 +143,28 @@ class ParserEventSource {
84
143
  }
85
144
  // Parse, relaying each pass into `sink`, then `end`.
86
145
  run(sink) {
146
+ return this.runWithValue(sink).flow;
147
+ }
148
+ // `run`, also handing back the value the engine returned: the engine's
149
+ // tree after pruning, when the run prunes. It is not the run's result
150
+ // (the passes are): it exists so a test can measure what pruning left in
151
+ // the tree, and nothing else should read it.
152
+ runWithValue(sink) {
87
153
  if (this.used) {
88
154
  throw new shared_1.Fail('STREAM_REUSED', "a ParserEventSource runs once: its parser carries the run's subscriber and budget; " +
89
155
  'make a new source, with a new parser, for another run');
90
156
  }
91
157
  this.used = true;
158
+ const refused = this.gate();
159
+ if (null !== refused)
160
+ throw refused;
92
161
  const abort = this.abortFlag;
93
162
  const stop = new shared_1.AbortFlag();
94
- const relay = new Relay(sink, this.sourceLimits.max_scalar_bytes, abort, stop);
163
+ const relay = new Relay(sink, this.sourceLimits.max_scalar_bytes, abort, stop, this.pruning);
95
164
  (0, rule_events_1.prepare)(this.parser, () => !abort.isAborted() && !stop.isAborted(), (rule, done) => relay.onDone(rule, done));
96
165
  let parsed;
97
166
  try {
98
- this.parser.parse(this.text);
99
- parsed = { ok: true };
167
+ parsed = { ok: true, value: this.parser.parse(this.text) };
100
168
  }
101
169
  catch (error) {
102
170
  parsed = { ok: false, error };
@@ -106,10 +174,10 @@ class ParserEventSource {
106
174
  if ('failed' === status.type)
107
175
  throw status.error;
108
176
  if ('stopped' === status.type)
109
- return 'stop';
177
+ return { flow: 'stop', value: undefined };
110
178
  if (!parsed.ok)
111
179
  throw (0, source_1.engineFailure)(parsed.error, abort);
112
- return relay.send({ type: 'end' });
180
+ return { flow: relay.send({ type: 'end' }), value: parsed.value };
113
181
  }
114
182
  finally {
115
183
  this.sourceMetrics.events += relay.events;
@@ -121,11 +189,14 @@ exports.ParserEventSource = ParserEventSource;
121
189
  class Relay {
122
190
  constructor(sink, maxScalarBytes, abort,
123
191
  // Set to make the parse guard cancel the parse.
124
- stop) {
192
+ stop,
193
+ // Empty the array a close pass's rule builds, once the sink has seen it.
194
+ prune) {
125
195
  this.sink = sink;
126
196
  this.maxScalarBytes = maxScalarBytes;
127
197
  this.abort = abort;
128
198
  this.stop = stop;
199
+ this.prune = prune;
129
200
  this.status = { type: 'running' };
130
201
  this.events = 0;
131
202
  }
@@ -160,12 +231,24 @@ class Relay {
160
231
  this.status = { type: 'stopped' };
161
232
  this.stop.abort();
162
233
  }
234
+ else if (this.prune && !open) {
235
+ emptyArray(rule);
236
+ }
163
237
  }
164
238
  catch (error) {
165
239
  this.fail(error);
166
240
  }
167
241
  }
168
242
  }
243
+ // Empty the array `rule`'s node is, in place, so every holder of it sees
244
+ // it emptied. Every element in it was built by passes the sink has seen,
245
+ // the last of them the close pass just sent, and what those passes carry
246
+ // is the sink's, so nothing sent so far changes.
247
+ function emptyArray(rule) {
248
+ const node = rule.node;
249
+ if (Array.isArray(node) && 0 < node.length)
250
+ node.length = 0;
251
+ }
169
252
  // The pass as alchemy's `RulePass`, its sizes held to `max_scalar_bytes`.
170
253
  function rulePass(rule, done, open, max) {
171
254
  const r = rule;
@@ -1 +1 @@
1
- {"version":3,"file":"parser-event-source.js","sourceRoot":"","sources":["../src/parser-event-source.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"parser-event-source.js","sourceRoot":"","sources":["../src/parser-event-source.ts"],"names":[],"mappings":"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"}
package/dist/routers.js CHANGED
@@ -24,5 +24,10 @@ exports.routers = Object.freeze({
24
24
  transduceTree(spec, downstream) {
25
25
  return new transduce_tree_1.TransduceTree(spec, downstream);
26
26
  },
27
+ // TransduceTree reads a spec's `:member` and `:text`, and holds a text to
28
+ // the spec's `maxTextBytes` as it grows.
29
+ transduceTreeReadsMemberAndText() {
30
+ return true;
31
+ },
27
32
  });
28
33
  //# sourceMappingURL=routers.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"routers.js","sourceRoot":"","sources":["../src/routers.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;AA2B5C,mCAAiC;AACjC,mCAAgC;AAChC,iCAAiC;AACjC,uDAAiD;AACjD,qDAAgD;AAEhD,sEAAsE;AACzD,QAAA,OAAO,GAAY,MAAM,CAAC,MAAM,CAAC;IAC5C,MAAM,CACJ,KAA6B,EAC7B,MAAc,EACd,UAAsB,EACtB,OAAgB,EAChB,UAAqB;QAErB,OAAO,IAAI,cAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;IACnE,CAAC;IAED,aAAa,CACX,OAAqB,EACrB,MAAc,EACd,UAAsB,EACtB,OAAgB,EAChB,IAAe;QAEf,OAAO,IAAI,+BAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IACtE,CAAC;IAED,QAAQ,CACN,OAAU,EACV,IAA6C,EAC7C,MAAyB,EACzB,GAAwB;QAExB,OAAO,IAAI,eAAQ,CAAU,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1D,CAAC;IAED,OAAO,CAAC,KAAW,EAAE,MAAc,EAAE,KAAgB,EAAE,OAAgB;QACrE,OAAO,IAAI,eAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;IACnD,CAAC;IAED,aAAa,CAAC,IAAc,EAAE,UAAgB;QAC5C,OAAO,IAAI,8BAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAC5C,CAAC;CACF,CAAC,CAAA"}
1
+ {"version":3,"file":"routers.js","sourceRoot":"","sources":["../src/routers.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;AA2B5C,mCAAiC;AACjC,mCAAgC;AAChC,iCAAiC;AACjC,uDAAiD;AACjD,qDAAgD;AAEhD,sEAAsE;AACzD,QAAA,OAAO,GAAY,MAAM,CAAC,MAAM,CAAC;IAC5C,MAAM,CACJ,KAA6B,EAC7B,MAAc,EACd,UAAsB,EACtB,OAAgB,EAChB,UAAqB;QAErB,OAAO,IAAI,cAAM,CAAC,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,UAAU,CAAC,CAAA;IACnE,CAAC;IAED,aAAa,CACX,OAAqB,EACrB,MAAc,EACd,UAAsB,EACtB,OAAgB,EAChB,IAAe;QAEf,OAAO,IAAI,+BAAa,CAAC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,OAAO,EAAE,IAAI,CAAC,CAAA;IACtE,CAAC;IAED,QAAQ,CACN,OAAU,EACV,IAA6C,EAC7C,MAAyB,EACzB,GAAwB;QAExB,OAAO,IAAI,eAAQ,CAAU,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,CAAC,CAAA;IAC1D,CAAC;IAED,OAAO,CAAC,KAAW,EAAE,MAAc,EAAE,KAAgB,EAAE,OAAgB;QACrE,OAAO,IAAI,eAAO,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,CAAC,CAAA;IACnD,CAAC;IAED,aAAa,CAAC,IAAc,EAAE,UAAgB;QAC5C,OAAO,IAAI,8BAAa,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;IAC5C,CAAC;IAED,0EAA0E;IAC1E,yCAAyC;IACzC,+BAA+B;QAC7B,OAAO,IAAI,CAAA;IACb,CAAC;CACF,CAAC,CAAA"}
@@ -4,8 +4,13 @@ export declare class TransduceTree implements ParserSink {
4
4
  readonly down: Sink;
5
5
  open: number;
6
6
  carry: boolean;
7
+ readonly texts: string[];
8
+ readonly bytes: number[];
7
9
  constructor(spec: TreeSpec, down: Sink);
8
10
  event(ev: ParserEvent): Flow;
11
+ private get max();
12
+ private spell;
13
+ private write;
9
14
  private openPass;
10
15
  private closePass;
11
16
  }
@@ -10,18 +10,32 @@ exports.TransduceTree = void 0;
10
10
  // alchemy's `TreeSpec` documents what a native must do: each pass is looked
11
11
  // up by its rule's name, one lookup per pass whatever the spec's size; an
12
12
  // open pass announces its key, then begins its container or yields its
13
- // scalar from one of its tokens; a close pass ends its container, or
14
- // yields its own value; and a container whose rule is replaced by a rule
15
- // the spec names a container is one container, so that close ends nothing
16
- // and the replacing open begins nothing. The state is the count of open
17
- // containers and whether a close handed its container on, so the native
18
- // retains the document's nesting and nothing of its width or length, as
19
- // the library's step does. alchemy-cli's differential test holds the two
20
- // to the same bytes.
13
+ // scalar from one of its tokens, then announces its member; a close pass
14
+ // yields its text, when its rule is a `:text` rule, then ends its
15
+ // container, or yields its own value; and a container whose rule is
16
+ // replaced by a rule the spec names a container is one container, so that
17
+ // close ends nothing and the replacing open begins nothing. The state is
18
+ // the count of open containers, whether a close handed its container on,
19
+ // and the text each open `:text` rule has gathered, to which every pass
20
+ // writes its tokens' source text, so the native retains the document's
21
+ // nesting and an open rule's text, and nothing else of its width or
22
+ // length, as the library's step does. alchemy-cli's differential test
23
+ // holds the two to the same bytes.
24
+ //
25
+ // A text is held to the spec's `maxTextBytes` as it grows, at the joins
26
+ // the library's `string-join` makes and in their order: a pass's tokens
27
+ // together, then the innermost text with them, and a closed text with the
28
+ // text around it, each refused past the bound with alchemy's
29
+ // `treeTextRefusal`. The routers say this native reads `:member` and
30
+ // `:text` (routers.ts), which is what lets the lowering hand it a spec
31
+ // that uses either.
21
32
  //
22
33
  // A pass's events are worked out before the first of them is written, as
23
34
  // the library's step returns them together: a pass that fails writes none.
24
- // The failures are the library's, with its codes and texts.
35
+ // The failures are the library's, with its codes and texts, and in its
36
+ // order: an open pass's key, then what it begins or yields, then its
37
+ // tokens' text, then its member; a close pass's text, then what it ends or
38
+ // yields.
25
39
  const shared_1 = require("@tabnas/alchemy/shared");
26
40
  // The library's `transduce-tree`, natively, writing to `down`.
27
41
  class TransduceTree {
@@ -32,6 +46,10 @@ class TransduceTree {
32
46
  this.open = 0;
33
47
  // A close handed its container on to the rule replacing it.
34
48
  this.carry = false;
49
+ // The text each open `:text` rule has gathered, the innermost last, and
50
+ // its length in UTF-8 bytes, which the bound is held to.
51
+ this.texts = [];
52
+ this.bytes = [];
35
53
  }
36
54
  event(ev) {
37
55
  switch (ev.type) {
@@ -46,30 +64,49 @@ class TransduceTree {
46
64
  return this.down.event(shared_1.Ev.end);
47
65
  }
48
66
  }
67
+ // The most bytes a text may hold.
68
+ get max() {
69
+ return this.spec.maxTextBytes ?? Infinity;
70
+ }
71
+ // The pass's tokens written to the innermost open text, if one is and the
72
+ // pass consumed any, as the library's `transduce-spell` writes them: the
73
+ // tokens' text joined, then written to the innermost, each join held to
74
+ // the bound.
75
+ spell(pass) {
76
+ if (0 === this.texts.length || 0 === pass.tokens.length)
77
+ return;
78
+ let more = '';
79
+ let n = 0;
80
+ for (const token of pass.tokens) {
81
+ more += token.src;
82
+ n += (0, shared_1.utf8Bytes)(token.src);
83
+ }
84
+ if (n > this.max)
85
+ throw (0, shared_1.treeTextRefusal)(n, this.max);
86
+ this.write(more, n);
87
+ }
88
+ // `more`, of `n` bytes, written at the end of the innermost open text, as
89
+ // the library's `transduce-write` joins the two, held to the bound.
90
+ write(more, n) {
91
+ const last = this.texts.length - 1;
92
+ const len = this.bytes[last] + n;
93
+ if (len > this.max)
94
+ throw (0, shared_1.treeTextRefusal)(len, this.max);
95
+ this.texts[last] += more;
96
+ this.bytes[last] = len;
97
+ }
49
98
  openPass(pass) {
50
99
  const rule = this.spec.rules.get(pass.name);
51
- if (undefined === rule)
100
+ if (undefined === rule) {
101
+ this.spell(pass);
52
102
  return 'continue';
53
- let key;
54
- if (undefined !== rule.key) {
55
- if ('name' in rule.key)
56
- key = rule.key.name;
57
- else {
58
- const token = pass.tokens[rule.key.token];
59
- if (undefined !== token) {
60
- if ('string' !== token.val.type) {
61
- throw typeError(`key: the name must be a string, not ${kind(token.val)}`);
62
- }
63
- key = token.val.value;
64
- }
65
- }
66
103
  }
104
+ const key = named(rule.key, pass);
67
105
  let then;
106
+ let begins = false;
68
107
  if (undefined !== rule.container) {
69
- if (this.carry)
70
- this.carry = false;
71
- else {
72
- this.open++;
108
+ if (!this.carry) {
109
+ begins = true;
73
110
  then = 'object' === rule.container ? shared_1.Ev.objectStart : shared_1.Ev.arrayStart;
74
111
  }
75
112
  }
@@ -78,31 +115,85 @@ class TransduceTree {
78
115
  if (undefined !== token)
79
116
  then = scalar(token.val);
80
117
  }
81
- if (undefined !== key && 'stop' === this.down.event(shared_1.Ev.key(key)))
82
- return 'stop';
83
- return undefined === then ? 'continue' : this.down.event(then);
118
+ this.spell(pass);
119
+ const member = named(rule.member, pass);
120
+ if (undefined !== rule.container) {
121
+ if (begins)
122
+ this.open++;
123
+ else
124
+ this.carry = false;
125
+ }
126
+ if (true === rule.text) {
127
+ this.texts.push('');
128
+ this.bytes.push(0);
129
+ }
130
+ for (const ev of [
131
+ undefined === key ? undefined : shared_1.Ev.key(key),
132
+ then,
133
+ undefined === member ? undefined : shared_1.Ev.key(member),
134
+ ]) {
135
+ if (undefined !== ev && 'stop' === this.down.event(ev))
136
+ return 'stop';
137
+ }
138
+ return 'continue';
84
139
  }
85
140
  closePass(pass) {
86
141
  const rule = this.spec.rules.get(pass.name);
87
- if (undefined === rule)
142
+ if (undefined === rule) {
143
+ this.spell(pass);
88
144
  return 'continue';
145
+ }
146
+ // A `:text` rule's text closes first, and joins the one around it
147
+ // before this pass's own tokens do; it is yielded before anything
148
+ // else, once the rest of the pass is known not to fail.
149
+ let text;
150
+ if (true === rule.text) {
151
+ text = this.texts.pop();
152
+ if (undefined === text)
153
+ throw typeError('top: the vector is empty; there is no last item');
154
+ const n = this.bytes.pop();
155
+ if (0 < this.texts.length)
156
+ this.write(text, n);
157
+ }
158
+ this.spell(pass);
159
+ let then;
89
160
  if (undefined === rule.container) {
90
161
  if ('value' === rule.scalar && undefined !== pass.value)
91
- return this.down.event(scalar(pass.value));
92
- return 'continue';
162
+ then = scalar(pass.value);
93
163
  }
94
- if (undefined !== pass.alt && (0, shared_1.isTreeContainer)(this.spec, pass.alt.r)) {
164
+ else if (undefined !== pass.alt && (0, shared_1.isTreeContainer)(this.spec, pass.alt.r)) {
95
165
  this.carry = true;
96
- return 'continue';
97
166
  }
98
- if (0 === this.open)
99
- throw typeError('pop: the vector is empty; there is no last item to remove');
100
- this.open--;
101
- this.carry = false;
102
- return this.down.event('object' === rule.container ? shared_1.Ev.objectEnd : shared_1.Ev.arrayEnd);
167
+ else {
168
+ if (0 === this.open)
169
+ throw typeError('pop: the vector is empty; there is no last item to remove');
170
+ this.open--;
171
+ this.carry = false;
172
+ then = 'object' === rule.container ? shared_1.Ev.objectEnd : shared_1.Ev.arrayEnd;
173
+ }
174
+ if (undefined !== text && 'stop' === this.down.event(shared_1.Ev.string(text)))
175
+ return 'stop';
176
+ return undefined === then ? 'continue' : this.down.event(then);
103
177
  }
104
178
  }
105
179
  exports.TransduceTree = TransduceTree;
180
+ // The member name a field of a rule's entry names for a pass: the string,
181
+ // or the `:val` of the pass's token at that index, nothing when the pass
182
+ // consumed no such token; the library's `key` refuses a name that is not a
183
+ // string.
184
+ function named(field, pass) {
185
+ if (undefined === field)
186
+ return undefined;
187
+ if ('name' in field)
188
+ return field.name;
189
+ const token = pass.tokens[field.token];
190
+ if (undefined === token)
191
+ return undefined;
192
+ if ('string' !== token.val.type) {
193
+ throw typeError(`key: the name must be a string, not ${kind(token.val)}`);
194
+ }
195
+ return token.val.value;
196
+ }
106
197
  // A value as the library's `scalar` takes it, or its refusal.
107
198
  function scalar(value) {
108
199
  switch (value.type) {
@@ -1 +1 @@
1
- {"version":3,"file":"transduce-tree.js","sourceRoot":"","sources":["../src/transduce-tree.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transduce-tree.js","sourceRoot":"","sources":["../src/transduce-tree.ts"],"names":[],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- export declare const VERSION = "0.2.9";
1
+ export declare const VERSION = "0.2.11";
2
2
  export { Datum, DatumBuilder, byteSize, fromJSON, fromTabnas, getPath, takePath, toJSON, toText, walkDatum, } from '@tabnas/alchemy/shared';
3
3
  export type { Duplicates } from '@tabnas/alchemy/shared';
4
4
  export { Code, Fail, isFail } from '@tabnas/alchemy/shared';
@@ -25,11 +25,11 @@ export { Guarded } from './guard';
25
25
  export { ParserSource } from './parser-source';
26
26
  export { ParserEventSource } from './parser-event-source';
27
27
  export { TransduceTree } from './transduce-tree';
28
- export { isTreeContainer, parserEventFromJSON, parserEventToJSON } from '@tabnas/alchemy/shared';
28
+ export { isTreeContainer, parserEventFromJSON, parserEventToJSON, treeTextRefusal } from '@tabnas/alchemy/shared';
29
29
  export type { ParserEvent, ParserSink, PassAlt, PassToken, RulePass, TreeContainer, TreeKey, TreeRule, TreeScalar, TreeSpec, } from '@tabnas/alchemy/shared';
30
30
  export { DEFAULT_CHUNK_BYTES, LineFormat, LinesSource } from './lines';
31
31
  export type { LinesChunk, LinesInput, LinesWriter } from './lines';
32
- export { INCREMENTAL, capability, isIncremental } from './capability';
32
+ export { INCREMENTAL, PRUNABLE, capability, isIncremental, isPrunable } from './capability';
33
33
  export { Cell, Schema, Table, boundColumn, columnFromMeta } from '@tabnas/alchemy/shared';
34
34
  export type { BoundColumn, ColumnMapper, MissingPolicy, PublicColumn, TableBinding, TableEvent, TableSink, } from '@tabnas/alchemy/shared';
35
35
  export { TableFromJson } from './table-from-json';
package/dist/transduce.js CHANGED
@@ -2,7 +2,7 @@
2
2
  /* Copyright (c) 2026 tabnas, MIT License */
3
3
  Object.defineProperty(exports, "__esModule", { value: true });
4
4
  exports.engineFailure = exports.ValueSource = exports.SourceMode = exports.Prune = exports.replay = exports.TreeContract = exports.FnSink = exports.EventRecorder = exports.CountSink = exports.pathText = exports.keyText = exports.Selector = exports.Path = exports.Transition = exports.ScanEmit = exports.CaptureSpec = exports.SelectedRecorder = exports.Router = exports.FnRoute = exports.Matcher = exports.utf8Bytes = exports.NODE_BYTES = exports.Metrics = exports.Limits = exports.LIMIT_NAMES = exports.AbortFlag = exports.numberText = exports.jsonString = exports.jsonNumber = exports.isJsonNumber = exports.isStart = exports.isScalar = exports.isEnd = exports.eventText = exports.eventEquals = exports.Ev = exports.isFail = exports.Fail = exports.Code = exports.walkDatum = exports.toText = exports.toJSON = exports.takePath = exports.getPath = exports.fromTabnas = exports.fromJSON = exports.byteSize = exports.DatumBuilder = exports.Datum = exports.VERSION = void 0;
5
- exports.routers = exports.TableFromJson = exports.columnFromMeta = exports.boundColumn = exports.Table = exports.Schema = exports.Cell = exports.isIncremental = exports.capability = exports.INCREMENTAL = exports.LinesSource = exports.LineFormat = exports.DEFAULT_CHUNK_BYTES = exports.parserEventToJSON = exports.parserEventFromJSON = exports.isTreeContainer = exports.TransduceTree = exports.ParserEventSource = exports.ParserSource = exports.Guarded = exports.walkValue = void 0;
5
+ exports.routers = exports.TableFromJson = exports.columnFromMeta = exports.boundColumn = exports.Table = exports.Schema = exports.Cell = exports.isPrunable = exports.isIncremental = exports.capability = exports.PRUNABLE = exports.INCREMENTAL = exports.LinesSource = exports.LineFormat = exports.DEFAULT_CHUNK_BYTES = exports.treeTextRefusal = exports.parserEventToJSON = exports.parserEventFromJSON = exports.isTreeContainer = exports.TransduceTree = exports.ParserEventSource = exports.ParserSource = exports.Guarded = exports.walkValue = void 0;
6
6
  // Streaming transducers over any tabnas parser.
7
7
  //
8
8
  // A transducer decides what a source contributes to an output model; a
@@ -34,7 +34,7 @@ exports.routers = exports.TableFromJson = exports.columnFromMeta = exports.bound
34
34
  // under the names it always exported them by. `routers` is this package's
35
35
  // stages as alchemy's `Routers`, for a host to pass to alchemy's `compile`.
36
36
  // This package's version, as package.json declares it.
37
- exports.VERSION = '0.2.9';
37
+ exports.VERSION = '0.2.11';
38
38
  var shared_1 = require("@tabnas/alchemy/shared");
39
39
  Object.defineProperty(exports, "Datum", { enumerable: true, get: function () { return shared_1.Datum; } });
40
40
  Object.defineProperty(exports, "DatumBuilder", { enumerable: true, get: function () { return shared_1.DatumBuilder; } });
@@ -110,14 +110,17 @@ var shared_10 = require("@tabnas/alchemy/shared");
110
110
  Object.defineProperty(exports, "isTreeContainer", { enumerable: true, get: function () { return shared_10.isTreeContainer; } });
111
111
  Object.defineProperty(exports, "parserEventFromJSON", { enumerable: true, get: function () { return shared_10.parserEventFromJSON; } });
112
112
  Object.defineProperty(exports, "parserEventToJSON", { enumerable: true, get: function () { return shared_10.parserEventToJSON; } });
113
+ Object.defineProperty(exports, "treeTextRefusal", { enumerable: true, get: function () { return shared_10.treeTextRefusal; } });
113
114
  var lines_1 = require("./lines");
114
115
  Object.defineProperty(exports, "DEFAULT_CHUNK_BYTES", { enumerable: true, get: function () { return lines_1.DEFAULT_CHUNK_BYTES; } });
115
116
  Object.defineProperty(exports, "LineFormat", { enumerable: true, get: function () { return lines_1.LineFormat; } });
116
117
  Object.defineProperty(exports, "LinesSource", { enumerable: true, get: function () { return lines_1.LinesSource; } });
117
118
  var capability_1 = require("./capability");
118
119
  Object.defineProperty(exports, "INCREMENTAL", { enumerable: true, get: function () { return capability_1.INCREMENTAL; } });
120
+ Object.defineProperty(exports, "PRUNABLE", { enumerable: true, get: function () { return capability_1.PRUNABLE; } });
119
121
  Object.defineProperty(exports, "capability", { enumerable: true, get: function () { return capability_1.capability; } });
120
122
  Object.defineProperty(exports, "isIncremental", { enumerable: true, get: function () { return capability_1.isIncremental; } });
123
+ Object.defineProperty(exports, "isPrunable", { enumerable: true, get: function () { return capability_1.isPrunable; } });
121
124
  var shared_11 = require("@tabnas/alchemy/shared");
122
125
  Object.defineProperty(exports, "Cell", { enumerable: true, get: function () { return shared_11.Cell; } });
123
126
  Object.defineProperty(exports, "Schema", { enumerable: true, get: function () { return shared_11.Schema; } });
@@ -1 +1 @@
1
- {"version":3,"file":"transduce.js","sourceRoot":"","sources":["../src/transduce.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"transduce.js","sourceRoot":"","sources":["../src/transduce.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tabnas/transduce",
3
- "version": "0.2.9",
3
+ "version": "0.2.11",
4
4
  "main": "dist/transduce.js",
5
5
  "type": "commonjs",
6
6
  "types": "dist/transduce.d.ts",
package/src/capability.ts CHANGED
@@ -58,7 +58,36 @@ export function isIncremental(grammar: string): boolean {
58
58
  return INCREMENTAL.includes(grammar)
59
59
  }
60
60
 
61
+ // The grammars whose passes a `ParserEventSource` relays alike whether it
62
+ // prunes or not, on every document `test/prune.test.ts` reads them, by the
63
+ // name of the format each reads, as `INCREMENTAL` names them. The suite
64
+ // asserts the list in both directions; `toml` is not on it, since its
65
+ // message for a key defined twice quotes the value, which pruning empties.
66
+ export const PRUNABLE: readonly string[] = Object.freeze([
67
+ 'csv',
68
+ 'feed',
69
+ 'ini',
70
+ 'json',
71
+ 'json5',
72
+ 'jsonc',
73
+ 'jsonic',
74
+ 'jsonl',
75
+ 'markdown',
76
+ 'pgn',
77
+ 'xml',
78
+ 'yaml',
79
+ 'zon',
80
+ ])
81
+
82
+ // Whether a `ParserEventSource` may empty `grammar`'s arrays behind its
83
+ // stream (`ParserEventSource.prune`).
84
+ export function isPrunable(grammar: string): boolean {
85
+ return PRUNABLE.includes(grammar)
86
+ }
87
+
61
88
  export const capability = Object.freeze({
62
89
  INCREMENTAL,
63
90
  incremental: isIncremental,
91
+ PRUNABLE,
92
+ prunable: isPrunable,
64
93
  })
@@ -13,22 +13,21 @@
13
13
  // What each pass carries is alchemy's `RulePass`:
14
14
  //
15
15
  // - the rule's `name`, its depth `d` and instance `i` (the engine's, which
16
- // counts from 1 here and from 0 in Go and Rust: DIVERGENCE.md 6), the
17
- // alternate that matched (`alt`: `p`, `r`, `b`, and its groups `g`,
18
- // sorted, since they are tags whose order the runtimes' engines keep
19
- // differently), whether recovery forced the close, and its named counters
20
- // `n`, sorted by name;
16
+ // numbers rules from 1, the start rule's, in the order it makes them),
17
+ // the alternate that matched
18
+ // (`alt`: `p`, `r`, `b`, and its groups `g`, sorted, since they are tags
19
+ // whose order the runtimes' engines keep differently), whether recovery
20
+ // forced the close, and its named counters `n`, sorted by name;
21
21
  // - the `tokens` the pass consumed: those its alternate matched (the
22
22
  // engine's `o[:oN]` or `c[:cN]`), less the `b` it gave back from their
23
23
  // end, which are the next rule's to consume, and none when `b` is more
24
24
  // than it recorded, since a close alternate can back up a token it did
25
25
  // not record. A token is its name, its value, its source text and its
26
26
  // 1-based row and column; a token with no value (the end of the source,
27
- // a fixed token such as `[`, which Rust's engine gives its text:
28
- // DIVERGENCE.md 7) has `null`, and a number carries its source text as its lexeme when
29
- // that text is a JSON number spelling the value (RFC 8259), the rule the
30
- // incremental source keeps lexemes by, so a renderer can write it as it
31
- // stands;
27
+ // or a fixed token such as `[`) has `null`, and a number carries
28
+ // its source text as its lexeme when that text is a JSON number spelling
29
+ // the value (RFC 8259), the rule the incremental source keeps lexemes by,
30
+ // so a renderer can write it as it stands;
32
31
  // - on a close pass, the rule's node when that is a scalar (`value`), a
33
32
  // number with the lexeme of the rule's first open token as above;
34
33
  // nothing on an open pass, nor for a container.
@@ -52,6 +51,23 @@
52
51
  // `AbortFlag` is `ABORTED`; any other engine error is `INPUT_INVALID` with
53
52
  // the engine's code and position. A source runs once, as `ParserSource`
54
53
  // does: its parser carries the run's subscriber and budget.
54
+ //
55
+ // The engine builds its value as it parses, so a long document's tree
56
+ // holds every record, though nothing reads the value the parse returns.
57
+ // `prune()` empties each array behind the stream: once the sink has seen a
58
+ // close pass whose rule's node is an array, the source empties that array
59
+ // in place, so the tree holds the elements of the passes since the last
60
+ // close on it. That alters the value the engine returns, which this source
61
+ // never reads, and it is sound for a grammar whose passes do not depend on
62
+ // what its arrays hold, so it is a verified capability, as the incremental
63
+ // source is: `test/prune.test.ts` runs every document of every grammar in
64
+ // the devDependencies pruned and not, and `capability.prunable` lists the
65
+ // grammars whose passes and outcomes never differed
66
+ // (rs/src/source/parser_events.rs has the contract's one difference, a
67
+ // token whose value is a container of the tree). A run that prunes is
68
+ // gated on the list, by the grammar's name (`grammar`), and without a
69
+ // listed name it fails with `STREAMABILITY_UNKNOWN` before the parse,
70
+ // having sent nothing; `unverified()` lifts the gate for the suite.
55
71
 
56
72
  import {
57
73
  AbortFlag,
@@ -67,6 +83,7 @@ import {
67
83
  import type { Flow, ParserEvent, ParserSink, PassAlt, PassToken, RulePass } from '@tabnas/alchemy/shared'
68
84
  import type { Rule, RuleDone, Tabnas } from '@tabnas/parser'
69
85
 
86
+ import { isPrunable } from './capability'
70
87
  import { prepare } from './rule-events'
71
88
  import { engineFailure } from './source'
72
89
 
@@ -77,15 +94,65 @@ export class ParserEventSource {
77
94
  private sourceLimits: Limits = Limits.default()
78
95
  private abortFlag: AbortFlag = new AbortFlag()
79
96
  private sourceMetrics: Metrics = new Metrics()
97
+ private grammarName: string | null = null
98
+ private pruning = false
99
+ private isUnverified = false
80
100
  private used = false
81
101
 
82
- // A source with default limits, its own abort flag and fresh metrics; the
83
- // builder methods change each.
102
+ // A source with default limits, its own abort flag and fresh metrics,
103
+ // that prunes nothing; the builder methods change each.
84
104
  constructor(parser: Tabnas, text: string) {
85
105
  this.parser = parser
86
106
  this.text = text
87
107
  }
88
108
 
109
+ // The grammar the parser implements, by the name of the format it reads,
110
+ // as `ParserSource.grammar` takes it. A run that prunes needs a name
111
+ // `capability.prunable` lists; one that does not prune needs no name.
112
+ grammar(name: string): this {
113
+ this.grammarName = name
114
+ return this
115
+ }
116
+
117
+ // Empty each array in the engine's tree once the sink has seen a close
118
+ // pass on it, so the tree does not hold the whole document. The passes
119
+ // are unchanged for a grammar `capability.prunable` lists, and `run`
120
+ // refuses to prune any other, with `STREAMABILITY_UNKNOWN` before the
121
+ // parse.
122
+ prune(): this {
123
+ this.pruning = true
124
+ return this
125
+ }
126
+
127
+ // Prune whatever the verified list says. This exists for the
128
+ // differential suite that maintains the list and for nothing else: a
129
+ // grammar that reads its arrays back may make other passes once they are
130
+ // emptied, and the run still returns.
131
+ unverified(): this {
132
+ this.isUnverified = true
133
+ return this
134
+ }
135
+
136
+ // Why the run may not prune, when it may not.
137
+ private gate(): Fail | null {
138
+ if (!this.pruning || this.isUnverified) return null
139
+ const name = this.grammarName
140
+ if (null !== name && isPrunable(name)) return null
141
+ if (null !== name) {
142
+ return new Fail(
143
+ 'STREAMABILITY_UNKNOWN',
144
+ `grammar ${JSON.stringify(name)} is not in capability.prunable: the differential suite ` +
145
+ 'has not verified that its passes are the same when its arrays are emptied behind ' +
146
+ 'the stream; run it without ParserEventSource.prune',
147
+ )
148
+ }
149
+ return new Fail(
150
+ 'STREAMABILITY_UNKNOWN',
151
+ "ParserEventSource.prune needs the grammar's name (ParserEventSource.grammar) to check " +
152
+ 'capability.prunable; without one, run it without pruning',
153
+ )
154
+ }
155
+
89
156
  limits(limits: Limits): this {
90
157
  this.sourceLimits = limits
91
158
  return this
@@ -103,6 +170,14 @@ export class ParserEventSource {
103
170
 
104
171
  // Parse, relaying each pass into `sink`, then `end`.
105
172
  run(sink: ParserSink): Flow {
173
+ return this.runWithValue(sink).flow
174
+ }
175
+
176
+ // `run`, also handing back the value the engine returned: the engine's
177
+ // tree after pruning, when the run prunes. It is not the run's result
178
+ // (the passes are): it exists so a test can measure what pruning left in
179
+ // the tree, and nothing else should read it.
180
+ runWithValue(sink: ParserSink): { flow: Flow; value: unknown } {
106
181
  if (this.used) {
107
182
  throw new Fail(
108
183
  'STREAM_REUSED',
@@ -111,27 +186,28 @@ export class ParserEventSource {
111
186
  )
112
187
  }
113
188
  this.used = true
189
+ const refused = this.gate()
190
+ if (null !== refused) throw refused
114
191
  const abort = this.abortFlag
115
192
  const stop = new AbortFlag()
116
- const relay = new Relay(sink, this.sourceLimits.max_scalar_bytes, abort, stop)
193
+ const relay = new Relay(sink, this.sourceLimits.max_scalar_bytes, abort, stop, this.pruning)
117
194
  prepare(
118
195
  this.parser,
119
196
  () => !abort.isAborted() && !stop.isAborted(),
120
197
  (rule, done) => relay.onDone(rule, done),
121
198
  )
122
- let parsed: { ok: true } | { ok: false; error: unknown }
199
+ let parsed: { ok: true; value: unknown } | { ok: false; error: unknown }
123
200
  try {
124
- this.parser.parse(this.text)
125
- parsed = { ok: true }
201
+ parsed = { ok: true, value: this.parser.parse(this.text) }
126
202
  } catch (error) {
127
203
  parsed = { ok: false, error }
128
204
  }
129
205
  try {
130
206
  const status = relay.status
131
207
  if ('failed' === status.type) throw status.error
132
- if ('stopped' === status.type) return 'stop'
208
+ if ('stopped' === status.type) return { flow: 'stop', value: undefined }
133
209
  if (!parsed.ok) throw engineFailure(parsed.error, abort)
134
- return relay.send({ type: 'end' })
210
+ return { flow: relay.send({ type: 'end' }), value: parsed.value }
135
211
  } finally {
136
212
  this.sourceMetrics.events += relay.events
137
213
  }
@@ -151,6 +227,8 @@ class Relay {
151
227
  readonly abort: AbortFlag,
152
228
  // Set to make the parse guard cancel the parse.
153
229
  readonly stop: AbortFlag,
230
+ // Empty the array a close pass's rule builds, once the sink has seen it.
231
+ readonly prune: boolean,
154
232
  ) {}
155
233
 
156
234
  send(ev: ParserEvent): Flow {
@@ -183,6 +261,8 @@ class Relay {
183
261
  if ('stop' === this.send(ev)) {
184
262
  this.status = { type: 'stopped' }
185
263
  this.stop.abort()
264
+ } else if (this.prune && !open) {
265
+ emptyArray(rule)
186
266
  }
187
267
  } catch (error) {
188
268
  this.fail(error)
@@ -190,6 +270,15 @@ class Relay {
190
270
  }
191
271
  }
192
272
 
273
+ // Empty the array `rule`'s node is, in place, so every holder of it sees
274
+ // it emptied. Every element in it was built by passes the sink has seen,
275
+ // the last of them the close pass just sent, and what those passes carry
276
+ // is the sink's, so nothing sent so far changes.
277
+ function emptyArray(rule: Rule): void {
278
+ const node: unknown = (rule as any).node
279
+ if (Array.isArray(node) && 0 < node.length) node.length = 0
280
+ }
281
+
193
282
  // The pass as alchemy's `RulePass`, its sizes held to `max_scalar_bytes`.
194
283
  function rulePass(rule: Rule, done: RuleDone, open: boolean, max: number): RulePass {
195
284
  const r: any = rule
package/src/routers.ts CHANGED
@@ -69,4 +69,10 @@ export const routers: Routers = Object.freeze({
69
69
  transduceTree(spec: TreeSpec, downstream: Sink): ParserSink {
70
70
  return new TransduceTree(spec, downstream)
71
71
  },
72
+
73
+ // TransduceTree reads a spec's `:member` and `:text`, and holds a text to
74
+ // the spec's `maxTextBytes` as it grows.
75
+ transduceTreeReadsMemberAndText(): boolean {
76
+ return true
77
+ },
72
78
  })
@@ -8,21 +8,35 @@
8
8
  // alchemy's `TreeSpec` documents what a native must do: each pass is looked
9
9
  // up by its rule's name, one lookup per pass whatever the spec's size; an
10
10
  // open pass announces its key, then begins its container or yields its
11
- // scalar from one of its tokens; a close pass ends its container, or
12
- // yields its own value; and a container whose rule is replaced by a rule
13
- // the spec names a container is one container, so that close ends nothing
14
- // and the replacing open begins nothing. The state is the count of open
15
- // containers and whether a close handed its container on, so the native
16
- // retains the document's nesting and nothing of its width or length, as
17
- // the library's step does. alchemy-cli's differential test holds the two
18
- // to the same bytes.
11
+ // scalar from one of its tokens, then announces its member; a close pass
12
+ // yields its text, when its rule is a `:text` rule, then ends its
13
+ // container, or yields its own value; and a container whose rule is
14
+ // replaced by a rule the spec names a container is one container, so that
15
+ // close ends nothing and the replacing open begins nothing. The state is
16
+ // the count of open containers, whether a close handed its container on,
17
+ // and the text each open `:text` rule has gathered, to which every pass
18
+ // writes its tokens' source text, so the native retains the document's
19
+ // nesting and an open rule's text, and nothing else of its width or
20
+ // length, as the library's step does. alchemy-cli's differential test
21
+ // holds the two to the same bytes.
22
+ //
23
+ // A text is held to the spec's `maxTextBytes` as it grows, at the joins
24
+ // the library's `string-join` makes and in their order: a pass's tokens
25
+ // together, then the innermost text with them, and a closed text with the
26
+ // text around it, each refused past the bound with alchemy's
27
+ // `treeTextRefusal`. The routers say this native reads `:member` and
28
+ // `:text` (routers.ts), which is what lets the lowering hand it a spec
29
+ // that uses either.
19
30
  //
20
31
  // A pass's events are worked out before the first of them is written, as
21
32
  // the library's step returns them together: a pass that fails writes none.
22
- // The failures are the library's, with its codes and texts.
33
+ // The failures are the library's, with its codes and texts, and in its
34
+ // order: an open pass's key, then what it begins or yields, then its
35
+ // tokens' text, then its member; a close pass's text, then what it ends or
36
+ // yields.
23
37
 
24
- import { Datum, Ev, Fail, isTreeContainer } from '@tabnas/alchemy/shared'
25
- import type { Flow, JsonEvent, ParserEvent, ParserSink, RulePass, Sink, TreeSpec } from '@tabnas/alchemy/shared'
38
+ import { Datum, Ev, Fail, isTreeContainer, treeTextRefusal, utf8Bytes } from '@tabnas/alchemy/shared'
39
+ import type { Flow, JsonEvent, ParserEvent, ParserSink, RulePass, Sink, TreeKey, TreeSpec } from '@tabnas/alchemy/shared'
26
40
 
27
41
  // The library's `transduce-tree`, natively, writing to `down`.
28
42
  export class TransduceTree implements ParserSink {
@@ -30,6 +44,10 @@ export class TransduceTree implements ParserSink {
30
44
  open = 0
31
45
  // A close handed its container on to the rule replacing it.
32
46
  carry = false
47
+ // The text each open `:text` rule has gathered, the innermost last, and
48
+ // its length in UTF-8 bytes, which the bound is held to.
49
+ readonly texts: string[] = []
50
+ readonly bytes: number[] = []
33
51
 
34
52
  constructor(
35
53
  readonly spec: TreeSpec,
@@ -50,53 +68,121 @@ export class TransduceTree implements ParserSink {
50
68
  }
51
69
  }
52
70
 
71
+ // The most bytes a text may hold.
72
+ private get max(): number {
73
+ return this.spec.maxTextBytes ?? Infinity
74
+ }
75
+
76
+ // The pass's tokens written to the innermost open text, if one is and the
77
+ // pass consumed any, as the library's `transduce-spell` writes them: the
78
+ // tokens' text joined, then written to the innermost, each join held to
79
+ // the bound.
80
+ private spell(pass: RulePass): void {
81
+ if (0 === this.texts.length || 0 === pass.tokens.length) return
82
+ let more = ''
83
+ let n = 0
84
+ for (const token of pass.tokens) {
85
+ more += token.src
86
+ n += utf8Bytes(token.src)
87
+ }
88
+ if (n > this.max) throw treeTextRefusal(n, this.max)
89
+ this.write(more, n)
90
+ }
91
+
92
+ // `more`, of `n` bytes, written at the end of the innermost open text, as
93
+ // the library's `transduce-write` joins the two, held to the bound.
94
+ private write(more: string, n: number): void {
95
+ const last = this.texts.length - 1
96
+ const len = this.bytes[last] + n
97
+ if (len > this.max) throw treeTextRefusal(len, this.max)
98
+ this.texts[last] += more
99
+ this.bytes[last] = len
100
+ }
101
+
53
102
  private openPass(pass: RulePass): Flow {
54
103
  const rule = this.spec.rules.get(pass.name)
55
- if (undefined === rule) return 'continue'
56
- let key: string | undefined
57
- if (undefined !== rule.key) {
58
- if ('name' in rule.key) key = rule.key.name
59
- else {
60
- const token = pass.tokens[rule.key.token]
61
- if (undefined !== token) {
62
- if ('string' !== token.val.type) {
63
- throw typeError(`key: the name must be a string, not ${kind(token.val)}`)
64
- }
65
- key = token.val.value
66
- }
67
- }
104
+ if (undefined === rule) {
105
+ this.spell(pass)
106
+ return 'continue'
68
107
  }
108
+ const key = named(rule.key, pass)
69
109
  let then: JsonEvent | undefined
110
+ let begins = false
70
111
  if (undefined !== rule.container) {
71
- if (this.carry) this.carry = false
72
- else {
73
- this.open++
112
+ if (!this.carry) {
113
+ begins = true
74
114
  then = 'object' === rule.container ? Ev.objectStart : Ev.arrayStart
75
115
  }
76
116
  } else if (undefined !== rule.scalar && 'value' !== rule.scalar) {
77
117
  const token = pass.tokens[rule.scalar.token]
78
118
  if (undefined !== token) then = scalar(token.val)
79
119
  }
80
- if (undefined !== key && 'stop' === this.down.event(Ev.key(key))) return 'stop'
81
- return undefined === then ? 'continue' : this.down.event(then)
120
+ this.spell(pass)
121
+ const member = named(rule.member, pass)
122
+ if (undefined !== rule.container) {
123
+ if (begins) this.open++
124
+ else this.carry = false
125
+ }
126
+ if (true === rule.text) {
127
+ this.texts.push('')
128
+ this.bytes.push(0)
129
+ }
130
+ for (const ev of [
131
+ undefined === key ? undefined : Ev.key(key),
132
+ then,
133
+ undefined === member ? undefined : Ev.key(member),
134
+ ]) {
135
+ if (undefined !== ev && 'stop' === this.down.event(ev)) return 'stop'
136
+ }
137
+ return 'continue'
82
138
  }
83
139
 
84
140
  private closePass(pass: RulePass): Flow {
85
141
  const rule = this.spec.rules.get(pass.name)
86
- if (undefined === rule) return 'continue'
87
- if (undefined === rule.container) {
88
- if ('value' === rule.scalar && undefined !== pass.value) return this.down.event(scalar(pass.value))
142
+ if (undefined === rule) {
143
+ this.spell(pass)
89
144
  return 'continue'
90
145
  }
91
- if (undefined !== pass.alt && isTreeContainer(this.spec, pass.alt.r)) {
146
+ // A `:text` rule's text closes first, and joins the one around it
147
+ // before this pass's own tokens do; it is yielded before anything
148
+ // else, once the rest of the pass is known not to fail.
149
+ let text: string | undefined
150
+ if (true === rule.text) {
151
+ text = this.texts.pop()
152
+ if (undefined === text) throw typeError('top: the vector is empty; there is no last item')
153
+ const n = this.bytes.pop() as number
154
+ if (0 < this.texts.length) this.write(text, n)
155
+ }
156
+ this.spell(pass)
157
+ let then: JsonEvent | undefined
158
+ if (undefined === rule.container) {
159
+ if ('value' === rule.scalar && undefined !== pass.value) then = scalar(pass.value)
160
+ } else if (undefined !== pass.alt && isTreeContainer(this.spec, pass.alt.r)) {
92
161
  this.carry = true
93
- return 'continue'
162
+ } else {
163
+ if (0 === this.open) throw typeError('pop: the vector is empty; there is no last item to remove')
164
+ this.open--
165
+ this.carry = false
166
+ then = 'object' === rule.container ? Ev.objectEnd : Ev.arrayEnd
94
167
  }
95
- if (0 === this.open) throw typeError('pop: the vector is empty; there is no last item to remove')
96
- this.open--
97
- this.carry = false
98
- return this.down.event('object' === rule.container ? Ev.objectEnd : Ev.arrayEnd)
168
+ if (undefined !== text && 'stop' === this.down.event(Ev.string(text))) return 'stop'
169
+ return undefined === then ? 'continue' : this.down.event(then)
170
+ }
171
+ }
172
+
173
+ // The member name a field of a rule's entry names for a pass: the string,
174
+ // or the `:val` of the pass's token at that index, nothing when the pass
175
+ // consumed no such token; the library's `key` refuses a name that is not a
176
+ // string.
177
+ function named(field: TreeKey | undefined, pass: RulePass): string | undefined {
178
+ if (undefined === field) return undefined
179
+ if ('name' in field) return field.name
180
+ const token = pass.tokens[field.token]
181
+ if (undefined === token) return undefined
182
+ if ('string' !== token.val.type) {
183
+ throw typeError(`key: the name must be a string, not ${kind(token.val)}`)
99
184
  }
185
+ return token.val.value
100
186
  }
101
187
 
102
188
  // A value as the library's `scalar` takes it, or its refusal.
package/src/transduce.ts CHANGED
@@ -32,7 +32,7 @@
32
32
  // stages as alchemy's `Routers`, for a host to pass to alchemy's `compile`.
33
33
 
34
34
  // This package's version, as package.json declares it.
35
- export const VERSION = '0.2.9'
35
+ export const VERSION = '0.2.11'
36
36
 
37
37
  export {
38
38
  Datum,
@@ -78,7 +78,7 @@ export { Guarded } from './guard'
78
78
  export { ParserSource } from './parser-source'
79
79
  export { ParserEventSource } from './parser-event-source'
80
80
  export { TransduceTree } from './transduce-tree'
81
- export { isTreeContainer, parserEventFromJSON, parserEventToJSON } from '@tabnas/alchemy/shared'
81
+ export { isTreeContainer, parserEventFromJSON, parserEventToJSON, treeTextRefusal } from '@tabnas/alchemy/shared'
82
82
  export type {
83
83
  ParserEvent,
84
84
  ParserSink,
@@ -93,7 +93,7 @@ export type {
93
93
  } from '@tabnas/alchemy/shared'
94
94
  export { DEFAULT_CHUNK_BYTES, LineFormat, LinesSource } from './lines'
95
95
  export type { LinesChunk, LinesInput, LinesWriter } from './lines'
96
- export { INCREMENTAL, capability, isIncremental } from './capability'
96
+ export { INCREMENTAL, PRUNABLE, capability, isIncremental, isPrunable } from './capability'
97
97
  export { Cell, Schema, Table, boundColumn, columnFromMeta } from '@tabnas/alchemy/shared'
98
98
  export type {
99
99
  BoundColumn,