stream-validate 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.
package/dist/parser.js ADDED
@@ -0,0 +1,257 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.IncrementalJsonParser = void 0;
4
+ /**
5
+ * Incremental JSON parser that emits ParsedField events as object fields complete.
6
+ * Uses a buffering + scanning approach: buffer incoming chunks, scan for complete
7
+ * JSON values using balanced delimiter counting.
8
+ */
9
+ class IncrementalJsonParser {
10
+ buf = '';
11
+ streamPos = 0; // cumulative position in overall stream
12
+ scanPos = 0; // where in buf we've already scanned
13
+ feed(chunk) {
14
+ this.buf += chunk;
15
+ this.streamPos += chunk.length;
16
+ return this.scan();
17
+ }
18
+ end() {
19
+ // Flush: attempt to parse whatever remains as a complete object
20
+ const remaining = this.buf.slice(this.scanPos).trim();
21
+ if (!remaining)
22
+ return [];
23
+ try {
24
+ const val = JSON.parse(remaining);
25
+ if (val !== null && typeof val === 'object' && !Array.isArray(val)) {
26
+ return this.extractFields(val, '', this.streamPos);
27
+ }
28
+ }
29
+ catch {
30
+ // incomplete/malformed — nothing more to emit
31
+ }
32
+ return [];
33
+ }
34
+ insideObject = false;
35
+ scan() {
36
+ const fields = [];
37
+ // Find the opening '{' if we haven't entered the object yet
38
+ if (!this.insideObject) {
39
+ const openIdx = this.buf.indexOf('{');
40
+ if (openIdx === -1)
41
+ return fields;
42
+ this.insideObject = true;
43
+ this.scanPos = openIdx + 1;
44
+ }
45
+ // Continue scanning for key-value pairs from scanPos
46
+ let pos = this.scanPos;
47
+ while (pos < this.buf.length) {
48
+ // Skip whitespace
49
+ pos = this.skipWhitespace(this.buf, pos);
50
+ if (pos >= this.buf.length)
51
+ break;
52
+ const ch = this.buf[pos];
53
+ // End of object
54
+ if (ch === '}') {
55
+ this.scanPos = pos + 1;
56
+ break;
57
+ }
58
+ // Skip commas between fields
59
+ if (ch === ',') {
60
+ pos++;
61
+ continue;
62
+ }
63
+ // Expect a key (string)
64
+ if (ch !== '"') {
65
+ pos++;
66
+ continue;
67
+ }
68
+ // Parse the key
69
+ const keyResult = this.parseString(this.buf, pos);
70
+ if (keyResult === null)
71
+ break; // incomplete key, wait for more data
72
+ const { value: key, endPos: afterKey } = keyResult;
73
+ // Skip whitespace and colon
74
+ let p = this.skipWhitespace(this.buf, afterKey);
75
+ if (p >= this.buf.length)
76
+ break;
77
+ if (this.buf[p] !== ':') {
78
+ pos = p + 1;
79
+ continue;
80
+ }
81
+ p++;
82
+ // Skip whitespace before value
83
+ p = this.skipWhitespace(this.buf, p);
84
+ if (p >= this.buf.length)
85
+ break;
86
+ // Parse the value
87
+ const valResult = this.parseValue(this.buf, p);
88
+ if (valResult === null)
89
+ break; // incomplete value, wait for more data
90
+ const { value, endPos: afterVal } = valResult;
91
+ const absPos = this.streamPos - this.buf.length + afterVal;
92
+ // Emit leaf fields for this value
93
+ const subFields = this.extractFields({ [key]: value }, '', absPos);
94
+ fields.push(...subFields);
95
+ this.scanPos = afterVal;
96
+ pos = afterVal;
97
+ }
98
+ return fields;
99
+ }
100
+ skipWhitespace(s, pos) {
101
+ while (pos < s.length && /\s/.test(s[pos]))
102
+ pos++;
103
+ return pos;
104
+ }
105
+ /**
106
+ * Parse a JSON string starting at pos (which must be `"`).
107
+ * Returns { value, endPos } where endPos is one past the closing `"`, or null if incomplete.
108
+ */
109
+ parseString(s, pos) {
110
+ if (s[pos] !== '"')
111
+ return null;
112
+ let i = pos + 1;
113
+ while (i < s.length) {
114
+ if (s[i] === '\\') {
115
+ i += 2; // skip escaped character
116
+ continue;
117
+ }
118
+ if (s[i] === '"') {
119
+ const raw = s.slice(pos, i + 1);
120
+ try {
121
+ return { value: JSON.parse(raw), endPos: i + 1 };
122
+ }
123
+ catch {
124
+ return null;
125
+ }
126
+ }
127
+ i++;
128
+ }
129
+ return null; // incomplete
130
+ }
131
+ /**
132
+ * Parse any JSON value starting at pos.
133
+ * Returns { value, endPos } or null if incomplete.
134
+ */
135
+ parseValue(s, pos) {
136
+ if (pos >= s.length)
137
+ return null;
138
+ const ch = s[pos];
139
+ if (ch === '"') {
140
+ return this.parseString(s, pos);
141
+ }
142
+ if (ch === '{' || ch === '[') {
143
+ return this.parseBalanced(s, pos);
144
+ }
145
+ // null, true, false
146
+ const literals = [
147
+ ['null', null],
148
+ ['true', true],
149
+ ['false', false],
150
+ ];
151
+ for (const [lit, val] of literals) {
152
+ if (s.startsWith(lit, pos)) {
153
+ return { value: val, endPos: pos + lit.length };
154
+ }
155
+ }
156
+ // Number: ends at `,`, `}`, `]`, whitespace
157
+ const numMatch = s.slice(pos).match(/^-?(?:0|[1-9]\d*)(?:\.\d+)?(?:[eE][+-]?\d+)?/);
158
+ if (numMatch) {
159
+ const numStr = numMatch[0];
160
+ // Make sure the number is actually complete (followed by delimiter or end of known token)
161
+ const afterNum = pos + numStr.length;
162
+ if (afterNum >= s.length) {
163
+ // Could be incomplete (e.g. "1" might become "123") — only safe if followed by delimiter
164
+ // Check if next non-whitespace is a delimiter
165
+ const next = this.skipWhitespace(s, afterNum);
166
+ if (next >= s.length)
167
+ return null; // wait for more
168
+ const nextCh = s[next];
169
+ if (nextCh === ',' || nextCh === '}' || nextCh === ']') {
170
+ return { value: JSON.parse(numStr), endPos: afterNum };
171
+ }
172
+ return null;
173
+ }
174
+ return { value: JSON.parse(numStr), endPos: afterNum };
175
+ }
176
+ return null;
177
+ }
178
+ /**
179
+ * Parse a balanced `{...}` or `[...]` block.
180
+ */
181
+ parseBalanced(s, pos) {
182
+ const open = s[pos];
183
+ const close = open === '{' ? '}' : ']';
184
+ let depth = 0;
185
+ let i = pos;
186
+ let inString = false;
187
+ while (i < s.length) {
188
+ const ch = s[i];
189
+ if (inString) {
190
+ if (ch === '\\') {
191
+ i += 2;
192
+ continue;
193
+ }
194
+ if (ch === '"')
195
+ inString = false;
196
+ }
197
+ else {
198
+ if (ch === '"')
199
+ inString = true;
200
+ else if (ch === open)
201
+ depth++;
202
+ else if (ch === close) {
203
+ depth--;
204
+ if (depth === 0) {
205
+ const raw = s.slice(pos, i + 1);
206
+ try {
207
+ return { value: JSON.parse(raw), endPos: i + 1 };
208
+ }
209
+ catch {
210
+ return null;
211
+ }
212
+ }
213
+ }
214
+ }
215
+ i++;
216
+ }
217
+ return null; // incomplete
218
+ }
219
+ /**
220
+ * Recursively extract leaf fields from a (possibly nested) object/value,
221
+ * emitting one ParsedField per leaf.
222
+ */
223
+ extractFields(obj, prefix, absPos) {
224
+ const fields = [];
225
+ if (obj !== null && typeof obj === 'object' && !Array.isArray(obj)) {
226
+ for (const [k, v] of Object.entries(obj)) {
227
+ const path = prefix ? `${prefix}.${k}` : k;
228
+ if (v !== null && typeof v === 'object' && !Array.isArray(v)) {
229
+ fields.push(...this.extractFields(v, path, absPos));
230
+ }
231
+ else if (Array.isArray(v)) {
232
+ // Emit the array as a single field (with path), plus individual items
233
+ fields.push({ path, value: v, position: absPos });
234
+ for (let idx = 0; idx < v.length; idx++) {
235
+ fields.push(...this.extractFields(v[idx], `${path}[${idx}]`, absPos));
236
+ }
237
+ }
238
+ else {
239
+ fields.push({ path, value: v, position: absPos });
240
+ }
241
+ }
242
+ }
243
+ else if (Array.isArray(obj)) {
244
+ for (let idx = 0; idx < obj.length; idx++) {
245
+ fields.push(...this.extractFields(obj[idx], `${prefix}[${idx}]`, absPos));
246
+ }
247
+ }
248
+ else {
249
+ if (prefix) {
250
+ fields.push({ path: prefix, value: obj, position: absPos });
251
+ }
252
+ }
253
+ return fields;
254
+ }
255
+ }
256
+ exports.IncrementalJsonParser = IncrementalJsonParser;
257
+ //# sourceMappingURL=parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"parser.js","sourceRoot":"","sources":["../src/parser.ts"],"names":[],"mappings":";;;AAMA;;;;GAIG;AACH,MAAa,qBAAqB;IACxB,GAAG,GAAG,EAAE,CAAA;IACR,SAAS,GAAG,CAAC,CAAA,CAAG,wCAAwC;IACxD,OAAO,GAAG,CAAC,CAAA,CAAK,qCAAqC;IAE7D,IAAI,CAAC,KAAa;QAChB,IAAI,CAAC,GAAG,IAAI,KAAK,CAAA;QACjB,IAAI,CAAC,SAAS,IAAI,KAAK,CAAC,MAAM,CAAA;QAC9B,OAAO,IAAI,CAAC,IAAI,EAAE,CAAA;IACpB,CAAC;IAED,GAAG;QACD,gEAAgE;QAChE,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,CAAA;QACrD,IAAI,CAAC,SAAS;YAAE,OAAO,EAAE,CAAA;QACzB,IAAI,CAAC;YACH,MAAM,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,SAAS,CAAC,CAAA;YACjC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;gBACnE,OAAO,IAAI,CAAC,aAAa,CAAC,GAA8B,EAAE,EAAE,EAAE,IAAI,CAAC,SAAS,CAAC,CAAA;YAC/E,CAAC;QACH,CAAC;QAAC,MAAM,CAAC;YACP,8CAA8C;QAChD,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAEO,YAAY,GAAG,KAAK,CAAA;IAEpB,IAAI;QACV,MAAM,MAAM,GAAkB,EAAE,CAAA;QAEhC,4DAA4D;QAC5D,IAAI,CAAC,IAAI,CAAC,YAAY,EAAE,CAAC;YACvB,MAAM,OAAO,GAAG,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,GAAG,CAAC,CAAA;YACrC,IAAI,OAAO,KAAK,CAAC,CAAC;gBAAE,OAAO,MAAM,CAAA;YACjC,IAAI,CAAC,YAAY,GAAG,IAAI,CAAA;YACxB,IAAI,CAAC,OAAO,GAAG,OAAO,GAAG,CAAC,CAAA;QAC5B,CAAC;QAED,qDAAqD;QACrD,IAAI,GAAG,GAAG,IAAI,CAAC,OAAO,CAAA;QAEtB,OAAO,GAAG,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC;YAC7B,kBAAkB;YAClB,GAAG,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YACxC,IAAI,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,MAAK;YAEjC,MAAM,EAAE,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YAExB,gBAAgB;YAChB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACf,IAAI,CAAC,OAAO,GAAG,GAAG,GAAG,CAAC,CAAA;gBACtB,MAAK;YACP,CAAC;YAED,6BAA6B;YAC7B,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACf,GAAG,EAAE,CAAA;gBACL,SAAQ;YACV,CAAC;YAED,wBAAwB;YACxB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;gBACf,GAAG,EAAE,CAAA;gBACL,SAAQ;YACV,CAAC;YAED,gBAAgB;YAChB,MAAM,SAAS,GAAG,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,CAAA;YACjD,IAAI,SAAS,KAAK,IAAI;gBAAE,MAAK,CAAE,qCAAqC;YACpE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAA;YAElD,4BAA4B;YAC5B,IAAI,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAA;YAC/C,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,MAAK;YAC/B,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBAAC,GAAG,GAAG,CAAC,GAAG,CAAC,CAAC;gBAAC,SAAQ;YAAC,CAAC;YAClD,CAAC,EAAE,CAAA;YAEH,+BAA+B;YAC/B,CAAC,GAAG,IAAI,CAAC,cAAc,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YACpC,IAAI,CAAC,IAAI,IAAI,CAAC,GAAG,CAAC,MAAM;gBAAE,MAAK;YAE/B,kBAAkB;YAClB,MAAM,SAAS,GAAG,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,CAAA;YAC9C,IAAI,SAAS,KAAK,IAAI;gBAAE,MAAK,CAAE,uCAAuC;YAEtE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,EAAE,GAAG,SAAS,CAAA;YAC7C,MAAM,MAAM,GAAG,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,GAAG,CAAC,MAAM,GAAG,QAAQ,CAAA;YAE1D,kCAAkC;YAClC,MAAM,SAAS,GAAG,IAAI,CAAC,aAAa,CAClC,EAAE,CAAC,GAAa,CAAC,EAAE,KAAK,EAAE,EAC1B,EAAE,EACF,MAAM,CACP,CAAA;YACD,MAAM,CAAC,IAAI,CAAC,GAAG,SAAS,CAAC,CAAA;YAEzB,IAAI,CAAC,OAAO,GAAG,QAAQ,CAAA;YACvB,GAAG,GAAG,QAAQ,CAAA;QAChB,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;IAEO,cAAc,CAAC,CAAS,EAAE,GAAW;QAC3C,OAAO,GAAG,GAAG,CAAC,CAAC,MAAM,IAAI,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAAE,GAAG,EAAE,CAAA;QACjD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED;;;OAGG;IACK,WAAW,CAAC,CAAS,EAAE,GAAW;QACxC,IAAI,CAAC,CAAC,GAAG,CAAC,KAAK,GAAG;YAAE,OAAO,IAAI,CAAA;QAC/B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,CAAA;QACf,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACpB,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC;gBAClB,CAAC,IAAI,CAAC,CAAA,CAAE,yBAAyB;gBACjC,SAAQ;YACV,CAAC;YACD,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,EAAE,CAAC;gBACjB,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;gBAC/B,IAAI,CAAC;oBACH,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAW,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAA;gBAC5D,CAAC;gBAAC,MAAM,CAAC;oBACP,OAAO,IAAI,CAAA;gBACb,CAAC;YACH,CAAC;YACD,CAAC,EAAE,CAAA;QACL,CAAC;QACD,OAAO,IAAI,CAAA,CAAE,aAAa;IAC5B,CAAC;IAED;;;OAGG;IACK,UAAU,CAAC,CAAS,EAAE,GAAW;QACvC,IAAI,GAAG,IAAI,CAAC,CAAC,MAAM;YAAE,OAAO,IAAI,CAAA;QAChC,MAAM,EAAE,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QAEjB,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YACf,OAAO,IAAI,CAAC,WAAW,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACjC,CAAC;QAED,IAAI,EAAE,KAAK,GAAG,IAAI,EAAE,KAAK,GAAG,EAAE,CAAC;YAC7B,OAAO,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QACnC,CAAC;QAED,oBAAoB;QACpB,MAAM,QAAQ,GAA6B;YACzC,CAAC,MAAM,EAAE,IAAI,CAAC;YACd,CAAC,MAAM,EAAE,IAAI,CAAC;YACd,CAAC,OAAO,EAAE,KAAK,CAAC;SACjB,CAAA;QACD,KAAK,MAAM,CAAC,GAAG,EAAE,GAAG,CAAC,IAAI,QAAQ,EAAE,CAAC;YAClC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,EAAE,GAAG,CAAC,EAAE,CAAC;gBAC3B,OAAO,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,GAAG,GAAG,CAAC,MAAM,EAAE,CAAA;YACjD,CAAC;QACH,CAAC;QAED,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,KAAK,CAAC,8CAA8C,CAAC,CAAA;QACnF,IAAI,QAAQ,EAAE,CAAC;YACb,MAAM,MAAM,GAAG,QAAQ,CAAC,CAAC,CAAC,CAAA;YAC1B,0FAA0F;YAC1F,MAAM,QAAQ,GAAG,GAAG,GAAG,MAAM,CAAC,MAAM,CAAA;YACpC,IAAI,QAAQ,IAAI,CAAC,CAAC,MAAM,EAAE,CAAC;gBACzB,yFAAyF;gBACzF,8CAA8C;gBAC9C,MAAM,IAAI,GAAG,IAAI,CAAC,cAAc,CAAC,CAAC,EAAE,QAAQ,CAAC,CAAA;gBAC7C,IAAI,IAAI,IAAI,CAAC,CAAC,MAAM;oBAAE,OAAO,IAAI,CAAA,CAAE,gBAAgB;gBACnD,MAAM,MAAM,GAAG,CAAC,CAAC,IAAI,CAAC,CAAA;gBACtB,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;oBACvD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;gBACxD,CAAC;gBACD,OAAO,IAAI,CAAA;YACb,CAAC;YACD,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,MAAM,EAAE,QAAQ,EAAE,CAAA;QACxD,CAAC;QAED,OAAO,IAAI,CAAA;IACb,CAAC;IAED;;OAEG;IACK,aAAa,CAAC,CAAS,EAAE,GAAW;QAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,GAAG,CAAC,CAAA;QACnB,MAAM,KAAK,GAAG,IAAI,KAAK,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAA;QACtC,IAAI,KAAK,GAAG,CAAC,CAAA;QACb,IAAI,CAAC,GAAG,GAAG,CAAA;QACX,IAAI,QAAQ,GAAG,KAAK,CAAA;QAEpB,OAAO,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC;YACpB,MAAM,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAA;YACf,IAAI,QAAQ,EAAE,CAAC;gBACb,IAAI,EAAE,KAAK,IAAI,EAAE,CAAC;oBAAC,CAAC,IAAI,CAAC,CAAC;oBAAC,SAAQ;gBAAC,CAAC;gBACrC,IAAI,EAAE,KAAK,GAAG;oBAAE,QAAQ,GAAG,KAAK,CAAA;YAClC,CAAC;iBAAM,CAAC;gBACN,IAAI,EAAE,KAAK,GAAG;oBAAE,QAAQ,GAAG,IAAI,CAAA;qBAC1B,IAAI,EAAE,KAAK,IAAI;oBAAE,KAAK,EAAE,CAAA;qBACxB,IAAI,EAAE,KAAK,KAAK,EAAE,CAAC;oBACtB,KAAK,EAAE,CAAA;oBACP,IAAI,KAAK,KAAK,CAAC,EAAE,CAAC;wBAChB,MAAM,GAAG,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,GAAG,CAAC,CAAC,CAAA;wBAC/B,IAAI,CAAC;4BACH,OAAO,EAAE,KAAK,EAAE,IAAI,CAAC,KAAK,CAAC,GAAG,CAAC,EAAE,MAAM,EAAE,CAAC,GAAG,CAAC,EAAE,CAAA;wBAClD,CAAC;wBAAC,MAAM,CAAC;4BACP,OAAO,IAAI,CAAA;wBACb,CAAC;oBACH,CAAC;gBACH,CAAC;YACH,CAAC;YACD,CAAC,EAAE,CAAA;QACL,CAAC;QACD,OAAO,IAAI,CAAA,CAAE,aAAa;IAC5B,CAAC;IAED;;;OAGG;IACK,aAAa,CACnB,GAAsC,EACtC,MAAc,EACd,MAAc;QAEd,MAAM,MAAM,GAAkB,EAAE,CAAA;QAEhC,IAAI,GAAG,KAAK,IAAI,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YACnE,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,GAA8B,CAAC,EAAE,CAAC;gBACpE,MAAM,IAAI,GAAG,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;gBAC1C,IAAI,CAAC,KAAK,IAAI,IAAI,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC7D,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC,CAAA;gBACrD,CAAC;qBAAM,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;oBAC5B,sEAAsE;oBACtE,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;oBACjD,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAG,CAAC,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;wBACxC,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,GAAG,CAAC,EAAE,GAAG,IAAI,IAAI,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;oBACvE,CAAC;gBACH,CAAC;qBAAM,CAAC;oBACN,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;gBACnD,CAAC;YACH,CAAC;QACH,CAAC;aAAM,IAAI,KAAK,CAAC,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC;YAC9B,KAAK,IAAI,GAAG,GAAG,CAAC,EAAE,GAAG,GAAI,GAAiB,CAAC,MAAM,EAAE,GAAG,EAAE,EAAE,CAAC;gBACzD,MAAM,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC,aAAa,CAAE,GAAiB,CAAC,GAAG,CAAC,EAAE,GAAG,MAAM,IAAI,GAAG,GAAG,EAAE,MAAM,CAAC,CAAC,CAAA;YAC1F,CAAC;QACH,CAAC;aAAM,CAAC;YACN,IAAI,MAAM,EAAE,CAAC;gBACX,MAAM,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC,CAAA;YAC7D,CAAC;QACH,CAAC;QAED,OAAO,MAAM,CAAA;IACf,CAAC;CACF;AAlQD,sDAkQC"}
@@ -0,0 +1,9 @@
1
+ import { z } from 'zod';
2
+ import type { StreamValidatorOptions, ValidatedPartial } from './types';
3
+ /**
4
+ * Async generator that consumes an AsyncIterable<string> of JSON chunks,
5
+ * progressively validates each field against the schema, and yields
6
+ * ValidatedPartial<T> events as fields complete.
7
+ */
8
+ export declare function streamValidate<T>(stream: AsyncIterable<string>, schema: z.ZodSchema<T>, options?: StreamValidatorOptions): AsyncIterable<ValidatedPartial<T>>;
9
+ //# sourceMappingURL=stream-validate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-validate.d.ts","sourceRoot":"","sources":["../src/stream-validate.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,OAAO,KAAK,EAAE,sBAAsB,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAEvE;;;;GAIG;AACH,wBAAuB,cAAc,CAAC,CAAC,EACrC,MAAM,EAAE,aAAa,CAAC,MAAM,CAAC,EAC7B,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,OAAO,GAAE,sBAA2B,GACnC,aAAa,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CA0CpC"}
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.streamValidate = streamValidate;
4
+ const stream_validator_1 = require("./stream-validator");
5
+ /**
6
+ * Async generator that consumes an AsyncIterable<string> of JSON chunks,
7
+ * progressively validates each field against the schema, and yields
8
+ * ValidatedPartial<T> events as fields complete.
9
+ */
10
+ async function* streamValidate(stream, schema, options = {}) {
11
+ const validator = (0, stream_validator_1.createStreamValidator)(schema, options);
12
+ // Collect partials via the async iterator from the validator
13
+ // We drive the validator with stream chunks and pull partials as they come.
14
+ // Use a two-pump approach: one for the input stream, one for output.
15
+ const partials = [];
16
+ const completionEvents = [];
17
+ let inputDone = false;
18
+ // Run input pump in background (push chunks to validator)
19
+ const inputDonePromise = (async () => {
20
+ for await (const chunk of stream) {
21
+ validator.write(chunk);
22
+ }
23
+ validator.end();
24
+ inputDone = true;
25
+ })();
26
+ // Subscribe to partial events to collect them
27
+ const unsubPartial = validator.on('partial', (p) => {
28
+ partials.push(p);
29
+ });
30
+ const unsubComplete = validator.on('complete', () => {
31
+ completionEvents.push({ done: true });
32
+ });
33
+ // Wait for input to complete, then flush
34
+ await inputDonePromise;
35
+ unsubPartial();
36
+ unsubComplete();
37
+ // Yield all collected partials
38
+ for (const p of partials) {
39
+ yield p;
40
+ }
41
+ void inputDone; // suppress unused warning
42
+ void completionEvents;
43
+ }
44
+ //# sourceMappingURL=stream-validate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-validate.js","sourceRoot":"","sources":["../src/stream-validate.ts"],"names":[],"mappings":";;AASA,wCA8CC;AAtDD,yDAA0D;AAG1D;;;;GAIG;AACI,KAAK,SAAS,CAAC,CAAC,cAAc,CACnC,MAA6B,EAC7B,MAAsB,EACtB,UAAkC,EAAE;IAEpC,MAAM,SAAS,GAAG,IAAA,wCAAqB,EAAI,MAAM,EAAE,OAAO,CAAC,CAAA;IAE3D,6DAA6D;IAC7D,4EAA4E;IAC5E,qEAAqE;IAErE,MAAM,QAAQ,GAA+B,EAAE,CAAA;IAC/C,MAAM,gBAAgB,GAA6B,EAAE,CAAA;IACrD,IAAI,SAAS,GAAG,KAAK,CAAA;IAErB,0DAA0D;IAC1D,MAAM,gBAAgB,GAAG,CAAC,KAAK,IAAI,EAAE;QACnC,IAAI,KAAK,EAAE,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YACjC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAA;QACxB,CAAC;QACD,SAAS,CAAC,GAAG,EAAE,CAAA;QACf,SAAS,GAAG,IAAI,CAAA;IAClB,CAAC,CAAC,EAAE,CAAA;IAEJ,8CAA8C;IAC9C,MAAM,YAAY,GAAG,SAAS,CAAC,EAAE,CAAC,SAAS,EAAE,CAAC,CAAC,EAAE,EAAE;QACjD,QAAQ,CAAC,IAAI,CAAC,CAAwB,CAAC,CAAA;IACzC,CAAC,CAAC,CAAA;IAEF,MAAM,aAAa,GAAG,SAAS,CAAC,EAAE,CAAC,UAAU,EAAE,GAAG,EAAE;QAClD,gBAAgB,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC,CAAA;IACvC,CAAC,CAAC,CAAA;IAEF,yCAAyC;IACzC,MAAM,gBAAgB,CAAA;IAEtB,YAAY,EAAE,CAAA;IACd,aAAa,EAAE,CAAA;IAEf,+BAA+B;IAC/B,KAAK,MAAM,CAAC,IAAI,QAAQ,EAAE,CAAC;QACzB,MAAM,CAAC,CAAA;IACT,CAAC;IAED,KAAK,SAAS,CAAA,CAAC,0BAA0B;IACzC,KAAK,gBAAgB,CAAA;AACvB,CAAC"}
@@ -0,0 +1,4 @@
1
+ import { z } from 'zod';
2
+ import type { StreamValidator, StreamValidatorOptions } from './types';
3
+ export declare function createStreamValidator<T>(schema: z.ZodSchema<T>, options?: StreamValidatorOptions): StreamValidator<T>;
4
+ //# sourceMappingURL=stream-validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-validator.d.ts","sourceRoot":"","sources":["../src/stream-validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAIvB,OAAO,KAAK,EACV,eAAe,EACf,sBAAsB,EAKvB,MAAM,SAAS,CAAA;AAShB,wBAAgB,qBAAqB,CAAC,CAAC,EACrC,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,EACtB,OAAO,GAAE,sBAA2B,GACnC,eAAe,CAAC,CAAC,CAAC,CAiKpB"}
@@ -0,0 +1,162 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createStreamValidator = createStreamValidator;
4
+ const parser_1 = require("./parser");
5
+ const validator_1 = require("./validator");
6
+ const events_1 = require("./events");
7
+ function createStreamValidator(schema, options = {}) {
8
+ const parser = new parser_1.IncrementalJsonParser();
9
+ const validator = new validator_1.ProgressiveValidator(schema);
10
+ const emitter = new events_1.TypedEmitter();
11
+ const startTime = Date.now();
12
+ let currentPartial = null;
13
+ let done = false;
14
+ const queue = [];
15
+ const waiters = [];
16
+ function enqueue(item) {
17
+ if (waiters.length > 0) {
18
+ const resolve = waiters.shift();
19
+ resolve(item);
20
+ }
21
+ else {
22
+ queue.push(item);
23
+ }
24
+ }
25
+ function processFields(fields) {
26
+ for (const field of fields) {
27
+ const { partial, error } = validator.applyField(field.path, field.value, {
28
+ strategy: options.validationErrorStrategy ?? 'skip',
29
+ });
30
+ currentPartial = partial;
31
+ if (error) {
32
+ emitter.emit('validation-error', error);
33
+ options.onValidationError?.(error);
34
+ }
35
+ emitter.emit('partial', partial);
36
+ enqueue({ value: partial, done: false });
37
+ if (partial.isComplete && !done) {
38
+ done = true;
39
+ emitComplete(false);
40
+ }
41
+ }
42
+ }
43
+ function emitComplete(truncated) {
44
+ const totalMs = Date.now() - startTime;
45
+ const meta = currentPartial?.meta ?? {};
46
+ const requiredPaths = validator.getRequiredPaths();
47
+ const completedFields = Object.values(meta).filter(s => s === 'complete').length;
48
+ const totalFields = requiredPaths.length || Object.keys(meta).length;
49
+ const event = {
50
+ data: (currentPartial?.data ?? {}),
51
+ isComplete: !truncated && validator.isComplete(),
52
+ truncated,
53
+ totalMs,
54
+ completedFields,
55
+ totalFields,
56
+ failedPaths: validator.getFailedPaths(),
57
+ };
58
+ emitter.emit('complete', event);
59
+ enqueue({ done: true });
60
+ }
61
+ // Timeout handling
62
+ let timeoutHandle;
63
+ if (options.timeoutMs) {
64
+ timeoutHandle = setTimeout(() => {
65
+ if (!done) {
66
+ done = true;
67
+ emitComplete(true);
68
+ }
69
+ }, options.timeoutMs);
70
+ }
71
+ // AbortSignal handling
72
+ if (options.signal) {
73
+ options.signal.addEventListener('abort', () => {
74
+ if (!done) {
75
+ done = true;
76
+ if (timeoutHandle)
77
+ clearTimeout(timeoutHandle);
78
+ emitComplete(true);
79
+ }
80
+ });
81
+ }
82
+ const streamValidator = {
83
+ write(chunk) {
84
+ if (done)
85
+ return;
86
+ try {
87
+ const fields = parser.feed(chunk);
88
+ processFields(fields);
89
+ }
90
+ catch (err) {
91
+ const parseErr = {
92
+ message: err instanceof Error ? err.message : String(err),
93
+ position: 0,
94
+ path: '',
95
+ elapsedMs: Date.now() - startTime,
96
+ };
97
+ emitter.emit('parse-error', parseErr);
98
+ options.onParseError?.(parseErr);
99
+ }
100
+ },
101
+ end() {
102
+ if (done)
103
+ return;
104
+ try {
105
+ const fields = parser.end();
106
+ processFields(fields);
107
+ }
108
+ catch (err) {
109
+ const parseErr = {
110
+ message: err instanceof Error ? err.message : String(err),
111
+ position: 0,
112
+ path: '',
113
+ elapsedMs: Date.now() - startTime,
114
+ };
115
+ emitter.emit('parse-error', parseErr);
116
+ options.onParseError?.(parseErr);
117
+ }
118
+ if (!done) {
119
+ done = true;
120
+ if (timeoutHandle)
121
+ clearTimeout(timeoutHandle);
122
+ emitComplete(false);
123
+ }
124
+ },
125
+ abort(_error) {
126
+ if (done)
127
+ return;
128
+ done = true;
129
+ if (timeoutHandle)
130
+ clearTimeout(timeoutHandle);
131
+ emitComplete(true);
132
+ },
133
+ on(event, fn) {
134
+ return emitter.on(event, fn);
135
+ },
136
+ get current() {
137
+ return currentPartial;
138
+ },
139
+ [Symbol.asyncIterator]() {
140
+ return {
141
+ next() {
142
+ if (queue.length > 0) {
143
+ const item = queue.shift();
144
+ if (item.done)
145
+ return Promise.resolve({ value: undefined, done: true });
146
+ return Promise.resolve({ value: item.value, done: false });
147
+ }
148
+ return new Promise(resolve => {
149
+ waiters.push((item) => {
150
+ if (item.done)
151
+ resolve({ value: undefined, done: true });
152
+ else
153
+ resolve({ value: item.value, done: false });
154
+ });
155
+ });
156
+ },
157
+ };
158
+ },
159
+ };
160
+ return streamValidator;
161
+ }
162
+ //# sourceMappingURL=stream-validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stream-validator.js","sourceRoot":"","sources":["../src/stream-validator.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,54 @@
1
+ import type { z } from 'zod';
2
+ export type DeepPartial<T> = T extends object ? {
3
+ [P in keyof T]?: DeepPartial<T[P]>;
4
+ } : T;
5
+ export type FieldStatus = 'complete' | 'active' | 'pending' | 'error';
6
+ export type FieldMeta = Record<string, FieldStatus>;
7
+ export interface ValidatedPartial<T> {
8
+ data: DeepPartial<T>;
9
+ meta: FieldMeta;
10
+ isComplete: boolean;
11
+ seq: number;
12
+ elapsedMs: number;
13
+ }
14
+ export interface StreamCompletionEvent<T> {
15
+ data: T | DeepPartial<T>;
16
+ isComplete: boolean;
17
+ truncated: boolean;
18
+ totalMs: number;
19
+ completedFields: number;
20
+ totalFields: number;
21
+ failedPaths: string[];
22
+ }
23
+ export interface StreamValidationError {
24
+ path: string;
25
+ value: unknown;
26
+ message: string;
27
+ elapsedMs: number;
28
+ }
29
+ export interface StreamParseError {
30
+ message: string;
31
+ position: number;
32
+ path: string;
33
+ elapsedMs: number;
34
+ }
35
+ export interface StreamValidatorOptions {
36
+ onParseError?: (err: StreamParseError) => void;
37
+ onValidationError?: (err: StreamValidationError) => void;
38
+ validationErrorStrategy?: 'skip' | 'include-invalid' | 'error';
39
+ timeoutMs?: number;
40
+ signal?: AbortSignal;
41
+ }
42
+ export interface StreamValidator<T> {
43
+ write(chunk: string): void;
44
+ end(): void;
45
+ abort(error?: Error): void;
46
+ on(event: 'partial', fn: (p: ValidatedPartial<T>) => void): () => void;
47
+ on(event: 'complete', fn: (e: StreamCompletionEvent<T>) => void): () => void;
48
+ on(event: 'parse-error', fn: (e: StreamParseError) => void): () => void;
49
+ on(event: 'validation-error', fn: (e: StreamValidationError) => void): () => void;
50
+ get current(): ValidatedPartial<T> | null;
51
+ [Symbol.asyncIterator](): AsyncIterator<ValidatedPartial<T>>;
52
+ }
53
+ export type _ZodSchemaRef = z.ZodSchema<unknown>;
54
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
package/dist/types.js ADDED
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,23 @@
1
+ import { z } from 'zod';
2
+ import type { ValidatedPartial, StreamValidationError } from './types';
3
+ export declare class ProgressiveValidator<T> {
4
+ private schema;
5
+ private data;
6
+ private meta;
7
+ private seq;
8
+ private startTime;
9
+ private requiredPaths;
10
+ private failedPaths;
11
+ constructor(schema: z.ZodSchema<T>);
12
+ applyField(path: string, value: unknown, options?: {
13
+ strategy?: 'skip' | 'include-invalid' | 'error';
14
+ }): {
15
+ partial: ValidatedPartial<T>;
16
+ error?: StreamValidationError;
17
+ };
18
+ isComplete(): boolean;
19
+ getFailedPaths(): string[];
20
+ getRequiredPaths(): string[];
21
+ buildPartial(): ValidatedPartial<T>;
22
+ }
23
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../src/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AACvB,OAAO,KAAK,EAAE,gBAAgB,EAA0B,qBAAqB,EAAE,MAAM,SAAS,CAAA;AAoF9F,qBAAa,oBAAoB,CAAC,CAAC;IAQrB,OAAO,CAAC,MAAM;IAP1B,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,GAAG,CAAI;IACf,OAAO,CAAC,SAAS,CAAa;IAC9B,OAAO,CAAC,aAAa,CAAU;IAC/B,OAAO,CAAC,WAAW,CAAe;gBAEd,MAAM,EAAE,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC;IAI1C,UAAU,CACR,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;QAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,iBAAiB,GAAG,OAAO,CAAA;KAAE,GAC5D;QAAE,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,CAAC;QAAC,KAAK,CAAC,EAAE,qBAAqB,CAAA;KAAE;IAsClE,UAAU,IAAI,OAAO;IAQrB,cAAc,IAAI,MAAM,EAAE;IAI1B,gBAAgB,IAAI,MAAM,EAAE;IAI5B,YAAY,IAAI,gBAAgB,CAAC,CAAC,CAAC;CASpC"}