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