Skip to content

Commit 1173d56

Browse files
Merge pull request #1395 from opencomponents/support-stream
Support stream
2 parents 2ac8b94 + fb019df commit 1173d56

File tree

5 files changed

+44
-7
lines changed

5 files changed

+44
-7
lines changed

package-lock.json

+9-2
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

+2-1
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,9 @@
116116
"serialize-error": "^8.1.0",
117117
"targz": "^1.0.1",
118118
"try-require": "^1.2.1",
119+
"turbo-stream": "^2.4.1",
119120
"undici": "^6.19.8",
120121
"universalify": "^2.0.0",
121122
"yargs": "^17.7.2"
122123
}
123-
}
124+
}

src/registry/domain/require-wrapper.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ import tryRequire from 'try-require';
55

66
import strings from '../../resources';
77

8-
const isCoreDependency = (x: string) => coreModules.includes(x);
8+
const allCoreModules = [...coreModules, ...coreModules.map((m) => `node:${m}`)];
9+
10+
const isCoreDependency = (x: string) => allCoreModules.includes(x);
911
const requireCoreDependency = (x: string) =>
1012
(isCoreDependency(x) && tryRequire(x)) || undefined;
1113

src/registry/routes/component.ts

+24-2
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
import { serializeError } from 'serialize-error';
22

3+
import { Readable } from 'node:stream';
34
import type { Request, RequestHandler, Response } from 'express';
5+
import { encode } from 'turbo-stream';
46
import strings from '../../resources';
57
import type { Config } from '../../types';
68
import type { Repository } from '../domain/repository';
7-
import GetComponentHelper from './helpers/get-component';
9+
import GetComponentHelper, { stream } from './helpers/get-component';
810

911
export default function component(
1012
conf: Config,
@@ -48,7 +50,27 @@ export default function component(
4850
res.set(result.headers);
4951
}
5052

51-
res.status(result.status).json(result.response);
53+
const streamEnabled =
54+
!!result.response.data?.component?.props?.[stream];
55+
if (streamEnabled) {
56+
delete result.response.data.component.props[stream];
57+
const webStream = encode({ ...result.response });
58+
59+
const nodeStream = Readable.from(webStream);
60+
61+
res.status(result.status);
62+
nodeStream.on('error', (err) => {
63+
res.status(500).end(String(err));
64+
});
65+
66+
res.setHeader('Content-Type', 'x-text/stream');
67+
68+
nodeStream.pipe(res).on('finish', () => {
69+
res.end();
70+
});
71+
} else {
72+
res.status(result.status).json(result.response);
73+
}
5274
} catch (e) {
5375
res.status(500).json({
5476
code: 'RENDER_ERROR',

src/registry/routes/helpers/get-component.ts

+6-1
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export interface GetComponentResult {
5656
};
5757
}
5858

59+
export const stream = Symbol('stream');
5960
const noop = () => {};
6061
const noopConsole = Object.fromEntries(
6162
Object.keys(console).map((key) => [key, noop])
@@ -520,7 +521,8 @@ export default function getComponent(conf: Config, repository: Repository) {
520521
responseHeaders[header.toLowerCase()] = value;
521522
}
522523
},
523-
templates: repository.getTemplatesInfo()
524+
templates: repository.getTemplatesInfo(),
525+
streamSymbol: stream
524526
};
525527

526528
const setCallbackTimeout = () => {
@@ -573,6 +575,9 @@ export default function getComponent(conf: Config, repository: Repository) {
573575
Buffer,
574576
AbortController: globalThis?.AbortController,
575577
AbortSignal: globalThis?.AbortSignal,
578+
Promise,
579+
Date,
580+
Symbol,
576581
eval: undefined,
577582
fetch: globalThis?.fetch
578583
};

0 commit comments

Comments
 (0)