@pretable/stream-adapter 0.9.0 → 0.11.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/index.mjs CHANGED
@@ -1,374 +1,409 @@
1
- import { create, push, isArrayNode, isComplete, finish, isObjectNode } from '@cacheplane/json-stream';
1
+ import { create, finish, isArrayNode, isComplete, isObjectNode, push } from "@cacheplane/json-stream";
2
2
 
3
- // src/create-batcher.ts
3
+ //#region src/create-batcher.ts
4
+ /**
5
+ * Create a `requestAnimationFrame`-batched mutator that coalesces
6
+ * `add` / `update` / `remove` calls into a single `applyTransaction` per
7
+ * frame. Use this when driving a row model from a stream that emits faster
8
+ * than the browser can render.
9
+ *
10
+ * @example
11
+ * ```ts
12
+ * const batcher = createBatcher(rowModel);
13
+ * batcher.add([{ id: "1", name: "Ada" }]);
14
+ * batcher.update([{ id: "1", changes: { age: 36 } }]);
15
+ * batcher.flush(); // optional — RAF will flush automatically
16
+ * ```
17
+ *
18
+ * @public
19
+ */
4
20
  function createBatcher(rowModel) {
5
- let addBuffer = [];
6
- let updateBuffer = [];
7
- let removeBuffer = [];
8
- let rafId = null;
9
- let disposed = false;
10
- let rejectError;
11
- const errorListeners = /* @__PURE__ */ new Set();
12
- let failed = false;
13
- let failure;
14
- const error = new Promise((_resolve, reject) => {
15
- rejectError = reject;
16
- });
17
- error.catch(() => void 0);
18
- function fail(error2) {
19
- if (disposed) return;
20
- disposed = true;
21
- failed = true;
22
- failure = error2;
23
- if (rafId !== null) {
24
- cancelAnimationFrame(rafId);
25
- rafId = null;
26
- }
27
- addBuffer = [];
28
- updateBuffer = [];
29
- removeBuffer = [];
30
- const listeners = [...errorListeners];
31
- errorListeners.clear();
32
- for (const listener of listeners) {
33
- try {
34
- listener(error2);
35
- } catch {
36
- }
37
- }
38
- rejectError(error2);
39
- }
40
- function scheduleFlush() {
41
- if (rafId !== null || disposed) return;
42
- rafId = requestAnimationFrame(() => {
43
- rafId = null;
44
- if (disposed) return;
45
- try {
46
- applyBuffered();
47
- } catch (error2) {
48
- fail(error2);
49
- }
50
- });
51
- }
52
- function applyBuffered() {
53
- if (addBuffer.length === 0 && updateBuffer.length === 0 && removeBuffer.length === 0) {
54
- return;
55
- }
56
- const bufferedAdds = addBuffer;
57
- const bufferedUpdates = updateBuffer;
58
- const bufferedRemovals = removeBuffer;
59
- addBuffer = [];
60
- updateBuffer = [];
61
- removeBuffer = [];
62
- const transaction = {};
63
- if (bufferedAdds.length > 0) {
64
- transaction.add = bufferedAdds.map((row) => ({ ...row }));
65
- }
66
- if (bufferedUpdates.length > 0) {
67
- transaction.update = bufferedUpdates.map(({ id, changes }) => ({
68
- id,
69
- changes: { ...changes }
70
- }));
71
- }
72
- if (bufferedRemovals.length > 0) {
73
- transaction.remove = [...bufferedRemovals];
74
- }
75
- rowModel.applyTransaction(transaction);
76
- }
77
- return {
78
- error,
79
- subscribeError(listener) {
80
- if (failed) {
81
- try {
82
- listener(failure);
83
- } catch {
84
- }
85
- return () => void 0;
86
- }
87
- if (disposed) return () => void 0;
88
- errorListeners.add(listener);
89
- return () => errorListeners.delete(listener);
90
- },
91
- add(rows) {
92
- if (disposed) return;
93
- addBuffer.push(...rows);
94
- scheduleFlush();
95
- },
96
- update(patches) {
97
- if (disposed) return;
98
- updateBuffer.push(...patches);
99
- scheduleFlush();
100
- },
101
- remove(ids) {
102
- if (disposed) return;
103
- removeBuffer.push(...ids);
104
- scheduleFlush();
105
- },
106
- flush() {
107
- if (disposed) return;
108
- if (rafId !== null) {
109
- cancelAnimationFrame(rafId);
110
- rafId = null;
111
- }
112
- applyBuffered();
113
- },
114
- dispose() {
115
- if (disposed) return;
116
- disposed = true;
117
- if (rafId !== null) {
118
- cancelAnimationFrame(rafId);
119
- rafId = null;
120
- }
121
- addBuffer = [];
122
- updateBuffer = [];
123
- removeBuffer = [];
124
- errorListeners.clear();
125
- }
126
- };
21
+ let addBuffer = [];
22
+ let updateBuffer = [];
23
+ let removeBuffer = [];
24
+ let rafId = null;
25
+ let disposed = false;
26
+ let rejectError;
27
+ const errorListeners = /* @__PURE__ */ new Set();
28
+ let failed = false;
29
+ let failure;
30
+ const error = new Promise((_resolve, reject) => {
31
+ rejectError = reject;
32
+ });
33
+ error.catch(() => void 0);
34
+ function fail(error) {
35
+ if (disposed) return;
36
+ disposed = true;
37
+ failed = true;
38
+ failure = error;
39
+ if (rafId !== null) {
40
+ cancelAnimationFrame(rafId);
41
+ rafId = null;
42
+ }
43
+ addBuffer = [];
44
+ updateBuffer = [];
45
+ removeBuffer = [];
46
+ const listeners = [...errorListeners];
47
+ errorListeners.clear();
48
+ for (const listener of listeners) try {
49
+ listener(error);
50
+ } catch (_unused) {}
51
+ rejectError(error);
52
+ }
53
+ function scheduleFlush() {
54
+ if (rafId !== null || disposed) return;
55
+ rafId = requestAnimationFrame(() => {
56
+ rafId = null;
57
+ if (disposed) return;
58
+ try {
59
+ applyBuffered();
60
+ } catch (error) {
61
+ fail(error);
62
+ }
63
+ });
64
+ }
65
+ function applyBuffered() {
66
+ if (addBuffer.length === 0 && updateBuffer.length === 0 && removeBuffer.length === 0) return;
67
+ const bufferedAdds = addBuffer;
68
+ const bufferedUpdates = updateBuffer;
69
+ const bufferedRemovals = removeBuffer;
70
+ addBuffer = [];
71
+ updateBuffer = [];
72
+ removeBuffer = [];
73
+ const transaction = {};
74
+ if (bufferedAdds.length > 0) transaction.add = bufferedAdds.map((row) => ({ ...row }));
75
+ if (bufferedUpdates.length > 0) transaction.update = bufferedUpdates.map(({ id, changes }) => ({
76
+ id,
77
+ changes: { ...changes }
78
+ }));
79
+ if (bufferedRemovals.length > 0) transaction.remove = [...bufferedRemovals];
80
+ rowModel.applyTransaction(transaction);
81
+ }
82
+ return {
83
+ error,
84
+ subscribeError(listener) {
85
+ if (failed) {
86
+ try {
87
+ listener(failure);
88
+ } catch (_unused2) {}
89
+ return () => void 0;
90
+ }
91
+ if (disposed) return () => void 0;
92
+ errorListeners.add(listener);
93
+ return () => errorListeners.delete(listener);
94
+ },
95
+ add(rows) {
96
+ if (disposed) return;
97
+ addBuffer.push(...rows);
98
+ scheduleFlush();
99
+ },
100
+ update(patches) {
101
+ if (disposed) return;
102
+ updateBuffer.push(...patches);
103
+ scheduleFlush();
104
+ },
105
+ remove(ids) {
106
+ if (disposed) return;
107
+ removeBuffer.push(...ids);
108
+ scheduleFlush();
109
+ },
110
+ flush() {
111
+ if (disposed) return;
112
+ if (rafId !== null) {
113
+ cancelAnimationFrame(rafId);
114
+ rafId = null;
115
+ }
116
+ applyBuffered();
117
+ },
118
+ dispose() {
119
+ if (disposed) return;
120
+ disposed = true;
121
+ if (rafId !== null) {
122
+ cancelAnimationFrame(rafId);
123
+ rafId = null;
124
+ }
125
+ addBuffer = [];
126
+ updateBuffer = [];
127
+ removeBuffer = [];
128
+ errorListeners.clear();
129
+ }
130
+ };
127
131
  }
