@react-router/node 7.15.0 → 7.16.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/CHANGELOG.md +18 -0
- package/dist/index.js +105 -6
- package/dist/index.mjs +105 -6
- package/package.json +3 -3
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,23 @@
|
|
|
1
1
|
# `@react-router/node`
|
|
2
2
|
|
|
3
|
+
## v7.16.0
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Honor Node writable backpressure in `writeReadableStreamToWritable` and `writeAsyncIterableToWritable` ([#15071](https://github.com/remix-run/react-router/pull/15071))
|
|
8
|
+
|
|
9
|
+
- Await `'drain'` when `writable.write()` returns `false` instead of letting chunks accumulate in the writable's internal buffer.
|
|
10
|
+
- Reject (rather than hang) if the writable errors or closes mid-stream.
|
|
11
|
+
- Updated dependencies:
|
|
12
|
+
- [`react-router@7.16.0`](https://github.com/remix-run/react-router/releases/tag/react-router@7.16.0)
|
|
13
|
+
|
|
14
|
+
## v7.15.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- Updated dependencies:
|
|
19
|
+
- [`react-router@7.15.1`](https://github.com/remix-run/react-router/releases/tag/react-router@7.15.1)
|
|
20
|
+
|
|
3
21
|
## v7.15.0
|
|
4
22
|
|
|
5
23
|
### Patch Changes
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/node v7.
|
|
2
|
+
* @react-router/node v7.16.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -144,32 +144,131 @@ var import_node_stream = require("stream");
|
|
|
144
144
|
async function writeReadableStreamToWritable(stream, writable) {
|
|
145
145
|
let reader = stream.getReader();
|
|
146
146
|
let flushable = writable;
|
|
147
|
+
let writableError = monitorWritableError(writable);
|
|
147
148
|
try {
|
|
148
149
|
while (true) {
|
|
149
|
-
|
|
150
|
+
writableError.throwIfClosed();
|
|
151
|
+
let { done, value } = await writableError.race(reader.read());
|
|
150
152
|
if (done) {
|
|
151
153
|
writable.end();
|
|
152
154
|
break;
|
|
153
155
|
}
|
|
154
|
-
|
|
156
|
+
writableError.throwIfClosed();
|
|
157
|
+
let canContinueWriting = writable.write(value);
|
|
155
158
|
if (typeof flushable.flush === "function") {
|
|
156
159
|
flushable.flush();
|
|
157
160
|
}
|
|
161
|
+
if (!canContinueWriting) {
|
|
162
|
+
await waitForDrain(writable, writableError);
|
|
163
|
+
}
|
|
158
164
|
}
|
|
159
165
|
} catch (error) {
|
|
166
|
+
try {
|
|
167
|
+
reader.cancel(error).catch(() => {
|
|
168
|
+
});
|
|
169
|
+
} catch {
|
|
170
|
+
}
|
|
160
171
|
writable.destroy(error);
|
|
161
172
|
throw error;
|
|
173
|
+
} finally {
|
|
174
|
+
writableError.cleanup();
|
|
175
|
+
try {
|
|
176
|
+
reader.releaseLock();
|
|
177
|
+
} catch {
|
|
178
|
+
}
|
|
162
179
|
}
|
|
163
180
|
}
|
|
181
|
+
function monitorWritableError(writable) {
|
|
182
|
+
let settled = false;
|
|
183
|
+
let writableError;
|
|
184
|
+
let rejectWritableError;
|
|
185
|
+
let writableErrorPromise = new Promise((_, reject2) => {
|
|
186
|
+
rejectWritableError = reject2;
|
|
187
|
+
});
|
|
188
|
+
writableErrorPromise.catch(() => {
|
|
189
|
+
});
|
|
190
|
+
function cleanup() {
|
|
191
|
+
writable.off("error", onError);
|
|
192
|
+
writable.off("close", onClose);
|
|
193
|
+
}
|
|
194
|
+
function reject(error) {
|
|
195
|
+
if (settled) {
|
|
196
|
+
return;
|
|
197
|
+
}
|
|
198
|
+
settled = true;
|
|
199
|
+
writableError = error;
|
|
200
|
+
cleanup();
|
|
201
|
+
rejectWritableError(error);
|
|
202
|
+
}
|
|
203
|
+
function onError(error) {
|
|
204
|
+
reject(error);
|
|
205
|
+
}
|
|
206
|
+
function onClose() {
|
|
207
|
+
reject(new Error("Writable closed before stream finished"));
|
|
208
|
+
}
|
|
209
|
+
writable.once("error", onError);
|
|
210
|
+
writable.once("close", onClose);
|
|
211
|
+
return {
|
|
212
|
+
cleanup,
|
|
213
|
+
race(promise) {
|
|
214
|
+
return Promise.race([promise, writableErrorPromise]);
|
|
215
|
+
},
|
|
216
|
+
throwIfClosed() {
|
|
217
|
+
if (writableError) {
|
|
218
|
+
throw writableError;
|
|
219
|
+
}
|
|
220
|
+
if (writable.destroyed || writable.writableEnded) {
|
|
221
|
+
throw new Error("Cannot write to a destroyed or ended writable stream");
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
function waitForDrain(writable, writableError) {
|
|
227
|
+
let cleanup = () => {
|
|
228
|
+
};
|
|
229
|
+
let drainPromise = new Promise((resolve) => {
|
|
230
|
+
function onDrain() {
|
|
231
|
+
cleanup();
|
|
232
|
+
resolve();
|
|
233
|
+
}
|
|
234
|
+
cleanup = function cleanup2() {
|
|
235
|
+
writable.off("drain", onDrain);
|
|
236
|
+
};
|
|
237
|
+
writable.once("drain", onDrain);
|
|
238
|
+
});
|
|
239
|
+
return writableError.race(drainPromise).finally(cleanup);
|
|
240
|
+
}
|
|
164
241
|
async function writeAsyncIterableToWritable(iterable, writable) {
|
|
242
|
+
let writableError = monitorWritableError(writable);
|
|
243
|
+
let iterator = iterable[Symbol.asyncIterator]();
|
|
244
|
+
let completed = false;
|
|
165
245
|
try {
|
|
166
|
-
|
|
167
|
-
|
|
246
|
+
while (true) {
|
|
247
|
+
writableError.throwIfClosed();
|
|
248
|
+
let { done, value: chunk } = await writableError.race(iterator.next());
|
|
249
|
+
if (done) {
|
|
250
|
+
completed = true;
|
|
251
|
+
break;
|
|
252
|
+
}
|
|
253
|
+
writableError.throwIfClosed();
|
|
254
|
+
let canContinueWriting = writable.write(chunk);
|
|
255
|
+
if (!canContinueWriting) {
|
|
256
|
+
await waitForDrain(writable, writableError);
|
|
257
|
+
}
|
|
168
258
|
}
|
|
169
259
|
writable.end();
|
|
170
260
|
} catch (error) {
|
|
261
|
+
if (!completed) {
|
|
262
|
+
try {
|
|
263
|
+
Promise.resolve(iterator.return?.()).catch(() => {
|
|
264
|
+
});
|
|
265
|
+
} catch {
|
|
266
|
+
}
|
|
267
|
+
}
|
|
171
268
|
writable.destroy(error);
|
|
172
269
|
throw error;
|
|
270
|
+
} finally {
|
|
271
|
+
writableError.cleanup();
|
|
173
272
|
}
|
|
174
273
|
}
|
|
175
274
|
async function readableStreamToString(stream, encoding) {
|
|
@@ -235,7 +334,7 @@ var StreamPump = class {
|
|
|
235
334
|
if (available <= 0) {
|
|
236
335
|
this.pause();
|
|
237
336
|
}
|
|
238
|
-
} catch (
|
|
337
|
+
} catch (e) {
|
|
239
338
|
this.controller.error(
|
|
240
339
|
new Error(
|
|
241
340
|
"Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object"
|
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
/**
|
|
2
|
-
* @react-router/node v7.
|
|
2
|
+
* @react-router/node v7.16.0
|
|
3
3
|
*
|
|
4
4
|
* Copyright (c) Remix Software Inc.
|
|
5
5
|
*
|
|
@@ -104,32 +104,131 @@ import { Stream } from "stream";
|
|
|
104
104
|
async function writeReadableStreamToWritable(stream, writable) {
|
|
105
105
|
let reader = stream.getReader();
|
|
106
106
|
let flushable = writable;
|
|
107
|
+
let writableError = monitorWritableError(writable);
|
|
107
108
|
try {
|
|
108
109
|
while (true) {
|
|
109
|
-
|
|
110
|
+
writableError.throwIfClosed();
|
|
111
|
+
let { done, value } = await writableError.race(reader.read());
|
|
110
112
|
if (done) {
|
|
111
113
|
writable.end();
|
|
112
114
|
break;
|
|
113
115
|
}
|
|
114
|
-
|
|
116
|
+
writableError.throwIfClosed();
|
|
117
|
+
let canContinueWriting = writable.write(value);
|
|
115
118
|
if (typeof flushable.flush === "function") {
|
|
116
119
|
flushable.flush();
|
|
117
120
|
}
|
|
121
|
+
if (!canContinueWriting) {
|
|
122
|
+
await waitForDrain(writable, writableError);
|
|
123
|
+
}
|
|
118
124
|
}
|
|
119
125
|
} catch (error) {
|
|
126
|
+
try {
|
|
127
|
+
reader.cancel(error).catch(() => {
|
|
128
|
+
});
|
|
129
|
+
} catch {
|
|
130
|
+
}
|
|
120
131
|
writable.destroy(error);
|
|
121
132
|
throw error;
|
|
133
|
+
} finally {
|
|
134
|
+
writableError.cleanup();
|
|
135
|
+
try {
|
|
136
|
+
reader.releaseLock();
|
|
137
|
+
} catch {
|
|
138
|
+
}
|
|
122
139
|
}
|
|
123
140
|
}
|
|
141
|
+
function monitorWritableError(writable) {
|
|
142
|
+
let settled = false;
|
|
143
|
+
let writableError;
|
|
144
|
+
let rejectWritableError;
|
|
145
|
+
let writableErrorPromise = new Promise((_, reject2) => {
|
|
146
|
+
rejectWritableError = reject2;
|
|
147
|
+
});
|
|
148
|
+
writableErrorPromise.catch(() => {
|
|
149
|
+
});
|
|
150
|
+
function cleanup() {
|
|
151
|
+
writable.off("error", onError);
|
|
152
|
+
writable.off("close", onClose);
|
|
153
|
+
}
|
|
154
|
+
function reject(error) {
|
|
155
|
+
if (settled) {
|
|
156
|
+
return;
|
|
157
|
+
}
|
|
158
|
+
settled = true;
|
|
159
|
+
writableError = error;
|
|
160
|
+
cleanup();
|
|
161
|
+
rejectWritableError(error);
|
|
162
|
+
}
|
|
163
|
+
function onError(error) {
|
|
164
|
+
reject(error);
|
|
165
|
+
}
|
|
166
|
+
function onClose() {
|
|
167
|
+
reject(new Error("Writable closed before stream finished"));
|
|
168
|
+
}
|
|
169
|
+
writable.once("error", onError);
|
|
170
|
+
writable.once("close", onClose);
|
|
171
|
+
return {
|
|
172
|
+
cleanup,
|
|
173
|
+
race(promise) {
|
|
174
|
+
return Promise.race([promise, writableErrorPromise]);
|
|
175
|
+
},
|
|
176
|
+
throwIfClosed() {
|
|
177
|
+
if (writableError) {
|
|
178
|
+
throw writableError;
|
|
179
|
+
}
|
|
180
|
+
if (writable.destroyed || writable.writableEnded) {
|
|
181
|
+
throw new Error("Cannot write to a destroyed or ended writable stream");
|
|
182
|
+
}
|
|
183
|
+
}
|
|
184
|
+
};
|
|
185
|
+
}
|
|
186
|
+
function waitForDrain(writable, writableError) {
|
|
187
|
+
let cleanup = () => {
|
|
188
|
+
};
|
|
189
|
+
let drainPromise = new Promise((resolve) => {
|
|
190
|
+
function onDrain() {
|
|
191
|
+
cleanup();
|
|
192
|
+
resolve();
|
|
193
|
+
}
|
|
194
|
+
cleanup = function cleanup2() {
|
|
195
|
+
writable.off("drain", onDrain);
|
|
196
|
+
};
|
|
197
|
+
writable.once("drain", onDrain);
|
|
198
|
+
});
|
|
199
|
+
return writableError.race(drainPromise).finally(cleanup);
|
|
200
|
+
}
|
|
124
201
|
async function writeAsyncIterableToWritable(iterable, writable) {
|
|
202
|
+
let writableError = monitorWritableError(writable);
|
|
203
|
+
let iterator = iterable[Symbol.asyncIterator]();
|
|
204
|
+
let completed = false;
|
|
125
205
|
try {
|
|
126
|
-
|
|
127
|
-
|
|
206
|
+
while (true) {
|
|
207
|
+
writableError.throwIfClosed();
|
|
208
|
+
let { done, value: chunk } = await writableError.race(iterator.next());
|
|
209
|
+
if (done) {
|
|
210
|
+
completed = true;
|
|
211
|
+
break;
|
|
212
|
+
}
|
|
213
|
+
writableError.throwIfClosed();
|
|
214
|
+
let canContinueWriting = writable.write(chunk);
|
|
215
|
+
if (!canContinueWriting) {
|
|
216
|
+
await waitForDrain(writable, writableError);
|
|
217
|
+
}
|
|
128
218
|
}
|
|
129
219
|
writable.end();
|
|
130
220
|
} catch (error) {
|
|
221
|
+
if (!completed) {
|
|
222
|
+
try {
|
|
223
|
+
Promise.resolve(iterator.return?.()).catch(() => {
|
|
224
|
+
});
|
|
225
|
+
} catch {
|
|
226
|
+
}
|
|
227
|
+
}
|
|
131
228
|
writable.destroy(error);
|
|
132
229
|
throw error;
|
|
230
|
+
} finally {
|
|
231
|
+
writableError.cleanup();
|
|
133
232
|
}
|
|
134
233
|
}
|
|
135
234
|
async function readableStreamToString(stream, encoding) {
|
|
@@ -195,7 +294,7 @@ var StreamPump = class {
|
|
|
195
294
|
if (available <= 0) {
|
|
196
295
|
this.pause();
|
|
197
296
|
}
|
|
198
|
-
} catch (
|
|
297
|
+
} catch (e) {
|
|
199
298
|
this.controller.error(
|
|
200
299
|
new Error(
|
|
201
300
|
"Could not create Buffer, chunk must be of type string or an instance of Buffer, ArrayBuffer, or Array or an Array-like Object"
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@react-router/node",
|
|
3
|
-
"version": "7.
|
|
3
|
+
"version": "7.16.0",
|
|
4
4
|
"description": "Node.js platform abstractions for React Router",
|
|
5
5
|
"bugs": {
|
|
6
6
|
"url": "https://github.com/remix-run/react-router/issues"
|
|
@@ -53,11 +53,11 @@
|
|
|
53
53
|
"tsup": "^8.3.0",
|
|
54
54
|
"typescript": "^5.4.5",
|
|
55
55
|
"wireit": "0.14.9",
|
|
56
|
-
"react-router": "7.
|
|
56
|
+
"react-router": "7.16.0"
|
|
57
57
|
},
|
|
58
58
|
"peerDependencies": {
|
|
59
59
|
"typescript": "^5.1.0 || ^6.0.0",
|
|
60
|
-
"react-router": "7.
|
|
60
|
+
"react-router": "7.16.0"
|
|
61
61
|
},
|
|
62
62
|
"peerDependenciesMeta": {
|
|
63
63
|
"typescript": {
|