@ereo/server 0.2.15 → 0.2.17

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.
@@ -159,6 +159,16 @@ export declare class BunServer {
159
159
  * Extract meta tags from meta descriptors (excluding title).
160
160
  */
161
161
  private extractMetaTags;
162
+ /**
163
+ * Build HTML string for meta tags from descriptors.
164
+ */
165
+ private buildMetaHtml;
166
+ /**
167
+ * Inject route meta tags into layout-rendered HTML.
168
+ * Replaces the <title> if a meta title is provided, and inserts
169
+ * meta/link tags before </head>.
170
+ */
171
+ private injectMetaIntoHtml;
162
172
  /**
163
173
  * Build matches data for useMatches hook.
164
174
  * Returns array of matched routes from outermost layout to page.
@@ -1 +1 @@
1
- {"version":3,"file":"bun-server.d.ts","sourceRoot":"","sources":["../src/bun-server.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"bun-server.d.ts","sourceRoot":"","sources":["../src/bun-server.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1034,9 +1034,9 @@ class BunServer {
1034
1034
  const hasRootLayout = layouts.length > 0 && layouts[0].module?.default;
1035
1035
  if (hasRootLayout) {
1036
1036
  if (this.options.renderMode === "streaming") {
1037
- return this.renderStreamingPageDirect(element, allLoaderData);
1037
+ return this.renderStreamingPageDirect(element, allLoaderData, metaDescriptors);
1038
1038
  } else {
1039
- return this.renderStringPageDirect(element, allLoaderData);
1039
+ return this.renderStringPageDirect(element, allLoaderData, metaDescriptors);
1040
1040
  }
1041
1041
  }
1042
1042
  if (this.options.renderMode === "streaming") {
@@ -1152,12 +1152,12 @@ class BunServer {
1152
1152
  return this.renderErrorPage(error);
1153
1153
  }
1154
1154
  }
1155
- async renderStreamingPageDirect(element, loaderData) {
1155
+ async renderStreamingPageDirect(element, loaderData, metaDescriptors = []) {
1156
1156
  let timeoutId;
1157
1157
  try {
1158
1158
  const { renderToReadableStream } = await getStreamingRenderer();
1159
1159
  if (!renderToReadableStream) {
1160
- return this.renderStringPageDirect(element, loaderData);
1160
+ return this.renderStringPageDirect(element, loaderData, metaDescriptors);
1161
1161
  }
1162
1162
  const hasDeferred = hasDeferredData2(loaderData);
1163
1163
  const clientEntry = this.options.clientEntry;
@@ -1172,8 +1172,12 @@ class BunServer {
1172
1172
  }
1173
1173
  });
1174
1174
  const loaderScript = !hasDeferred && loaderData ? encoder.encode(`<script>window.__EREO_DATA__=${serializeLoaderData2(loaderData)}</script>`) : null;
1175
+ const metaHtml = metaDescriptors.length > 0 ? this.buildMetaHtml(metaDescriptors) : "";
1176
+ let metaInjected = metaHtml.length === 0;
1177
+ const decoder = new TextDecoder;
1175
1178
  const reader = reactStream.getReader();
1176
1179
  let done = false;
1180
+ const self = this;
1177
1181
  const stream = new ReadableStream({
1178
1182
  async pull(controller) {
1179
1183
  if (done)
@@ -1199,6 +1203,15 @@ class BunServer {
1199
1203
  controller.close();
1200
1204
  done = true;
1201
1205
  } else {
1206
+ if (!metaInjected) {
1207
+ const chunk = decoder.decode(result.value, { stream: true });
1208
+ if (chunk.includes("</head>")) {
1209
+ const injected = self.injectMetaIntoHtml(chunk, metaDescriptors);
1210
+ controller.enqueue(encoder.encode(injected));
1211
+ metaInjected = true;
1212
+ return;
1213
+ }
1214
+ }
1202
1215
  controller.enqueue(result.value);
1203
1216
  }
1204
1217
  },
@@ -1216,14 +1229,17 @@ class BunServer {
1216
1229
  } catch (error) {
1217
1230
  clearTimeout(timeoutId);
1218
1231
  console.error("Streaming render failed:", error);
1219
- return this.renderStringPageDirect(element, loaderData);
1232
+ return this.renderStringPageDirect(element, loaderData, metaDescriptors);
1220
1233
  }
1221
1234
  }
1222
- async renderStringPageDirect(element, loaderData) {
1235
+ async renderStringPageDirect(element, loaderData, metaDescriptors = []) {
1223
1236
  try {
1224
1237
  const { renderToString: reactRenderToString } = await import("react-dom/server");
1225
1238
  const resolvedData = hasDeferredData2(loaderData) ? await resolveAllDeferred2(loaderData) : loaderData;
1226
1239
  let html = reactRenderToString(element);
1240
+ if (metaDescriptors.length > 0) {
1241
+ html = this.injectMetaIntoHtml(html, metaDescriptors);
1242
+ }
1227
1243
  const loaderScript = resolvedData ? `<script>window.__EREO_DATA__=${serializeLoaderData2(resolvedData)}</script>` : "";
1228
1244
  const clientScript = `<script type="module" src="${this.options.clientEntry}"></script>`;
1229
1245
  if (html.includes("</body>")) {
@@ -1340,6 +1356,38 @@ class BunServer {
1340
1356
  }
1341
1357
  return tags;
1342
1358
  }
1359
+ buildMetaHtml(meta) {
1360
+ let html = "";
1361
+ for (const descriptor of meta) {
1362
+ if (descriptor.name && descriptor.content) {
1363
+ const name = descriptor.name.replace(/"/g, "&quot;");
1364
+ const content = descriptor.content.replace(/"/g, "&quot;");
1365
+ html += `<meta name="${name}" content="${content}"/>`;
1366
+ } else if (descriptor.property && descriptor.content) {
1367
+ const property = descriptor.property.replace(/"/g, "&quot;");
1368
+ const content = descriptor.content.replace(/"/g, "&quot;");
1369
+ html += `<meta property="${property}" content="${content}"/>`;
1370
+ } else if (descriptor["script:ld+json"]) {
1371
+ html += `<script type="application/ld+json">${descriptor["script:ld+json"]}</script>`;
1372
+ } else if (descriptor.tagName === "link") {
1373
+ const attrs = Object.entries(descriptor).filter(([k]) => k !== "tagName").map(([k, v]) => `${k}="${String(v).replace(/"/g, "&quot;")}"`).join(" ");
1374
+ html += `<link ${attrs}/>`;
1375
+ }
1376
+ }
1377
+ return html;
1378
+ }
1379
+ injectMetaIntoHtml(html, meta) {
1380
+ const title = this.extractTitle(meta);
1381
+ const metaHtml = this.buildMetaHtml(meta);
1382
+ if (title) {
1383
+ const escapedTitle = title.replace(/</g, "&lt;").replace(/>/g, "&gt;");
1384
+ html = html.replace(/<title>[^<]*<\/title>/, `<title>${escapedTitle}</title>`);
1385
+ }
1386
+ if (metaHtml) {
1387
+ html = html.replace("</head>", `${metaHtml}</head>`);
1388
+ }
1389
+ return html;
1390
+ }
1343
1391
  buildMatchesData(match, loaderData, layoutLoaderData) {
1344
1392
  const matches = [];
1345
1393
  for (const layout of match.layouts || []) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ereo/server",
3
- "version": "0.2.15",
3
+ "version": "0.2.17",
4
4
  "license": "MIT",
5
5
  "author": "Ereo Team",
6
6
  "homepage": "https://ereojs.github.io/ereoJS",
@@ -32,10 +32,10 @@
32
32
  "typecheck": "tsc --noEmit"
33
33
  },
34
34
  "dependencies": {
35
- "@ereo/core": "^0.2.15",
36
- "@ereo/client": "^0.2.15",
37
- "@ereo/router": "^0.2.15",
38
- "@ereo/data": "^0.2.15"
35
+ "@ereo/core": "^0.2.17",
36
+ "@ereo/client": "^0.2.17",
37
+ "@ereo/router": "^0.2.17",
38
+ "@ereo/data": "^0.2.17"
39
39
  },
40
40
  "devDependencies": {
41
41
  "@types/bun": "^1.1.0",