@absolutejs/absolute 0.20.0-beta.53 → 0.20.0-beta.55

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.
Files changed (37) hide show
  1. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  2. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  3. package/dist/angular/index.js +25 -4
  4. package/dist/angular/index.js.map +6 -5
  5. package/dist/angular/server.js +25 -4
  6. package/dist/angular/server.js.map +6 -5
  7. package/dist/build.js +56 -9
  8. package/dist/build.js.map +10 -9
  9. package/dist/cli/config/server.js +4 -1
  10. package/dist/client/index.js +126 -7
  11. package/dist/client/index.js.map +8 -6
  12. package/dist/index.js +279 -232
  13. package/dist/index.js.map +12 -11
  14. package/dist/islands/index.js +17 -2
  15. package/dist/islands/index.js.map +5 -4
  16. package/dist/react/index.js +19 -3
  17. package/dist/react/index.js.map +6 -5
  18. package/dist/react/server.js +17 -2
  19. package/dist/react/server.js.map +5 -4
  20. package/dist/src/client/browserTranslation.d.ts +19 -0
  21. package/dist/src/client/index.d.ts +1 -0
  22. package/dist/src/core/browserTranslation.d.ts +6 -0
  23. package/dist/src/ember/browser.d.ts +0 -16
  24. package/dist/src/vue/browser.d.ts +1 -0
  25. package/dist/src/vue/browserTranslation.d.ts +5 -0
  26. package/dist/src/vue/index.d.ts +1 -0
  27. package/dist/svelte/index.js +19 -3
  28. package/dist/svelte/index.js.map +6 -5
  29. package/dist/svelte/server.js +17 -2
  30. package/dist/svelte/server.js.map +5 -4
  31. package/dist/vue/browser.js +96 -1
  32. package/dist/vue/browser.js.map +5 -3
  33. package/dist/vue/index.js +114 -3
  34. package/dist/vue/index.js.map +8 -5
  35. package/dist/vue/server.js +17 -2
  36. package/dist/vue/server.js.map +5 -4
  37. package/package.json +7 -7
@@ -39067,6 +39067,9 @@ var renderSpaNotFound = async (framework, pageName, request) => {
39067
39067
  });
39068
39068
  };
39069
39069
 
39070
+ // src/core/browserTranslation.ts
39071
+ var BROWSER_TRANSLATION_BASELINE_SCRIPT = "window.__ABSOLUTE_SSR_TEXT_BASELINES__=new WeakMap();" + "{const r=document.body,b=window.__ABSOLUTE_SSR_TEXT_BASELINES__;" + 'if(r)for(const e of [r,...r.querySelectorAll("*")]){' + "const t=new Map();for(const [i,n]of[...e.childNodes].entries())" + 'if(n.nodeType===3)t.set(i,n.nodeValue??"");if(t.size)b.set(e,t);}}';
39072
+
39070
39073
  // src/react/pageHandler.ts
39071
39074
  var withRequestUrl = (props, url) => Object.assign(Object.create(null), props, { url });
