@proteinjs/server 3.6.0 → 3.8.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 CHANGED
@@ -3,6 +3,28 @@
3
3
  All notable changes to this project will be documented in this file.
4
4
  See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
5
 
6
+ # [3.8.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.7.0...@proteinjs/server@3.8.0) (2026-09-17)
7
+
8
+
9
+ ### Features
10
+
11
+ * **server-api:** server-rendered head tags — a ServerRenderedHeadTag loadable rendered into the page's <head> ([816b92e](https://github.com/proteinjs/server/commit/816b92ee1595681db1a9e92a364e0997e82081ad))
12
+
13
+
14
+
15
+
16
+
17
+ # [3.7.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.6.0...@proteinjs/server@3.7.0) (2026-09-12)
18
+
19
+
20
+ ### Features
21
+
22
+ * **server:** the react app page boots in one round — the server-rendered scripts render concurrently (emitted in registration order), the bundles are deferred and preloaded from the head, and the dev page renders the compile's own entrypoint files (DevClientBuild.assets) stamped ?v=<hash> instead of a hard-coded app.js + vendor.js pair ([206412a](https://github.com/proteinjs/server/commit/206412a0f4176d0052d3ed95b24c4ce5c08c5e06))
23
+
24
+
25
+
26
+
27
+
6
28
  # [3.6.0](https://github.com/proteinjs/server/compare/@proteinjs/server@3.5.3...@proteinjs/server@3.6.0) (2026-09-10)
7
29
 
8
30
 
@@ -13,6 +13,12 @@ export type DevClientBuildInfo = {
13
13
  builtAt: string;
14
14
  durationMs?: number;
15
15
  errorCount: number;
16
+ /**
17
+ * The entrypoint's script files (`app.js`, `vendor.js`, …) in the compile's own load order —
18
+ * the dev page's bundle tags are rendered from THIS list (reactApp.ts), so the page follows the
19
+ * chunk graph the webpack config declares instead of a hard-coded pair of names.
20
+ */
21
+ assets: string[];
16
22
  };
