@tabnas/transduce 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 (63) hide show
  1. package/LICENSE +21 -0
  2. package/dist/capability.d.ts +6 -0
  3. package/dist/capability.js +52 -0
  4. package/dist/capability.js.map +1 -0
  5. package/dist/datum.d.ts +64 -0
  6. package/dist/datum.js +391 -0
  7. package/dist/datum.js.map +1 -0
  8. package/dist/error.d.ts +43 -0
  9. package/dist/error.js +169 -0
  10. package/dist/error.js.map +1 -0
  11. package/dist/event.d.ts +56 -0
  12. package/dist/event.js +101 -0
  13. package/dist/event.js.map +1 -0
  14. package/dist/guard.d.ts +20 -0
  15. package/dist/guard.js +90 -0
  16. package/dist/guard.js.map +1 -0
  17. package/dist/json.d.ts +4 -0
  18. package/dist/json.js +92 -0
  19. package/dist/json.js.map +1 -0
  20. package/dist/limits.d.ts +36 -0
  21. package/dist/limits.js +133 -0
  22. package/dist/limits.js.map +1 -0
  23. package/dist/lines.d.ts +39 -0
  24. package/dist/lines.js +1139 -0
  25. package/dist/lines.js.map +1 -0
  26. package/dist/matcher.d.ts +26 -0
  27. package/dist/matcher.js +245 -0
  28. package/dist/matcher.js.map +1 -0
  29. package/dist/parser-source.d.ts +27 -0
  30. package/dist/parser-source.js +194 -0
  31. package/dist/parser-source.js.map +1 -0
  32. package/dist/route.d.ts +61 -0
  33. package/dist/route.js +197 -0
  34. package/dist/route.js.map +1 -0
  35. package/dist/rule-events.d.ts +58 -0
  36. package/dist/rule-events.js +598 -0
  37. package/dist/rule-events.js.map +1 -0
  38. package/dist/scan.d.ts +19 -0
  39. package/dist/scan.js +70 -0
  40. package/dist/scan.js.map +1 -0
  41. package/dist/selector.d.ts +40 -0
  42. package/dist/selector.js +154 -0
  43. package/dist/selector.js.map +1 -0
  44. package/dist/sink.d.ts +29 -0
  45. package/dist/sink.js +184 -0
  46. package/dist/sink.js.map +1 -0
  47. package/dist/source.d.ts +37 -0
  48. package/dist/source.js +113 -0
  49. package/dist/source.js.map +1 -0
  50. package/dist/table-from-json.d.ts +12 -0
  51. package/dist/table-from-json.js +217 -0
  52. package/dist/table-from-json.js.map +1 -0
  53. package/dist/table.d.ts +81 -0
  54. package/dist/table.js +141 -0
  55. package/dist/table.js.map +1 -0
  56. package/dist/transduce.d.ts +28 -0
  57. package/dist/transduce.js +109 -0
  58. package/dist/transduce.js.map +1 -0
  59. package/dist/tsconfig.tsbuildinfo +1 -0
  60. package/dist/value.d.ts +16 -0
  61. package/dist/value.js +96 -0
  62. package/dist/value.js.map +1 -0
  63. package/package.json +65 -0