39072
39075
  var resolveRequestPathname = (request) => {
@@ -39121,7 +39124,7 @@ var handleReactPageRequest = async (input) => {
39121
39124
  const refreshSetup = buildRefreshSetup();
39122
39125
  const stream = await renderToReadableStream(element, {
39123
39126
  bootstrapModules: [resolvedIndex],
39124
- bootstrapScriptContent: propsScript + refreshSetup || undefined,
39127
+ bootstrapScriptContent: BROWSER_TRANSLATION_BASELINE_SCRIPT + propsScript + refreshSetup,
39125
39128
  onError(error) {
39126
39129
  console.error("[SSR] React streaming error:", error);
39127
39130
  }
@@ -235,6 +235,82 @@ var init_islandMarkupAttributes = __esm(() => {
235
235
  init_islands();
236
236
  });
237
237
 
238
+ // src/client/browserTranslation.ts
239
+ var translationRestorer = (restore, hasTranslation) => Object.assign(restore, { hasTranslation }), emptyTranslationRestorer = () => translationRestorer(() => {
240
+ return;
241
+ }, false), textNodeAt = (parent, index) => {
242
+ const node = parent.childNodes[index];
243
+ return node instanceof Text ? node : undefined;
244
+ }, visitElements = (root, visit) => {
245
+ visit(root);
246
+ for (const element of root.querySelectorAll("*"))
247
+ visit(element);
248
+ }, elementPath = (root, element) => {
249
+ const path = [];
250
+ let current = element;
251
+ while (current !== root) {
252
+ const parent = current.parentElement;
253
+ if (parent === null)
254
+ return null;
255
+ path.unshift([...parent.children].indexOf(current));
256
+ current = parent;
257
+ }
258
+ return path;
259
+ }, elementAtPath = (root, path) => {
260
+ let current = root;
261
+ for (const index of path) {
262
+ const child = current.children[index];
263
+ if (!(child instanceof Element))
264
+ return null;
265
+ current = child;
266
+ }
267
+ return current;
268
+ }, captureSsrTextBaselines = (root) => {
269
+ if (root === null || typeof window === "undefined")
270
+ return;
271
+ const baselines = window.__ABSOLUTE_SSR_TEXT_BASELINES__ ?? new WeakMap;
272
+ visitElements(root, (element) => {
273
+ const text = new Map;
274
+ for (const [index, node] of [...element.childNodes].entries()) {
275
+ if (node.nodeType === Node.TEXT_NODE)
276
+ text.set(index, node.nodeValue ?? "");
277
+ }
278
+ if (text.size > 0)
279
+ baselines.set(element, text);
280
+ });
281
+ window.__ABSOLUTE_SSR_TEXT_BASELINES__ = baselines;
282
+ }, prepareBrowserTranslationHydration = (root) => {
283
+ if (root === null || typeof window === "undefined")
284
+ return emptyTranslationRestorer();
285
+ const baselines = window.__ABSOLUTE_SSR_TEXT_BASELINES__;
286
+ if (baselines === undefined)
287
+ return emptyTranslationRestorer();
288
+ const translated = [];
289
+ visitElements(root, (element) => {
290
+ const text = baselines.get(element);
291
+ const path = elementPath(root, element);
292
+ if (text === undefined || path === null)
293
+ return;
294
+ for (const [index, baseline] of text) {
295
+ const node = textNodeAt(element, index);
296
+ if (node === undefined || node.data === baseline)
297
+ continue;
298
+ translated.push({ baseline, index, path, translated: node.data });
299
+ node.data = baseline;
300
+ }
301
+ });
302
+ return translationRestorer(() => {
303
+ for (const snapshot of translated) {
304
+ const parent = elementAtPath(root, snapshot.path);
305
+ if (parent === null)
306
+ continue;
307
+ const node = textNodeAt(parent, snapshot.index);
308
+ if (node !== undefined && node.data === snapshot.baseline)
309
+ node.data = snapshot.translated;
310
+ }
311
+ }, translated.length > 0);
312
+ };
313
+
238
314
  // src/client/hydrators/react.ts
239
315
  var exports_react = {};
240
316
  __export(exports_react, {
@@ -243,6 +319,7 @@ __export(exports_react, {
243
319
  });
244
320
  import { createElement } from "react";
245
321
  import { hydrateRoot } from "react-dom/client";
322
+ import { flushSync } from "react-dom";
246
323
  var reactIslandRoots, isPropsRecord = (value) => typeof value === "object" && value !== null, HOST_REACT_EXPANDO_PREFIXES, detachFromHostReactRoot = (element) => {
247
324
  for (const key of Object.keys(element)) {
248
325
  const isHostExpando = HOST_REACT_EXPANDO_PREFIXES.some((prefix) => key.startsWith(prefix));
@@ -257,11 +334,28 @@ var reactIslandRoots, isPropsRecord = (value) => typeof value === "object" && va
257
334
  return;
258
335
  }
259
336
  detachFromHostReactRoot(element);
337
+ const restoreTranslation = prepareBrowserTranslationHydration(element);
338
+ const hydrate = (elementToHydrate) => {
339
+ let root;
340
+ const startHydration = () => {
341
+ root = hydrateRoot(element, elementToHydrate);
342
+ };
343
+ try {
344
+ if (restoreTranslation.hasTranslation)
345
+ flushSync(startHydration);
346
+ else
347
+ startHydration();
348
+ } finally {
349
+ restoreTranslation();
350
+ }
351
+ if (root !== undefined)
352
+ reactIslandRoots.set(element, root);
353
+ };
260
354
  if (!isPropsRecord(props)) {
261
- reactIslandRoots.set(element, hydrateRoot(element, createElement(component)));
355
+ hydrate(createElement(component));
262
356
  return;
263
357
  }
264
- reactIslandRoots.set(element, hydrateRoot(element, createElement(component, props)));
358
+ hydrate(createElement(component, props));
265
359
  }, isReactComponent = (value) => typeof value === "function";
266
360
  var init_react = __esm(() => {
267
361
  reactIslandRoots = new WeakMap;
@@ -638,6 +732,20 @@ var init_registerClientScript = __esm(() => {
638
732
  }
639
733
  });
640
734
 
735
+ // src/core/browserTranslation.ts
736
+ var BASELINE_MARKER = "__ABSOLUTE_SSR_TEXT_BASELINES__", BROWSER_TRANSLATION_BASELINE_SCRIPT, browserTranslationBaselineTag = () => `<script>${BROWSER_TRANSLATION_BASELINE_SCRIPT}</script>`, injectBrowserTranslationBaseline = (html) => {
737
+ if (html.includes(BASELINE_MARKER))
738
+ return html;
739
+ const script = browserTranslationBaselineTag();
740
+ const closingBodyIndex = html.lastIndexOf("</body>");
741
+ if (closingBodyIndex < 0)
742
+ return `${html}${script}`;
743
+ return `${html.slice(0, closingBodyIndex)}${script}${html.slice(closingBodyIndex)}`;
744
+ };
745
+ var init_browserTranslation = __esm(() => {
746
+ BROWSER_TRANSLATION_BASELINE_SCRIPT = "window.__ABSOLUTE_SSR_TEXT_BASELINES__=new WeakMap();" + "{const r=document.body,b=window.__ABSOLUTE_SSR_TEXT_BASELINES__;" + 'if(r)for(const e of [r,...r.querySelectorAll("*")]){' + "const t=new Map();for(const [i,n]of[...e.childNodes].entries())" + 'if(n.nodeType===3)t.set(i,n.nodeValue??"");if(t.size)b.set(e,t);}}';
747
+ });
748
+
641
749
  // src/angular/httpTransferCache.ts
642
750
  var ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER = "x-skip-transfer-cache", buildAbsoluteHttpTransferCacheOptions = (options = {}) => {
643
751
  const {
@@ -690,7 +798,7 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
690
798
  }
691
799
  return html + snippet;
692
800
  }, injectSsrScripts = (html, requestId, indexPath, requestContext) => {
693
- let result = html;
801
+ let result = injectBeforeClose(html, browserTranslationBaselineTag());
694
802
  const registeredScripts = getAndClearClientScripts(requestId);
695
803
  if (registeredScripts.length > 0) {
696
804
  result = injectBeforeClose(result, generateClientScriptCode(registeredScripts));
@@ -726,6 +834,7 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
726
834
  };
727
835
  var init_ssrRender = __esm(() => {
728
836
  init_registerClientScript();
837
+ init_browserTranslation();
729
838
  routeContextCache = new Map;
730
839
  selectorCache = new Map;
731
840
  });
@@ -1113,6 +1222,14 @@ var isPropsRecord4 = (value) => typeof value === "object" && value !== null;
1113
1222
  var isIslandElement = (value) => value instanceof HTMLElement && value.dataset.island === "true";
1114
1223
  var observedRoots = new WeakSet;
1115
1224
  var hydratingIslands = new WeakSet;
1225
+ var hydratePreservingBrowserTranslation = async (element, hydrate) => {
1226
+ const restoreTranslation = prepareBrowserTranslationHydration(element);
1227
+ try {
1228
+ await hydrate();
1229
+ } finally {
1230
+ restoreTranslation();
1231
+ }
1232
+ };
1116
1233
  var hydrateByFramework = async (registry, framework, componentName, element, props, resolveComponent) => {
1117
1234
  const propsRecord = isPropsRecord4(props) ? props : undefined;
1118
1235
  if (framework === "react") {
@@ -1129,7 +1246,7 @@ var hydrateByFramework = async (registry, framework, componentName, element, pro
1129
1246
  const resolvedComponent = await resolveComponent?.(framework, componentName) ?? getIslandComponent(registry.svelte?.[componentName]);
1130
1247
  if (!isSvelteComponent2(resolvedComponent))
1131
1248
  return;
1132
- hydrateSvelteIsland2(resolvedComponent, element, propsRecord);
1249
+ await hydratePreservingBrowserTranslation(element, () => hydrateSvelteIsland2(resolvedComponent, element, propsRecord));
1133
1250
  element.dataset.hydrated = "true";
1134
1251
  return;
1135
1252
  }
@@ -1138,7 +1255,7 @@ var hydrateByFramework = async (registry, framework, componentName, element, pro
1138
1255
  const resolvedComponent = await resolveComponent?.(framework, componentName) ?? getIslandComponent(registry.vue?.[componentName]);
1139
1256
  if (!isVueComponent2(resolvedComponent))
1140
1257
  return;
1141
- hydrateVueIsland2(resolvedComponent, element, propsRecord);
1258
+ await hydratePreservingBrowserTranslation(element, () => hydrateVueIsland2(resolvedComponent, element, propsRecord));
1142
1259
  element.dataset.hydrated = "true";
1143
1260
  return;
1144
1261
  }
@@ -1148,7 +1265,7 @@ var hydrateByFramework = async (registry, framework, componentName, element, pro
1148
1265
  const { islandId } = element.dataset;
1149
1266
  if (!isAngularComponent2(resolvedComponent) || !islandId)
1150
1267
  return;
1151
- await mountAngularIsland2(resolvedComponent, element, propsRecord ?? {}, islandId);
1268
+ await hydratePreservingBrowserTranslation(element, () => mountAngularIsland2(resolvedComponent, element, propsRecord ?? {}, islandId));
1152
1269
  element.dataset.hydrated = "true";
1153
1270
  }
1154
1271
  };
@@ -1239,15 +1356,17 @@ var startIslands = ({
1239
1356
  });
1240
1357
  };
1241
1358
  export {
1359
+ captureSsrTextBaselines,
1242
1360
  createIslandManifestResolver,
1243
1361
  createIslandStore,
1244
1362
  getIslandStoreServerSnapshot,
1245
1363
  getStreamSwapRuntimeScript,
1246
1364
  initializeIslandStores,
1365
+ prepareBrowserTranslationHydration,
1247
1366
  readIslandStore,
1248
1367
  startIslands,
1249
1368
  subscribeIslandStore
1250
1369
  };
1251
1370
 
1252
- //# debugId=A44D536D7433EB4864756E2164756E21
1371
+ //# debugId=77AFDE1DACC53DED64756E2164756E21
1253
1372
  //# sourceMappingURL=index.js.map