eclipsa 0.1.7 → 0.1.8

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "eclipsa",
3
- "version": "0.1.7",
3
+ "version": "0.1.8",
4
4
  "homepage": "https://github.com/pnsk-lab/eclipsa",
5
5
  "bugs": {
6
6
  "url": "https://github.com/pnsk-lab/eclipsa/issues"
@@ -63,7 +63,7 @@
63
63
  }
64
64
  },
65
65
  "dependencies": {
66
- "@eclipsa/optimizer": "^0.1.7",
66
+ "@eclipsa/optimizer": "^0.1.8",
67
67
  "fast-glob": "^3.3.2",
68
68
  "hono": "^4.6.4"
69
69
  },
package/vite/mod.mjs CHANGED
@@ -877,6 +877,27 @@ const RESUME_PAYLOAD_PLACEHOLDER = "__ECLIPSA_RESUME_PAYLOAD__";
877
877
  const ROUTE_MANIFEST_PLACEHOLDER = "__ECLIPSA_ROUTE_MANIFEST__";
878
878
  const APP_HOOKS_PLACEHOLDER = "__ECLIPSA_APP_HOOKS__";
879
879
  const replaceHeadPlaceholder = (html, placeholder, value) => html.replaceAll(placeholder, value);
880
+ const replaceResumePayloadPlaceholderValue = (value, replacements) => {
881
+ if (typeof value === "string") return replacements[value] ?? value;
882
+ if (Array.isArray(value)) {
883
+ let changed = false;
884
+ const next = value.map((entry) => {
885
+ const replaced = replaceResumePayloadPlaceholderValue(entry, replacements);
886
+ if (replaced !== entry) changed = true;
887
+ return replaced;
888
+ });
889
+ return changed ? next : value;
890
+ }
891
+ if (!value || typeof value !== "object") return value;
892
+ let changed = false;
893
+ const next = {};
894
+ for (const [key, entry] of Object.entries(value)) {
895
+ const replaced = replaceResumePayloadPlaceholderValue(entry, replacements);
896
+ if (replaced !== entry) changed = true;
897
+ next[key] = replaced;
898
+ }
899
+ return changed ? next : value;
900
+ };
880
901
  const splitHtmlForStreaming = (html) => {
881
902
  const bodyCloseIndex = html.lastIndexOf("</body>");
882
903
  if (bodyCloseIndex >= 0) return {
@@ -1163,6 +1184,10 @@ const createDevApp = async (init) => {
1163
1184
  const [pageModule, ...layoutModules] = modules;
1164
1185
  const { default: Page } = pageModule;
1165
1186
  const Layouts = layoutModules.map((module) => module.default);
1187
+ const serializeAppResumePayload = (payload) => serializeResumePayload(replaceResumePayloadPlaceholderValue(payload, {
1188
+ [ROUTE_MANIFEST_PLACEHOLDER]: JSON.stringify(routeManifest),
1189
+ [APP_HOOKS_PLACEHOLDER]: JSON.stringify(appHooksManifest)
1190
+ }));
1166
1191
  const metadata = composeRouteMetadata([...layoutModules.map((module) => module.metadata ?? null), pageModule.metadata ?? null], {
1167
1192
  params,
1168
1193
  url: getRequestUrl(c.req.raw)
@@ -1230,7 +1255,7 @@ const createDevApp = async (init) => {
1230
1255
  resolvePendingLoaders: async (container) => resolvePendingLoaders(container, c),
1231
1256
  symbols: symbolUrls
1232
1257
  });
1233
- const { prefix, suffix } = splitHtmlForStreaming(replaceHeadPlaceholder(replaceHeadPlaceholder(replaceHeadPlaceholder(html, RESUME_PAYLOAD_PLACEHOLDER, serializeResumePayload(payload)), ROUTE_MANIFEST_PLACEHOLDER, escapeJSONScriptText(JSON.stringify(routeManifest))), APP_HOOKS_PLACEHOLDER, escapeJSONScriptText(JSON.stringify(appHooksManifest))));
1258
+ const { prefix, suffix } = splitHtmlForStreaming(replaceHeadPlaceholder(replaceHeadPlaceholder(replaceHeadPlaceholder(html, RESUME_PAYLOAD_PLACEHOLDER, serializeAppResumePayload(payload)), ROUTE_MANIFEST_PLACEHOLDER, escapeJSONScriptText(JSON.stringify(routeManifest))), APP_HOOKS_PLACEHOLDER, escapeJSONScriptText(JSON.stringify(appHooksManifest))));
1234
1259
  const encoder = new TextEncoder();
1235
1260
  return new Response(new ReadableStream({ start(controller) {
1236
1261
  controller.enqueue(encoder.encode(prefix));
@@ -1240,9 +1265,9 @@ const createDevApp = async (init) => {
1240
1265
  latestPayload = chunk.payload;
1241
1266
  const templateId = `eclipsa-suspense-template-${chunk.boundaryId}`;
1242
1267
  const payloadId = `eclipsa-suspense-payload-${chunk.boundaryId}`;
1243
- controller.enqueue(encoder.encode(`<template id="${templateId}">${chunk.html}</template><script id="${payloadId}" type="application/eclipsa-resume+json">${serializeResumePayload(chunk.payload)}<\/script><script>window.__eclipsa_stream.enqueue({boundaryId:${JSON.stringify(chunk.boundaryId)},payloadScriptId:${JSON.stringify(payloadId)},templateId:${JSON.stringify(templateId)}})<\/script>`));
1268
+ controller.enqueue(encoder.encode(`<template id="${templateId}">${chunk.html}</template><script id="${payloadId}" type="application/eclipsa-resume+json">${serializeAppResumePayload(chunk.payload)}<\/script><script>window.__eclipsa_stream.enqueue({boundaryId:${JSON.stringify(chunk.boundaryId)},payloadScriptId:${JSON.stringify(payloadId)},templateId:${JSON.stringify(templateId)}})<\/script>`));
1244
1269
  }
1245
- controller.enqueue(encoder.encode(`<script id="${RESUME_FINAL_STATE_ELEMENT_ID}" type="application/eclipsa-resume+json">${serializeResumePayload(latestPayload)}<\/script>${suffix}`));
1270
+ controller.enqueue(encoder.encode(`<script id="${RESUME_FINAL_STATE_ELEMENT_ID}" type="application/eclipsa-resume+json">${serializeAppResumePayload(latestPayload)}<\/script>${suffix}`));
1246
1271
  controller.close();
1247
1272
  })().catch((error) => {
1248
1273
  controller.error(error);
@@ -2308,7 +2333,47 @@ const resolvePreflightTarget = (pathname) => {
2308
2333
  return null;
2309
2334
  };
2310
2335
 
2311
- const replaceHeadPlaceholder = (html, placeholder, value) => html.replace(placeholder, value);
2336
+ const replaceHeadPlaceholder = (html, placeholder, value) => html.replaceAll(placeholder, value);
2337
+ const replaceResumePayloadPlaceholderValue = (value, replacements) => {
2338
+ if (typeof value === "string") {
2339
+ return replacements[value] ?? value;
2340
+ }
2341
+ if (Array.isArray(value)) {
2342
+ let changed = false;
2343
+ const next = value.map((entry) => {
2344
+ const replaced = replaceResumePayloadPlaceholderValue(entry, replacements);
2345
+ if (replaced !== entry) {
2346
+ changed = true;
2347
+ }
2348
+ return replaced;
2349
+ });
2350
+ return changed ? next : value;
2351
+ }
2352
+ if (!value || typeof value !== "object") {
2353
+ return value;
2354
+ }
2355
+ let changed = false;
2356
+ const next = {};
2357
+ for (const [key, entry] of Object.entries(value)) {
2358
+ const replaced = replaceResumePayloadPlaceholderValue(entry, replacements);
2359
+ if (replaced !== entry) {
2360
+ changed = true;
2361
+ }
2362
+ next[key] = replaced;
2363
+ }
2364
+ return changed ? next : value;
2365
+ };
2366
+ const createResumePayloadPlaceholderReplacements = (pathname, payload) => ({
2367
+ [ROUTE_MANIFEST_PLACEHOLDER]: JSON.stringify(routeManifest),
2368
+ [APP_HOOKS_PLACEHOLDER]: JSON.stringify(appHooksManifest),
2369
+ [CHUNK_CACHE_PLACEHOLDER]: createChunkCacheRegistrationScript(pathname, payload),
2370
+ });
2371
+ const serializeAppResumePayload = (pathname, payload) => serializeResumePayload(
2372
+ replaceResumePayloadPlaceholderValue(
2373
+ payload,
2374
+ createResumePayloadPlaceholderReplacements(pathname, payload),
2375
+ ),
2376
+ );
2312
2377
  const splitHtmlForStreaming = (html) => {
2313
2378
  const bodyCloseIndex = html.lastIndexOf("</body>");
2314
2379
  if (bodyCloseIndex >= 0) {
@@ -2498,7 +2563,7 @@ const renderRouteResponse = async (route, pathname, params, c, moduleUrl, status
2498
2563
  const shellHtml = replaceHeadPlaceholder(
2499
2564
  replaceHeadPlaceholder(
2500
2565
  replaceHeadPlaceholder(
2501
- replaceHeadPlaceholder(html, RESUME_PAYLOAD_PLACEHOLDER, serializeResumePayload(payload)),
2566
+ replaceHeadPlaceholder(html, RESUME_PAYLOAD_PLACEHOLDER, serializeAppResumePayload(pathname, payload)),
2502
2567
  CHUNK_CACHE_PLACEHOLDER,
2503
2568
  escapeInlineScriptText(createChunkCacheRegistrationScript(pathname, payload)),
2504
2569
  ),
@@ -2524,7 +2589,7 @@ const renderRouteResponse = async (route, pathname, params, c, moduleUrl, status
2524
2589
  controller.enqueue(
2525
2590
  encoder.encode(
2526
2591
  "<template id=\\"" + templateId + "\\">" + chunk.html + "</template>" +
2527
- "<script id=\\"" + payloadId + "\\" type=\\"application/eclipsa-resume+json\\">" + serializeResumePayload(chunk.payload) + "<\/script>" +
2592
+ "<script id=\\"" + payloadId + "\\" type=\\"application/eclipsa-resume+json\\">" + serializeAppResumePayload(pathname, chunk.payload) + "<\/script>" +
2528
2593
  "<script>window.__eclipsa_stream.enqueue({boundaryId:" + JSON.stringify(chunk.boundaryId) + ",payloadScriptId:" + JSON.stringify(payloadId) + ",templateId:" + JSON.stringify(templateId) + "})<\/script>",
2529
2594
  ),
2530
2595
  );
@@ -2532,7 +2597,7 @@ const renderRouteResponse = async (route, pathname, params, c, moduleUrl, status
2532
2597
 
2533
2598
  controller.enqueue(
2534
2599
  encoder.encode(
2535
- "<script id=\\"" + RESUME_FINAL_STATE_ELEMENT_ID + "\\" type=\\"application/eclipsa-resume+json\\">" + serializeResumePayload(latestPayload) + "<\/script>" +
2600
+ "<script id=\\"" + RESUME_FINAL_STATE_ELEMENT_ID + "\\" type=\\"application/eclipsa-resume+json\\">" + serializeAppResumePayload(pathname, latestPayload) + "<\/script>" +
2536
2601
  "<script>" + escapeInlineScriptText(createChunkCacheRegistrationScript(pathname, latestPayload)) + "<\/script>" +
2537
2602
  suffix,
2538
2603
  ),