turbo-stream 2.4.0 → 2.4.1

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.
@@ -133,56 +133,79 @@ function encode(input, options) {
133
133
  lastSentIndex = encoder.stringified.length - 1;
134
134
  }
135
135
  const seenPromises = new WeakSet();
136
- while (Object.keys(encoder.deferred).length > 0) {
137
- for (const [deferredId, deferred] of Object.entries(encoder.deferred)) {
138
- if (seenPromises.has(deferred))
139
- continue;
140
- seenPromises.add((encoder.deferred[Number(deferredId)] = raceSignal(deferred, encoder.signal)
141
- .then((resolved) => {
142
- const id = flatten_js_1.flatten.call(encoder, resolved);
143
- if (Array.isArray(id)) {
144
- controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_PROMISE}${deferredId}:[["${utils_js_1.TYPE_PREVIOUS_RESOLVED}",${id[0]}]]\n`));
145
- encoder.index++;
146
- lastSentIndex++;
147
- }
148
- else if (id < 0) {
149
- controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_PROMISE}${deferredId}:${id}\n`));
136
+ if (Object.keys(encoder.deferred).length) {
137
+ let raceDone;
138
+ const racePromise = new Promise((resolve, reject) => {
139
+ raceDone = resolve;
140
+ if (signal) {
141
+ const rejectPromise = () => reject(signal.reason || new Error("Signal was aborted."));
142
+ if (signal.aborted) {
143
+ rejectPromise();
150
144
  }
151
145
  else {
152
- const values = encoder.stringified
153
- .slice(lastSentIndex + 1)
154
- .join(",");
155
- controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_PROMISE}${deferredId}:[${values}]\n`));
156
- lastSentIndex = encoder.stringified.length - 1;
157
- }
158
- }, (reason) => {
159
- if (!reason ||
160
- typeof reason !== "object" ||
161
- !(reason instanceof Error)) {
162
- reason = new Error("An unknown error occurred");
163
- }
164
- const id = flatten_js_1.flatten.call(encoder, reason);
165
- if (Array.isArray(id)) {
166
- controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_ERROR}${deferredId}:[["${utils_js_1.TYPE_PREVIOUS_RESOLVED}",${id[0]}]]\n`));
167
- encoder.index++;
168
- lastSentIndex++;
146
+ signal.addEventListener("abort", (event) => {
147
+ rejectPromise();
148
+ });
169
149
  }
170
- else if (id < 0) {
171
- controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_ERROR}${deferredId}:${id}\n`));
172
- }
173
- else {
174
- const values = encoder.stringified
175
- .slice(lastSentIndex + 1)
176
- .join(",");
177
- controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_ERROR}${deferredId}:[${values}]\n`));
178
- lastSentIndex = encoder.stringified.length - 1;
179
- }
180
- })
181
- .finally(() => {
182
- delete encoder.deferred[Number(deferredId)];
183
- })));
150
+ }
151
+ });
152
+ while (Object.keys(encoder.deferred).length > 0) {
153
+ for (const [deferredId, deferred] of Object.entries(encoder.deferred)) {
154
+ if (seenPromises.has(deferred))
155
+ continue;
156
+ seenPromises.add(
157
+ // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
158
+ (encoder.deferred[Number(deferredId)] = Promise.race([
159
+ racePromise,
160
+ deferred,
161
+ ])
162
+ .then((resolved) => {
163
+ const id = flatten_js_1.flatten.call(encoder, resolved);
164
+ if (Array.isArray(id)) {
165
+ controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_PROMISE}${deferredId}:[["${utils_js_1.TYPE_PREVIOUS_RESOLVED}",${id[0]}]]\n`));
166
+ encoder.index++;
167
+ lastSentIndex++;
168
+ }
169
+ else if (id < 0) {
170
+ controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_PROMISE}${deferredId}:${id}\n`));
171
+ }
172
+ else {
173
+ const values = encoder.stringified
174
+ .slice(lastSentIndex + 1)
175
+ .join(",");
176
+ controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_PROMISE}${deferredId}:[${values}]\n`));
177
+ lastSentIndex = encoder.stringified.length - 1;
178
+ }
179
+ }, (reason) => {
180
+ if (!reason ||
181
+ typeof reason !== "object" ||
182
+ !(reason instanceof Error)) {
183
+ reason = new Error("An unknown error occurred");
184
+ }
185
+ const id = flatten_js_1.flatten.call(encoder, reason);
186
+ if (Array.isArray(id)) {
187
+ controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_ERROR}${deferredId}:[["${utils_js_1.TYPE_PREVIOUS_RESOLVED}",${id[0]}]]\n`));
188
+ encoder.index++;
189
+ lastSentIndex++;
190
+ }
191
+ else if (id < 0) {
192
+ controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_ERROR}${deferredId}:${id}\n`));
193
+ }
194
+ else {
195
+ const values = encoder.stringified
196
+ .slice(lastSentIndex + 1)
197
+ .join(",");
198
+ controller.enqueue(textEncoder.encode(`${utils_js_1.TYPE_ERROR}${deferredId}:[${values}]\n`));
199
+ lastSentIndex = encoder.stringified.length - 1;
200
+ }
201
+ })
202
+ .finally(() => {
203
+ delete encoder.deferred[Number(deferredId)];
204
+ })));
205
+ }
206
+ await Promise.race(Object.values(encoder.deferred));
184
207
  }
185
- await Promise.race(Object.values(encoder.deferred));
208
+ raceDone();
186
209
  }
187
210
  await Promise.all(Object.values(encoder.deferred));
188
211
  controller.close();
@@ -191,17 +214,3 @@ function encode(input, options) {
191
214
  return readable;
192
215
  }
193
216
  exports.encode = encode;
194
- function raceSignal(promise, signal) {
195
- if (!signal)
196
- return promise;
197
- if (signal.aborted)
198
- return Promise.reject(signal.reason || new Error("Signal was aborted."));
199
- const abort = new Promise((resolve, reject) => {
200
- signal.addEventListener("abort", (event) => {
201
- reject(signal.reason || new Error("Signal was aborted."));
202
- });
203
- promise.then(resolve).catch(reject);
204
- });
205
- abort.catch(() => { });
206
- return Promise.race([abort, promise]);
207
- }
@@ -573,78 +573,100 @@ function encode(input, options) {
573
573
  lastSentIndex = encoder.stringified.length - 1;
574
574
  }
575
575
  const seenPromises = /* @__PURE__ */ new WeakSet();
576
- while (Object.keys(encoder.deferred).length > 0) {
577
- for (const [deferredId, deferred] of Object.entries(encoder.deferred)) {
578
- if (seenPromises.has(deferred))
579
- continue;
580
- seenPromises.add(
581
- encoder.deferred[Number(deferredId)] = raceSignal(
582
- deferred,
583
- encoder.signal
584
- ).then(
585
- (resolved) => {
586
- const id2 = flatten.call(encoder, resolved);
587
- if (Array.isArray(id2)) {
588
- controller.enqueue(
589
- textEncoder.encode(
590
- `${TYPE_PROMISE}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
576
+ if (Object.keys(encoder.deferred).length) {
577
+ let raceDone;
578
+ const racePromise = new Promise((resolve, reject) => {
579
+ raceDone = resolve;
580
+ if (signal) {
581
+ const rejectPromise = () => reject(signal.reason || new Error("Signal was aborted."));
582
+ if (signal.aborted) {
583
+ rejectPromise();
584
+ } else {
585
+ signal.addEventListener("abort", (event) => {
586
+ rejectPromise();
587
+ });
588
+ }
589
+ }
590
+ });
591
+ while (Object.keys(encoder.deferred).length > 0) {
592
+ for (const [deferredId, deferred] of Object.entries(
593
+ encoder.deferred
594
+ )) {
595
+ if (seenPromises.has(deferred))
596
+ continue;
597
+ seenPromises.add(
598
+ // biome-ignore lint/suspicious/noAssignInExpressions: <explanation>
599
+ encoder.deferred[Number(deferredId)] = Promise.race([
600
+ racePromise,
601
+ deferred
602
+ ]).then(
603
+ (resolved) => {
604
+ const id2 = flatten.call(encoder, resolved);
605
+ if (Array.isArray(id2)) {
606
+ controller.enqueue(
607
+ textEncoder.encode(
608
+ `${TYPE_PROMISE}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
591
609
  `
592
- )
593
- );
594
- encoder.index++;
595
- lastSentIndex++;
596
- } else if (id2 < 0) {
597
- controller.enqueue(
598
- textEncoder.encode(`${TYPE_PROMISE}${deferredId}:${id2}
599
- `)
600
- );
601
- } else {
602
- const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
603
- controller.enqueue(
604
- textEncoder.encode(
605
- `${TYPE_PROMISE}${deferredId}:[${values}]
610
+ )
611
+ );
612
+ encoder.index++;
613
+ lastSentIndex++;
614
+ } else if (id2 < 0) {
615
+ controller.enqueue(
616
+ textEncoder.encode(
617
+ `${TYPE_PROMISE}${deferredId}:${id2}
606
618
  `
607
- )
608
- );
609
- lastSentIndex = encoder.stringified.length - 1;
610
- }
611
- },
612
- (reason) => {
613
- if (!reason || typeof reason !== "object" || !(reason instanceof Error)) {
614
- reason = new Error("An unknown error occurred");
615
- }
616
- const id2 = flatten.call(encoder, reason);
617
- if (Array.isArray(id2)) {
618
- controller.enqueue(
619
- textEncoder.encode(
620
- `${TYPE_ERROR}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
619
+ )
620
+ );
621
+ } else {
622
+ const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
623
+ controller.enqueue(
624
+ textEncoder.encode(
625
+ `${TYPE_PROMISE}${deferredId}:[${values}]
621
626
  `
622
- )
623
- );
624
- encoder.index++;
625
- lastSentIndex++;
626
- } else if (id2 < 0) {
627
- controller.enqueue(
628
- textEncoder.encode(`${TYPE_ERROR}${deferredId}:${id2}
627
+ )
628
+ );
629
+ lastSentIndex = encoder.stringified.length - 1;
630
+ }
631
+ },
632
+ (reason) => {
633
+ if (!reason || typeof reason !== "object" || !(reason instanceof Error)) {
634
+ reason = new Error("An unknown error occurred");
635
+ }
636
+ const id2 = flatten.call(encoder, reason);
637
+ if (Array.isArray(id2)) {
638
+ controller.enqueue(
639
+ textEncoder.encode(
640
+ `${TYPE_ERROR}${deferredId}:[["${TYPE_PREVIOUS_RESOLVED}",${id2[0]}]]
641
+ `
642
+ )
643
+ );
644
+ encoder.index++;
645
+ lastSentIndex++;
646
+ } else if (id2 < 0) {
647
+ controller.enqueue(
648
+ textEncoder.encode(`${TYPE_ERROR}${deferredId}:${id2}
629
649
  `)
630
- );
631
- } else {
632
- const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
633
- controller.enqueue(
634
- textEncoder.encode(
635
- `${TYPE_ERROR}${deferredId}:[${values}]
650
+ );
651
+ } else {
652
+ const values = encoder.stringified.slice(lastSentIndex + 1).join(",");
653
+ controller.enqueue(
654
+ textEncoder.encode(
655
+ `${TYPE_ERROR}${deferredId}:[${values}]
636
656
  `
637
- )
638
- );
639
- lastSentIndex = encoder.stringified.length - 1;
657
+ )
658
+ );
659
+ lastSentIndex = encoder.stringified.length - 1;
660
+ }
640
661
  }
641
- }
642
- ).finally(() => {
643
- delete encoder.deferred[Number(deferredId)];
644
- })
645
- );
662
+ ).finally(() => {
663
+ delete encoder.deferred[Number(deferredId)];
664
+ })
665
+ );
666
+ }
667
+ await Promise.race(Object.values(encoder.deferred));
646
668
  }
647
- await Promise.race(Object.values(encoder.deferred));
669
+ raceDone();
648
670
  }
649
671
  await Promise.all(Object.values(encoder.deferred));
650
672
  controller.close();
@@ -652,21 +674,6 @@ function encode(input, options) {
652
674
  });
653
675
  return readable;
654
676
  }
655
- function raceSignal(promise, signal) {
656
- if (!signal)
657
- return promise;
658
- if (signal.aborted)
659
- return Promise.reject(signal.reason || new Error("Signal was aborted."));
660
- const abort = new Promise((resolve, reject) => {
661
- signal.addEventListener("abort", (event) => {
662
- reject(signal.reason || new Error("Signal was aborted."));
663
- });
664
- promise.then(resolve).catch(reject);
665
- });
666
- abort.catch(() => {
667
- });
668
- return Promise.race([abort, promise]);
669
- }
670
677
  export {
671
678
  decode,
672
679
  encode
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "turbo-stream",
3
- "version": "2.4.0",
3
+ "version": "2.4.1",
4
4
  "description": "A streaming data transport format that aims to support built-in features such as Promises, Dates, RegExps, Maps, Sets and more.",
5
5
  "files": [
6
6
  "dist",