@tanstack/router-core 1.139.11 → 1.139.13
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/cjs/router.cjs +7 -2
- package/dist/cjs/router.cjs.map +1 -1
- package/dist/cjs/ssr/createRequestHandler.cjs +32 -24
- package/dist/cjs/ssr/createRequestHandler.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.cjs +19 -3
- package/dist/cjs/ssr/ssr-server.cjs.map +1 -1
- package/dist/cjs/ssr/ssr-server.d.cts +1 -0
- package/dist/cjs/ssr/transformStreamWithRouter.cjs +29 -15
- package/dist/cjs/ssr/transformStreamWithRouter.cjs.map +1 -1
- package/dist/esm/router.js +8 -3
- package/dist/esm/router.js.map +1 -1
- package/dist/esm/ssr/createRequestHandler.js +32 -24
- package/dist/esm/ssr/createRequestHandler.js.map +1 -1
- package/dist/esm/ssr/ssr-server.d.ts +1 -0
- package/dist/esm/ssr/ssr-server.js +19 -3
- package/dist/esm/ssr/ssr-server.js.map +1 -1
- package/dist/esm/ssr/transformStreamWithRouter.js +29 -15
- package/dist/esm/ssr/transformStreamWithRouter.js.map +1 -1
- package/package.json +1 -1
- package/src/router.ts +16 -2
- package/src/ssr/createRequestHandler.ts +40 -26
- package/src/ssr/ssr-server.ts +28 -4
- package/src/ssr/transformStreamWithRouter.ts +46 -19
|
@@ -35,7 +35,7 @@ type ReadablePassthrough = {
|
|
|
35
35
|
destroyed: boolean
|
|
36
36
|
}
|
|
37
37
|
|
|
38
|
-
function createPassthrough(onCancel
|
|
38
|
+
function createPassthrough(onCancel: () => void) {
|
|
39
39
|
let controller: ReadableStreamDefaultController<any>
|
|
40
40
|
const encoder = new TextEncoder()
|
|
41
41
|
const stream = new ReadableStream({
|
|
@@ -44,13 +44,15 @@ function createPassthrough(onCancel?: () => void) {
|
|
|
44
44
|
},
|
|
45
45
|
cancel() {
|
|
46
46
|
res.destroyed = true
|
|
47
|
-
onCancel
|
|
47
|
+
onCancel()
|
|
48
48
|
},
|
|
49
49
|
})
|
|
50
50
|
|
|
51
51
|
const res: ReadablePassthrough = {
|
|
52
52
|
stream,
|
|
53
53
|
write: (chunk) => {
|
|
54
|
+
// Don't write to destroyed stream
|
|
55
|
+
if (res.destroyed) return
|
|
54
56
|
if (typeof chunk === 'string') {
|
|
55
57
|
controller.enqueue(encoder.encode(chunk))
|
|
56
58
|
} else {
|
|
@@ -58,13 +60,17 @@ function createPassthrough(onCancel?: () => void) {
|
|
|
58
60
|
}
|
|
59
61
|
},
|
|
60
62
|
end: (chunk) => {
|
|
63
|
+
// Don't end already destroyed stream
|
|
64
|
+
if (res.destroyed) return
|
|
61
65
|
if (chunk) {
|
|
62
66
|
res.write(chunk)
|
|
63
67
|
}
|
|
64
|
-
controller.close()
|
|
65
68
|
res.destroyed = true
|
|
69
|
+
controller.close()
|
|
66
70
|
},
|
|
67
71
|
destroy: (error) => {
|
|
72
|
+
// Don't destroy already destroyed stream
|
|
73
|
+
if (res.destroyed) return
|
|
68
74
|
res.destroyed = true
|
|
69
75
|
controller.error(error)
|
|
70
76
|
},
|
|
@@ -105,14 +111,20 @@ export function transformStreamWithRouter(
|
|
|
105
111
|
) {
|
|
106
112
|
let stopListeningToInjectedHtml: (() => void) | undefined = undefined
|
|
107
113
|
let timeoutHandle: NodeJS.Timeout
|
|
114
|
+
let cleanedUp = false
|
|
108
115
|
|
|
109
|
-
|
|
116
|
+
function cleanup() {
|
|
117
|
+
if (cleanedUp) return
|
|
118
|
+
cleanedUp = true
|
|
110
119
|
if (stopListeningToInjectedHtml) {
|
|
111
120
|
stopListeningToInjectedHtml()
|
|
112
121
|
stopListeningToInjectedHtml = undefined
|
|
113
122
|
}
|
|
114
123
|
clearTimeout(timeoutHandle)
|
|
115
|
-
|
|
124
|
+
router.serverSsr?.cleanup()
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
const finalPassThrough = createPassthrough(cleanup)
|
|
116
128
|
const textDecoder = new TextDecoder()
|
|
117
129
|
|
|
118
130
|
let isAppRendering = true
|
|
@@ -149,13 +161,16 @@ export function transformStreamWithRouter(
|
|
|
149
161
|
)
|
|
150
162
|
|
|
151
163
|
function handleInjectedHtml() {
|
|
164
|
+
// Don't process if already cleaned up
|
|
165
|
+
if (cleanedUp) return
|
|
166
|
+
|
|
152
167
|
router.serverSsr!.injectedHtml.forEach((promise) => {
|
|
153
168
|
processingCount++
|
|
154
169
|
|
|
155
170
|
promise
|
|
156
171
|
.then((html) => {
|
|
157
|
-
// Don't write to destroyed stream
|
|
158
|
-
if (finalPassThrough.destroyed) {
|
|
172
|
+
// Don't write to destroyed stream or after cleanup
|
|
173
|
+
if (cleanedUp || finalPassThrough.destroyed) {
|
|
159
174
|
return
|
|
160
175
|
}
|
|
161
176
|
if (isAppRendering) {
|
|
@@ -165,10 +180,7 @@ export function transformStreamWithRouter(
|
|
|
165
180
|
}
|
|
166
181
|
})
|
|
167
182
|
.catch((err) => {
|
|
168
|
-
|
|
169
|
-
if (!finalPassThrough.destroyed) {
|
|
170
|
-
injectedHtmlDonePromise.reject(err)
|
|
171
|
-
}
|
|
183
|
+
injectedHtmlDonePromise.reject(err)
|
|
172
184
|
})
|
|
173
185
|
.finally(() => {
|
|
174
186
|
processingCount--
|
|
@@ -183,6 +195,11 @@ export function transformStreamWithRouter(
|
|
|
183
195
|
|
|
184
196
|
injectedHtmlDonePromise
|
|
185
197
|
.then(() => {
|
|
198
|
+
// Don't process if already cleaned up or destroyed
|
|
199
|
+
if (cleanedUp || finalPassThrough.destroyed) {
|
|
200
|
+
return
|
|
201
|
+
}
|
|
202
|
+
|
|
186
203
|
clearTimeout(timeoutHandle)
|
|
187
204
|
const finalHtml =
|
|
188
205
|
leftover + leftoverHtml + getBufferedRouterStream() + pendingClosingTags
|
|
@@ -194,19 +211,24 @@ export function transformStreamWithRouter(
|
|
|
194
211
|
finalPassThrough.end(finalHtml)
|
|
195
212
|
})
|
|
196
213
|
.catch((err) => {
|
|
214
|
+
// Don't process if already cleaned up
|
|
215
|
+
if (cleanedUp || finalPassThrough.destroyed) {
|
|
216
|
+
return
|
|
217
|
+
}
|
|
218
|
+
|
|
197
219
|
console.error('Error reading routerStream:', err)
|
|
198
220
|
finalPassThrough.destroy(err)
|
|
199
221
|
})
|
|
200
|
-
.finally(
|
|
201
|
-
if (stopListeningToInjectedHtml) {
|
|
202
|
-
stopListeningToInjectedHtml()
|
|
203
|
-
stopListeningToInjectedHtml = undefined
|
|
204
|
-
}
|
|
205
|
-
})
|
|
222
|
+
.finally(cleanup)
|
|
206
223
|
|
|
207
224
|
// Transform the appStream
|
|
208
225
|
readStream(appStream, {
|
|
209
226
|
onData: (chunk) => {
|
|
227
|
+
// Don't process if already cleaned up
|
|
228
|
+
if (cleanedUp || finalPassThrough.destroyed) {
|
|
229
|
+
return
|
|
230
|
+
}
|
|
231
|
+
|
|
210
232
|
const text = decodeChunk(chunk.value)
|
|
211
233
|
const chunkString = leftover + text
|
|
212
234
|
const bodyEndMatch = chunkString.match(patternBodyEnd)
|
|
@@ -266,8 +288,8 @@ export function transformStreamWithRouter(
|
|
|
266
288
|
}
|
|
267
289
|
},
|
|
268
290
|
onEnd: () => {
|
|
269
|
-
// Don't process if stream was already destroyed/cancelled
|
|
270
|
-
if (finalPassThrough.destroyed) {
|
|
291
|
+
// Don't process if stream was already destroyed/cancelled or cleaned up
|
|
292
|
+
if (cleanedUp || finalPassThrough.destroyed) {
|
|
271
293
|
return
|
|
272
294
|
}
|
|
273
295
|
|
|
@@ -288,6 +310,11 @@ export function transformStreamWithRouter(
|
|
|
288
310
|
}
|
|
289
311
|
},
|
|
290
312
|
onError: (error) => {
|
|
313
|
+
// Don't process if already cleaned up
|
|
314
|
+
if (cleanedUp) {
|
|
315
|
+
return
|
|
316
|
+
}
|
|
317
|
+
|
|
291
318
|
console.error('Error reading appStream:', error)
|
|
292
319
|
isAppRendering = false
|
|
293
320
|
router.serverSsr!.setRenderFinished()
|