@taujs/server 0.1.3 → 0.1.5
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/README.md +8 -0
- package/dist/index.d.ts +58 -28
- package/dist/index.js +149 -66
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -14,6 +14,14 @@ Supports rendering modes:
|
|
|
14
14
|
- Server-side rendering (SSR)
|
|
15
15
|
- Streaming SSR
|
|
16
16
|
|
|
17
|
+
Supported application structure and composition:
|
|
18
|
+
|
|
19
|
+
- Single-page Application (SPA)
|
|
20
|
+
- Multi-page Application (MPA)
|
|
21
|
+
- Build-time Micro-Frontends, server orchestration and delivery
|
|
22
|
+
|
|
23
|
+
Assemble independently built frontends at build time incorporating flexible per-route SPA-MPA hybrid with CSR, SSR, and Streaming SSR, rendering options.
|
|
24
|
+
|
|
17
25
|
Fastify Plugin for integration with taujs [ τjs ] template https://github.com/aoede3/taujs
|
|
18
26
|
|
|
19
27
|
- Production: Fastify, React
|
package/dist/index.d.ts
CHANGED
|
@@ -5,8 +5,46 @@ declare const RENDERTYPE: {
|
|
|
5
5
|
ssr: string;
|
|
6
6
|
streaming: string;
|
|
7
7
|
};
|
|
8
|
+
declare const TEMPLATE: {
|
|
9
|
+
defaultEntryClient: string;
|
|
10
|
+
defaultEntryServer: string;
|
|
11
|
+
defaultHtmlTemplate: string;
|
|
12
|
+
};
|
|
8
13
|
|
|
14
|
+
declare const createMaps: () => {
|
|
15
|
+
bootstrapModules: Map<string, string>;
|
|
16
|
+
cssLinks: Map<string, string>;
|
|
17
|
+
manifests: Map<string, Manifest>;
|
|
18
|
+
preloadLinks: Map<string, string>;
|
|
19
|
+
renderModules: Map<string, RenderModule>;
|
|
20
|
+
ssrManifests: Map<string, SSRManifest>;
|
|
21
|
+
templates: Map<string, string>;
|
|
22
|
+
};
|
|
23
|
+
declare const processConfigs: (configs: Config[], baseClientRoot: string, templateDefaults: typeof TEMPLATE) => ProcessedConfig[];
|
|
9
24
|
declare const SSRServer: FastifyPluginAsync<SSRServerOptions>;
|
|
25
|
+
type Config = {
|
|
26
|
+
appId: string;
|
|
27
|
+
entryPoint: string;
|
|
28
|
+
entryClient?: string;
|
|
29
|
+
entryServer?: string;
|
|
30
|
+
htmlTemplate?: string;
|
|
31
|
+
};
|
|
32
|
+
type ProcessedConfig = {
|
|
33
|
+
appId: string;
|
|
34
|
+
clientRoot: string;
|
|
35
|
+
entryClient: string;
|
|
36
|
+
entryPoint: string;
|
|
37
|
+
entryServer: string;
|
|
38
|
+
htmlTemplate: string;
|
|
39
|
+
};
|
|
40
|
+
type SSRServerOptions = {
|
|
41
|
+
alias?: Record<string, string>;
|
|
42
|
+
clientRoot: string;
|
|
43
|
+
configs: Config[];
|
|
44
|
+
routes: Route<RouteParams>[];
|
|
45
|
+
serviceRegistry: ServiceRegistry;
|
|
46
|
+
isDebug?: boolean;
|
|
47
|
+
};
|
|
10
48
|
type ServiceRegistry = {
|
|
11
49
|
[serviceName: string]: {
|
|
12
50
|
[methodName: string]: (params: Record<string, unknown>) => Promise<Record<string, unknown>>;
|
|
@@ -25,25 +63,19 @@ type FetchConfig = {
|
|
|
25
63
|
serviceName?: string;
|
|
26
64
|
serviceMethod?: string;
|
|
27
65
|
};
|
|
28
|
-
type
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
66
|
+
type SSRManifest = {
|
|
67
|
+
[key: string]: string[];
|
|
68
|
+
};
|
|
69
|
+
type ManifestEntry = {
|
|
70
|
+
file: string;
|
|
71
|
+
src?: string;
|
|
72
|
+
isDynamicEntry?: boolean;
|
|
73
|
+
imports?: string[];
|
|
74
|
+
css?: string[];
|
|
75
|
+
assets?: string[];
|
|
37
76
|
};
|
|
38
77
|
type Manifest = {
|
|
39
|
-
[key: string]:
|
|
40
|
-
file: string;
|
|
41
|
-
src?: string;
|
|
42
|
-
isDynamicEntry?: boolean;
|
|
43
|
-
imports?: string[];
|
|
44
|
-
css?: string[];
|
|
45
|
-
assets?: string[];
|
|
46
|
-
};
|
|
78
|
+
[key: string]: ManifestEntry;
|
|
47
79
|
};
|
|
48
80
|
type RenderSSR = (initialDataResolved: Record<string, unknown>, location: string, meta?: Record<string, unknown>) => Promise<{
|
|
49
81
|
headContent: string;
|
|
@@ -58,20 +90,18 @@ type RenderModule = {
|
|
|
58
90
|
type RouteAttributes<Params = {}> = {
|
|
59
91
|
fetch?: (params?: Params, options?: RequestInit & {
|
|
60
92
|
params?: Record<string, unknown>;
|
|
61
|
-
}) => Promise<
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
};
|
|
65
|
-
serviceName?: string;
|
|
66
|
-
serviceMethod?: string;
|
|
67
|
-
url?: string;
|
|
68
|
-
}>;
|
|
93
|
+
}) => Promise<FetchConfig>;
|
|
94
|
+
} & ({
|
|
95
|
+
render?: typeof RENDERTYPE.ssr;
|
|
69
96
|
meta?: Record<string, unknown>;
|
|
70
|
-
|
|
71
|
-
|
|
97
|
+
} | {
|
|
98
|
+
render: typeof RENDERTYPE.streaming;
|
|
99
|
+
meta: Record<string, unknown>;
|
|
100
|
+
});
|
|
72
101
|
type Route<Params = {}> = {
|
|
73
102
|
attr?: RouteAttributes<Params>;
|
|
74
103
|
path: string;
|
|
104
|
+
appId?: string;
|
|
75
105
|
};
|
|
76
106
|
interface InitialRouteParams extends Record<string, unknown> {
|
|
77
107
|
serviceName?: string;
|
|
@@ -80,4 +110,4 @@ interface InitialRouteParams extends Record<string, unknown> {
|
|
|
80
110
|
type RouteParams = InitialRouteParams & Record<string, unknown>;
|
|
81
111
|
type RoutePathsAndAttributes<Params = {}> = Omit<Route<Params>, 'element'>;
|
|
82
112
|
|
|
83
|
-
export { type FetchConfig, type InitialRouteParams, type Manifest, type RenderCallbacks, type RenderModule, type RenderSSR, type RenderStream, type Route, type RouteAttributes, type RouteParams, type RoutePathsAndAttributes, SSRServer, type SSRServerOptions, type ServiceRegistry };
|
|
113
|
+
export { type Config, type FetchConfig, type InitialRouteParams, type Manifest, type ManifestEntry, type ProcessedConfig, type RenderCallbacks, type RenderModule, type RenderSSR, type RenderStream, type Route, type RouteAttributes, type RouteParams, type RoutePathsAndAttributes, type SSRManifest, SSRServer, type SSRServerOptions, type ServiceRegistry, TEMPLATE, createMaps, processConfigs };
|
package/dist/index.js
CHANGED
|
@@ -118,7 +118,7 @@ var require_plugin = __commonJS({
|
|
|
118
118
|
// src/SSRServer.ts
|
|
119
119
|
var import_fastify_plugin = __toESM(require_plugin(), 1);
|
|
120
120
|
import { readFile } from "node:fs/promises";
|
|
121
|
-
import
|
|
121
|
+
import path2 from "node:path";
|
|
122
122
|
import { createViteRuntime } from "vite";
|
|
123
123
|
|
|
124
124
|
// src/constants.ts
|
|
@@ -130,10 +130,16 @@ var SSRTAG = {
|
|
|
130
130
|
ssrHead: "<!--ssr-head-->",
|
|
131
131
|
ssrHtml: "<!--ssr-html-->"
|
|
132
132
|
};
|
|
133
|
+
var TEMPLATE = {
|
|
134
|
+
defaultEntryClient: "entry-client",
|
|
135
|
+
defaultEntryServer: "entry-server",
|
|
136
|
+
defaultHtmlTemplate: "index.html"
|
|
137
|
+
};
|
|
133
138
|
|
|
134
139
|
// src/utils/Utils.ts
|
|
135
|
-
import { fileURLToPath } from "node:url";
|
|
136
140
|
import { dirname, join } from "node:path";
|
|
141
|
+
import "node:path";
|
|
142
|
+
import { fileURLToPath } from "node:url";
|
|
137
143
|
import { match } from "path-to-regexp";
|
|
138
144
|
var isDevelopment = process.env.NODE_ENV === "development";
|
|
139
145
|
var __filename = fileURLToPath(import.meta.url);
|
|
@@ -163,20 +169,20 @@ async function collectStyleUrls(server, entries) {
|
|
|
163
169
|
await Promise.all(entries.map((url) => traverse(url)));
|
|
164
170
|
return [...visited].filter((url) => url.match(CSS_LANGS_RE));
|
|
165
171
|
}
|
|
166
|
-
function renderPreloadLinks(
|
|
172
|
+
function renderPreloadLinks(ssrManifest, basePath = "") {
|
|
167
173
|
const seen = /* @__PURE__ */ new Set();
|
|
168
174
|
let links = "";
|
|
169
|
-
|
|
170
|
-
const files =
|
|
175
|
+
for (const moduleId in ssrManifest) {
|
|
176
|
+
const files = ssrManifest[moduleId];
|
|
171
177
|
if (files) {
|
|
172
178
|
files.forEach((file) => {
|
|
173
179
|
if (!seen.has(file)) {
|
|
174
180
|
seen.add(file);
|
|
175
|
-
links += renderPreloadLink(file);
|
|
181
|
+
links += renderPreloadLink(basePath ? `${basePath}/${file}` : `${file}`);
|
|
176
182
|
}
|
|
177
183
|
});
|
|
178
184
|
}
|
|
179
|
-
}
|
|
185
|
+
}
|
|
180
186
|
return links;
|
|
181
187
|
}
|
|
182
188
|
function renderPreloadLink(file) {
|
|
@@ -248,17 +254,22 @@ var matchRoute = (url, renderRoutes) => {
|
|
|
248
254
|
}
|
|
249
255
|
return null;
|
|
250
256
|
};
|
|
251
|
-
|
|
252
|
-
const
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
257
|
+
function getCssLinks(manifest, basePath = "") {
|
|
258
|
+
const seen = /* @__PURE__ */ new Set();
|
|
259
|
+
const styles = [];
|
|
260
|
+
for (const key in manifest) {
|
|
261
|
+
const entry = manifest[key];
|
|
262
|
+
if (entry && entry.css) {
|
|
263
|
+
for (const cssFile of entry.css) {
|
|
264
|
+
if (!seen.has(cssFile)) {
|
|
265
|
+
seen.add(cssFile);
|
|
266
|
+
styles.push(`<link rel="preload stylesheet" as="style" type="text/css" href="${basePath}/${cssFile}">`);
|
|
267
|
+
}
|
|
268
|
+
}
|
|
258
269
|
}
|
|
259
270
|
}
|
|
260
|
-
return
|
|
261
|
-
}
|
|
271
|
+
return styles.join("\n");
|
|
272
|
+
}
|
|
262
273
|
var overrideCSSHMRConsoleError = () => {
|
|
263
274
|
const originalConsoleError = console.error;
|
|
264
275
|
console.error = function(message, ...optionalParams) {
|
|
@@ -266,29 +277,76 @@ var overrideCSSHMRConsoleError = () => {
|
|
|
266
277
|
originalConsoleError.apply(console, [message, ...optionalParams]);
|
|
267
278
|
};
|
|
268
279
|
};
|
|
280
|
+
var ensureNonNull = (value, errorMessage) => {
|
|
281
|
+
if (value === void 0 || value === null) throw new Error(errorMessage);
|
|
282
|
+
return value;
|
|
283
|
+
};
|
|
269
284
|
|
|
270
285
|
// src/SSRServer.ts
|
|
286
|
+
var createMaps = () => {
|
|
287
|
+
return {
|
|
288
|
+
bootstrapModules: /* @__PURE__ */ new Map(),
|
|
289
|
+
cssLinks: /* @__PURE__ */ new Map(),
|
|
290
|
+
manifests: /* @__PURE__ */ new Map(),
|
|
291
|
+
preloadLinks: /* @__PURE__ */ new Map(),
|
|
292
|
+
renderModules: /* @__PURE__ */ new Map(),
|
|
293
|
+
ssrManifests: /* @__PURE__ */ new Map(),
|
|
294
|
+
templates: /* @__PURE__ */ new Map()
|
|
295
|
+
};
|
|
296
|
+
};
|
|
297
|
+
var processConfigs = (configs, baseClientRoot, templateDefaults) => {
|
|
298
|
+
return configs.map((config) => {
|
|
299
|
+
const clientRoot = path2.resolve(baseClientRoot, config.entryPoint);
|
|
300
|
+
return {
|
|
301
|
+
clientRoot,
|
|
302
|
+
entryPoint: config.entryPoint,
|
|
303
|
+
entryClient: config.entryClient || templateDefaults.defaultEntryClient,
|
|
304
|
+
entryServer: config.entryServer || templateDefaults.defaultEntryServer,
|
|
305
|
+
htmlTemplate: config.htmlTemplate || templateDefaults.defaultHtmlTemplate,
|
|
306
|
+
appId: config.appId
|
|
307
|
+
};
|
|
308
|
+
});
|
|
309
|
+
};
|
|
271
310
|
var SSRServer = (0, import_fastify_plugin.default)(
|
|
272
311
|
async (app, opts) => {
|
|
273
|
-
const { alias,
|
|
274
|
-
const
|
|
275
|
-
const
|
|
276
|
-
const
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
312
|
+
const { alias, configs, routes, serviceRegistry, isDebug, clientRoot: baseClientRoot } = opts;
|
|
313
|
+
const { bootstrapModules, cssLinks, manifests, preloadLinks, renderModules, ssrManifests, templates } = createMaps();
|
|
314
|
+
const processedConfigs = processConfigs(configs, baseClientRoot, TEMPLATE);
|
|
315
|
+
for (const config of processedConfigs) {
|
|
316
|
+
const { clientRoot, entryClient, htmlTemplate } = config;
|
|
317
|
+
const templateHtmlPath = path2.join(clientRoot, htmlTemplate);
|
|
318
|
+
const templateHtml = await readFile(templateHtmlPath, "utf-8");
|
|
319
|
+
templates.set(clientRoot, templateHtml);
|
|
320
|
+
const relativeBasePath = path2.relative(baseClientRoot, clientRoot).replace(/\\/g, "/");
|
|
321
|
+
const adjustedRelativePath = relativeBasePath ? `/${relativeBasePath}` : "";
|
|
322
|
+
if (!isDevelopment) {
|
|
323
|
+
const manifestPath = path2.join(clientRoot, ".vite/manifest.json");
|
|
324
|
+
const manifestContent = await readFile(manifestPath, "utf-8");
|
|
325
|
+
const manifest = JSON.parse(manifestContent);
|
|
326
|
+
manifests.set(clientRoot, manifest);
|
|
327
|
+
const ssrManifestPath = path2.join(clientRoot, ".vite/ssr-manifest.json");
|
|
328
|
+
const ssrManifestContent = await readFile(ssrManifestPath, "utf-8");
|
|
329
|
+
const ssrManifest = JSON.parse(ssrManifestContent);
|
|
330
|
+
ssrManifests.set(clientRoot, ssrManifest);
|
|
331
|
+
const entryClientFile = manifest[`${entryClient}.tsx`]?.file;
|
|
332
|
+
if (!entryClientFile) throw new Error(`Entry client file not found in manifest for ${entryClient}.tsx`);
|
|
333
|
+
const bootstrapModule = `/${adjustedRelativePath}/${entryClientFile}`.replace(/\/{2,}/g, "/");
|
|
334
|
+
bootstrapModules.set(clientRoot, bootstrapModule);
|
|
335
|
+
const preloadLink = renderPreloadLinks(ssrManifest, adjustedRelativePath);
|
|
336
|
+
preloadLinks.set(clientRoot, preloadLink);
|
|
337
|
+
const cssLink = getCssLinks(manifest, adjustedRelativePath);
|
|
338
|
+
cssLinks.set(clientRoot, cssLink);
|
|
339
|
+
} else {
|
|
340
|
+
const bootstrapModule = `/${adjustedRelativePath}/${entryClient}`.replace(/\/{2,}/g, "/");
|
|
341
|
+
bootstrapModules.set(clientRoot, bootstrapModule);
|
|
342
|
+
}
|
|
343
|
+
}
|
|
286
344
|
let viteDevServer;
|
|
287
345
|
let viteRuntime;
|
|
288
|
-
|
|
346
|
+
await app.register(import("@fastify/static"), {
|
|
289
347
|
index: false,
|
|
290
348
|
prefix: "/",
|
|
291
|
-
root:
|
|
349
|
+
root: baseClientRoot,
|
|
292
350
|
wildcard: false
|
|
293
351
|
});
|
|
294
352
|
if (isDevelopment) {
|
|
@@ -306,31 +364,27 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
306
364
|
plugins: [
|
|
307
365
|
...isDebug ? [
|
|
308
366
|
{
|
|
367
|
+
name: "taujs-development-server-debug-logging",
|
|
309
368
|
configureServer(server) {
|
|
310
|
-
console.log("\u03C4js
|
|
369
|
+
console.log("\u03C4js development server debug started.");
|
|
311
370
|
server.middlewares.use((req, res, next) => {
|
|
312
371
|
console.log(`rx: ${req.url}`);
|
|
313
|
-
res.on("finish", () => {
|
|
314
|
-
console.log(`tx: ${req.url}`);
|
|
315
|
-
});
|
|
372
|
+
res.on("finish", () => console.log(`tx: ${req.url}`));
|
|
316
373
|
next();
|
|
317
374
|
});
|
|
318
|
-
}
|
|
319
|
-
name: "taujs-ssr-server-debug-logging"
|
|
375
|
+
}
|
|
320
376
|
}
|
|
321
377
|
] : []
|
|
322
378
|
],
|
|
323
379
|
resolve: {
|
|
324
380
|
alias: {
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
"@shared": path.resolve(__dirname, "../shared")
|
|
329
|
-
},
|
|
381
|
+
"@client": path2.resolve(baseClientRoot),
|
|
382
|
+
"@server": path2.resolve(__dirname),
|
|
383
|
+
"@shared": path2.resolve(__dirname, "../shared"),
|
|
330
384
|
...alias
|
|
331
385
|
}
|
|
332
386
|
},
|
|
333
|
-
root:
|
|
387
|
+
root: baseClientRoot,
|
|
334
388
|
server: {
|
|
335
389
|
middlewareMode: true,
|
|
336
390
|
hmr: {
|
|
@@ -340,17 +394,15 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
340
394
|
});
|
|
341
395
|
viteRuntime = await createViteRuntime(viteDevServer);
|
|
342
396
|
overrideCSSHMRConsoleError();
|
|
343
|
-
|
|
397
|
+
app.addHook("onRequest", async (request, reply) => {
|
|
344
398
|
await new Promise((resolve) => {
|
|
345
399
|
viteDevServer.middlewares(request.raw, reply.raw, () => {
|
|
346
400
|
if (!reply.sent) resolve();
|
|
347
401
|
});
|
|
348
402
|
});
|
|
349
403
|
});
|
|
350
|
-
} else {
|
|
351
|
-
renderModule = await import(path.join(clientRoot, `${clientEntryServer}.js`));
|
|
352
404
|
}
|
|
353
|
-
|
|
405
|
+
app.get("/*", async (req, reply) => {
|
|
354
406
|
try {
|
|
355
407
|
if (/\.\w+$/.test(req.raw.url ?? "")) return reply.callNotFound();
|
|
356
408
|
const url = req.url ? new URL(req.url, `http://${req.headers.host}`).pathname : "/";
|
|
@@ -359,26 +411,49 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
359
411
|
reply.callNotFound();
|
|
360
412
|
return;
|
|
361
413
|
}
|
|
414
|
+
const { route, params } = matchedRoute;
|
|
415
|
+
const { attr, appId } = route;
|
|
416
|
+
const config = processedConfigs.find((config2) => config2.appId === appId) || processedConfigs[0];
|
|
417
|
+
if (!config) throw new Error("No configuration found for the request.");
|
|
418
|
+
const { clientRoot, entryServer } = config;
|
|
419
|
+
let template = ensureNonNull(templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
|
|
420
|
+
const bootstrapModule = bootstrapModules.get(clientRoot);
|
|
421
|
+
const cssLink = cssLinks.get(clientRoot);
|
|
422
|
+
const manifest = manifests.get(clientRoot);
|
|
423
|
+
const preloadLink = preloadLinks.get(clientRoot);
|
|
424
|
+
const ssrManifest = ssrManifests.get(clientRoot);
|
|
425
|
+
let renderModule;
|
|
362
426
|
if (isDevelopment) {
|
|
363
427
|
template = template.replace(/<script type="module" src="\/@vite\/client"><\/script>/g, "");
|
|
364
428
|
template = template.replace(/<style type="text\/css">[\s\S]*?<\/style>/g, "");
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
429
|
+
const entryServerPath = path2.join(clientRoot, `${entryServer}.tsx`);
|
|
430
|
+
const executedModule = await viteRuntime.executeEntrypoint(entryServerPath);
|
|
431
|
+
renderModule = executedModule;
|
|
432
|
+
const styles = await collectStyle(viteDevServer, [entryServerPath]);
|
|
433
|
+
template = template?.replace("</head>", `<style type="text/css">${styles}</style></head>`);
|
|
368
434
|
template = await viteDevServer.transformIndexHtml(url, template);
|
|
435
|
+
} else {
|
|
436
|
+
renderModule = renderModules.get(clientRoot);
|
|
437
|
+
if (!renderModule) {
|
|
438
|
+
const renderModulePath = path2.join(clientRoot, `${entryServer}.js`);
|
|
439
|
+
const importedModule = await import(renderModulePath);
|
|
440
|
+
renderModule = importedModule;
|
|
441
|
+
renderModules.set(clientRoot, renderModule);
|
|
442
|
+
}
|
|
369
443
|
}
|
|
370
|
-
const
|
|
371
|
-
const
|
|
372
|
-
const
|
|
373
|
-
const [beforeBody = "", afterBody] = template.split(SSRTAG.ssrHtml);
|
|
374
|
-
const [beforeHead, afterHead] = beforeBody.split(SSRTAG.ssrHead);
|
|
444
|
+
const renderType = attr?.render || RENDERTYPE.ssr;
|
|
445
|
+
const [beforeBody = "", afterBody = ""] = template.split(SSRTAG.ssrHtml);
|
|
446
|
+
const [beforeHead = "", afterHead = ""] = beforeBody.split(SSRTAG.ssrHead);
|
|
375
447
|
const initialDataPromise = fetchInitialData(attr, params, serviceRegistry);
|
|
376
448
|
if (renderType === RENDERTYPE.ssr) {
|
|
377
449
|
const { renderSSR } = renderModule;
|
|
378
450
|
const initialDataResolved = await initialDataPromise;
|
|
379
451
|
const initialDataScript = `<script>window.__INITIAL_DATA__ = ${JSON.stringify(initialDataResolved).replace(/</g, "\\u003c")}</script>`;
|
|
380
452
|
const { headContent, appHtml } = await renderSSR(initialDataResolved, req.url, attr?.meta);
|
|
381
|
-
|
|
453
|
+
let aggregateHeadContent = headContent;
|
|
454
|
+
if (ssrManifest && preloadLink) aggregateHeadContent += preloadLink;
|
|
455
|
+
if (manifest && cssLink) aggregateHeadContent += cssLink;
|
|
456
|
+
const fullHtml = template.replace(SSRTAG.ssrHead, aggregateHeadContent).replace(SSRTAG.ssrHtml, `${appHtml}${initialDataScript}<script type="module" src="${bootstrapModule}" async=""></script>`);
|
|
382
457
|
return reply.status(200).header("Content-Type", "text/html").send(fullHtml);
|
|
383
458
|
} else {
|
|
384
459
|
const { renderStream } = renderModule;
|
|
@@ -388,8 +463,8 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
388
463
|
{
|
|
389
464
|
onHead: (headContent) => {
|
|
390
465
|
let aggregateHeadContent = headContent;
|
|
391
|
-
if (ssrManifest) aggregateHeadContent +=
|
|
392
|
-
if (manifest) aggregateHeadContent +=
|
|
466
|
+
if (ssrManifest && preloadLink) aggregateHeadContent += preloadLink;
|
|
467
|
+
if (manifest && cssLink) aggregateHeadContent += cssLink;
|
|
393
468
|
reply.raw.write(`${beforeHead}${aggregateHeadContent}${afterHead}`);
|
|
394
469
|
},
|
|
395
470
|
onFinish: async (initialDataResolved) => {
|
|
@@ -404,7 +479,7 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
404
479
|
},
|
|
405
480
|
initialDataPromise,
|
|
406
481
|
req.url,
|
|
407
|
-
|
|
482
|
+
bootstrapModule,
|
|
408
483
|
attr?.meta
|
|
409
484
|
);
|
|
410
485
|
}
|
|
@@ -414,14 +489,19 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
414
489
|
reply.raw.end("Internal Server Error");
|
|
415
490
|
}
|
|
416
491
|
});
|
|
417
|
-
|
|
492
|
+
app.setNotFoundHandler(async (req, reply) => {
|
|
418
493
|
if (/\.\w+$/.test(req.raw.url ?? "")) return reply.callNotFound();
|
|
419
494
|
try {
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
495
|
+
const defaultConfig = processedConfigs[0];
|
|
496
|
+
if (!defaultConfig) throw new Error("No default configuration found.");
|
|
497
|
+
const { clientRoot } = defaultConfig;
|
|
498
|
+
let template = ensureNonNull(templates.get(clientRoot), `Template not found for clientRoot: ${clientRoot}`);
|
|
499
|
+
const cssLink = cssLinks.get(clientRoot);
|
|
500
|
+
const bootstrapModule = bootstrapModules.get(clientRoot);
|
|
501
|
+
template = template.replace(SSRTAG.ssrHead, "").replace(SSRTAG.ssrHtml, "");
|
|
502
|
+
if (!isDevelopment && cssLink) template = template.replace("</head>", `${cssLink}</head>`);
|
|
503
|
+
if (bootstrapModule) template = template.replace("</body>", `<script type="module" src="${bootstrapModule}" async=""></script></body>`);
|
|
504
|
+
reply.status(200).type("text/html").send(template);
|
|
425
505
|
} catch (error) {
|
|
426
506
|
console.error("Failed to serve clientHtmlTemplate:", error);
|
|
427
507
|
reply.status(500).send("Internal Server Error");
|
|
@@ -431,5 +511,8 @@ var SSRServer = (0, import_fastify_plugin.default)(
|
|
|
431
511
|
{ name: "taujs-ssr-server" }
|
|
432
512
|
);
|
|
433
513
|
export {
|
|
434
|
-
SSRServer
|
|
514
|
+
SSRServer,
|
|
515
|
+
TEMPLATE,
|
|
516
|
+
createMaps,
|
|
517
|
+
processConfigs
|
|
435
518
|
};
|