@canonical/react-ssr 0.21.0 → 0.23.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/esm/bin/serve-express.js +86 -0
- package/dist/esm/bin/serve-express.js.map +1 -0
- package/dist/esm/index.js +2 -2
- package/dist/esm/index.js.map +1 -1
- package/dist/esm/lib/index.js +3 -0
- package/dist/esm/lib/index.js.map +1 -0
- package/dist/esm/lib/renderer/Extractor.js +172 -0
- package/dist/esm/lib/renderer/Extractor.js.map +1 -0
- package/dist/esm/lib/renderer/JSXRenderer.js +283 -0
- package/dist/esm/lib/renderer/JSXRenderer.js.map +1 -0
- package/dist/esm/lib/renderer/SitemapRenderer.js +241 -0
- package/dist/esm/lib/renderer/SitemapRenderer.js.map +1 -0
- package/dist/esm/lib/renderer/TextRenderer.js +124 -0
- package/dist/esm/lib/renderer/TextRenderer.js.map +1 -0
- package/dist/esm/lib/renderer/constants.js.map +1 -0
- package/dist/esm/lib/renderer/index.js +6 -0
- package/dist/esm/lib/renderer/index.js.map +1 -0
- package/dist/esm/lib/renderer/types.js +10 -0
- package/dist/esm/lib/renderer/types.js.map +1 -0
- package/dist/esm/lib/server/index.js +3 -0
- package/dist/esm/lib/server/index.js.map +1 -0
- package/dist/esm/lib/server/serveStream.js +53 -0
- package/dist/esm/lib/server/serveStream.js.map +1 -0
- package/dist/esm/lib/server/serveString.js +49 -0
- package/dist/esm/lib/server/serveString.js.map +1 -0
- package/dist/types/bin/serve-express.d.ts +24 -0
- package/dist/types/bin/serve-express.d.ts.map +1 -0
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.d.ts.map +1 -1
- package/dist/types/lib/index.d.ts +3 -0
- package/dist/types/lib/index.d.ts.map +1 -0
- package/dist/types/lib/renderer/Extractor.d.ts +93 -0
- package/dist/types/lib/renderer/Extractor.d.ts.map +1 -0
- package/dist/types/lib/renderer/JSXRenderer.d.ts +163 -0
- package/dist/types/lib/renderer/JSXRenderer.d.ts.map +1 -0
- package/dist/types/lib/renderer/SitemapRenderer.d.ts +153 -0
- package/dist/types/lib/renderer/SitemapRenderer.d.ts.map +1 -0
- package/dist/types/lib/renderer/TextRenderer.d.ts +83 -0
- package/dist/types/lib/renderer/TextRenderer.d.ts.map +1 -0
- package/dist/types/lib/renderer/constants.d.ts.map +1 -0
- package/dist/types/lib/renderer/index.d.ts +7 -0
- package/dist/types/lib/renderer/index.d.ts.map +1 -0
- package/dist/types/lib/renderer/types.d.ts +161 -0
- package/dist/types/lib/renderer/types.d.ts.map +1 -0
- package/dist/types/lib/server/index.d.ts +3 -0
- package/dist/types/lib/server/index.d.ts.map +1 -0
- package/dist/types/lib/server/serveStream.d.ts +41 -0
- package/dist/types/lib/server/serveStream.d.ts.map +1 -0
- package/dist/types/lib/server/serveString.d.ts +37 -0
- package/dist/types/lib/server/serveString.d.ts.map +1 -0
- package/package.json +32 -17
- package/dist/esm/renderer/Extractor.js +0 -127
- package/dist/esm/renderer/Extractor.js.map +0 -1
- package/dist/esm/renderer/JSXRenderer.js +0 -168
- package/dist/esm/renderer/JSXRenderer.js.map +0 -1
- package/dist/esm/renderer/constants.js.map +0 -1
- package/dist/esm/renderer/index.js +0 -4
- package/dist/esm/renderer/index.js.map +0 -1
- package/dist/esm/renderer/types.js +0 -2
- package/dist/esm/renderer/types.js.map +0 -1
- package/dist/esm/server/index.js +0 -2
- package/dist/esm/server/index.js.map +0 -1
- package/dist/esm/server/serve-express.js +0 -58
- package/dist/esm/server/serve-express.js.map +0 -1
- package/dist/esm/server/serve.js +0 -41
- package/dist/esm/server/serve.js.map +0 -1
- package/dist/types/renderer/Extractor.d.ts +0 -68
- package/dist/types/renderer/Extractor.d.ts.map +0 -1
- package/dist/types/renderer/JSXRenderer.d.ts +0 -71
- package/dist/types/renderer/JSXRenderer.d.ts.map +0 -1
- package/dist/types/renderer/constants.d.ts.map +0 -1
- package/dist/types/renderer/index.d.ts +0 -5
- package/dist/types/renderer/index.d.ts.map +0 -1
- package/dist/types/renderer/types.d.ts +0 -35
- package/dist/types/renderer/types.d.ts.map +0 -1
- package/dist/types/server/index.d.ts +0 -2
- package/dist/types/server/index.d.ts.map +0 -1
- package/dist/types/server/serve-express.d.ts +0 -3
- package/dist/types/server/serve-express.d.ts.map +0 -1
- package/dist/types/server/serve.d.ts +0 -30
- package/dist/types/server/serve.d.ts.map +0 -1
- /package/dist/esm/{renderer → lib/renderer}/constants.js +0 -0
- /package/dist/types/{renderer → lib/renderer}/constants.d.ts +0 -0
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
/**
|
|
3
|
+
* Renders an XML sitemap from a set of async data sources.
|
|
4
|
+
*
|
|
5
|
+
* Unlike `JSXRenderer`, this renderer produces XML (not HTML) and does not use
|
|
6
|
+
* React. The render pipeline is functional: each stage returns data rather than
|
|
7
|
+
* mutating instance state, so calling render methods multiple times produces
|
|
8
|
+
* identical results for the same underlying data.
|
|
9
|
+
*
|
|
10
|
+
* Implements the same three render methods as `JSXRenderer` — `renderToReadableStream`,
|
|
11
|
+
* `renderToPipeableStream`, and `renderToString` — with the same `statusCode` /
|
|
12
|
+
* `statusReady` metadata contract. This allows consumers to use either renderer
|
|
13
|
+
* interchangeably.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* const renderer = new SitemapRenderer(
|
|
18
|
+
* [() => fetchPages(), () => fetchPosts()],
|
|
19
|
+
* { baseUrl: "https://example.com", defaultChangefreq: "weekly" },
|
|
20
|
+
* );
|
|
21
|
+
*
|
|
22
|
+
* const stream = await renderer.renderToReadableStream();
|
|
23
|
+
* return new Response(stream, {
|
|
24
|
+
* status: renderer.statusCode,
|
|
25
|
+
* headers: { "Content-Type": "application/xml; charset=utf-8" },
|
|
26
|
+
* });
|
|
27
|
+
* ```
|
|
28
|
+
*/
|
|
29
|
+
export default class SitemapRenderer {
|
|
30
|
+
getters;
|
|
31
|
+
config;
|
|
32
|
+
/**
|
|
33
|
+
* HTTP status code determined during rendering.
|
|
34
|
+
*
|
|
35
|
+
* Set to 200 on successful render. Errors from getters propagate as
|
|
36
|
+
* thrown exceptions rather than setting this to 500 — the consumer's
|
|
37
|
+
* error handler decides the status code for unexpected failures.
|
|
38
|
+
*/
|
|
39
|
+
statusCode = 200;
|
|
40
|
+
/**
|
|
41
|
+
* Resolves when `statusCode` is determined.
|
|
42
|
+
*
|
|
43
|
+
* For all three render methods on `SitemapRenderer`, this resolves by
|
|
44
|
+
* the time the method's returned Promise settles (or synchronously for
|
|
45
|
+
* the portions that are sync).
|
|
46
|
+
*/
|
|
47
|
+
statusReady = Promise.resolve();
|
|
48
|
+
/**
|
|
49
|
+
* Create a sitemap renderer.
|
|
50
|
+
*
|
|
51
|
+
* @param getters - Async functions that each return a batch of sitemap items.
|
|
52
|
+
* Called concurrently via `Promise.all` during rendering.
|
|
53
|
+
* @param config - Base URL and optional defaults for changefreq / priority.
|
|
54
|
+
*/
|
|
55
|
+
constructor(getters, config) {
|
|
56
|
+
this.getters = getters;
|
|
57
|
+
this.config = config;
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Load sitemap items from all configured getters.
|
|
61
|
+
*
|
|
62
|
+
* Calls every getter concurrently and flattens the results into a single
|
|
63
|
+
* array. This is the only async step in the pipeline.
|
|
64
|
+
*
|
|
65
|
+
* @note This method is impure — it calls external async data sources.
|
|
66
|
+
* @returns A flat array of raw sitemap items from all getters.
|
|
67
|
+
*/
|
|
68
|
+
async loadItems() {
|
|
69
|
+
const results = await Promise.all(this.getters.map((getter) => getter()));
|
|
70
|
+
return results.flat();
|
|
71
|
+
}
|
|
72
|
+
/**
|
|
73
|
+
* Resolve URLs and apply defaults to raw sitemap items.
|
|
74
|
+
*
|
|
75
|
+
* For each item:
|
|
76
|
+
* - Relative `loc` values are resolved against `config.baseUrl`. An empty
|
|
77
|
+
* `loc` resolves to the base URL itself.
|
|
78
|
+
* - `lastmod` dates are formatted to `YYYY-MM-DD` (ISO 8601 date-only).
|
|
79
|
+
* - Missing `changefreq` and `priority` are filled from `config` defaults.
|
|
80
|
+
*
|
|
81
|
+
* @param items - Raw items as returned by `loadItems`.
|
|
82
|
+
* @returns A new array of items with resolved URLs and applied defaults.
|
|
83
|
+
*/
|
|
84
|
+
formatItems(items) {
|
|
85
|
+
return items.map((item) => ({
|
|
86
|
+
loc: item.loc.length
|
|
87
|
+
? new URL(item.loc, this.config.baseUrl).href
|
|
88
|
+
: this.config.baseUrl,
|
|
89
|
+
lastmod: item.lastmod != null
|
|
90
|
+
? SitemapRenderer.formatDate(item.lastmod)
|
|
91
|
+
: undefined,
|
|
92
|
+
changefreq: item.changefreq ?? this.config.defaultChangefreq,
|
|
93
|
+
priority: item.priority ?? this.config.defaultPriority,
|
|
94
|
+
}));
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Format a `Date` object or ISO string to a `YYYY-MM-DD` date string.
|
|
98
|
+
*
|
|
99
|
+
* The Sitemaps protocol specifies W3C Datetime format; the date-only
|
|
100
|
+
* variant (`YYYY-MM-DD`) is the most common form used in practice.
|
|
101
|
+
*
|
|
102
|
+
* @param date - A `Date` instance or an ISO 8601 date/datetime string.
|
|
103
|
+
* @returns The date formatted as `YYYY-MM-DD`.
|
|
104
|
+
*/
|
|
105
|
+
static formatDate(date) {
|
|
106
|
+
const d = typeof date === "string" ? new Date(date) : date;
|
|
107
|
+
return d.toISOString().slice(0, 10);
|
|
108
|
+
}
|
|
109
|
+
/**
|
|
110
|
+
* Escape the five XML special characters in a string.
|
|
111
|
+
*
|
|
112
|
+
* Prevents malformed XML when interpolating user-supplied URLs that may
|
|
113
|
+
* contain `&` (common in query strings), `<`, `>`, `"`, or `'`.
|
|
114
|
+
*
|
|
115
|
+
* @param value - The raw string to escape.
|
|
116
|
+
* @returns The string with `&`, `<`, `>`, `"`, and `'` replaced by their XML entities.
|
|
117
|
+
*/
|
|
118
|
+
static escapeXml(value) {
|
|
119
|
+
return value
|
|
120
|
+
.replace(/&/g, "&")
|
|
121
|
+
.replace(/</g, "<")
|
|
122
|
+
.replace(/>/g, ">")
|
|
123
|
+
.replace(/"/g, """)
|
|
124
|
+
.replace(/'/g, "'");
|
|
125
|
+
}
|
|
126
|
+
/**
|
|
127
|
+
* Serialise a list of formatted sitemap items into an XML sitemap string.
|
|
128
|
+
*
|
|
129
|
+
* Produces a complete `<?xml>` document with a `<urlset>` root element
|
|
130
|
+
* conforming to the Sitemaps 0.9 schema. Only non-null optional fields
|
|
131
|
+
* (`lastmod`, `changefreq`, `priority`) are included in the output.
|
|
132
|
+
*
|
|
133
|
+
* @param items - Formatted items (URLs resolved, dates formatted).
|
|
134
|
+
* @returns The complete XML sitemap as a string.
|
|
135
|
+
*/
|
|
136
|
+
toXml(items) {
|
|
137
|
+
const urlEntries = items
|
|
138
|
+
.map((item) => {
|
|
139
|
+
const parts = [
|
|
140
|
+
` <loc>${SitemapRenderer.escapeXml(String(item.loc))}</loc>`,
|
|
141
|
+
];
|
|
142
|
+
if (item.lastmod != null) {
|
|
143
|
+
parts.push(` <lastmod>${SitemapRenderer.escapeXml(String(item.lastmod))}</lastmod>`);
|
|
144
|
+
}
|
|
145
|
+
if (item.changefreq != null) {
|
|
146
|
+
parts.push(` <changefreq>${item.changefreq}</changefreq>`);
|
|
147
|
+
}
|
|
148
|
+
if (item.priority != null) {
|
|
149
|
+
parts.push(` <priority>${item.priority}</priority>`);
|
|
150
|
+
}
|
|
151
|
+
return ` <url>\n${parts.join("\n")}\n </url>`;
|
|
152
|
+
})
|
|
153
|
+
.join("\n");
|
|
154
|
+
return [
|
|
155
|
+
'<?xml version="1.0" encoding="UTF-8"?>',
|
|
156
|
+
'<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">',
|
|
157
|
+
urlEntries,
|
|
158
|
+
"</urlset>",
|
|
159
|
+
].join("\n");
|
|
160
|
+
}
|
|
161
|
+
/**
|
|
162
|
+
* Build the full XML string by loading items, applying formatting, and
|
|
163
|
+
* serialising to XML.
|
|
164
|
+
*/
|
|
165
|
+
async buildXml() {
|
|
166
|
+
const rawItems = await this.loadItems();
|
|
167
|
+
const items = this.formatItems(rawItems);
|
|
168
|
+
return this.toXml(items);
|
|
169
|
+
}
|
|
170
|
+
/**
|
|
171
|
+
* Render the sitemap to a web `ReadableStream`.
|
|
172
|
+
*
|
|
173
|
+
* Loads items from all getters, formats them, serialises to XML, and
|
|
174
|
+
* wraps the result in a `ReadableStream`. Sets `statusCode` to 200.
|
|
175
|
+
*
|
|
176
|
+
* @note This method is impure — it calls external data sources and mutates `statusCode`.
|
|
177
|
+
*
|
|
178
|
+
* @param _signal - Accepted for API compatibility with `JSXRenderer`. Not used.
|
|
179
|
+
* @returns A `ReadableStream` of the XML sitemap.
|
|
180
|
+
*/
|
|
181
|
+
renderToReadableStream = async (_signal) => {
|
|
182
|
+
const xml = await this.buildXml();
|
|
183
|
+
this.statusCode = 200;
|
|
184
|
+
this.statusReady = Promise.resolve();
|
|
185
|
+
return new ReadableStream({
|
|
186
|
+
start(controller) {
|
|
187
|
+
controller.enqueue(new TextEncoder().encode(xml));
|
|
188
|
+
controller.close();
|
|
189
|
+
},
|
|
190
|
+
});
|
|
191
|
+
};
|
|
192
|
+
/**
|
|
193
|
+
* Render the sitemap to a Node.js pipeable stream.
|
|
194
|
+
*
|
|
195
|
+
* Returns `{ pipe, abort }` synchronously. The actual XML generation is
|
|
196
|
+
* async (getters are called), so data is pushed to the stream when ready.
|
|
197
|
+
* `statusReady` resolves when the XML is built and `statusCode` is set.
|
|
198
|
+
*
|
|
199
|
+
* @note This method is impure — it calls external data sources and mutates `statusCode`.
|
|
200
|
+
*
|
|
201
|
+
* @returns The pipe/abort handles for the XML stream.
|
|
202
|
+
*/
|
|
203
|
+
renderToPipeableStream = () => {
|
|
204
|
+
/* v8 ignore next -- read() is a required no-op for push-based Readable streams */
|
|
205
|
+
const readable = new Readable({ read() { } });
|
|
206
|
+
let aborted = false;
|
|
207
|
+
this.statusReady = this.buildXml().then((xml) => {
|
|
208
|
+
this.statusCode = 200;
|
|
209
|
+
if (!aborted) {
|
|
210
|
+
readable.push(xml);
|
|
211
|
+
readable.push(null);
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
return {
|
|
215
|
+
pipe: (destination) => readable.pipe(destination),
|
|
216
|
+
abort: () => {
|
|
217
|
+
aborted = true;
|
|
218
|
+
readable.destroy();
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
};
|
|
222
|
+
/**
|
|
223
|
+
* Render the sitemap to a complete XML string.
|
|
224
|
+
*
|
|
225
|
+
* Loads items from all getters, formats them, and returns the serialised
|
|
226
|
+
* XML. Sets `statusCode` to 200.
|
|
227
|
+
*
|
|
228
|
+
* Async because the getters are async.
|
|
229
|
+
*
|
|
230
|
+
* @note This method is impure — it calls external data sources and mutates `statusCode`.
|
|
231
|
+
*
|
|
232
|
+
* @returns The complete XML sitemap string.
|
|
233
|
+
*/
|
|
234
|
+
renderToString = async () => {
|
|
235
|
+
const xml = await this.buildXml();
|
|
236
|
+
this.statusCode = 200;
|
|
237
|
+
this.statusReady = Promise.resolve();
|
|
238
|
+
return xml;
|
|
239
|
+
};
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=SitemapRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"SitemapRenderer.js","sourceRoot":"","sources":["../../../../src/lib/renderer/SitemapRenderer.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { Readable } from "node:stream";
|
|
2
|
+
/**
|
|
3
|
+
* Renders a plain-text document from async data sources.
|
|
4
|
+
*
|
|
5
|
+
* Produces output suitable for `llms.txt`, `humans.txt`, `security.txt`, or
|
|
6
|
+
* any text file that requires dynamic data (e.g. fetching page descriptions
|
|
7
|
+
* from a CMS for an LLM context file).
|
|
8
|
+
*
|
|
9
|
+
* The renderer is intentionally minimal — it accepts an array of async getters,
|
|
10
|
+
* each returning a string, and concatenates the results. No structure is imposed.
|
|
11
|
+
* The consumer controls formatting entirely.
|
|
12
|
+
*
|
|
13
|
+
* Implements the same three render methods and `statusCode` / `statusReady`
|
|
14
|
+
* contract as `JSXRenderer` and `SitemapRenderer`.
|
|
15
|
+
*
|
|
16
|
+
* @example
|
|
17
|
+
* ```ts
|
|
18
|
+
* const renderer = new TextRenderer([
|
|
19
|
+
* async () => "# My App\n\nContext for LLMs about this application.\n",
|
|
20
|
+
* async () => {
|
|
21
|
+
* const pages = await fetchPages();
|
|
22
|
+
* return pages.map(p => `- ${p.title}: ${p.url}`).join("\n");
|
|
23
|
+
* },
|
|
24
|
+
* ]);
|
|
25
|
+
*
|
|
26
|
+
* const stream = await renderer.renderToReadableStream();
|
|
27
|
+
* return new Response(stream, {
|
|
28
|
+
* status: renderer.statusCode,
|
|
29
|
+
* headers: { "Content-Type": "text/plain; charset=utf-8" },
|
|
30
|
+
* });
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export default class TextRenderer {
|
|
34
|
+
getters;
|
|
35
|
+
/**
|
|
36
|
+
* HTTP status code determined during rendering.
|
|
37
|
+
*
|
|
38
|
+
* Set to 200 on successful render. Errors from getters propagate as
|
|
39
|
+
* thrown exceptions — the consumer's error handler decides the status code.
|
|
40
|
+
*/
|
|
41
|
+
statusCode = 200;
|
|
42
|
+
/**
|
|
43
|
+
* Resolves when `statusCode` is determined.
|
|
44
|
+
*/
|
|
45
|
+
statusReady = Promise.resolve();
|
|
46
|
+
/**
|
|
47
|
+
* Create a text renderer.
|
|
48
|
+
*
|
|
49
|
+
* @param getters - Async functions that each return a string. Called
|
|
50
|
+
* sequentially (order matters) and concatenated into the final document.
|
|
51
|
+
*/
|
|
52
|
+
constructor(getters) {
|
|
53
|
+
this.getters = getters;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Build the full text by calling all getters sequentially and concatenating.
|
|
57
|
+
*/
|
|
58
|
+
async buildText() {
|
|
59
|
+
const parts = [];
|
|
60
|
+
for (const getter of this.getters) {
|
|
61
|
+
parts.push(await getter());
|
|
62
|
+
}
|
|
63
|
+
return parts.join("");
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Render to a web `ReadableStream`.
|
|
67
|
+
*
|
|
68
|
+
* @note This method is impure — it calls external data sources and mutates `statusCode`.
|
|
69
|
+
*
|
|
70
|
+
* @param _signal - Accepted for API compatibility. Not used.
|
|
71
|
+
* @returns A `ReadableStream` of the plain-text document.
|
|
72
|
+
*/
|
|
73
|
+
renderToReadableStream = async (_signal) => {
|
|
74
|
+
const text = await this.buildText();
|
|
75
|
+
this.statusCode = 200;
|
|
76
|
+
this.statusReady = Promise.resolve();
|
|
77
|
+
return new ReadableStream({
|
|
78
|
+
start(controller) {
|
|
79
|
+
controller.enqueue(new TextEncoder().encode(text));
|
|
80
|
+
controller.close();
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
};
|
|
84
|
+
/**
|
|
85
|
+
* Render to a Node.js pipeable stream.
|
|
86
|
+
*
|
|
87
|
+
* Returns `{ pipe, abort }` synchronously. Data is pushed when ready.
|
|
88
|
+
*
|
|
89
|
+
* @note This method is impure — it calls external data sources and mutates `statusCode`.
|
|
90
|
+
*/
|
|
91
|
+
renderToPipeableStream = () => {
|
|
92
|
+
/* v8 ignore next -- read() is a required no-op for push-based Readable streams */
|
|
93
|
+
const readable = new Readable({ read() { } });
|
|
94
|
+
let aborted = false;
|
|
95
|
+
this.statusReady = this.buildText().then((text) => {
|
|
96
|
+
this.statusCode = 200;
|
|
97
|
+
if (!aborted) {
|
|
98
|
+
readable.push(text);
|
|
99
|
+
readable.push(null);
|
|
100
|
+
}
|
|
101
|
+
});
|
|
102
|
+
return {
|
|
103
|
+
pipe: (destination) => readable.pipe(destination),
|
|
104
|
+
abort: () => {
|
|
105
|
+
aborted = true;
|
|
106
|
+
readable.destroy();
|
|
107
|
+
},
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
/**
|
|
111
|
+
* Render to a complete string.
|
|
112
|
+
*
|
|
113
|
+
* Async because the getters are async.
|
|
114
|
+
*
|
|
115
|
+
* @note This method is impure — it calls external data sources and mutates `statusCode`.
|
|
116
|
+
*/
|
|
117
|
+
renderToString = async () => {
|
|
118
|
+
const text = await this.buildText();
|
|
119
|
+
this.statusCode = 200;
|
|
120
|
+
this.statusReady = Promise.resolve();
|
|
121
|
+
return text;
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
//# sourceMappingURL=TextRenderer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TextRenderer.js","sourceRoot":"","sources":["../../../../src/lib/renderer/TextRenderer.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAGvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,CAAC,OAAO,OAAO,YAAY;IAoBA;IAnB/B;;;;;OAKG;IACI,UAAU,GAAG,GAAG,CAAC;IAExB;;OAEG;IACI,WAAW,GAAkB,OAAO,CAAC,OAAO,EAAE,CAAC;IAEtD;;;;;OAKG;IACH,YAA+B,OAA8B;QAA9B,YAAO,GAAP,OAAO,CAAuB;IAAG,CAAC;IAEjE;;OAEG;IACO,KAAK,CAAC,SAAS;QACvB,MAAM,KAAK,GAAa,EAAE,CAAC;QAC3B,KAAK,MAAM,MAAM,IAAI,IAAI,CAAC,OAAO,EAAE,CAAC;YAClC,KAAK,CAAC,IAAI,CAAC,MAAM,MAAM,EAAE,CAAC,CAAC;QAC7B,CAAC;QACD,OAAO,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACxB,CAAC;IAED;;;;;;;OAOG;IACH,sBAAsB,GAAG,KAAK,EAC5B,OAAqB,EACI,EAAE;QAC3B,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QAErC,OAAO,IAAI,cAAc,CAAC;YACxB,KAAK,CAAC,UAAU;gBACd,UAAU,CAAC,OAAO,CAAC,IAAI,WAAW,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC;gBACnD,UAAU,CAAC,KAAK,EAAE,CAAC;YACrB,CAAC;SACF,CAAC,CAAC;IACL,CAAC,CAAC;IAEF;;;;;;OAMG;IACH,sBAAsB,GAAG,GAAyB,EAAE;QAClD,kFAAkF;QAClF,MAAM,QAAQ,GAAG,IAAI,QAAQ,CAAC,EAAE,IAAI,KAAI,CAAC,EAAE,CAAC,CAAC;QAC7C,IAAI,OAAO,GAAG,KAAK,CAAC;QAEpB,IAAI,CAAC,WAAW,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE;YAChD,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;YACtB,IAAI,CAAC,OAAO,EAAE,CAAC;gBACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;gBACpB,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACtB,CAAC;QACH,CAAC,CAAC,CAAC;QAEH,OAAO;YACL,IAAI,EAAE,CAAkC,WAAc,EAAE,EAAE,CACxD,QAAQ,CAAC,IAAI,CAAC,WAAW,CAAC;YAC5B,KAAK,EAAE,GAAG,EAAE;gBACV,OAAO,GAAG,IAAI,CAAC;gBACf,QAAQ,CAAC,OAAO,EAAE,CAAC;YACrB,CAAC;SACF,CAAC;IACJ,CAAC,CAAC;IAEF;;;;;;OAMG;IACH,cAAc,GAAG,KAAK,IAAqB,EAAE;QAC3C,MAAM,IAAI,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,CAAC;QACpC,IAAI,CAAC,UAAU,GAAG,GAAG,CAAC;QACtB,IAAI,CAAC,WAAW,GAAG,OAAO,CAAC,OAAO,EAAE,CAAC;QACrC,OAAO,IAAI,CAAC;IACd,CAAC,CAAC;CACH"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../../../src/lib/renderer/constants.ts"],"names":[],"mappings":"AAAA,MAAM,CAAC,MAAM,gBAAgB,GAAG,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export * from "./constants.js";
|
|
2
|
+
export { default as Extractor } from "./Extractor.js";
|
|
3
|
+
export { default as JSXRenderer } from "./JSXRenderer.js";
|
|
4
|
+
export { default as SitemapRenderer } from "./SitemapRenderer.js";
|
|
5
|
+
export { default as TextRenderer } from "./TextRenderer.js";
|
|
6
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/renderer/index.ts"],"names":[],"mappings":"AAAA,cAAc,gBAAgB,CAAC;AAC/B,OAAO,EAAE,OAAO,IAAI,SAAS,EAAE,MAAM,gBAAgB,CAAC;AACtD,OAAO,EAAE,OAAO,IAAI,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC1D,OAAO,EAAE,OAAO,IAAI,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAClE,OAAO,EAAE,OAAO,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type contracts for the SSR renderer domain.
|
|
3
|
+
*
|
|
4
|
+
* These types define the interface between renderers (which produce HTML or XML
|
|
5
|
+
* content and record metadata like status codes) and server adapters (which
|
|
6
|
+
* deliver that content over HTTP). Renderers are transport-agnostic — they
|
|
7
|
+
* never write to a response object.
|
|
8
|
+
*/
|
|
9
|
+
export {};
|
|
10
|
+
//# sourceMappingURL=types.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../../../../src/lib/renderer/types.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../src/lib/server/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAC"}
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience wrapper that adapts a renderer factory into a Node.js `(req, res)` handler
|
|
3
|
+
* for pipeable stream rendering.
|
|
4
|
+
*
|
|
5
|
+
* Calls the factory with each incoming request. The factory is expected to construct
|
|
6
|
+
* a renderer (with per-request context like locale, auth, theme) and call
|
|
7
|
+
* `renderToPipeableStream()` on it. This wrapper then awaits `statusReady`, writes
|
|
8
|
+
* headers with the renderer's `statusCode`, and pipes the stream to the response.
|
|
9
|
+
*
|
|
10
|
+
* Does not set `Content-Type` — the consumer controls headers through the factory
|
|
11
|
+
* or by wrapping this handler. Defaults to `text/html; charset=utf-8`.
|
|
12
|
+
*
|
|
13
|
+
* @note This function is impure — it writes to the HTTP response.
|
|
14
|
+
*
|
|
15
|
+
* @param factory - A function that receives the request and returns a renderer.
|
|
16
|
+
* The renderer must have `renderToPipeableStream()`, `statusCode`, and `statusReady`.
|
|
17
|
+
* @returns A Node.js request handler suitable for `app.use()` or `http.createServer()`.
|
|
18
|
+
*
|
|
19
|
+
* @example
|
|
20
|
+
* ```ts
|
|
21
|
+
* import { JSXRenderer } from "@canonical/react-ssr/renderer";
|
|
22
|
+
* import { serveStream } from "@canonical/react-ssr/server";
|
|
23
|
+
*
|
|
24
|
+
* app.use(serveStream((req) => {
|
|
25
|
+
* return new JSXRenderer(
|
|
26
|
+
* EntryServer,
|
|
27
|
+
* { locale: getLocale(req), user: getUser(req) },
|
|
28
|
+
* { htmlString },
|
|
29
|
+
* );
|
|
30
|
+
* }));
|
|
31
|
+
* ```
|
|
32
|
+
*/
|
|
33
|
+
export function serveStream(factory) {
|
|
34
|
+
return async (req, res) => {
|
|
35
|
+
try {
|
|
36
|
+
const renderer = factory(req);
|
|
37
|
+
const result = renderer.renderToPipeableStream();
|
|
38
|
+
await renderer.statusReady;
|
|
39
|
+
res.writeHead(renderer.statusCode, {
|
|
40
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
41
|
+
});
|
|
42
|
+
result.pipe(res);
|
|
43
|
+
/* v8 ignore next -- finish event fires after stream completes; not triggered in unit tests */
|
|
44
|
+
res.on("finish", () => res.end());
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
console.error("Error during rendering:", error);
|
|
48
|
+
res.statusCode = 500;
|
|
49
|
+
res.end("Internal server error");
|
|
50
|
+
}
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
//# sourceMappingURL=serveStream.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serveStream.js","sourceRoot":"","sources":["../../../../src/lib/server/serveStream.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AACH,MAAM,UAAU,WAAW,CACzB,OAMC;IAED,OAAO,KAAK,EAAE,GAAoB,EAAE,GAAmB,EAAE,EAAE;QACzD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,MAAM,GAAG,QAAQ,CAAC,sBAAsB,EAAE,CAAC;YACjD,MAAM,QAAQ,CAAC,WAAW,CAAC;YAC3B,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE;gBACjC,cAAc,EAAE,0BAA0B;aAC3C,CAAC,CAAC;YACH,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;YACjB,8FAA8F;YAC9F,GAAG,CAAC,EAAE,CAAC,QAAQ,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,GAAG,EAAE,CAAC,CAAC;QACpC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Convenience wrapper that adapts a renderer factory into a Node.js `(req, res)` handler
|
|
3
|
+
* for string rendering.
|
|
4
|
+
*
|
|
5
|
+
* Calls the factory with each incoming request. The factory is expected to construct
|
|
6
|
+
* a renderer (with per-request context like locale, auth, theme) and call
|
|
7
|
+
* `renderToString()` on it. This wrapper then writes headers with the renderer's
|
|
8
|
+
* `statusCode` and sends the HTML string as the response body.
|
|
9
|
+
*
|
|
10
|
+
* Does not set `Content-Type` — defaults to `text/html; charset=utf-8`.
|
|
11
|
+
*
|
|
12
|
+
* @note This function is impure — it writes to the HTTP response.
|
|
13
|
+
*
|
|
14
|
+
* @param factory - A function that receives the request and returns a renderer.
|
|
15
|
+
* The renderer must have `renderToString()` and `statusCode`.
|
|
16
|
+
* @returns A Node.js request handler suitable for `app.use()` or `http.createServer()`.
|
|
17
|
+
*
|
|
18
|
+
* @example
|
|
19
|
+
* ```ts
|
|
20
|
+
* import { JSXRenderer } from "@canonical/react-ssr/renderer";
|
|
21
|
+
* import { serveString } from "@canonical/react-ssr/server";
|
|
22
|
+
*
|
|
23
|
+
* app.use(serveString((req) => {
|
|
24
|
+
* return new JSXRenderer(
|
|
25
|
+
* EntryServer,
|
|
26
|
+
* { locale: getLocale(req), user: getUser(req) },
|
|
27
|
+
* { htmlString },
|
|
28
|
+
* );
|
|
29
|
+
* }));
|
|
30
|
+
* ```
|
|
31
|
+
*/
|
|
32
|
+
export function serveString(factory) {
|
|
33
|
+
return (req, res) => {
|
|
34
|
+
try {
|
|
35
|
+
const renderer = factory(req);
|
|
36
|
+
const body = renderer.renderToString();
|
|
37
|
+
res.writeHead(renderer.statusCode, {
|
|
38
|
+
"Content-Type": "text/html; charset=utf-8",
|
|
39
|
+
});
|
|
40
|
+
res.end(body);
|
|
41
|
+
}
|
|
42
|
+
catch (error) {
|
|
43
|
+
console.error("Error during rendering:", error);
|
|
44
|
+
res.statusCode = 500;
|
|
45
|
+
res.end("Internal server error");
|
|
46
|
+
}
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
//# sourceMappingURL=serveString.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serveString.js","sourceRoot":"","sources":["../../../../src/lib/server/serveString.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8BG;AACH,MAAM,UAAU,WAAW,CACzB,OAGC;IAED,OAAO,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;QACnD,IAAI,CAAC;YACH,MAAM,QAAQ,GAAG,OAAO,CAAC,GAAG,CAAC,CAAC;YAC9B,MAAM,IAAI,GAAG,QAAQ,CAAC,cAAc,EAAE,CAAC;YACvC,GAAG,CAAC,SAAS,CAAC,QAAQ,CAAC,UAAU,EAAE;gBACjC,cAAc,EAAE,0BAA0B;aAC3C,CAAC,CAAC;YACH,GAAG,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QAChB,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,OAAO,CAAC,KAAK,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAC;YAChD,GAAG,CAAC,UAAU,GAAG,GAAG,CAAC;YACrB,GAAG,CAAC,GAAG,CAAC,uBAAuB,CAAC,CAAC;QACnC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Standalone Express server for serving an SSR application.
|
|
4
|
+
*
|
|
5
|
+
* Dynamically imports a renderer module that exports a factory function.
|
|
6
|
+
* The factory receives a Node `IncomingMessage` and returns a renderer.
|
|
7
|
+
* Supports both streaming and string rendering modes.
|
|
8
|
+
*
|
|
9
|
+
* @example
|
|
10
|
+
* ```sh
|
|
11
|
+
* # String rendering (default), one static directory
|
|
12
|
+
* serve-express dist/server/renderer.js --static assets:dist/client/assets
|
|
13
|
+
*
|
|
14
|
+
* # Streaming, multiple static directories
|
|
15
|
+
* serve-express dist/server/renderer.js --streaming \
|
|
16
|
+
* --static assets:dist/client/assets \
|
|
17
|
+
* --static public:dist/client/public
|
|
18
|
+
*
|
|
19
|
+
* # Custom port
|
|
20
|
+
* serve-express dist/server/renderer.js -p 3000 --static assets:dist/client/assets
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export {};
|
|
24
|
+
//# sourceMappingURL=serve-express.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"serve-express.d.ts","sourceRoot":"","sources":["../../../src/bin/serve-express.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;;;;;GAoBG"}
|
package/dist/types/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * as renderer from "./renderer/index.js";
|
|
2
|
-
export * as server from "./server/index.js";
|
|
1
|
+
export * as renderer from "./lib/renderer/index.js";
|
|
2
|
+
export * as server from "./lib/server/index.js";
|
|
3
3
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,yBAAyB,CAAC;AACpD,OAAO,KAAK,MAAM,MAAM,uBAAuB,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/lib/index.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,QAAQ,MAAM,qBAAqB,CAAC;AAChD,OAAO,KAAK,MAAM,MAAM,mBAAmB,CAAC"}
|