128
132
 
129
- // src/connect-element-stream.ts
133
+ //#endregion
134
+ //#region src/connect-element-stream.ts
135
+ /**
136
+ * Drive a row model from an `AsyncIterable<TRow>`. Each yielded row is added
137
+ * via a {@link createBatcher | RAF batcher}; the returned
138
+ * {@link StreamConnection} resolves `done` when the stream ends and
139
+ * supports `dispose()` for early cancellation.
140
+ *
141
+ * Pair with {@link parseElementStream} to turn a raw UTF-8 string stream
142
+ * (e.g., from `fetch().body`) into a row stream end-to-end.
143
+ *
144
+ * @public
145
+ */
130
146
  function connectElementStream(rowModel, stream) {
131
- const iterator = stream[Symbol.asyncIterator]();
132
- const batcher = createBatcher(rowModel);
133
- let disposed = false;
134
- let sourceClosed = false;
135
- let resolveDone;
136
- let rejectDone;
137
- const done = new Promise((resolve, reject) => {
138
- resolveDone = resolve;
139
- rejectDone = reject;
140
- });
141
- done.catch(() => void 0);
142
- const closeSource = () => {
143
- if (sourceClosed) return;
144
- sourceClosed = true;
145
- try {
146
- const closing = iterator.return?.();
147
- if (closing !== void 0)
148
- void Promise.resolve(closing).catch(() => void 0);
149
- } catch {
150
- }
151
- };
152
- let settled = false;
153
- const settle = (failure, flush = true, close = failure !== void 0) => {
154
- if (settled) return;
155
- settled = true;
156
- disposed = true;
157
- if (close) closeSource();
158
- let finalFailure = failure;
159
- if (flush) {
160
- try {
161
- batcher.flush();
162
- } catch (error) {
163
- finalFailure ??= { error };
164
- }
165
- }
166
- batcher.dispose();
167
- if (finalFailure === void 0) resolveDone();
168
- else rejectDone(finalFailure.error);
169
- };
170
- batcher.subscribeError((error) => {
171
- settle({ error }, false, true);
172
- });
173
- void (async () => {
174
- try {
175
- while (!disposed) {
176
- const result = await iterator.next();
177
- if (disposed) return;
178
- if (result.done) {
179
- settle();
180
- return;
181
- }
182
- batcher.add([result.value]);
183
- }
184
- } catch (err) {
185
- settle({ error: err }, true, true);
186
- }
187
- })().catch((error) => settle({ error }));
188
- return {
189
- done,
190
- dispose() {
191
- if (disposed) return;
192
- settle(void 0, true, true);
193
- }
194
- };
147
+ const iterator = stream[Symbol.asyncIterator]();
148
+ const batcher = createBatcher(rowModel);
149
+ let disposed = false;
150
+ let sourceClosed = false;
151
+ let resolveDone;
152
+ let rejectDone;
153
+ const done = new Promise((resolve, reject) => {
154
+ resolveDone = resolve;
155
+ rejectDone = reject;
156
+ });
157
+ done.catch(() => void 0);
158
+ const closeSource = () => {
159
+ if (sourceClosed) return;
160
+ sourceClosed = true;
161
+ try {
162
+ var _iterator$return;
163
+ const closing = (_iterator$return = iterator.return) === null || _iterator$return === void 0 ? void 0 : _iterator$return.call(iterator);
164
+ if (closing !== void 0) Promise.resolve(closing).catch(() => void 0);
165
+ } catch (_unused) {}
166
+ };
167
+ let settled = false;
168
+ const settle = (failure, flush = true, close = failure !== void 0) => {
169
+ if (settled) return;
170
+ settled = true;
171
+ disposed = true;
172
+ if (close) closeSource();
173
+ let finalFailure = failure;
174
+ if (flush) try {
175
+ batcher.flush();
176
+ } catch (error) {
177
+ var _finalFailure;
178
+ (_finalFailure = finalFailure) !== null && _finalFailure !== void 0 || (finalFailure = { error });
179
+ }
180
+ batcher.dispose();
181
+ if (finalFailure === void 0) resolveDone();
182
+ else rejectDone(finalFailure.error);
183
+ };
184
+ batcher.subscribeError((error) => {
185
+ settle({ error }, false, true);
186
+ });
187
+ (async () => {
188
+ try {
189
+ while (!disposed) {
190
+ const result = await iterator.next();
191
+ if (disposed) return;
192
+ if (result.done) {
193
+ settle();
194
+ return;
195
+ }
196
+ batcher.add([result.value]);
197
+ }
198
+ } catch (err) {
199
+ settle({ error: err }, true, true);
200
+ }
201
+ })().catch((error) => settle({ error }));
202
+ return {
203
+ done,
204
+ dispose() {
205
+ if (disposed) return;
206
+ settle(void 0, true, true);
207
+ }
208
+ };
195
209
  }