package/dist/scan.js ADDED
@@ -0,0 +1,70 @@
1
+ "use strict";
2
+ /* Copyright (c) 2026 tabnas, MIT License */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ScanEmit = exports.Transition = void 0;
5
+ // `scan-emit`: declarative state evolution over a stream.
6
+ //
7
+ // A pure step function takes the state and one item and returns the next
8
+ // state with the items to emit; a finish function turns the final state
9
+ // into the closing items. The operator owns the state and the iteration;
10
+ // the functions own nothing. This is what the DSL's `scan-emit` lowers to,
11
+ // and the table transducer is one instance of it.
12
+ const error_1 = require("./error");
13
+ exports.Transition = Object.freeze({
14
+ of(state, outputs) {
15
+ return { state, outputs };
16
+ },
17
+ // A step that emits nothing.
18
+ stay(state) {
19
+ return { state, outputs: [] };
20
+ },
21
+ // A step that emits one item.
22
+ emit(state, output) {
23
+ return { state, outputs: [output] };
24
+ },
25
+ });
26
+ // The operator. Feed items with `item`, then call `finish` exactly once
27
+ // when the input completed successfully; never call it after a failure or
28
+ // a cancellation. A step or the finish throws a `Fail` to fail the run; a
29
+ // step that failed leaves the operator without a state, so a later item or
30
+ // `finish` is a `PROTOCOL_ORDER_ERROR`.
31
+ class ScanEmit {
32
+ constructor(initial, step, finish, out) {
33
+ this.state = { value: initial };
34
+ this.step = step;
35
+ this.finisher = finish;
36
+ this.out = out;
37
+ }
38
+ // One input item. Its outputs go downstream before this returns.
39
+ item(item) {
40
+ const state = this.state;
41
+ if (null === state) {
42
+ throw error_1.Fail.protocol('scan-emit received an item after it finished');
43
+ }
44
+ this.state = null;
45
+ const transition = this.step(state.value, item);
46
+ this.state = { value: transition.state };
47
+ for (const o of transition.outputs) {
48
+ if ('stop' === this.out(o))
49
+ return 'stop';
50
+ }
51
+ return 'continue';
52
+ }
53
+ // The input completed: emit the closing items.
54
+ finish() {
55
+ const state = this.state;
56
+ const finish = this.finisher;
57
+ if (null === state || null === finish) {
58
+ throw error_1.Fail.protocol('scan-emit finished twice');
59
+ }
60
+ this.state = null;
61
+ this.finisher = null;
62
+ for (const o of finish(state.value)) {
63
+ if ('stop' === this.out(o))
64
+ return 'stop';
65
+ }
66
+ return 'continue';
67
+ }
68
+ }
69
+ exports.ScanEmit = ScanEmit;
70
+ //# sourceMappingURL=scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scan.js","sourceRoot":"","sources":["../src/scan.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;AAE5C,0DAA0D;AAC1D,EAAE;AACF,yEAAyE;AACzE,wEAAwE;AACxE,yEAAyE;AACzE,2EAA2E;AAC3E,kDAAkD;AAElD,mCAA8B;AAMjB,QAAA,UAAU,GAAG,MAAM,CAAC,MAAM,CAAC;IACtC,EAAE,CAAO,KAAQ,EAAE,OAAY;QAC7B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;IAC3B,CAAC;IACD,6BAA6B;IAC7B,IAAI,CAAO,KAAQ;QACjB,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,EAAE,CAAA;IAC/B,CAAC;IACD,8BAA8B;IAC9B,IAAI,CAAO,KAAQ,EAAE,MAAS;QAC5B,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,CAAC,MAAM,CAAC,EAAE,CAAA;IACrC,CAAC;CACF,CAAC,CAAA;AAEF,wEAAwE;AACxE,0EAA0E;AAC1E,0EAA0E;AAC1E,2EAA2E;AAC3E,wCAAwC;AACxC;IAME,YACE,OAAU,EACV,IAA6C,EAC7C,MAAyB,EACzB,GAAwB;QAExB,IAAI,CAAC,KAAK,GAAG,EAAE,KAAK,EAAE,OAAO,EAAE,CAAA;QAC/B,IAAI,CAAC,IAAI,GAAG,IAAI,CAAA;QAChB,IAAI,CAAC,QAAQ,GAAG,MAAM,CAAA;QACtB,IAAI,CAAC,GAAG,GAAG,GAAG,CAAA;IAChB,CAAC;IAED,iEAAiE;IACjE,IAAI,CAAC,IAAO;QACV,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,IAAI,IAAI,KAAK,KAAK,EAAE,CAAC;YACnB,MAAM,YAAI,CAAC,QAAQ,CAAC,8CAA8C,CAAC,CAAA;QACrE,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QAC/C,IAAI,CAAC,KAAK,GAAG,EAAE,KAAK,EAAE,UAAU,CAAC,KAAK,EAAE,CAAA;QACxC,KAAK,MAAM,CAAC,IAAI,UAAU,CAAC,OAAO,EAAE,CAAC;YACnC,IAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,MAAM,CAAA;QAC3C,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;IAED,+CAA+C;IAC/C,MAAM;QACJ,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAA;QACxB,MAAM,MAAM,GAAG,IAAI,CAAC,QAAQ,CAAA;QAC5B,IAAI,IAAI,KAAK,KAAK,IAAI,IAAI,KAAK,MAAM,EAAE,CAAC;YACtC,MAAM,YAAI,CAAC,QAAQ,CAAC,0BAA0B,CAAC,CAAA;QACjD,CAAC;QACD,IAAI,CAAC,KAAK,GAAG,IAAI,CAAA;QACjB,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAA;QACpB,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EAAE,CAAC;YACpC,IAAI,MAAM,KAAK,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC;gBAAE,OAAO,MAAM,CAAA;QAC3C,CAAC;QACD,OAAO,UAAU,CAAA;IACnB,CAAC;CACF"}
@@ -0,0 +1,40 @@
1
+ export type Segment = string | number;
2
+ export declare function keyText(key: string): string;
3
+ export declare class Path {
4
+ readonly segments: Segment[];
5
+ constructor(segments?: Segment[]);
6
+ static root(): Path;
7
+ push(seg: Segment): void;
8
+ pop(): Segment | undefined;
9
+ depth(): number;
10
+ clone(): Path;
11
+ toString(): string;
12
+ }
13
+ export declare function pathText(segments: readonly Segment[]): string;
14
+ export type Step = {
15
+ readonly type: 'property';
16
+ readonly name: string;
17
+ } | {
18
+ readonly type: 'index';
19
+ readonly index: number;
20
+ } | {
21
+ readonly type: 'each_index';
22
+ } | {
23
+ readonly type: 'each_member';
24
+ };
25
+ export declare class Selector {
26
+ readonly steps: readonly Step[];
27
+ constructor(steps?: readonly Step[]);
28
+ static root(): Selector;
29
+ property(name: string): Selector;
30
+ index(index: number): Selector;
31
+ eachIndex(): Selector;
32
+ eachMember(): Selector;
33
+ compose(other: Selector): Selector;
34
+ static fromSegments(segments: readonly Segment[]): Selector;
35
+ isRoot(): boolean;
36
+ isMulti(): boolean;
37
+ mayOverlap(other: Selector): boolean;
38
+ equals(other: Selector): boolean;
39
+ toString(): string;
40
+ }
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ /* Copyright (c) 2026 tabnas, MIT License */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.Selector = exports.Path = void 0;
5
+ exports.keyText = keyText;
6
+ exports.pathText = pathText;
7
+ // Selectors: reusable descriptions of where in a document to look.
8
+ //
9
+ // A selector is data, never code: it is built from constructors or from
10
+ // validated path segments (`Selector.fromSegments`), and a matcher
11
+ // interprets it. A concrete `Path` names one location; a `Selector` may
12
+ // name many (`each_index`, `each_member`). Both print in jq syntax, which
13
+ // is what the rest of the fleet prints and accepts.
14
+ const json_1 = require("./json");
15
+ // One key as jq writes it: bare when it is an ASCII identifier, a JSON
16
+ // string otherwise.
17
+ function keyText(key) {
18
+ return /^[A-Za-z_][A-Za-z0-9_]*$/.test(key) ? '.' + key : '.' + (0, json_1.jsonString)(key);
19
+ }
20
+ // A concrete location in a document.
21
+ class Path {
22
+ constructor(segments = []) {
23
+ this.segments = segments;
24
+ }
25
+ static root() {
26
+ return new Path([]);
27
+ }
28
+ push(seg) {
29
+ this.segments.push(seg);
30
+ }
31
+ pop() {
32
+ return this.segments.pop();
33
+ }
34
+ depth() {
35
+ return this.segments.length;
36
+ }
37
+ clone() {
38
+ return new Path(this.segments.slice());
39
+ }
40
+ // jq syntax: `.a[0]."b-c"`, and `.` for the root.
41
+ toString() {
42
+ return pathText(this.segments);
43
+ }
44
+ }
45
+ exports.Path = Path;
46
+ // Segments in jq syntax.
47
+ function pathText(segments) {
48
+ if (0 === segments.length)
49
+ return '.';
50
+ let out = '';
51
+ for (const seg of segments) {
52
+ out += 'number' === typeof seg ? `[${seg}]` : keyText(seg);
53
+ }
54
+ return out;
55
+ }
56
+ const EACH_INDEX = Object.freeze({ type: 'each_index' });
57
+ const EACH_MEMBER = Object.freeze({ type: 'each_member' });
58
+ // A description of locations: the root, narrowed step by step. Immutable:
59
+ // every builder returns a new selector.
60
+ class Selector {
61
+ constructor(steps = []) {
62
+ this.steps = Object.freeze(steps.slice());
63
+ }
64
+ // The document itself.
65
+ static root() {
66
+ return new Selector([]);
67
+ }
68
+ property(name) {
69
+ return new Selector([...this.steps, { type: 'property', name }]);
70
+ }
71
+ index(index) {
72
+ if (!Number.isInteger(index) || index < 0) {
73
+ throw new TypeError('an index step is a non-negative integer: ' + index);
74
+ }
75
+ return new Selector([...this.steps, { type: 'index', index }]);
76
+ }
77
+ eachIndex() {
78
+ return new Selector([...this.steps, EACH_INDEX]);
79
+ }
80
+ eachMember() {
81
+ return new Selector([...this.steps, EACH_MEMBER]);
82
+ }
83
+ // `this`, then `other` below every location `this` names.
84
+ compose(other) {
85
+ return new Selector([...this.steps, ...other.steps]);
86
+ }
87
+ // A selector naming exactly one location: `as-path` over data.
88
+ static fromSegments(segments) {
89
+ let s = Selector.root();
90
+ for (const seg of segments) {
91
+ s = 'number' === typeof seg ? s.index(seg) : s.property(seg);
92
+ }
93
+ return s;
94
+ }
95
+ isRoot() {
96
+ return 0 === this.steps.length;
97
+ }
98
+ // Whether the selector can name more than one location.
99
+ isMulti() {
100
+ return this.steps.some((s) => 'each_index' === s.type || 'each_member' === s.type);
101
+ }
102
+ // Whether this selector names a location strictly inside a location
103
+ // `other` names, or the same one: the test a router uses to refuse
104
+ // overlapping captures.
105
+ mayOverlap(other) {
106
+ const [short, long] = this.steps.length <= other.steps.length ? [this, other] : [other, this];
107
+ for (let i = 0; i < short.steps.length; i++) {
108
+ if (!stepMayMatchSame(short.steps[i], long.steps[i]))
109
+ return false;
110
+ }
111
+ return true;
112
+ }
113
+ equals(other) {
114
+ return this.toString() === other.toString();
115
+ }
116
+ // jq syntax: `.response.records[*]`, `."odd key"`, `[3]`, `[]` for
117
+ // every member, `.` for the root.
118
+ toString() {
119
+ if (0 === this.steps.length)
120
+ return '.';
121
+ let out = '';
122
+ for (const step of this.steps) {
123
+ switch (step.type) {
124
+ case 'property':
125
+ out += keyText(step.name);
126
+ break;
127
+ case 'index':
128
+ out += `[${step.index}]`;
129
+ break;
130
+ case 'each_index':
131
+ out += '[*]';
132
+ break;
133
+ case 'each_member':
134
+ out += '[]';
135
+ break;
136
+ }
137
+ }
138
+ return out;
139
+ }
140
+ }
141
+ exports.Selector = Selector;
142
+ function stepMayMatchSame(a, b) {
143
+ switch (a.type) {
144
+ case 'property':
145
+ return (('property' === b.type && a.name === b.name) || 'each_member' === b.type);
146
+ case 'each_member':
147
+ return 'property' === b.type || 'each_member' === b.type;
148
+ case 'index':
149
+ return ('index' === b.type && a.index === b.index) || 'each_index' === b.type;
150
+ case 'each_index':
151
+ return 'index' === b.type || 'each_index' === b.type;
152
+ }
153
+ }
154
+ //# sourceMappingURL=selector.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"selector.js","sourceRoot":"","sources":["../src/selector.ts"],"names":[],"mappings":";AAAA,4CAA4C;;;;;AAE5C,mEAAmE;AACnE,EAAE;AACF,wEAAwE;AACxE,mEAAmE;AACnE,wEAAwE;AACxE,0EAA0E;AAC1E,oDAAoD;AAEpD,iCAAmC;AAMnC,uEAAuE;AACvE,oBAAoB;AACpB,iBAAwB,GAAW;IACjC,OAAO,0BAA0B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,GAAG,GAAG,CAAC,CAAC,CAAC,GAAG,GAAG,IAAA,iBAAU,EAAC,GAAG,CAAC,CAAA;AACjF,CAAC;AAED,qCAAqC;AACrC;IAGE,YAAY,QAAQ,GAAc,EAAE;QAClC,IAAI,CAAC,QAAQ,GAAG,QAAQ,CAAA;IAC1B,CAAC;IAED,MAAM,CAAC,IAAI;QACT,OAAO,IAAI,IAAI,CAAC,EAAE,CAAC,CAAA;IACrB,CAAC;IAED,IAAI,CAAC,GAAY;QACf,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACzB,CAAC;IAED,GAAG;QACD,OAAO,IAAI,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAA;IAC5B,CAAC;IAED,KAAK;QACH,OAAO,IAAI,CAAC,QAAQ,CAAC,MAAM,CAAA;IAC7B,CAAC;IAED,KAAK;QACH,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,KAAK,EAAE,CAAC,CAAA;IACxC,CAAC;IAED,kDAAkD;IAClD,QAAQ;QACN,OAAO,QAAQ,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAA;IAChC,CAAC;CACF;;AAED,yBAAyB;AACzB,kBAAyB,QAA4B;IACnD,IAAI,CAAC,KAAK,QAAQ,CAAC,MAAM;QAAE,OAAO,GAAG,CAAA;IACrC,IAAI,GAAG,GAAG,EAAE,CAAA;IACZ,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;QAC3B,GAAG,IAAI,QAAQ,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,IAAI,GAAG,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,GAAG,CAAA;AACZ,CAAC;AAaD,MAAM,UAAU,GAAS,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,YAAY,EAAE,CAAC,CAAA;AAC9D,MAAM,WAAW,GAAS,MAAM,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,aAAa,EAAE,CAAC,CAAA;AAEhE,0EAA0E;AAC1E,wCAAwC;AACxC;IAGE,YAAY,KAAK,GAAoB,EAAE;QACrC,IAAI,CAAC,KAAK,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC,CAAA;IAC3C,CAAC;IAED,uBAAuB;IACvB,MAAM,CAAC,IAAI;QACT,OAAO,IAAI,QAAQ,CAAC,EAAE,CAAC,CAAA;IACzB,CAAC;IAED,QAAQ,CAAC,IAAY;QACnB,OAAO,IAAI,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAC,CAAC,CAAA;IAClE,CAAC;IAED,KAAK,CAAC,KAAa;QACjB,IAAI,CAAC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC,EAAE,CAAC;YAC1C,MAAM,IAAI,SAAS,CAAC,2CAA2C,GAAG,KAAK,CAAC,CAAA;QAC1E,CAAC;QACD,OAAO,IAAI,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC,CAAC,CAAA;IAChE,CAAC;IAED,SAAS;QACP,OAAO,IAAI,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,UAAU,CAAC,CAAC,CAAA;IAClD,CAAC;IAED,UAAU;QACR,OAAO,IAAI,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;IACnD,CAAC;IAED,0DAA0D;IAC1D,OAAO,CAAC,KAAe;QACrB,OAAO,IAAI,QAAQ,CAAC,CAAC,GAAG,IAAI,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC,CAAA;IACtD,CAAC;IAED,+DAA+D;IAC/D,MAAM,CAAC,YAAY,CAAC,QAA4B;QAC9C,IAAI,CAAC,GAAG,QAAQ,CAAC,IAAI,EAAE,CAAA;QACvB,KAAK,MAAM,GAAG,IAAI,QAAQ,EAAE,CAAC;YAC3B,CAAC,GAAG,QAAQ,KAAK,OAAO,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,CAAA;QAC9D,CAAC;QACD,OAAO,CAAC,CAAA;IACV,CAAC;IAED,MAAM;QACJ,OAAO,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM,CAAA;IAChC,CAAC;IAED,wDAAwD;IACxD,OAAO;QACL,OAAO,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,YAAY,KAAK,CAAC,CAAC,IAAI,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,CAAC,CAAA;IACpF,CAAC;IAED,oEAAoE;IACpE,mEAAmE;IACnE,wBAAwB;IACxB,UAAU,CAAC,KAAe;QACxB,MAAM,CAAC,KAAK,EAAE,IAAI,CAAC,GACjB,IAAI,CAAC,KAAK,CAAC,MAAM,IAAI,KAAK,CAAC,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,EAAE,IAAI,CAAC,CAAA;QACzE,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;YAC5C,IAAI,CAAC,gBAAgB,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC;gBAAE,OAAO,KAAK,CAAA;QACpE,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC;IAED,MAAM,CAAC,KAAe;QACpB,OAAO,IAAI,CAAC,QAAQ,EAAE,KAAK,KAAK,CAAC,QAAQ,EAAE,CAAA;IAC7C,CAAC;IAED,mEAAmE;IACnE,kCAAkC;IAClC,QAAQ;QACN,IAAI,CAAC,KAAK,IAAI,CAAC,KAAK,CAAC,MAAM;YAAE,OAAO,GAAG,CAAA;QACvC,IAAI,GAAG,GAAG,EAAE,CAAA;QACZ,KAAK,MAAM,IAAI,IAAI,IAAI,CAAC,KAAK,EAAE,CAAC;YAC9B,QAAQ,IAAI,CAAC,IAAI,EAAE,CAAC;gBAClB,KAAK,UAAU;oBACb,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;oBACzB,MAAK;gBACP,KAAK,OAAO;oBACV,GAAG,IAAI,IAAI,IAAI,CAAC,KAAK,GAAG,CAAA;oBACxB,MAAK;gBACP,KAAK,YAAY;oBACf,GAAG,IAAI,KAAK,CAAA;oBACZ,MAAK;gBACP,KAAK,aAAa;oBAChB,GAAG,IAAI,IAAI,CAAA;oBACX,MAAK;YACT,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CACF;;AAED,SAAS,gBAAgB,CAAC,CAAO,EAAE,CAAO;IACxC,QAAQ,CAAC,CAAC,IAAI,EAAE,CAAC;QACf,KAAK,UAAU;YACb,OAAO,CACL,CAAC,UAAU,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,IAAI,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,CACzE,CAAA;QACH,KAAK,aAAa;YAChB,OAAO,UAAU,KAAK,CAAC,CAAC,IAAI,IAAI,aAAa,KAAK,CAAC,CAAC,IAAI,CAAA;QAC1D,KAAK,OAAO;YACV,OAAO,CAAC,OAAO,KAAK,CAAC,CAAC,IAAI,IAAI,CAAC,CAAC,KAAK,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,CAAA;QAC/E,KAAK,YAAY;YACf,OAAO,OAAO,KAAK,CAAC,CAAC,IAAI,IAAI,YAAY,KAAK,CAAC,CAAC,IAAI,CAAA;IACxD,CAAC;AACH,CAAC"}
package/dist/sink.d.ts ADDED
@@ -0,0 +1,29 @@
1
+ import { JsonEvent } from './event';
2
+ export type Flow = 'continue' | 'stop';
3
+ export interface Sink {
4
+ event(ev: JsonEvent): Flow;
5
+ }
6
+ export declare class EventRecorder implements Sink {
7
+ readonly events: JsonEvent[];
8
+ event(ev: JsonEvent): Flow;
9
+ }
10
+ export declare class FnSink implements Sink {
11
+ private fn;
12
+ constructor(fn: (ev: JsonEvent) => Flow | void);
13
+ event(ev: JsonEvent): Flow;
14
+ }
15
+ export declare class CountSink implements Sink {
16
+ events: number;
17
+ event(_ev: JsonEvent): Flow;
18
+ }
19
+ export declare function replay(events: Iterable<JsonEvent>, sink: Sink): Flow;
20
+ export declare class TreeContract<S extends Sink> implements Sink {
21
+ readonly inner: S;
22
+ private open;
23
+ private rootDone;
24
+ constructor(inner: S);
25
+ private path;
26
+ private notATree;
27
+ private closed;
28
+ event(ev: JsonEvent): Flow;
29
+ }
package/dist/sink.js ADDED
@@ -0,0 +1,184 @@
1
+ "use strict";
2
+ /* Copyright (c) 2026 tabnas, MIT License */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.TreeContract = exports.CountSink = exports.FnSink = exports.EventRecorder = void 0;
5
+ exports.replay = replay;
6
+ // The push boundary between stages.
7
+ //
8
+ // A pipeline is a chain of sinks. The source calls the first sink once per
9
+ // event, synchronously, inside the parse; each stage does its work and
10
+ // calls the next. Nothing is queued between stages, so a slow writer at the
11
+ // end slows the parser at the start: that is the backpressure, and it
12
+ // costs no buffer. A stage that must stop early (a `take`) answers
13
+ // `'stop'`, which the source turns into a cancelled parse. A stage that
14
+ // fails throws a `Fail`; the source stops the parse and the failure
15
+ // reaches the caller unchanged.
16
+ const error_1 = require("./error");
17
+ const selector_1 = require("./selector");
18
+ // A sink that records every event, for tests and small results.
19
+ class EventRecorder {
20
+ constructor() {
21
+ this.events = [];
22
+ }
23
+ event(ev) {
24
+ this.events.push(ev);
25
+ return 'continue';
26
+ }
27
+ }
28
+ exports.EventRecorder = EventRecorder;
29
+ // A sink made of a function. A function that returns nothing continues.
30
+ class FnSink {
31
+ constructor(fn) {
32
+ this.fn = fn;
33
+ }
34
+ event(ev) {
35
+ return this.fn(ev) || 'continue';
36
+ }
37
+ }
38
+ exports.FnSink = FnSink;
39
+ // A sink that counts events and drops them: the cheapest consumer, for
40
+ // measuring a source on its own.
41
+ class CountSink {
42
+ constructor() {
43
+ this.events = 0;
44
+ }
45
+ event(_ev) {
46
+ this.events++;
47
+ return 'continue';
48
+ }
49
+ }
50
+ exports.CountSink = CountSink;
51
+ // Replay a recording into a sink, stopping where the sink stops.
52
+ function replay(events, sink) {
53
+ for (const ev of events) {
54
+ if ('stop' === sink.event(ev))
55
+ return 'stop';
56
+ }
57
+ return 'continue';
58
+ }
59
+ // A tree's events, held to their contract in front of a sink that takes
60
+ // them as one (a render that writes a document from them): one root value,
61
+ // and in each object a key and then its value, each key once. A value
62
+ // walked from a parsed tree keeps it by construction. A parse streamed as
63
+ // it proceeds may not: it hands on a member its grammar reads twice
64
+ // (JSON's `{"a":1,"a":2}`, whose value keeps the last) where a tree has
65
+ // one, and the rule-event adapter refuses most shapes it cannot follow but
66
+ // not every one a grammar can produce. A repeated key in one object is
67
+ // refused with `DUPLICATE_MEMBER`, and events no tree has (a value where a
68
+ // key is due, a key outside an object, a close with nothing open, a second
69
+ // root) with `STREAMABILITY_UNKNOWN`, each at the path of the object
70
+ // concerned; the event is not passed on. Each open object keeps the keys
71
+ // it has had, dropped when it closes.
72
+ class TreeContract {
73
+ constructor(inner) {
74
+ this.open = [];
75
+ this.rootDone = false;
76
+ this.inner = inner;
77
+ }
78
+ // The path of the value due next: the open containers, each by the member
79
+ // or element open in it, and in the innermost object its last key when
80
+ // that member's value is due.
81
+ path() {
82
+ const segments = [];
83
+ const last = this.open.length - 1;
84
+ this.open.forEach((open, i) => {
85
+ if (open.array) {
86
+ segments.push(open.next);
87
+ }
88
+ else if ((i !== last || !open.keyDue) && null != open.last) {
89
+ // A container open inside this object is its last key's value,
90
+ // whatever `keyDue` says: the member was counted as taken when its
91
+ // value opened.
92
+ segments.push(open.last);
93
+ }
94
+ });
95
+ return new selector_1.Path(segments);
96
+ }
97
+ notATree(what) {
98
+ return new error_1.Fail('STREAMABILITY_UNKNOWN', `the stream holds ${what}, which a tree's events never do, so it is not a tree's`).atPath(this.path().toString());
99
+ }
100
+ // A value is complete: the next in its array is due, or the root is.
101
+ closed() {
102
+ const top = this.open[this.open.length - 1];
103
+ if (undefined === top)
104
+ this.rootDone = true;
105
+ else if (top.array)
106
+ top.next++;
107
+ }
108
+ event(ev) {
109
+ const top = this.open[this.open.length - 1];
110
+ switch (ev.type) {
111
+ case 'key': {
112
+ if (undefined !== top && !top.array && top.keyDue) {
113
+ if (top.keys.has(ev.key)) {
114
+ const path = this.path();
115
+ path.push(ev.key);
116
+ throw new error_1.Fail('DUPLICATE_MEMBER', `member ${JSON.stringify(ev.key)} appears twice in one object, and a tree's ` +
117
+ `events hold each key once`).atPath(path.toString());
118
+ }
119
+ top.keys.add(ev.key);
120
+ top.last = ev.key;
121
+ top.keyDue = false;
122
+ }
123
+ else if (undefined !== top && !top.array) {
124
+ throw this.notATree('a key where a value is due');
125
+ }
126
+ else {
127
+ throw this.notATree('a key outside an object');
128
+ }
129
+ break;
130
+ }
131
+ case 'object_end':
132
+ if (undefined !== top && !top.array && top.keyDue) {
133
+ this.open.pop();
134
+ this.closed();
135
+ }
136
+ else if (undefined !== top && !top.array) {
137
+ throw this.notATree("an object's end where a value is due");
138
+ }
139
+ else {
140
+ throw this.notATree("an object's end where none is due");
141
+ }
142
+ break;
143
+ case 'array_end':
144
+ if (undefined !== top && top.array) {
145
+ this.open.pop();
146
+ this.closed();
147
+ }
148
+ else {
149
+ throw this.notATree("an array's end where none is due");
150
+ }
151
+ break;
152
+ case 'end':
153
+ if (0 < this.open.length) {
154
+ throw this.notATree('its end inside an open container');
155
+ }
156
+ break;
157
+ default: {
158
+ // A value: in an object, only once its key is in; at the root,
159
+ // only once.
160
+ if (undefined === top) {
161
+ if (this.rootDone)
162
+ throw this.notATree('a second root value');
163
+ }
164
+ else if (!top.array) {
165
+ if (top.keyDue)
166
+ throw this.notATree('a value where a key is due');
167
+ top.keyDue = true;
168
+ }
169
+ if ('object_start' === ev.type) {
170
+ this.open.push({ array: false, keys: new Set(), last: null, keyDue: true });
171
+ }
172
+ else if ('array_start' === ev.type) {
173
+ this.open.push({ array: true, next: 0 });
174
+ }
175
+ else {
176
+ this.closed();
177
+ }
178
+ }
179
+ }
180
+ return this.inner.event(ev);
181
+ }
182
+ }
183
+ exports.TreeContract = TreeContract;
184
+ //# sourceMappingURL=sink.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sink.js","sourceRoot":"","sources":["../src/sink.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,37 @@
1
+ import { Fail } from './error';
2
+ import { AbortFlag } from './limits';
3
+ import { Selector } from './selector';
4
+ import { Flow, Sink } from './sink';
5
+ export type Prune = {
6
+ type: 'never';
7
+ } | {
8
+ type: 'under';
9
+ selector: Selector;
10
+ } | {
11
+ type: 'all_arrays';
12
+ };
13
+ export declare const Prune: Readonly<{
14
+ never(): Prune;
15
+ under(selector: Selector): Prune;
16
+ allArrays(): Prune;
17
+ }>;
18
+ export type SourceMode = {
19
+ type: 'materialize';
20
+ } | {
21
+ type: 'incremental';
22
+ prune: Prune;
23
+ };
24
+ export declare const SourceMode: Readonly<{
25
+ materialize(): SourceMode;
26
+ incremental(prune?: Prune): SourceMode;
27
+ }>;
28
+ export interface Source {
29
+ run(sink: Sink): Flow;
30
+ }
31
+ export declare function engineFailure(error: unknown, abort: AbortFlag): Fail;
32
+ export declare function walkValue(value: unknown, sink: Sink): Flow;
33
+ export declare class ValueSource implements Source {
34
+ readonly value: unknown;
35
+ constructor(value: unknown);
36
+ run(sink: Sink): Flow;
37
+ }
package/dist/source.js ADDED
@@ -0,0 +1,113 @@
1
+ "use strict";
2
+ /* Copyright (c) 2026 tabnas, MIT License */
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.ValueSource = exports.SourceMode = exports.Prune = void 0;
5
+ exports.engineFailure = engineFailure;
6
+ exports.walkValue = walkValue;
7
+ // Sources: where `JsonEvents/1` come from.
8
+ //
9
+ // - `ValueSource` walks a parsed engine value. Always correct, retains the
10
+ // whole value: the fallback for every grammar.
11
+ // - `ParserSource` drives a tabnas parse of one text and, in incremental
12
+ // mode, turns its rule events into source events as they happen, for the
13
+ // grammars the differential suite has verified (`capability`); in
14
+ // materialize mode it parses and walks.
15
+ // - `LinesSource` reads JSON Lines or CSV a record (or a chunk of records)
16
+ // at a time, bounding memory whatever the input's size.
17
+ //
18
+ // Every source emits through `Guarded`, which enforces the source limits,
19
+ // polls the abort flag and counts the source metrics.
20
+ const error_1 = require("./error");
21
+ const event_1 = require("./event");
22
+ const value_1 = require("./value");
23
+ exports.Prune = Object.freeze({
24
+ never() {
25
+ return { type: 'never' };
26
+ },
27
+ under(selector) {
28
+ return { type: 'under', selector };
29
+ },
30
+ allArrays() {
31
+ return { type: 'all_arrays' };
32
+ },
33
+ });
34
+ exports.SourceMode = Object.freeze({
35
+ materialize() {
36
+ return { type: 'materialize' };
37
+ },
38
+ incremental(prune = exports.Prune.never()) {
39
+ return { type: 'incremental', prune };
40
+ },
41
+ });
42
+ // The engine's cancel code: what a cancelled parse reports, whether the
43
+ // canceller is this crate's abort or a guard of the grammar's own.
44
+ const CANCEL = 'cancel';
45
+ // Map an engine error to a failure. A cancel while the caller's flag is set
46
+ // is `ABORTED`. A cancel otherwise is a guard the GRAMMAR installed, so
47
+ // the message says so instead of "parse cancelled", which would read as
48
+ // the caller's doing; it stays `INPUT_INVALID`, because the document is
49
+ // what the grammar refused. Any other error is the input's, with the
50
+ // engine's code and position. A thrown value that is not an engine error
51
+ // (a grammar's plugin threw) is the input's too, without a position.
52
+ function engineFailure(error, abort) {
53
+ if (error instanceof error_1.Fail)
54
+ return error;
55
+ if (CANCEL !== (0, error_1.engineCode)(error))
56
+ return error_1.Fail.fromTabnas(error);
57
+ if (abort.isAborted())
58
+ return error_1.Fail.aborted();
59
+ const fail = error_1.Fail.fromTabnas(error);
60
+ fail.message =
61
+ `the grammar stopped the parse with a guard of its own (${(0, error_1.engineCode)(error)}: ` +
62
+ `${(0, error_1.engineDetail)(error)}); a grammar may refuse nesting or size below this crate's Limits`;
63
+ return fail;
64
+ }
65
+ // Emit one engine value's events (without `end`). `undefined` is `null`,
66
+ // as the engine serializes it; an object's members are in insertion order.
67
+ function walkValue(value, sink) {
68
+ if (Array.isArray(value)) {
69
+ if ('stop' === sink.event(event_1.Ev.arrayStart))
70
+ return 'stop';
71
+ for (const item of value) {
72
+ if ('stop' === walkValue(item, sink))
73
+ return 'stop';
74
+ }
75
+ return sink.event(event_1.Ev.arrayEnd);
76
+ }
77
+ const scalar = (0, value_1.engineScalar)(value);
78
+ if (undefined !== scalar) {
79
+ switch (scalar.type) {
80
+ case 'null':
81
+ return sink.event(event_1.Ev.null);
82
+ case 'bool':
83
+ return sink.event(event_1.Ev.bool(scalar.value));
84
+ case 'number':
85
+ return sink.event(event_1.Ev.number(scalar.value));
86
+ case 'string':
87
+ return sink.event(event_1.Ev.string(scalar.value));
88
+ }
89
+ }
90
+ if ('stop' === sink.event(event_1.Ev.objectStart))
91
+ return 'stop';
92
+ for (const k of (0, value_1.engineKeys)(value)) {
93
+ if ('stop' === sink.event(event_1.Ev.key(k)))
94
+ return 'stop';
95
+ if ('stop' === walkValue(value[k], sink))
96
+ return 'stop';
97
+ }
98
+ return sink.event(event_1.Ev.objectEnd);
99
+ }
100
+ // Emit a parsed engine value as events, ending with `end`. Applies no
101
+ // limits: wrap the sink in `Guarded` for those.
102
+ class ValueSource {
103
+ constructor(value) {
104
+ this.value = value;
105
+ }
106
+ run(sink) {
107
+ if ('stop' === walkValue(this.value, sink))
108
+ return 'stop';
109
+ return sink.event(event_1.Ev.end);
110
+ }
111
+ }
112
+ exports.ValueSource = ValueSource;
113
+ //# sourceMappingURL=source.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"source.js","sourceRoot":"","sources":["../src/source.ts"],"names":[],"mappings":"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"}