17
23
  export declare class DevClientBuild {
18
24
  private static current;
@@ -1 +1 @@
1
- {"version":3,"file":"DevClientBuild.d.ts","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;CACpB,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAiC;IAEvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAI7C,MAAM,CAAC,GAAG,IAAI,kBAAkB,GAAG,SAAS;CAG7C"}
1
+ {"version":3,"file":"DevClientBuild.d.ts","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,MAAM,MAAM,kBAAkB,GAAG;IAC/B,2EAA2E;IAC3E,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,MAAM,EAAE,MAAM,EAAE,CAAC;CAClB,CAAC;AAEF,qBAAa,cAAc;IACzB,OAAO,CAAC,MAAM,CAAC,OAAO,CAAiC;IAEvD,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI;IAI7C,MAAM,CAAC,GAAG,IAAI,kBAAkB,GAAG,SAAS;CAG7C"}
@@ -1 +1 @@
1
- {"version":3,"file":"DevClientBuild.js","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":";;;AAiBA;IAAA;IAUA,CAAC;IAPQ,qBAAM,GAAb,UAAc,IAAwB;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEM,kBAAG,GAAV;QACE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACH,qBAAC;AAAD,CAAC,AAVD,IAUC;AAVY,wCAAc"}
1
+ {"version":3,"file":"DevClientBuild.js","sourceRoot":"","sources":["../../src/DevClientBuild.ts"],"names":[],"mappings":";;;AAuBA;IAAA;IAUA,CAAC;IAPQ,qBAAM,GAAb,UAAc,IAAwB;QACpC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAEM,kBAAG,GAAV;QACE,OAAO,IAAI,CAAC,OAAO,CAAC;IACtB,CAAC;IACH,qBAAC;AAAD,CAAC,AAVD,IAUC;AAVY,wCAAc"}
@@ -1 +1 @@
1
- {"version":3,"file":"reactApp.d.ts","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAA4B,MAAM,uBAAuB,CAAC;AAU/E,eAAO,MAAM,cAAc,iBAAkB,YAAY;;;yBAI1B,GAAG,YAAY,GAAG,KAAG,QAAQ,IAAI,CAAC;CAsChE,CAAC"}
1
+ {"version":3,"file":"reactApp.d.ts","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,YAAY,EAAuD,MAAM,uBAAuB,CAAC;AAU1G,eAAO,MAAM,cAAc,iBAAkB,YAAY;;;yBAI1B,GAAG,YAAY,GAAG,KAAG,QAAQ,IAAI,CAAC;CAiDhE,CAAC"}
@@ -55,18 +55,25 @@ var createReactApp = function (serverConfig) {
55
55
  path: '*',
56
56
  method: 'get',
57
57
  onRequest: function (request, response) { return __awaiter(void 0, void 0, void 0, function () {
58
- var helmet, _a, _b, _c, _d, _e, _f;
59
- var _g, _h, _j;
60
- return __generator(this, function (_k) {
61
- switch (_k.label) {
58
+ var helmet, _a, serverRenderedScripts, bundleUrls, headTags;
59
+ var _b, _c, _d;
60
+ return __generator(this, function (_e) {
61
+ switch (_e.label) {
62
62
  case 0:
63
63
  if (request.path.startsWith('/static')) {
64
64
  return [2 /*return*/];
65
65
  }
66
- if (!(((_g = serverConfig.staticContent) === null || _g === void 0 ? void 0 : _g.bundlePaths) || ((_h = serverConfig.staticContent) === null || _h === void 0 ? void 0 : _h.bundlesDir))) {
66
+ if (!(((_b = serverConfig.staticContent) === null || _b === void 0 ? void 0 : _b.bundlePaths) || ((_c = serverConfig.staticContent) === null || _c === void 0 ? void 0 : _c.bundlesDir))) {
67
67
  throw new Error("ServerConfig.bundlePath or ServerConfig.bundlesDir must be provided to serve a react app");
68
68
  }
69
69
  helmet = react_helmet_1.default.renderStatic();
70
+ return [4 /*yield*/, Promise.all([
71
+ serverRenderedScriptTags(),
72
+ bundleScriptUrls(serverConfig),
73
+ serverRenderedHeadTags(request),
74
+ ])];
75
+ case 1:
76
+ _a = _e.sent(), serverRenderedScripts = _a[0], bundleUrls = _a[1], headTags = _a[2];
70
77
  // The page must ALWAYS revalidate (found live 2026-09-01, the mobile-app stale-page
71
78
  // investigation): without an explicit policy, HTTP heuristic caching applies (RFC 9111
72
79
  // §4.2.2) — WKWebView in particular can serve the cached page without revalidating,
@@ -74,14 +81,7 @@ var createReactApp = function (serverConfig) {
74
81
  // bundles under /static keep their long cache (a fresh page always points at fresh
75
82
  // hashes); `no-cache` + the ETag express already stamps = a cheap 304 on every load.
76
83
  response.set('Cache-Control', 'no-cache');
77
- _b = (_a = response).send;
78
- _e = (_d = "<!DOCTYPE html>\n <html ".concat(helmet.htmlAttributes, ">\n <head>\n <meta charset='utf-8' />\n <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover'>\n <meta name='theme-color' content='").concat(THEME_COLOR_LIGHT, "' media='(prefers-color-scheme: light)'>\n <meta name='theme-color' content='").concat(THEME_COLOR_DARK, "' media='(prefers-color-scheme: dark)'>\n <link href='").concat(((_j = serverConfig.staticContent) === null || _j === void 0 ? void 0 : _j.faviconPath) ? path_1.default.join('/static/', serverConfig.staticContent.faviconPath) : '', "' rel='icon' type='image/png' />\n ").concat(helmet.title.toString(), "\n ").concat(helmet.meta.toString(), "\n ").concat(helmet.link.toString(), "\n </head>\n <body ").concat(helmet.bodyAttributes.toString(), ">\n <div id='app'></div>\n <script>proteinjs = {};</script>\n ")).concat;
79
- return [4 /*yield*/, serverRenderedScriptTags()];
80
- case 1:
81
- _f = (_c = _e.apply(_d, [_k.sent(), "\n "])).concat;
82
- return [4 /*yield*/, bundleScriptTags(serverConfig)];
83
- case 2:
84
- _b.apply(_a, [_f.apply(_c, [_k.sent(), "\n </body>\n </html>"])]);
84
+ response.send("<!DOCTYPE html>\n <html ".concat(helmet.htmlAttributes, ">\n <head>\n <meta charset='utf-8' />\n <meta name='viewport' content='width=device-width, initial-scale=1.0, maximum-scale=1, viewport-fit=cover'>\n <meta name='theme-color' content='").concat(THEME_COLOR_LIGHT, "' media='(prefers-color-scheme: light)'>\n <meta name='theme-color' content='").concat(THEME_COLOR_DARK, "' media='(prefers-color-scheme: dark)'>\n <link href='").concat(((_d = serverConfig.staticContent) === null || _d === void 0 ? void 0 : _d.faviconPath) ? path_1.default.join('/static/', serverConfig.staticContent.faviconPath) : '', "' rel='icon' type='image/png' />\n ").concat(bundlePreloadTags(bundleUrls), "\n ").concat(helmet.title.toString(), "\n ").concat(helmet.meta.toString(), "\n ").concat(helmet.link.toString(), "\n ").concat(headTags, "\n </head>\n <body ").concat(helmet.bodyAttributes.toString(), ">\n <div id='app'></div>\n <script>proteinjs = {};</script>\n ").concat(serverRenderedScripts, "\n ").concat(bundleScriptTags(bundleUrls), "\n </body>\n </html>"));
85
85
  return [2 /*return*/];
86
86
  }
87
87
  });
@@ -89,69 +89,92 @@ var createReactApp = function (serverConfig) {
89
89
  };
90
90
  };
91
91
  exports.createReactApp = createReactApp;
92
- function bundleScriptTags(serverConfig) {
92
+ /**
93
+ * The bundle URLs the page loads, in load order. Dev: the entrypoint's files as the LAST compile
94
+ * recorded them (DevClientBuild — the page follows the chunk graph the webpack config declares),
95
+ * each stamped `?v=<hash>` so the page is verifiable against /dev/build-info (matching hash =
96
+ * provably running the current build). Prod: the configured bundle paths, or every `.js` under the
97
+ * bundles dir in a stable (sorted) order — webpack's runtime registers chunks in any order.
98
+ */
99
+ function bundleScriptUrls(serverConfig) {
93
100
  var _a, _b, _c, _d, _e;
94
101
  return __awaiter(this, void 0, void 0, function () {
95
- var scriptTags, stamp, _i, _f, bundlePath, resolvedBundlesDir, filePaths, _g, filePaths_1, filePath, relativePath;
96
- return __generator(this, function (_h) {
97
- switch (_h.label) {
102
+ var build_1, staticContentDir_1, resolvedBundlesDir, filePaths;
103
+ return __generator(this, function (_f) {
104
+ switch (_f.label) {
98
105
  case 0:
99
106
  if (!(((_a = serverConfig.staticContent) === null || _a === void 0 ? void 0 : _a.bundlePaths) || ((_b = serverConfig.staticContent) === null || _b === void 0 ? void 0 : _b.bundlesDir))) {
100
- return [2 /*return*/];
107
+ return [2 /*return*/, []];
101
108
  }
102
- scriptTags = [];
103
- if (!(process.env.DEVELOPMENT && !process.env.DISABLE_HOT_CLIENT_BUILDS)) return [3 /*break*/, 1];
104
- stamp = DevClientBuild_1.DevClientBuild.get() ? "?v=".concat(DevClientBuild_1.DevClientBuild.get().hash) : '';
105
- scriptTags.push("<script src='".concat(path_1.default.join('/static/', 'app.js')).concat(stamp, "'></script>"));
106
- scriptTags.push("<script src='".concat(path_1.default.join('/static/', 'vendor.js')).concat(stamp, "'></script>"));
107
- return [3 /*break*/, 4];
108
- case 1:
109
- if (!((_c = serverConfig.staticContent) === null || _c === void 0 ? void 0 : _c.bundlePaths)) return [3 /*break*/, 2];
110
- for (_i = 0, _f = serverConfig.staticContent.bundlePaths; _i < _f.length; _i++) {
111
- bundlePath = _f[_i];
112
- scriptTags.push("<script src='".concat(path_1.default.join('/static/', bundlePath), "'></script>"));
109
+ if (process.env.DEVELOPMENT && !process.env.DISABLE_HOT_CLIENT_BUILDS) {
110
+ build_1 = DevClientBuild_1.DevClientBuild.get();
111
+ if (!build_1) {
112
+ // start() gates the listen READY on the first compile, so a page is never served before
113
+ // a build is recorded; a missing record is a wiring fault, said aloud rather than papered.
114
+ throw new Error('the dev client build has not been recorded yet — no bundle to serve');
115
+ }
116
+ return [2 /*return*/, build_1.assets.map(function (asset) { return "".concat(path_1.default.join('/static/', asset), "?v=").concat(build_1.hash); })];
113
117
  }
114
- return [3 /*break*/, 4];
115
- case 2:
116
- if (!(((_d = serverConfig.staticContent) === null || _d === void 0 ? void 0 : _d.bundlesDir) && ((_e = serverConfig.staticContent) === null || _e === void 0 ? void 0 : _e.staticContentDir))) return [3 /*break*/, 4];
117
- resolvedBundlesDir = path_1.default.join(serverConfig.staticContent.staticContentDir, serverConfig.staticContent.bundlesDir);
118
- return [4 /*yield*/, util_node_1.Fs.getFilePathsMatchingGlob(resolvedBundlesDir, '**/*.js')];
119
- case 3:
120
- filePaths = _h.sent();
121
- for (_g = 0, filePaths_1 = filePaths; _g < filePaths_1.length; _g++) {
122
- filePath = filePaths_1[_g];
123
- relativePath = path_1.default.relative(serverConfig.staticContent.staticContentDir, filePath);
124
- scriptTags.push("<script src='".concat(path_1.default.join('/static/', relativePath), "'></script>"));
118
+ if ((_c = serverConfig.staticContent) === null || _c === void 0 ? void 0 : _c.bundlePaths) {
119
+ return [2 /*return*/, serverConfig.staticContent.bundlePaths.map(function (bundlePath) { return path_1.default.join('/static/', bundlePath); })];
125
120
  }
126
- _h.label = 4;
127
- case 4: return [2 /*return*/, scriptTags.join('\n')];
121
+ if (!(((_d = serverConfig.staticContent) === null || _d === void 0 ? void 0 : _d.bundlesDir) && ((_e = serverConfig.staticContent) === null || _e === void 0 ? void 0 : _e.staticContentDir))) return [3 /*break*/, 2];
122
+ staticContentDir_1 = serverConfig.staticContent.staticContentDir;
123
+ resolvedBundlesDir = path_1.default.join(staticContentDir_1, serverConfig.staticContent.bundlesDir);
124
+ return [4 /*yield*/, util_node_1.Fs.getFilePathsMatchingGlob(resolvedBundlesDir, '**/*.js')];
125
+ case 1:
126
+ filePaths = _f.sent();
127
+ return [2 /*return*/, filePaths.map(function (filePath) { return path_1.default.join('/static/', path_1.default.relative(staticContentDir_1, filePath)); }).sort()];
128
+ case 2: return [2 /*return*/, []];
128
129
  }
129
130
  });
130
131
  });
131
132
  }
133
+ /**
134
+ * `defer`: the bundles download in parallel WHILE the HTML parses and execute in document order
135
+ * once it has — a synchronous `<script src>` blocked the parser on every byte of the vendor chunk,
136
+ * and on iOS the previous page stayed painted (and tappable) under the user's thumb until the new
137
+ * document's first paint. The inline server-rendered scripts above them still run at parse time,
138
+ * so `proteinjs[...]` globals exist before any bundle executes.
139
+ */
140
+ function bundleScriptTags(bundleUrls) {
141
+ return bundleUrls.map(function (url) { return "<script defer src='".concat(url, "'></script>"); }).join('\n');
142
+ }
143
+ /** `<link rel=preload>` in the head: the fetches start from the first bytes of the document. */
144
+ function bundlePreloadTags(bundleUrls) {
145
+ return bundleUrls.map(function (url) { return "<link rel='preload' href='".concat(url, "' as='script'>"); }).join('\n');
146
+ }
147
+ /** Every server-rendered script rendered CONCURRENTLY; emitted in registration order. */
132
148
  function serverRenderedScriptTags() {
133
149
  return __awaiter(this, void 0, void 0, function () {
134
- var scripts, scriptTags, _i, scripts_1, script, _a, _b, _c;
135
- return __generator(this, function (_d) {
136
- switch (_d.label) {
150
+ var scripts, rendered;
151
+ return __generator(this, function (_a) {
152
+ switch (_a.label) {
137
153
  case 0:
138
154
  scripts = (0, server_api_1.getServerRenderedScripts)();
139
- scriptTags = [];
140
- _i = 0, scripts_1 = scripts;
141
- _d.label = 1;
155
+ return [4 /*yield*/, Promise.all(scripts.map(function (script) { return script.script(); }))];
156
+ case 1:
157
+ rendered = _a.sent();
158
+ return [2 /*return*/, rendered.map(function (script) { return "<script>".concat(script, "</script>"); }).join('\n')];
159
+ }
160
+ });
161
+ });
162
+ }
163
+ /**
164
+ * Every server-rendered head tag rendered CONCURRENTLY for this request (the same one round the
165
+ * scripts ride); emitted in registration order, an empty render dropped.
166
+ */
167
+ function serverRenderedHeadTags(request) {
168
+ return __awaiter(this, void 0, void 0, function () {
169
+ var tags, rendered;
170
+ return __generator(this, function (_a) {
171
+ switch (_a.label) {
172
+ case 0:
173
+ tags = (0, server_api_1.getServerRenderedHeadTags)();
174
+ return [4 /*yield*/, Promise.all(tags.map(function (tag) { return tag.headTag(request); }))];
142
175
  case 1:
143
- if (!(_i < scripts_1.length)) return [3 /*break*/, 4];
144
- script = scripts_1[_i];
145
- _b = (_a = scriptTags).push;
146
- _c = "<script>".concat;
147
- return [4 /*yield*/, script.script()];
148
- case 2:
149
- _b.apply(_a, [_c.apply("<script>", [_d.sent(), "</script>"])]);
150
- _d.label = 3;
151
- case 3:
152
- _i++;
153
- return [3 /*break*/, 1];
154
- case 4: return [2 /*return*/, scriptTags.join('\n')];
176
+ rendered = _a.sent();
177
+ return [2 /*return*/, rendered.filter(function (tag) { return tag.length > 0; }).join('\n')];
155
178
  }
156
179
  });
157
180
  });
@@ -1 +1 @@
1
- {"version":3,"file":"reactApp.js","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"reactApp.js","sourceRoot":"","sources":["../../../src/routes/reactApp.ts"],"names":[],"mappings":"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"}
@@ -222,9 +222,24 @@ function initializeHotReloading(app, config) {
222
222
  // and logged, so "which build is this page running?" is answerable instead of guessable.
223
223
  compiler.hooks.done.tap('proteinjs-server', function (stats) {
224
224
  var _a;
225
- var _b = stats.toJson({ all: false, hash: true, timings: true, errors: true }), hash = _b.hash, time = _b.time, errors = _b.errors;
225
+ var _b = stats.toJson({
226
+ all: false,
227
+ hash: true,
228
+ timings: true,
229
+ errors: true,
230
+ entrypoints: true,
231
+ chunkGroupAssets: true,
232
+ }), hash = _b.hash, time = _b.time, errors = _b.errors, entrypoints = _b.entrypoints;
226
233
  var errorCount = (_a = errors === null || errors === void 0 ? void 0 : errors.length) !== null && _a !== void 0 ? _a : 0;
227
- DevClientBuild_1.DevClientBuild.record({ hash: hash, builtAt: new Date().toISOString(), durationMs: time, errorCount: errorCount });
234
+ // The entrypoint's script files in the compile's own load order — what the dev page's bundle
235
+ // tags render (reactApp.ts). Source maps and hot-update chunks are not entrypoint files.
236
+ var assets = Object.values(entrypoints !== null && entrypoints !== void 0 ? entrypoints : {}).flatMap(function (entrypoint) {
237
+ var _a;
238
+ return ((_a = entrypoint.assets) !== null && _a !== void 0 ? _a : [])
239
+ .map(function (asset) { return (typeof asset === 'string' ? asset : asset.name); })
240
+ .filter(function (name) { return name.endsWith('.js'); });
241
+ });
242
+ DevClientBuild_1.DevClientBuild.record({ hash: hash, builtAt: new Date().toISOString(), durationMs: time, errorCount: errorCount, assets: assets });
228
243
  if (errorCount > 0) {
229
244
  logger.error({ message: "Client bundle compiled WITH ERRORS", obj: { hash: hash, durationMs: time, errorCount: errorCount } });
230
245
  }
@@ -1 +1 @@
1
- {"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"startServer.js","sourceRoot":"","sources":["../../src/startServer.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@proteinjs/server",
3
- "version": "3.6.0",
3
+ "version": "3.8.0",
4
4
  "description": "A server impl",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -25,7 +25,7 @@
25
25
  "@proteinjs/event": "^1.0.18",
26
26
  "@proteinjs/logger": "^1.0.21",
27
27
  "@proteinjs/reflection": "^1.1.12",
28
- "@proteinjs/server-api": "^3.2.0",
28
+ "@proteinjs/server-api": "^3.3.0",
29
29
  "@proteinjs/util-node": "^1.10.1",
30
30
  "body-parser": "1.19.0",
31
31
  "cookie-parser": "1.4.5",
@@ -64,5 +64,5 @@
64
64
  },
65
65
  "main": "./dist/generated/index.js",
66
66
  "types": "./dist/generated/index.d.ts",
67
- "gitHead": "c1a14f62c4e023db66161869955baf616aab31bb"
67
+ "gitHead": "b0b0c21b42e6e4feb27ccaae147c047f0786b932"
68
68
  }
@@ -13,6 +13,12 @@ export type DevClientBuildInfo = {
13
13
  builtAt: string;
14
14
  durationMs?: number;
15
15
  errorCount: number;
16
+ /**
17
+ * The entrypoint's script files (`app.js`, `vendor.js`, …) in the compile's own load order —
18
+ * the dev page's bundle tags are rendered from THIS list (reactApp.ts), so the page follows the
19
+ * chunk graph the webpack config declares instead of a hard-coded pair of names.
20
+ */
21
+ assets: string[];
16
22
  };
17
23
 
18
24
  export class DevClientBuild {
@@ -1,6 +1,7 @@
1
1
  import path from 'path';
2
+ import express from 'express';
2
3
  import ReactHelmet from 'react-helmet';
3
- import { ServerConfig, getServerRenderedScripts } from '@proteinjs/server-api';
4
+ import { ServerConfig, getServerRenderedHeadTags, getServerRenderedScripts } from '@proteinjs/server-api';
4
5
  import { Fs } from '@proteinjs/util-node';
5
6
  import { DevClientBuild } from '../DevClientBuild';
6
7
 
@@ -24,6 +25,15 @@ export const createReactApp = (serverConfig: ServerConfig) => {
24
25
  }
25
26
 
26
27
  const helmet = ReactHelmet.renderStatic();
28
+ // ONE boot round: the server-rendered scripts (each a settings read for the logged-in user)
29
+ // and the bundle listing run concurrently — the page's TTFB is the SLOWEST of them, not their
30
+ // sum (measured on a phone: 5–6 reads awaited one after another sat in front of every byte
31
+ // of the page).
32
+ const [serverRenderedScripts, bundleUrls, headTags] = await Promise.all([
33
+ serverRenderedScriptTags(),
34
+ bundleScriptUrls(serverConfig),
35
+ serverRenderedHeadTags(request),
36
+ ]);
27
37
  // The page must ALWAYS revalidate (found live 2026-09-01, the mobile-app stale-page
28
38
  // investigation): without an explicit policy, HTTP heuristic caching applies (RFC 9111
29
39
  // §4.2.2) — WKWebView in particular can serve the cached page without revalidating,
@@ -39,59 +49,88 @@ export const createReactApp = (serverConfig: ServerConfig) => {
39
49
  <meta name='theme-color' content='${THEME_COLOR_LIGHT}' media='(prefers-color-scheme: light)'>
40
50
  <meta name='theme-color' content='${THEME_COLOR_DARK}' media='(prefers-color-scheme: dark)'>
41
51
  <link href='${serverConfig.staticContent?.faviconPath ? path.join('/static/', serverConfig.staticContent.faviconPath) : ''}' rel='icon' type='image/png' />
52
+ ${bundlePreloadTags(bundleUrls)}
42
53
  ${helmet.title.toString()}
43
54
  ${helmet.meta.toString()}
44
55
  ${helmet.link.toString()}
56
+ ${headTags}
45
57
  </head>
46
58
  <body ${helmet.bodyAttributes.toString()}>
47
59
  <div id='app'></div>
48
60
  <script>proteinjs = {};</script>
49
- ${await serverRenderedScriptTags()}
50
- ${await bundleScriptTags(serverConfig)}
61
+ ${serverRenderedScripts}
62
+ ${bundleScriptTags(bundleUrls)}
51
63
  </body>
52
64
  </html>`);
53
65
  },
54
66
  };
55
67
  };
56
68
 
57
- async function bundleScriptTags(serverConfig: ServerConfig) {
69
+ /**
70
+ * The bundle URLs the page loads, in load order. Dev: the entrypoint's files as the LAST compile
71
+ * recorded them (DevClientBuild — the page follows the chunk graph the webpack config declares),
72
+ * each stamped `?v=<hash>` so the page is verifiable against /dev/build-info (matching hash =
73
+ * provably running the current build). Prod: the configured bundle paths, or every `.js` under the
74
+ * bundles dir in a stable (sorted) order — webpack's runtime registers chunks in any order.
75
+ */
76
+ async function bundleScriptUrls(serverConfig: ServerConfig): Promise<string[]> {
58
77
  if (!(serverConfig.staticContent?.bundlePaths || serverConfig.staticContent?.bundlesDir)) {
59
- return;
78
+ return [];
60
79
  }
61
80
 
62
- const scriptTags: string[] = [];
63
81
  if (process.env.DEVELOPMENT && !process.env.DISABLE_HOT_CLIENT_BUILDS) {
64
- // `?v=<hash>` stamps the page with the compile it was served against: it deterministically
65
- // busts the browser cache on new builds, and lets tooling verify a live page against
66
- // /dev/build-info (matching hash = provably running the current build).
67
- const stamp = DevClientBuild.get() ? `?v=${DevClientBuild.get()!.hash}` : '';
68
- scriptTags.push(`<script src='${path.join('/static/', 'app.js')}${stamp}'></script>`);
69
- scriptTags.push(`<script src='${path.join('/static/', 'vendor.js')}${stamp}'></script>`);
70
- } else if (serverConfig.staticContent?.bundlePaths) {
71
- for (const bundlePath of serverConfig.staticContent.bundlePaths) {
72
- scriptTags.push(`<script src='${path.join('/static/', bundlePath)}'></script>`);
82
+ const build = DevClientBuild.get();
83
+ if (!build) {
84
+ // start() gates the listen READY on the first compile, so a page is never served before
85
+ // a build is recorded; a missing record is a wiring fault, said aloud rather than papered.
86
+ throw new Error('the dev client build has not been recorded yet — no bundle to serve');
73
87
  }
74
- } else if (serverConfig.staticContent?.bundlesDir && serverConfig.staticContent?.staticContentDir) {
75
- const resolvedBundlesDir = path.join(
76
- serverConfig.staticContent.staticContentDir,
77
- serverConfig.staticContent.bundlesDir
78
- );
88
+ return build.assets.map((asset) => `${path.join('/static/', asset)}?v=${build.hash}`);
89
+ }
90
+
91
+ if (serverConfig.staticContent?.bundlePaths) {
92
+ return serverConfig.staticContent.bundlePaths.map((bundlePath) => path.join('/static/', bundlePath));
93
+ }
94
+
95
+ if (serverConfig.staticContent?.bundlesDir && serverConfig.staticContent?.staticContentDir) {
96
+ const staticContentDir = serverConfig.staticContent.staticContentDir;
97
+ const resolvedBundlesDir = path.join(staticContentDir, serverConfig.staticContent.bundlesDir);
79
98
  const filePaths = await Fs.getFilePathsMatchingGlob(resolvedBundlesDir, '**/*.js');
80
- for (const filePath of filePaths) {
81
- const relativePath = path.relative(serverConfig.staticContent.staticContentDir, filePath);
82
- scriptTags.push(`<script src='${path.join('/static/', relativePath)}'></script>`);
83
- }
99
+ return filePaths.map((filePath) => path.join('/static/', path.relative(staticContentDir, filePath))).sort();
84
100
  }
85
101
 
86
- return scriptTags.join('\n');
102
+ return [];
87
103
  }
88
104
 
89
- async function serverRenderedScriptTags() {
105
+ /**
106
+ * `defer`: the bundles download in parallel WHILE the HTML parses and execute in document order
107
+ * once it has — a synchronous `<script src>` blocked the parser on every byte of the vendor chunk,
108
+ * and on iOS the previous page stayed painted (and tappable) under the user's thumb until the new
109
+ * document's first paint. The inline server-rendered scripts above them still run at parse time,
110
+ * so `proteinjs[...]` globals exist before any bundle executes.
111
+ */
112
+ function bundleScriptTags(bundleUrls: string[]): string {
113
+ return bundleUrls.map((url) => `<script defer src='${url}'></script>`).join('\n');
114
+ }
115
+
116
+ /** `<link rel=preload>` in the head: the fetches start from the first bytes of the document. */
117
+ function bundlePreloadTags(bundleUrls: string[]): string {
118
+ return bundleUrls.map((url) => `<link rel='preload' href='${url}' as='script'>`).join('\n');
119
+ }
120
+
121
+ /** Every server-rendered script rendered CONCURRENTLY; emitted in registration order. */
122
+ async function serverRenderedScriptTags(): Promise<string> {
90
123
  const scripts = getServerRenderedScripts();
91
- const scriptTags: string[] = [];
92
- for (const script of scripts) {
93
- scriptTags.push(`<script>${await script.script()}</script>`);
94
- }
124
+ const rendered = await Promise.all(scripts.map((script) => script.script()));
125
+ return rendered.map((script) => `<script>${script}</script>`).join('\n');
126
+ }
95
127
 
96
- return scriptTags.join('\n');
128
+ /**
129
+ * Every server-rendered head tag rendered CONCURRENTLY for this request (the same one round the
130
+ * scripts ride); emitted in registration order, an empty render dropped.
131
+ */
132
+ async function serverRenderedHeadTags(request: express.Request): Promise<string> {
133
+ const tags = getServerRenderedHeadTags();
134
+ const rendered = await Promise.all(tags.map((tag) => tag.headTag(request)));
135
+ return rendered.filter((tag) => tag.length > 0).join('\n');
97
136
  }
@@ -153,9 +153,23 @@ function initializeHotReloading(app: express.Express, config: ServerConfig): Pro
153
153
  // Every completed compile is recorded (for the `?v=<hash>` script-tag stamp + /dev/build-info)
154
154
  // and logged, so "which build is this page running?" is answerable instead of guessable.
155
155
  compiler.hooks.done.tap('proteinjs-server', (stats: any) => {
156
- const { hash, time, errors } = stats.toJson({ all: false, hash: true, timings: true, errors: true });
156
+ const { hash, time, errors, entrypoints } = stats.toJson({
157
+ all: false,
158
+ hash: true,
159
+ timings: true,
160
+ errors: true,
161
+ entrypoints: true,
162
+ chunkGroupAssets: true,
163
+ });
157
164
  const errorCount = errors?.length ?? 0;
158
- DevClientBuild.record({ hash, builtAt: new Date().toISOString(), durationMs: time, errorCount });
165
+ // The entrypoint's script files in the compile's own load order — what the dev page's bundle
166
+ // tags render (reactApp.ts). Source maps and hot-update chunks are not entrypoint files.
167
+ const assets: string[] = Object.values(entrypoints ?? {}).flatMap((entrypoint: any) =>
168
+ (entrypoint.assets ?? [])
169
+ .map((asset: any) => (typeof asset === 'string' ? asset : asset.name))
170
+ .filter((name: string) => name.endsWith('.js'))
171
+ );
172
+ DevClientBuild.record({ hash, builtAt: new Date().toISOString(), durationMs: time, errorCount, assets });
159
173
  if (errorCount > 0) {
160
174
  logger.error({ message: `Client bundle compiled WITH ERRORS`, obj: { hash, durationMs: time, errorCount } });
161
175
  } else {
@@ -0,0 +1,168 @@
1
+ import * as fs from 'fs';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+
5
+ /**
6
+ * The react app page's boot shape:
7
+ *
8
+ * 1. ONE boot round — every server-rendered script (each a settings read for the logged-in user)
9
+ * is rendered CONCURRENTLY, and emitted in registration order regardless of which resolves
10
+ * first. Pre-fix red: reactApp.ts awaited the scripts one after another (the page's TTFB was
11
+ * the SUM of 5–6 serial reads), so the second script did not START until the first resolved.
12
+ * 2. The bundles are `defer`red and `<link rel=preload>`ed from the head — a synchronous body
13
+ * `<script src>` blocked the parser on every byte of the vendor chunk. Pre-fix red: no defer,
14
+ * no preload.
15
+ * 3. The dev page renders its bundle tags from the compile's own entrypoint files (DevClientBuild
16
+ * `assets`), each stamped `?v=<hash>` — the page follows the chunk graph the webpack config
17
+ * declares, and stays verifiable against /dev/build-info. Pre-fix red: two hard-coded names.
18
+ */
19
+ const scripts: { script: () => Promise<string> }[] = [];
20
+ jest.mock('@proteinjs/server-api', () => ({
21
+ ...jest.requireActual('@proteinjs/server-api'),
22
+ getServerRenderedScripts: () => scripts,
23
+ }));
24
+
25
+ import { createReactApp } from '../src/routes/reactApp';
26
+ import { DevClientBuild } from '../src/DevClientBuild';
27
+
28
+ type Rendered = { headers: Record<string, string>; html: string };
29
+
30
+ async function render(staticContent: Record<string, unknown>): Promise<Rendered> {
31
+ const rendered: Rendered = { headers: {}, html: '' };
32
+ await renderInto(rendered, staticContent);
33
+ return rendered;
34
+ }
35
+
36
+ function renderInto(rendered: Rendered, staticContent: Record<string, unknown>): Promise<void> {
37
+ const response = {
38
+ set: (name: string, value: string) => {
39
+ rendered.headers[name] = value;
40
+ },
41
+ send: (html: string) => {
42
+ rendered.html = html;
43
+ },
44
+ };
45
+ return createReactApp({ staticContent } as any).onRequest({ path: '/' }, response);
46
+ }
47
+
48
+ const flushMicrotasks = async () => {
49
+ for (let i = 0; i < 10; i++) {
50
+ await Promise.resolve();
51
+ }
52
+ };
53
+
54
+ describe('the react app page boots in one round', () => {
55
+ let tmp: string;
56
+ const env = {
57
+ DEVELOPMENT: process.env.DEVELOPMENT,
58
+ DISABLE_HOT_CLIENT_BUILDS: process.env.DISABLE_HOT_CLIENT_BUILDS,
59
+ };
60
+
61
+ beforeEach(() => {
62
+ scripts.length = 0;
63
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'react-app-boot-'));
64
+ fs.mkdirSync(path.join(tmp, 'bundles'));
65
+ delete process.env.DEVELOPMENT;
66
+ delete process.env.DISABLE_HOT_CLIENT_BUILDS;
67
+ });
68
+
69
+ afterEach(() => {
70
+ fs.rmSync(tmp, { recursive: true, force: true });
71
+ if (env.DEVELOPMENT === undefined) {
72
+ delete process.env.DEVELOPMENT;
73
+ } else {
74
+ process.env.DEVELOPMENT = env.DEVELOPMENT;
75
+ }
76
+ if (env.DISABLE_HOT_CLIENT_BUILDS === undefined) {
77
+ delete process.env.DISABLE_HOT_CLIENT_BUILDS;
78
+ } else {
79
+ process.env.DISABLE_HOT_CLIENT_BUILDS = env.DISABLE_HOT_CLIENT_BUILDS;
80
+ }
81
+ });
82
+
83
+ const prodStaticContent = () => ({ staticContentDir: tmp, bundlesDir: 'bundles' });
84
+
85
+ it('pin 1: every server-rendered script STARTS before any resolves, and they are emitted in registration order', async () => {
86
+ fs.writeFileSync(path.join(tmp, 'bundles', 'app.js'), '');
87
+ const started: string[] = [];
88
+ const release: Record<string, () => void> = {};
89
+ const gated = (name: string) => ({
90
+ script: () =>
91
+ new Promise<string>((resolve) => {
92
+ started.push(name);
93
+ release[name] = () => resolve(`window.${name} = 1;`);
94
+ }),
95
+ });
96
+ scripts.push(gated('a'), gated('b'), { script: async () => (started.push('c'), 'window.c = 1;') });
97
+
98
+ const rendered: Rendered = { headers: {}, html: '' };
99
+ const done = renderInto(rendered, prodStaticContent());
100
+ await flushMicrotasks();
101
+ // Pre-fix red: ['a'] — the page awaited a's read before b's began.
102
+ expect(started).toEqual(['a', 'b', 'c']);
103
+ expect(rendered.html).toBe('');
104
+
105
+ // b answers first; the page still carries a, b, c in registration order.
106
+ release.b();
107
+ await flushMicrotasks();
108
+ release.a();
109
+ await done;
110
+ const order = ['window.a = 1;', 'window.b = 1;', 'window.c = 1;'].map((s) =>
111
+ rendered.html.indexOf(`<script>${s}</script>`)
112
+ );
113
+ expect(order.every((i) => i >= 0)).toBe(true);
114
+ expect(order).toEqual([...order].sort((x, y) => x - y));
115
+ // The globals object the scripts write into is declared ahead of them.
116
+ expect(rendered.html.indexOf('<script>proteinjs = {};</script>')).toBeLessThan(order[0]);
117
+ });
118
+
119
+ it('pin 2: the production bundles are deferred and preloaded from the head, in a stable order', async () => {
120
+ fs.writeFileSync(path.join(tmp, 'bundles', 'vendor.def456.js'), '');
121
+ fs.writeFileSync(path.join(tmp, 'bundles', 'app.abc123.js'), '');
122
+ fs.writeFileSync(path.join(tmp, 'bundles', 'app.abc123.js.map'), '');
123
+ fs.writeFileSync(path.join(tmp, 'bundles', 'app.abc123.js.br'), '');
124
+ scripts.push({ script: async () => 'window.settings = {};' });
125
+
126
+ const { html, headers } = await render(prodStaticContent());
127
+ const head = html.slice(0, html.indexOf('<body'));
128
+ const body = html.slice(html.indexOf('<body'));
129
+ for (const bundle of ['/static/bundles/app.abc123.js', '/static/bundles/vendor.def456.js']) {
130
+ // Pre-fix red: `<script src=…>` with no defer; no preload anywhere.
131
+ expect(body).toContain(`<script defer src='${bundle}'></script>`);
132
+ expect(head).toContain(`<link rel='preload' href='${bundle}' as='script'>`);
133
+ }
134
+ expect(body).not.toMatch(/<script src=/);
135
+ expect(html).not.toContain('.js.map');
136
+ expect(html).not.toContain('.js.br');
137
+ // Stable order: sorted paths, app before vendor.
138
+ expect(body.indexOf('app.abc123.js')).toBeLessThan(body.indexOf('vendor.def456.js'));
139
+ // The inline scripts run at parse time, ahead of the deferred bundles.
140
+ expect(body.indexOf('<script>window.settings = {};</script>')).toBeLessThan(body.indexOf('<script defer'));
141
+ expect(headers['Cache-Control']).toBe('no-cache');
142
+ });
143
+
144
+ it('pin 3: the dev page renders the compile’s own entrypoint files, each stamped ?v=<hash>, deferred and preloaded', async () => {
145
+ process.env.DEVELOPMENT = 'true';
146
+ DevClientBuild.record({
147
+ hash: 'cafe0123',
148
+ builtAt: new Date().toISOString(),
149
+ errorCount: 0,
150
+ assets: ['react.js', 'vendor.js', 'app.js'],
151
+ });
152
+ scripts.push({ script: async () => 'window.settings = {};' });
153
+
154
+ const { html } = await render(prodStaticContent());
155
+ const body = html.slice(html.indexOf('<body'));
156
+ const head = html.slice(0, html.indexOf('<body'));
157
+ const tags = ['react.js', 'vendor.js', 'app.js'].map((asset) =>
158
+ body.indexOf(`<script defer src='/static/${asset}?v=cafe0123'></script>`)
159
+ );
160
+ // Pre-fix red: two hard-coded names (app.js, vendor.js), no react.js, no defer.
161
+ expect(tags.every((i) => i >= 0)).toBe(true);
162
+ expect(tags).toEqual([...tags].sort((x, y) => x - y));
163
+ for (const asset of ['react.js', 'vendor.js', 'app.js']) {
164
+ expect(head).toContain(`<link rel='preload' href='/static/${asset}?v=cafe0123' as='script'>`);
165
+ }
166
+ expect(body).not.toContain('bundles/');
167
+ });
168
+ });
@@ -0,0 +1,142 @@
1
+ import * as fs from 'fs';
2
+ import * as os from 'os';
3
+ import * as path from 'path';
4
+
5
+ /**
6
+ * Server-rendered HEAD tags (`ServerRenderedHeadTag`): the head counterpart of the server-rendered
7
+ * scripts. A browser reads some tags at parse time — a `<meta>` the client bundle would inject too
8
+ * late — so the page carries them in the served document:
9
+ *
10
+ * 1. every registered tag lands inside `<head>`, in registration order, rendered concurrently in
11
+ * the page's ONE boot round (started before any resolves, like the scripts);
12
+ * 2. the request is handed to each tag, so a tag can name the page being served;
13
+ * 3. an empty render is dropped — nothing for this request, no blank line left behind.
14
+ */
15
+ const scripts: { script: () => Promise<string> }[] = [];
16
+ const headTags: { headTag: (request: unknown) => Promise<string> }[] = [];
17
+ jest.mock('@proteinjs/server-api', () => ({
18
+ ...jest.requireActual('@proteinjs/server-api'),
19
+ getServerRenderedScripts: () => scripts,
20
+ getServerRenderedHeadTags: () => headTags,
21
+ }));
22
+
23
+ import { createReactApp } from '../src/routes/reactApp';
24
+
25
+ type Rendered = { headers: Record<string, string>; html: string };
26
+
27
+ function renderInto(rendered: Rendered, staticContent: Record<string, unknown>, request: unknown): Promise<void> {
28
+ const response = {
29
+ set: (name: string, value: string) => {
30
+ rendered.headers[name] = value;
31
+ },
32
+ send: (html: string) => {
33
+ rendered.html = html;
34
+ },
35
+ };
36
+ return createReactApp({ staticContent } as any).onRequest(request, response);
37
+ }
38
+
39
+ async function render(staticContent: Record<string, unknown>, request: unknown = { path: '/' }): Promise<Rendered> {
40
+ const rendered: Rendered = { headers: {}, html: '' };
41
+ await renderInto(rendered, staticContent, request);
42
+ return rendered;
43
+ }
44
+
45
+ const flushMicrotasks = async () => {
46
+ for (let i = 0; i < 10; i++) {
47
+ await Promise.resolve();
48
+ }
49
+ };
50
+
51
+ const headOf = (html: string) => html.slice(html.indexOf('<head>'), html.indexOf('</head>'));
52
+
53
+ describe('server-rendered head tags', () => {
54
+ let tmp: string;
55
+ const env = {
56
+ DEVELOPMENT: process.env.DEVELOPMENT,
57
+ DISABLE_HOT_CLIENT_BUILDS: process.env.DISABLE_HOT_CLIENT_BUILDS,
58
+ };
59
+
60
+ beforeEach(() => {
61
+ scripts.length = 0;
62
+ headTags.length = 0;
63
+ tmp = fs.mkdtempSync(path.join(os.tmpdir(), 'react-app-head-'));
64
+ fs.mkdirSync(path.join(tmp, 'bundles'));
65
+ fs.writeFileSync(path.join(tmp, 'bundles', 'app.js'), '');
66
+ delete process.env.DEVELOPMENT;
67
+ delete process.env.DISABLE_HOT_CLIENT_BUILDS;
68
+ });
69
+
70
+ afterEach(() => {
71
+ fs.rmSync(tmp, { recursive: true, force: true });
72
+ for (const [name, value] of Object.entries(env)) {
73
+ if (value === undefined) {
74
+ delete process.env[name];
75
+ } else {
76
+ process.env[name] = value;
77
+ }
78
+ }
79
+ });
80
+
81
+ const staticContent = () => ({ staticContentDir: tmp, bundlesDir: 'bundles' });
82
+
83
+ it('renders every tag inside <head>, in registration order, handing each the request', async () => {
84
+ headTags.push(
85
+ { headTag: async (request: any) => `<meta name="page" content="${request.originalUrl}">` },
86
+ { headTag: async () => `<link rel="manifest" href="/manifest.json">` }
87
+ );
88
+ const { html } = await render(staticContent(), { path: '/', originalUrl: '/things?id=7' });
89
+ const head = headOf(html);
90
+ expect(head).toContain('<meta name="page" content="/things?id=7">');
91
+ expect(head).toContain('<link rel="manifest" href="/manifest.json">');
92
+ expect(head.indexOf('<meta name="page"')).toBeLessThan(head.indexOf('<link rel="manifest"'));
93
+ // Never in the body.
94
+ expect(html.slice(html.indexOf('<body'))).not.toContain('<meta name="page"');
95
+ });
96
+
97
+ it('drops an empty render — nothing for this request leaves nothing behind', async () => {
98
+ const blankLines = (head: string) => head.split('\n').filter((line) => line.trim() === '').length;
99
+ headTags.push({ headTag: async () => '<meta name="only" content="1">' });
100
+ const alone = blankLines(headOf((await render(staticContent())).html));
101
+
102
+ headTags.unshift({ headTag: async () => '' });
103
+ const { html } = await render(staticContent());
104
+ const head = headOf(html);
105
+ expect(head).toContain('<meta name="only" content="1">');
106
+ // The empty render added no line of its own: the head carries exactly the blank lines it
107
+ // carries with the one tag alone (an unfiltered empty would join as a stray newline).
108
+ expect(blankLines(head)).toBe(alone);
109
+ });
110
+
111
+ it('a page with no registered tags renders exactly as before', async () => {
112
+ const { html } = await render(staticContent());
113
+ expect(html).toContain('<head>');
114
+ expect(html).not.toContain('undefined');
115
+ });
116
+
117
+ it('starts every tag before any resolves — the one boot round the scripts ride', async () => {
118
+ const started: string[] = [];
119
+ const release: Record<string, () => void> = {};
120
+ const gated = (name: string) => ({
121
+ headTag: () =>
122
+ new Promise<string>((resolve) => {
123
+ started.push(name);
124
+ release[name] = () => resolve(`<meta name="${name}">`);
125
+ }),
126
+ });
127
+ headTags.push(gated('a'), gated('b'));
128
+ scripts.push({ script: async () => (started.push('script'), 'window.s = 1;') });
129
+
130
+ const rendered: Rendered = { headers: {}, html: '' };
131
+ const done = renderInto(rendered, staticContent(), { path: '/' });
132
+ await flushMicrotasks();
133
+ expect(started).toEqual(['script', 'a', 'b']);
134
+ expect(rendered.html).toBe('');
135
+ release.b();
136
+ await flushMicrotasks();
137
+ release.a();
138
+ await done;
139
+ const head = headOf(rendered.html);
140
+ expect(head.indexOf('<meta name="a">')).toBeLessThan(head.indexOf('<meta name="b">'));
141
+ });
142
+ });