196
210
 
197
- // src/connect-partial-stream.ts
211
+ //#endregion
212
+ //#region src/connect-partial-stream.ts
198
213
  function sameValueZero(left, right) {
199
- return left === right || typeof left === "number" && typeof right === "number" && Number.isNaN(left) && Number.isNaN(right);
214
+ return left === right || typeof left === "number" && typeof right === "number" && Number.isNaN(left) && Number.isNaN(right);
200
215
  }
216
+ /**
217
+ * Drive a row model from an `AsyncIterable<Partial<TRow>>`. Every yielded
218
+ * partial updates the fixed `options.rowId` via a RAF-batched
219
+ * `{ id, changes }` transaction. A missing target is reported instead of
220
+ * fabricating a row; provide `createRow` when the stream is allowed to add one.
221
+ *
222
+ * Pair with {@link parsePartialStream} for end-to-end partial-update
223
+ * streaming over UTF-8 strings.
224
+ *
225
+ * @public
226
+ */
201
227
  function connectPartialStream(rowModel, stream, options) {
202
- const iterator = stream[Symbol.asyncIterator]();
203
- const issueAwareRowModel = {
204
- applyTransaction(transaction) {
205
- const result = rowModel.applyTransaction(transaction);
206
- if (result === void 0 || result.issues === void 0) return result;
207
- let targetMissing = false;
208
- for (const issue of result.issues) {
209
- if (issue.code !== "unknown-update-id" || issue.rowId === void 0 || !sameValueZero(issue.rowId, options.rowId)) {
210
- continue;
211
- }
212
- targetMissing = true;
213
- options.onIssue?.({
214
- code: "unknown-update-id",
215
- rowId: options.rowId
216
- });
217
- }
218
- if (targetMissing && options.createRow !== void 0) {
219
- const updates = transaction.update ?? [];
220
- const combinedChanges = {};
221
- let hasTargetUpdate = false;
222
- for (const update of updates) {
223
- if (!sameValueZero(update.id, options.rowId)) continue;
224
- Object.assign(combinedChanges, update.changes);
225
- hasTargetUpdate = true;
226
- }
227
- if (hasTargetUpdate) {
228
- const row = options.createRow(combinedChanges, options.rowId);
229
- rowModel.applyTransaction({ add: [row] });
230
- }
231
- }
232
- return result;
233
- }
234
- };
235
- const batcher = createBatcher(issueAwareRowModel);
236
- let disposed = false;
237
- let sourceClosed = false;
238
- let resolveDone;
239
- let rejectDone;
240
- const done = new Promise((resolve, reject) => {
241
- resolveDone = resolve;
242
- rejectDone = reject;
243
- });
244
- done.catch(() => void 0);
245
- const closeSource = () => {
246
- if (sourceClosed) return;
247
- sourceClosed = true;
248
- try {
249
- const closing = iterator.return?.();
250
- if (closing !== void 0)
251
- void Promise.resolve(closing).catch(() => void 0);
252
- } catch {
253
- }
254
- };
255
- let settled = false;
256
- const settle = (failure, flush = true, close = failure !== void 0) => {
257
- if (settled) return;
258
- settled = true;
259
- disposed = true;
260
- if (close) closeSource();
261
- let finalFailure = failure;
262
- if (flush) {
263
- try {
264
- batcher.flush();
265
- } catch (error) {
266
- finalFailure ??= { error };
267
- }
268
- }
269
- batcher.dispose();
270
- if (finalFailure === void 0) resolveDone();
271
- else rejectDone(finalFailure.error);
272
- };
273
- batcher.subscribeError((error) => {
274
- settle({ error }, false, true);
275
- });
276
- void (async () => {
277
- try {
278
- while (!disposed) {
279
- const result = await iterator.next();
280
- if (disposed) return;
281
- if (result.done) {
282
- settle();
283
- return;
284
- }
285
- batcher.update([{ id: options.rowId, changes: result.value }]);
286
- }
287
- } catch (err) {
288
- settle({ error: err }, true, true);
289
- }
290
- })().catch((error) => settle({ error }));
291
- return {
292
- done,
293
- dispose() {
294
- if (disposed) return;
295
- settle(void 0, true, true);
296
- }
297
- };
228
+ const iterator = stream[Symbol.asyncIterator]();
229
+ const batcher = createBatcher({ applyTransaction(transaction) {
230
+ const result = rowModel.applyTransaction(transaction);
231
+ if (result === void 0 || result.issues === void 0) return result;
232
+ let targetMissing = false;
233
+ for (const issue of result.issues) {
234
+ var _options$onIssue;
235
+ if (issue.code !== "unknown-update-id" || issue.rowId === void 0 || !sameValueZero(issue.rowId, options.rowId)) continue;
236
+ targetMissing = true;
237
+ (_options$onIssue = options.onIssue) === null || _options$onIssue === void 0 || _options$onIssue.call(options, {
238
+ code: "unknown-update-id",
239
+ rowId: options.rowId
240
+ });
241
+ }
242
+ if (targetMissing && options.createRow !== void 0) {
243
+ var _transaction$update;
244
+ const updates = (_transaction$update = transaction.update) !== null && _transaction$update !== void 0 ? _transaction$update : [];
245
+ const combinedChanges = {};
246
+ let hasTargetUpdate = false;
247
+ for (const update of updates) {
248
+ if (!sameValueZero(update.id, options.rowId)) continue;
249
+ Object.assign(combinedChanges, update.changes);
250
+ hasTargetUpdate = true;
251
+ }
252
+ if (hasTargetUpdate) {
253
+ const row = options.createRow(combinedChanges, options.rowId);
254
+ rowModel.applyTransaction({ add: [row] });
255
+ }
256
+ }
257
+ return result;
258
+ } });
259
+ let disposed = false;
260
+ let sourceClosed = false;
261
+ let resolveDone;
262
+ let rejectDone;
263
+ const done = new Promise((resolve, reject) => {
264
+ resolveDone = resolve;
265
+ rejectDone = reject;
266
+ });
267
+ done.catch(() => void 0);
268
+ const closeSource = () => {
269
+ if (sourceClosed) return;
270
+ sourceClosed = true;
271
+ try {
272
+ var _iterator$return;
273
+ const closing = (_iterator$return = iterator.return) === null || _iterator$return === void 0 ? void 0 : _iterator$return.call(iterator);
274
+ if (closing !== void 0) Promise.resolve(closing).catch(() => void 0);
275
+ } catch (_unused) {}
276
+ };
277
+ let settled = false;
278
+ const settle = (failure, flush = true, close = failure !== void 0) => {
279
+ if (settled) return;
280
+ settled = true;
281
+ disposed = true;
282
+ if (close) closeSource();
283
+ let finalFailure = failure;
284
+ if (flush) try {
285
+ batcher.flush();
286
+ } catch (error) {
287
+ var _finalFailure;
288
+ (_finalFailure = finalFailure) !== null && _finalFailure !== void 0 || (finalFailure = { error });
289
+ }
290
+ batcher.dispose();
291
+ if (finalFailure === void 0) resolveDone();
292
+ else rejectDone(finalFailure.error);
293
+ };
294
+ batcher.subscribeError((error) => {
295
+ settle({ error }, false, true);
296
+ });
297
+ (async () => {
298
+ try {
299
+ while (!disposed) {
300
+ const result = await iterator.next();
301
+ if (disposed) return;
302
+ if (result.done) {
303
+ settle();
304
+ return;
305
+ }
306
+ batcher.update([{
307
+ id: options.rowId,
308
+ changes: result.value
309
+ }]);
310
+ }
311
+ } catch (err) {
312
+ settle({ error: err }, true, true);
313
+ }
314
+ })().catch((error) => settle({ error }));
315
+ return {
316
+ done,
317
+ dispose() {
318
+ if (disposed) return;
319
+ settle(void 0, true, true);
320
+ }
321
+ };
298
322
  }
323
+
324
+ //#endregion
325
+ //#region src/parse-element-stream.ts
326
+ /**
327
+ * Parse a UTF-8 string stream into an `AsyncIterable<TRow>`. Built on
328
+ * `@cacheplane/json-stream`'s incremental JSON parser; emits each
329
+ * complete top-level array element as a typed row.
330
+ *
331
+ * Pair with {@link connectElementStream} for end-to-end element-stream
332
+ * → grid wiring.
333
+ *
334
+ * @public
335
+ */
299
336
  async function* parseElementStream(stream) {
300
- let state = create();
301
- let yieldedCount = 0;
302
- for await (const chunk of stream) {
303
- state = push(state, chunk);
304
- if (state.error) {
305
- throw new Error(state.error.message);
306
- }
307
- if (state.rootId !== null) {
308
- const root = state.nodes[state.rootId];
309
- if (!isArrayNode(root)) {
310
- throw new Error(
311
- `parseElementStream expects root to be an array, got "${root.kind}"`
312
- );
313
- }
314
- while (yieldedCount < root.children.length) {
315
- const childNode = state.nodes[root.children[yieldedCount]];
316
- if (!isComplete(childNode)) break;
317
- if (childNode.value !== void 0) {
318
- yield childNode.value;
319
- }
320
- yieldedCount++;
321
- }
322
- }
323
- }
324
- state = finish(state);
325
- if (state.error) {
326
- throw new Error(state.error.message);
327
- }
328
- if (state.rootId !== null) {
329
- const root = state.nodes[state.rootId];
330
- if (isArrayNode(root)) {
331
- while (yieldedCount < root.children.length) {
332
- const childNode = state.nodes[root.children[yieldedCount]];
333
- if (isComplete(childNode) && childNode.value !== void 0) {
334
- yield childNode.value;
335
- }
336
- yieldedCount++;
337
- }
338
- }
339
- }
337
+ let state = create();
338
+ let yieldedCount = 0;
339
+ for await (const chunk of stream) {
340
+ state = push(state, chunk);
341
+ if (state.error) throw new Error(state.error.message);
342
+ if (state.rootId !== null) {
343
+ const root = state.nodes[state.rootId];
344
+ if (!isArrayNode(root)) throw new Error(`parseElementStream expects root to be an array, got "${root.kind}"`);
345
+ while (yieldedCount < root.children.length) {
346
+ const childNode = state.nodes[root.children[yieldedCount]];
347
+ if (!isComplete(childNode)) break;
348
+ if (childNode.value !== void 0) yield childNode.value;
349
+ yieldedCount++;
350
+ }
351
+ }
352
+ }
353
+ state = finish(state);
354
+ if (state.error) throw new Error(state.error.message);
355
+ if (state.rootId !== null) {
356
+ const root = state.nodes[state.rootId];
357
+ if (isArrayNode(root)) while (yieldedCount < root.children.length) {
358
+ const childNode = state.nodes[root.children[yieldedCount]];
359
+ if (isComplete(childNode) && childNode.value !== void 0) yield childNode.value;
360
+ yieldedCount++;
361
+ }
362
+ }
340
363
  }
364
+
365
+ //#endregion
366
+ //#region src/parse-partial-stream.ts
367
+ /**
368
+ * Parse a UTF-8 string stream into an `AsyncIterable<Partial<TRow>>`.
369
+ *
370
+ * The root must be a single JSON **object**, not an array — a non-object root
371
+ * throws. Each yielded value is the cumulative snapshot of that object as more
372
+ * keys resolve, not a delta, so the last value yielded is the complete row.
373
+ * Useful when an LLM is streaming partial JSON for one row and you want
374
+ * field-by-field updates instead of waiting for the object to close.
375
+ *
376
+ * For a stream of many complete rows, use {@link parseElementStream}, which
377
+ * does take a top-level array.
378
+ *
379
+ * Pair with {@link connectPartialStream} for end-to-end partial-stream
380
+ * → grid wiring.
381
+ *
382
+ * @public
383
+ */
341
384
  async function* parsePartialStream(stream) {
342
- let state = create();
343
- let lastValue;
344
- for await (const chunk of stream) {
345
- state = push(state, chunk);
346
- if (state.error) {
347
- throw new Error(state.error.message);
348
- }
349
- if (state.rootId !== null) {
350
- const root = state.nodes[state.rootId];
351
- if (!isObjectNode(root)) {
352
- throw new Error(
353
- `parsePartialStream expects root to be an object, got "${root.kind}"`
354
- );
355
- }
356
- if (root.value !== void 0 && root.value !== lastValue && Object.keys(root.value).length > 0) {
357
- lastValue = root.value;
358
- yield root.value;
359
- }
360
- }
361
- }
362
- state = finish(state);
363
- if (state.error) {
364
- throw new Error(state.error.message);
365
- }
366
- if (state.rootId !== null) {
367
- const root = state.nodes[state.rootId];
368
- if (isObjectNode(root) && root.value !== void 0 && root.value !== lastValue && Object.keys(root.value).length > 0) {
369
- yield root.value;
370
- }
371
- }
385
+ let state = create();
386
+ let lastValue;
387
+ for await (const chunk of stream) {
388
+ state = push(state, chunk);
389
+ if (state.error) throw new Error(state.error.message);
390
+ if (state.rootId !== null) {
391
+ const root = state.nodes[state.rootId];
392
+ if (!isObjectNode(root)) throw new Error(`parsePartialStream expects root to be an object, got "${root.kind}"`);
393
+ if (root.value !== void 0 && root.value !== lastValue && Object.keys(root.value).length > 0) {
394
+ lastValue = root.value;
395
+ yield root.value;
396
+ }
397
+ }
398
+ }
399
+ state = finish(state);
400
+ if (state.error) throw new Error(state.error.message);
401
+ if (state.rootId !== null) {
402
+ const root = state.nodes[state.rootId];
403
+ if (isObjectNode(root) && root.value !== void 0 && root.value !== lastValue && Object.keys(root.value).length > 0) yield root.value;
404
+ }
372
405
  }
373
406
 
407
+ //#endregion
374
408
  export { connectElementStream, connectPartialStream, createBatcher, parseElementStream, parsePartialStream };
409
+ //# sourceMappingURL=index.mjs.map