@absolutejs/absolute 0.20.0-beta.54 → 0.20.0-beta.56

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 (45) 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 +66 -10
  8. package/dist/build.js.map +11 -10
  9. package/dist/cli/config/server.js +4 -1
  10. package/dist/cli/index.js +53 -3
  11. package/dist/client/index.js +126 -7
  12. package/dist/client/index.js.map +8 -6
  13. package/dist/index.js +289 -233
  14. package/dist/index.js.map +13 -12
  15. package/dist/islands/index.js +17 -2
  16. package/dist/islands/index.js.map +5 -4
  17. package/dist/mobile/index.js +1332 -64
  18. package/dist/mobile/index.js.map +8 -6
  19. package/dist/mobile/remoteMacAgentEntry.js +101 -92
  20. package/dist/mobile/shellBootstrap.js +258 -4
  21. package/dist/react/index.js +19 -3
  22. package/dist/react/index.js.map +6 -5
  23. package/dist/react/server.js +17 -2
  24. package/dist/react/server.js.map +5 -4
  25. package/dist/src/client/browserTranslation.d.ts +19 -0
  26. package/dist/src/client/index.d.ts +1 -0
  27. package/dist/src/core/browserTranslation.d.ts +6 -0
  28. package/dist/src/ember/browser.d.ts +0 -16
  29. package/dist/src/mobile/adaptiveShell.d.ts +27 -0
  30. package/dist/src/mobile/deviceCapabilities.d.ts +1 -0
  31. package/dist/src/mobile/index.d.ts +1 -0
  32. package/dist/src/vue/browser.d.ts +1 -0
  33. package/dist/src/vue/browserTranslation.d.ts +5 -0
  34. package/dist/src/vue/index.d.ts +1 -0
  35. package/dist/svelte/index.js +19 -3
  36. package/dist/svelte/index.js.map +6 -5
  37. package/dist/svelte/server.js +17 -2
  38. package/dist/svelte/server.js.map +5 -4
  39. package/dist/vue/browser.js +96 -1
  40. package/dist/vue/browser.js.map +5 -3
  41. package/dist/vue/index.js +114 -3
  42. package/dist/vue/index.js.map +8 -5
  43. package/dist/vue/server.js +17 -2
  44. package/dist/vue/server.js.map +5 -4
  45. package/package.json +7 -7
package/dist/index.js CHANGED
@@ -6882,6 +6882,20 @@ var init_registerClientScript = __esm(() => {
6882
6882
  }
6883
6883
  });
6884
6884
 
6885
+ // src/core/browserTranslation.ts
6886
+ var BASELINE_MARKER = "__ABSOLUTE_SSR_TEXT_BASELINES__", BROWSER_TRANSLATION_BASELINE_SCRIPT, browserTranslationBaselineTag = () => `<script>${BROWSER_TRANSLATION_BASELINE_SCRIPT}</script>`, injectBrowserTranslationBaseline = (html) => {
6887
+ if (html.includes(BASELINE_MARKER))
6888
+ return html;
6889
+ const script = browserTranslationBaselineTag();
6890
+ const closingBodyIndex = html.lastIndexOf("</body>");
6891
+ if (closingBodyIndex < 0)
6892
+ return `${html}${script}`;
6893
+ return `${html.slice(0, closingBodyIndex)}${script}${html.slice(closingBodyIndex)}`;
6894
+ };
6895
+ var init_browserTranslation = __esm(() => {
6896
+ 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);}}';
6897
+ });
6898
+
6885
6899
  // src/angular/httpTransferCache.ts
6886
6900
  var ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER = "x-skip-transfer-cache", buildAbsoluteHttpTransferCacheOptions = (options = {}) => {
6887
6901
  const {
@@ -6934,7 +6948,7 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
6934
6948
  }
6935
6949
  return html + snippet;
6936
6950
  }, injectSsrScripts = (html, requestId, indexPath, requestContext) => {
6937
- let result = html;
6951
+ let result = injectBeforeClose(html, browserTranslationBaselineTag());
6938
6952
  const registeredScripts = getAndClearClientScripts(requestId);
6939
6953
  if (registeredScripts.length > 0) {
6940
6954
  result = injectBeforeClose(result, generateClientScriptCode(registeredScripts));
@@ -6970,6 +6984,7 @@ var routeContextCache, cacheRouteData = (pagePath, data) => {
6970
6984
  };
6971
6985
  var init_ssrRender = __esm(() => {
6972
6986
  init_registerClientScript();
6987
+ init_browserTranslation();
6973
6988
  routeContextCache = new Map;
6974
6989
  selectorCache = new Map;
6975
6990
  });
@@ -10308,10 +10323,14 @@ var indexContentCache, resolveDevClientDir = () => {
10308
10323
  ] : [];
10309
10324
  const reactImports = isDev2 ? [
10310
10325
  `import { hydrateRoot, createRoot } from 'react-dom/client';`,
10311
- `import { createElement, Component } from 'react';`
10326
+ `import { flushSync } from 'react-dom';`,
10327
+ `import { createElement, Component } from 'react';`,
10328
+ `import { prepareBrowserTranslationHydration } from '@absolutejs/absolute/client';`
10312
10329
  ] : [
10313
10330
  `import { hydrateRoot, createRoot } from 'react-dom/client';`,
10314
- `import { createElement } from 'react';`
10331
+ `import { flushSync } from 'react-dom';`,
10332
+ `import { createElement } from 'react';`,
10333
+ `import { prepareBrowserTranslationHydration } from '@absolutejs/absolute/client';`
10315
10334
  ];
10316
10335
  const errorBoundaryDef = isDev2 ? [
10317
10336
  `
@@ -10506,8 +10525,10 @@ var indexContentCache, resolveDevClientDir = () => {
10506
10525
  ` root.render(${isDev2 ? `createElement(ErrorBoundary, null, createElement(PageComponent, mergedProps))` : `createElement(PageComponent, mergedProps)`});`,
10507
10526
  ` window.__REACT_ROOT__ = root;`,
10508
10527
  ` } else {`,
10528
+ ` const restoreTranslation = prepareBrowserTranslationHydration(container);`,
10509
10529
  ` try {`,
10510
10530
  ` // Use onRecoverableError to catch hydration errors (React 19)`,
10531
+ ` const startHydration = () => {`,
10511
10532
  ` root = hydrateRoot(`,
10512
10533
  ` container,`,
10513
10534
  ` ${isDev2 ? `createElement(ErrorBoundary, null, createElement(PageComponent, mergedProps))` : `createElement(PageComponent, mergedProps)`},`,
@@ -10544,8 +10565,13 @@ var indexContentCache, resolveDevClientDir = () => {
10544
10565
  ` }`,
10545
10566
  ` }`,
10546
10567
  ` );`,
10568
+ ` };`,
10569
+ ` if (restoreTranslation.hasTranslation) flushSync(startHydration);`,
10570
+ ` else startHydration();`,
10571
+ ` restoreTranslation();`,
10547
10572
  ` window.__REACT_ROOT__ = root;`,
10548
10573
  ` } catch (error) {`,
10574
+ ` restoreTranslation();`,
10549
10575
  ` // Catch synchronous errors (shouldn't happen with hydrateRoot, but safety net)`,
10550
10576
  ` if (isDev && isHydrationError(error)) {`,
10551
10577
  ` handleHydrationFallback(error);`,
@@ -13395,7 +13421,7 @@ import { existsSync as existsSync23, readFileSync as readFileSync17 } from "fs";
13395
13421
  import { extname as extname7, join as join29, relative as relative11, resolve as resolve25 } from "path";
13396
13422
  import { fileURLToPath as fileURLToPath2 } from "url";
13397
13423
  import ts8 from "typescript";
13398
- var DEVICES_PACKAGE = "@absolutejs/devices", ADAPTERS, SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, providerModulePattern = (provider) => new RegExp(`^@absolutejs/devices-${provider}/[a-z][a-z0-9-]*$`, "u"), providerPackagePattern = (provider) => provider === "capacitor" ? /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u : /^(?:expo-[a-z][a-z0-9-]*|@react-native-[a-z0-9-]+\/[a-z][a-z0-9-]*)@\d+\.\d+\.\d+$/u, providerLabel = (provider) => provider === "capacitor" ? "Capacitor" : "Expo", ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, IOS_PRIVACY_ACCESSED_API_REASONS, IOS_PRIVACY_ACCESSED_APIS, object = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
13424
+ var DEVICES_PACKAGE = "@absolutejs/devices", ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES, ADAPTERS, SOURCE_GLOB, IGNORED_DIRECTORIES, IDENTIFIER_PATTERN, providerModulePattern = (provider) => new RegExp(`^@absolutejs/devices-${provider}/[a-z][a-z0-9-]*$`, "u"), providerPackagePattern = (provider) => provider === "capacitor" ? /^@capacitor\/[a-z][a-z0-9-]*@\d+\.\d+\.\d+$/u : /^(?:expo-[a-z][a-z0-9-]*|@react-native-[a-z0-9-]+\/[a-z][a-z0-9-]*)@\d+\.\d+\.\d+$/u, providerLabel = (provider) => provider === "capacitor" ? "Capacitor" : "Expo", ANDROID_PERMISSION_PATTERN, IOS_USAGE_DESCRIPTIONS, IOS_PRIVACY_ACCESSED_API_REASONS, IOS_PRIVACY_ACCESSED_APIS, object = (value) => typeof value === "object" && value !== null && !Array.isArray(value), readJson = (path) => {
13399
13425
  const value = JSON.parse(readFileSync17(path, "utf8"));
13400
13426
  if (!object(value))
13401
13427
  throw new TypeError(`${path} must contain an object.`);
@@ -13626,6 +13652,11 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ADAPTERS, SOURCE_GLOB, IGNORED_DIRE
13626
13652
  }, resolveAbsoluteDeviceCapabilityPlan = (projectRoot, provider = "capacitor") => {
13627
13653
  const allProviders = loadAbsoluteDeviceCapabilityProviders(projectRoot, provider);
13628
13654
  const capabilities = discoverAbsoluteDeviceCapabilities(projectRoot, allProviders);
13655
+ for (const capability of ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES) {
13656
+ if (allProviders[capability] && !capabilities.includes(capability))
13657
+ capabilities.push(capability);
13658
+ }
13659
+ capabilities.sort();
13629
13660
  const providers = {};
13630
13661
  for (const name of capabilities) {
13631
13662
  const capabilityProvider = allProviders[name];
@@ -13641,6 +13672,10 @@ var DEVICES_PACKAGE = "@absolutejs/devices", ADAPTERS, SOURCE_GLOB, IGNORED_DIRE
13641
13672
  };
13642
13673
  };
13643
13674
  var init_deviceCapabilities = __esm(() => {
13675
+ ABSOLUTE_MOBILE_SHELL_DEVICE_CAPABILITIES = [
13676
+ "keyboard",
13677
+ "systemBars"
13678
+ ];
13644
13679
  ADAPTERS = {
13645
13680
  capacitor: "@absolutejs/devices-capacitor",
13646
13681
  expo: "@absolutejs/devices-expo"
@@ -15101,6 +15136,7 @@ import "${hmrClientPath3}";
15101
15136
  ` : "";
15102
15137
  const bootstrap = `${hmrImports}import Component from "${importPath}";
15103
15138
  import { hydrate, mount, unmount } from "svelte";
15139
+ import { prepareBrowserTranslationHydration } from "@absolutejs/absolute/client";
15104
15140
 
15105
15141
  var initialProps = (typeof window !== "undefined" && window.__INITIAL_PROPS__) ? window.__INITIAL_PROPS__ : {};
15106
15142
  var isHMR = typeof window !== "undefined" && window.__SVELTE_COMPONENT__ !== undefined;
@@ -15145,7 +15181,12 @@ if (isHMR) {
15145
15181
  } else if (isSsrDirty || hasIslandHtml) {
15146
15182
  component = mount(Component, { target, props: initialProps });
15147
15183
  } else {
15148
- component = hydrate(Component, { target, props: initialProps });
15184
+ var restoreTranslation = prepareBrowserTranslationHydration(target);
15185
+ try {
15186
+ component = hydrate(Component, { target, props: initialProps });
15187
+ } finally {
15188
+ restoreTranslation();
15189
+ }
15149
15190
  }
15150
15191
 
15151
15192
  if (typeof window !== "undefined") {
@@ -16088,6 +16129,7 @@ if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
16088
16129
  ...vueHmrImports,
16089
16130
  `import Comp, * as PageModule from "${relative13(dirname20(indexOutputFile), clientOutputFile).replace(/\\/g, "/")}";`,
16090
16131
  'import { createSSRApp, createApp } from "vue";',
16132
+ 'import { prepareBrowserTranslationHydration } from "@absolutejs/absolute/vue";',
16091
16133
  "",
16092
16134
  "// HMR State Preservation: Check for preserved state from HMR",
16093
16135
  'let preservedState = (typeof window !== "undefined" && window.__HMR_PRESERVED_STATE__) ? window.__HMR_PRESERVED_STATE__ : {};',
@@ -16150,7 +16192,14 @@ if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
16150
16192
  " url: clientUrl",
16151
16193
  " });",
16152
16194
  " }",
16153
- ' app.mount("#root");',
16195
+ " const restoreBrowserTranslation = shouldHydrate",
16196
+ ' ? prepareBrowserTranslationHydration(document.querySelector("#root"))',
16197
+ " : () => undefined;",
16198
+ " try {",
16199
+ ' app.mount("#root");',
16200
+ " } finally {",
16201
+ " restoreBrowserTranslation();",
16202
+ " }",
16154
16203
  "}",
16155
16204
  "const absolutePageReady = bootstrapApp();",
16156
16205
  "",
@@ -17911,6 +17960,7 @@ import { bootstrapApplication } from '@angular/platform-browser';
17911
17960
  import { provideClientHydration } from '@angular/platform-browser';
17912
17961
  import { withHttpTransferCacheOptions } from '@angular/platform-browser';
17913
17962
  import { provideZonelessChangeDetection, REQUEST_CONTEXT } from '@angular/core';
17963
+ import { prepareBrowserTranslationHydration } from '@absolutejs/absolute/client';
17914
17964
  import * as pageModule from '${normalizedImportPath}';
17915
17965
  var ${componentClassName} = pageModule.default;
17916
17966
  // REQUEST_CONTEXT is hydrated from the SSR-serialized payload so client-side
@@ -17974,8 +18024,10 @@ if (!document.querySelector(_sel)) {
17974
18024
  }
17975
18025
 
17976
18026
  var providers = [provideZonelessChangeDetection()];
18027
+ var restoreTranslation = function() {};
17977
18028
  if (!isClientRender && !window.__HMR_SKIP_HYDRATION__ && !pageHasIslands) {
17978
18029
  providers.push(provideClientHydration(withHttpTransferCacheOptions(absoluteHttpTransferCacheOptions)));
18030
+ restoreTranslation = prepareBrowserTranslationHydration(document.querySelector(_sel));
17979
18031
  }
17980
18032
  delete window.__HMR_SKIP_HYDRATION__;
17981
18033
  providers.push.apply(providers, pageProviders);
@@ -18002,7 +18054,7 @@ if (pageHasRawStreamingSlots) {
18002
18054
  });
18003
18055
  }
18004
18056
  return appRef;
18005
- });
18057
+ }).finally(restoreTranslation);
18006
18058
  }
18007
18059
  window.__ABSOLUTE_PAGE_READY__ = absolutePageReady;
18008
18060
  window.__ABSOLUTE_PAGE_DISPOSE__ = async function() {
@@ -18018,6 +18070,7 @@ import { bootstrapApplication } from '@angular/platform-browser';
18018
18070
  import { provideClientHydration } from '@angular/platform-browser';
18019
18071
  import { withHttpTransferCacheOptions } from '@angular/platform-browser';
18020
18072
  import { enableProdMode, provideZonelessChangeDetection, REQUEST_CONTEXT } from '@angular/core';
18073
+ import { prepareBrowserTranslationHydration } from '@absolutejs/absolute/client';
18021
18074
  import * as pageModule from '${normalizedImportPath}';
18022
18075
  var ${componentClassName} = pageModule.default;
18023
18076
  // REQUEST_CONTEXT is hydrated from the SSR-serialized payload so client-side
@@ -18060,8 +18113,10 @@ if (!document.querySelector(_sel)) {
18060
18113
  }
18061
18114
 
18062
18115
  var providers = [provideZonelessChangeDetection()].concat(pageProviders).concat(contextProviders);
18116
+ var restoreTranslation = function() {};
18063
18117
  if (!isClientRender && !pageHasIslands) {
18064
18118
  providers.unshift(provideClientHydration(withHttpTransferCacheOptions(absoluteHttpTransferCacheOptions)));
18119
+ restoreTranslation = prepareBrowserTranslationHydration(document.querySelector(_sel));
18065
18120
  }
18066
18121
  window.__ABS_SLOT_HYDRATION_PENDING__ = pageHasRawStreamingSlots;
18067
18122
  var absolutePageReady = Promise.resolve();
@@ -18085,7 +18140,7 @@ if (pageHasRawStreamingSlots) {
18085
18140
  });
18086
18141
  }
18087
18142
  return appRef;
18088
- });
18143
+ }).finally(restoreTranslation);
18089
18144
  }
18090
18145
  window.__ABSOLUTE_PAGE_READY__ = absolutePageReady;
18091
18146
  window.__ABSOLUTE_PAGE_DISPOSE__ = async function() {
@@ -26982,7 +27037,7 @@ var resolveRequestPathname = (request) => {
26982
27037
  }, buildHtmlShell = (headTag, bodyContent, indexPath, props, hmrShim) => {
26983
27038
  const propsScript = `window.__INITIAL_PROPS__=${JSON.stringify(props ?? {})};`;
26984
27039
  const indexImport = indexPath ? `<script type="module" src="${indexPath}"></script>` : "";
26985
- return `<!DOCTYPE html><html>${headTag}<body>` + `<div id="ember-root">${bodyContent}</div>` + `<script>${propsScript}</script>${indexImport}${hmrShim}</body></html>`;
27040
+ return injectBrowserTranslationBaseline(`<!DOCTYPE html><html>${headTag}<body>` + `<div id="ember-root">${bodyContent}</div>` + `<script>${propsScript}</script>${indexImport}${hmrShim}</body></html>`);
26986
27041
  }, cachedEmberHmrShim = null, getEmberHmrShim = () => {
26987
27042
  if (cachedEmberHmrShim)
26988
27043
  return cachedEmberHmrShim;
@@ -27019,6 +27074,7 @@ var resolveRequestPathname = (request) => {
27019
27074
  };
27020
27075
  var init_pageHandler = __esm(() => {
27021
27076
  init_pageResponseCache();
27077
+ init_browserTranslation();
27022
27078
  });
27023
27079
 
27024
27080
  // src/ember/index.ts
@@ -31945,230 +32001,9 @@ init_islands();
31945
32001
 
31946
32002
  // src/core/pageHandlers.ts
31947
32003
  init_staticIslandPages();
31948
- var {file } = globalThis.Bun;
31949
-
31950
- // src/core/islandPageContext.ts
31951
- var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient";
31952
- var ISLAND_MARKER = 'data-island="true"';
31953
- var MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__";
31954
- var ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__";
31955
- var CLOSING_HEAD_TAG2 = "</head>";
31956
- var buildIslandsHeadMarkup = (manifest) => {
31957
- const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
31958
- const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
31959
- const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
31960
- const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
31961
- return `${manifestScript}${islandStateScript}${bootstrapScript}`;
31962
- };
31963
- var injectHeadMarkup = (html, markup) => {
31964
- const closingHeadIndex = html.indexOf("</head>");
31965
- if (closingHeadIndex >= 0) {
31966
- return `${html.slice(0, closingHeadIndex)}${markup}${html.slice(closingHeadIndex)}`;
31967
- }
31968
- const openingBodyIndex = html.indexOf("<body");
31969
- if (openingBodyIndex >= 0) {
31970
- const bodyStart = html.indexOf(">", openingBodyIndex);
31971
- if (bodyStart >= 0) {
31972
- return `${html.slice(0, openingBodyIndex)}<head>${markup}</head>${html.slice(openingBodyIndex)}`;
31973
- }
31974
- }
31975
- return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
31976
- };
31977
- var streamChunkToString2 = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true });
31978
- var flushSafePendingText = (controller, encoder, pending, lookbehind) => {
31979
- if (pending.length <= lookbehind) {
31980
- return pending;
31981
- }
31982
- const safeText = pending.slice(0, pending.length - lookbehind);
31983
- controller.enqueue(encoder.encode(safeText));
31984
- return pending.slice(-lookbehind);
31985
- };
31986
- var updateInjectedState = (consumed, injected, pending) => {
31987
- if (consumed.done) {
31988
- return { done: true, injected, pending };
31989
- }
31990
- return {
31991
- done: false,
31992
- injected: consumed.injected,
31993
- pending: consumed.pending
31994
- };
31995
- };
31996
- var readStreamChunk = async (reader) => {
31997
- const { done, value } = await reader.read();
31998
- if (done || !value) {
31999
- return { done, value: undefined };
32000
- }
32001
- return { done, value };
32002
- };
32003
- var pipeStreamWithHeadInjection = (stream, markup) => {
32004
- const encoder = new TextEncoder;
32005
- const decoder = new TextDecoder;
32006
- const lookbehind = CLOSING_HEAD_TAG2.length - 1;
32007
- const processPending = (controller, pending, injected) => {
32008
- if (injected) {
32009
- controller.enqueue(encoder.encode(pending));
32010
- return { injected, pending: "" };
32011
- }
32012
- const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
32013
- if (headIndex >= 0) {
32014
- const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
32015
- controller.enqueue(encoder.encode(next));
32016
- return { injected: true, pending: "" };
32017
- }
32018
- return {
32019
- injected,
32020
- pending: flushSafePendingText(controller, encoder, pending, lookbehind)
32021
- };
32022
- };
32023
- const finishHeadInjectionStream = (controller, pending, injected) => {
32024
- let finalPending = pending + decoder.decode();
32025
- if (!injected) {
32026
- finalPending = injectHeadMarkup(finalPending, markup);
32027
- }
32028
- if (finalPending.length > 0) {
32029
- controller.enqueue(encoder.encode(finalPending));
32030
- }
32031
- controller.close();
32032
- };
32033
- const consumeHeadChunk = async (controller, reader, pending, injected) => {
32034
- const { done, value } = await readStreamChunk(reader);
32035
- if (done || !value) {
32036
- return { done, injected, pending };
32037
- }
32038
- const processed = processPending(controller, pending + streamChunkToString2(value, decoder), injected);
32039
- return {
32040
- done,
32041
- injected: processed.injected,
32042
- pending: processed.pending
32043
- };
32044
- };
32045
- const runHeadInjectionLoop = async (controller, reader) => {
32046
- const consumeNextHeadChunk = async (injected, pending) => {
32047
- const consumed = await consumeHeadChunk(controller, reader, pending, injected);
32048
- const nextState = updateInjectedState(consumed, injected, pending);
32049
- if (nextState.done) {
32050
- return { injected, pending };
32051
- }
32052
- return consumeNextHeadChunk(nextState.injected, nextState.pending);
32053
- };
32054
- return consumeNextHeadChunk(false, "");
32055
- };
32056
- return new ReadableStream({
32057
- async start(controller) {
32058
- const reader = stream.getReader();
32059
- try {
32060
- const { injected, pending } = await runHeadInjectionLoop(controller, reader);
32061
- finishHeadInjectionStream(controller, pending, injected);
32062
- } catch (error) {
32063
- controller.error(error);
32064
- }
32065
- }
32066
- });
32067
- };
32068
- var pipeStreamWithIslandMarkerDetection = (stream, markup) => {
32069
- const encoder = new TextEncoder;
32070
- const decoder = new TextDecoder;
32071
- const headLookbehind = CLOSING_HEAD_TAG2.length - 1;
32072
- const enqueue = (controller, text) => {
32073
- if (text.length > 0) {
32074
- controller.enqueue(encoder.encode(text));
32075
- }
32076
- };
32077
- const processHolding = (controller, held) => {
32078
- if (!held.includes(ISLAND_MARKER)) {
32079
- return { held, injected: false, pending: "", sawHead: true };
32080
- }
32081
- enqueue(controller, `${markup}${held}`);
32082
- return { held: "", injected: true, pending: "", sawHead: true };
32083
- };
32084
- const processHead = (controller, pending) => {
32085
- const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
32086
- if (headIndex < 0) {
32087
- return {
32088
- held: "",
32089
- injected: false,
32090
- pending: flushSafePendingText(controller, encoder, pending, headLookbehind),
32091
- sawHead: false
32092
- };
32093
- }
32094
- enqueue(controller, pending.slice(0, headIndex));
32095
- return processHolding(controller, pending.slice(headIndex));
32096
- };
32097
- const processChunk = (controller, state, chunk) => {
32098
- if (state.injected) {
32099
- enqueue(controller, chunk);
32100
- return state;
32101
- }
32102
- if (!state.sawHead) {
32103
- return processHead(controller, state.pending + chunk);
32104
- }
32105
- return processHolding(controller, state.held + chunk);
32106
- };
32107
- const finishMarkerStream = (controller, state) => {
32108
- const tail = decoder.decode();
32109
- const remainder = state.injected ? tail : (state.sawHead ? state.held : state.pending) + tail;
32110
- enqueue(controller, remainder);
32111
- controller.close();
32112
- };
32113
- const runMarkerLoop = (controller, reader) => {
32114
- const consumeNext = async (state) => {
32115
- const { done, value } = await readStreamChunk(reader);
32116
- if (done || !value) {
32117
- return state;
32118
- }
32119
- return consumeNext(processChunk(controller, state, streamChunkToString2(value, decoder)));
32120
- };
32121
- return consumeNext({
32122
- held: "",
32123
- injected: false,
32124
- pending: "",
32125
- sawHead: false
32126
- });
32127
- };
32128
- return new ReadableStream({
32129
- async start(controller) {
32130
- const reader = stream.getReader();
32131
- try {
32132
- const finalState = await runMarkerLoop(controller, reader);
32133
- finishMarkerStream(controller, finalState);
32134
- } catch (error) {
32135
- controller.error(error);
32136
- }
32137
- }
32138
- });
32139
- };
32140
- var htmlContainsIslands = (html) => html.includes(ISLAND_MARKER);
32141
- var injectIslandPageContext = (html, options) => {
32142
- const manifest = globalThis.__absoluteManifest;
32143
- const hasIslands = options?.hasIslands ?? htmlContainsIslands(html);
32144
- if (!manifest || !hasIslands) {
32145
- return html;
32146
- }
32147
- if (html.includes(MANIFEST_MARKER) || html.includes(ISLAND_STATE_MARKER)) {
32148
- return html;
32149
- }
32150
- return injectHeadMarkup(html, buildIslandsHeadMarkup(manifest));
32151
- };
32152
- var injectIslandPageContextStream = (stream, options) => {
32153
- const manifest = globalThis.__absoluteManifest;
32154
- if (!manifest)
32155
- return stream;
32156
- const markup = buildIslandsHeadMarkup(manifest);
32157
- if (options?.hasIslands === true) {
32158
- return pipeStreamWithHeadInjection(stream, markup);
32159
- }
32160
- if (options?.hasIslands === false) {
32161
- return stream;
32162
- }
32163
- return pipeStreamWithIslandMarkerDetection(stream, markup);
32164
- };
32165
- var setCurrentIslandManifest = (manifest) => {
32166
- globalThis.__absoluteManifest = manifest;
32167
- };
32168
-
32169
- // src/core/pageHandlers.ts
32170
32004
  init_pageResponseCache();
32171
32005
  init_staticStreaming();
32006
+ var {file } = globalThis.Bun;
32172
32007
 
32173
32008
  // src/core/responseEnhancers.ts
32174
32009
  init_streamingSlots();
@@ -32527,7 +32362,227 @@ var finalizeAbsoluteMobilePage = (input) => {
32527
32362
  }
32528
32363
  };
32529
32364
 
32365
+ // src/core/islandPageContext.ts
32366
+ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient";
32367
+ var ISLAND_MARKER = 'data-island="true"';
32368
+ var MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__";
32369
+ var ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__";
32370
+ var CLOSING_HEAD_TAG2 = "</head>";
32371
+ var buildIslandsHeadMarkup = (manifest) => {
32372
+ const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
32373
+ const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
32374
+ const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
32375
+ const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
32376
+ return `${manifestScript}${islandStateScript}${bootstrapScript}`;
32377
+ };
32378
+ var injectHeadMarkup = (html, markup) => {
32379
+ const closingHeadIndex = html.indexOf("</head>");
32380
+ if (closingHeadIndex >= 0) {
32381
+ return `${html.slice(0, closingHeadIndex)}${markup}${html.slice(closingHeadIndex)}`;
32382
+ }
32383
+ const openingBodyIndex = html.indexOf("<body");
32384
+ if (openingBodyIndex >= 0) {
32385
+ const bodyStart = html.indexOf(">", openingBodyIndex);
32386
+ if (bodyStart >= 0) {
32387
+ return `${html.slice(0, openingBodyIndex)}<head>${markup}</head>${html.slice(openingBodyIndex)}`;
32388
+ }
32389
+ }
32390
+ return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
32391
+ };
32392
+ var streamChunkToString2 = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true });
32393
+ var flushSafePendingText = (controller, encoder, pending, lookbehind) => {
32394
+ if (pending.length <= lookbehind) {
32395
+ return pending;
32396
+ }
32397
+ const safeText = pending.slice(0, pending.length - lookbehind);
32398
+ controller.enqueue(encoder.encode(safeText));
32399
+ return pending.slice(-lookbehind);
32400
+ };
32401
+ var updateInjectedState = (consumed, injected, pending) => {
32402
+ if (consumed.done) {
32403
+ return { done: true, injected, pending };
32404
+ }
32405
+ return {
32406
+ done: false,
32407
+ injected: consumed.injected,
32408
+ pending: consumed.pending
32409
+ };
32410
+ };
32411
+ var readStreamChunk = async (reader) => {
32412
+ const { done, value } = await reader.read();
32413
+ if (done || !value) {
32414
+ return { done, value: undefined };
32415
+ }
32416
+ return { done, value };
32417
+ };
32418
+ var pipeStreamWithHeadInjection = (stream, markup) => {
32419
+ const encoder = new TextEncoder;
32420
+ const decoder = new TextDecoder;
32421
+ const lookbehind = CLOSING_HEAD_TAG2.length - 1;
32422
+ const processPending = (controller, pending, injected) => {
32423
+ if (injected) {
32424
+ controller.enqueue(encoder.encode(pending));
32425
+ return { injected, pending: "" };
32426
+ }
32427
+ const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
32428
+ if (headIndex >= 0) {
32429
+ const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
32430
+ controller.enqueue(encoder.encode(next));
32431
+ return { injected: true, pending: "" };
32432
+ }
32433
+ return {
32434
+ injected,
32435
+ pending: flushSafePendingText(controller, encoder, pending, lookbehind)
32436
+ };
32437
+ };
32438
+ const finishHeadInjectionStream = (controller, pending, injected) => {
32439
+ let finalPending = pending + decoder.decode();
32440
+ if (!injected) {
32441
+ finalPending = injectHeadMarkup(finalPending, markup);
32442
+ }
32443
+ if (finalPending.length > 0) {
32444
+ controller.enqueue(encoder.encode(finalPending));
32445
+ }
32446
+ controller.close();
32447
+ };
32448
+ const consumeHeadChunk = async (controller, reader, pending, injected) => {
32449
+ const { done, value } = await readStreamChunk(reader);
32450
+ if (done || !value) {
32451
+ return { done, injected, pending };
32452
+ }
32453
+ const processed = processPending(controller, pending + streamChunkToString2(value, decoder), injected);
32454
+ return {
32455
+ done,
32456
+ injected: processed.injected,
32457
+ pending: processed.pending
32458
+ };
32459
+ };
32460
+ const runHeadInjectionLoop = async (controller, reader) => {
32461
+ const consumeNextHeadChunk = async (injected, pending) => {
32462
+ const consumed = await consumeHeadChunk(controller, reader, pending, injected);
32463
+ const nextState = updateInjectedState(consumed, injected, pending);
32464
+ if (nextState.done) {
32465
+ return { injected, pending };
32466
+ }
32467
+ return consumeNextHeadChunk(nextState.injected, nextState.pending);
32468
+ };
32469
+ return consumeNextHeadChunk(false, "");
32470
+ };
32471
+ return new ReadableStream({
32472
+ async start(controller) {
32473
+ const reader = stream.getReader();
32474
+ try {
32475
+ const { injected, pending } = await runHeadInjectionLoop(controller, reader);
32476
+ finishHeadInjectionStream(controller, pending, injected);
32477
+ } catch (error) {
32478
+ controller.error(error);
32479
+ }
32480
+ }
32481
+ });
32482
+ };
32483
+ var pipeStreamWithIslandMarkerDetection = (stream, markup) => {
32484
+ const encoder = new TextEncoder;
32485
+ const decoder = new TextDecoder;
32486
+ const headLookbehind = CLOSING_HEAD_TAG2.length - 1;
32487
+ const enqueue = (controller, text) => {
32488
+ if (text.length > 0) {
32489
+ controller.enqueue(encoder.encode(text));
32490
+ }
32491
+ };
32492
+ const processHolding = (controller, held) => {
32493
+ if (!held.includes(ISLAND_MARKER)) {
32494
+ return { held, injected: false, pending: "", sawHead: true };
32495
+ }
32496
+ enqueue(controller, `${markup}${held}`);
32497
+ return { held: "", injected: true, pending: "", sawHead: true };
32498
+ };
32499
+ const processHead = (controller, pending) => {
32500
+ const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
32501
+ if (headIndex < 0) {
32502
+ return {
32503
+ held: "",
32504
+ injected: false,
32505
+ pending: flushSafePendingText(controller, encoder, pending, headLookbehind),
32506
+ sawHead: false
32507
+ };
32508
+ }
32509
+ enqueue(controller, pending.slice(0, headIndex));
32510
+ return processHolding(controller, pending.slice(headIndex));
32511
+ };
32512
+ const processChunk = (controller, state, chunk) => {
32513
+ if (state.injected) {
32514
+ enqueue(controller, chunk);
32515
+ return state;
32516
+ }
32517
+ if (!state.sawHead) {
32518
+ return processHead(controller, state.pending + chunk);
32519
+ }
32520
+ return processHolding(controller, state.held + chunk);
32521
+ };
32522
+ const finishMarkerStream = (controller, state) => {
32523
+ const tail = decoder.decode();
32524
+ const remainder = state.injected ? tail : (state.sawHead ? state.held : state.pending) + tail;
32525
+ enqueue(controller, remainder);
32526
+ controller.close();
32527
+ };
32528
+ const runMarkerLoop = (controller, reader) => {
32529
+ const consumeNext = async (state) => {
32530
+ const { done, value } = await readStreamChunk(reader);
32531
+ if (done || !value) {
32532
+ return state;
32533
+ }
32534
+ return consumeNext(processChunk(controller, state, streamChunkToString2(value, decoder)));
32535
+ };
32536
+ return consumeNext({
32537
+ held: "",
32538
+ injected: false,
32539
+ pending: "",
32540
+ sawHead: false
32541
+ });
32542
+ };
32543
+ return new ReadableStream({
32544
+ async start(controller) {
32545
+ const reader = stream.getReader();
32546
+ try {
32547
+ const finalState = await runMarkerLoop(controller, reader);
32548
+ finishMarkerStream(controller, finalState);
32549
+ } catch (error) {
32550
+ controller.error(error);
32551
+ }
32552
+ }
32553
+ });
32554
+ };
32555
+ var htmlContainsIslands = (html) => html.includes(ISLAND_MARKER);
32556
+ var injectIslandPageContext = (html, options) => {
32557
+ const manifest = globalThis.__absoluteManifest;
32558
+ const hasIslands = options?.hasIslands ?? htmlContainsIslands(html);
32559
+ if (!manifest || !hasIslands) {
32560
+ return html;
32561
+ }
32562
+ if (html.includes(MANIFEST_MARKER) || html.includes(ISLAND_STATE_MARKER)) {
32563
+ return html;
32564
+ }
32565
+ return injectHeadMarkup(html, buildIslandsHeadMarkup(manifest));
32566
+ };
32567
+ var injectIslandPageContextStream = (stream, options) => {
32568
+ const manifest = globalThis.__absoluteManifest;
32569
+ if (!manifest)
32570
+ return stream;
32571
+ const markup = buildIslandsHeadMarkup(manifest);
32572
+ if (options?.hasIslands === true) {
32573
+ return pipeStreamWithHeadInjection(stream, markup);
32574
+ }
32575
+ if (options?.hasIslands === false) {
32576
+ return stream;
32577
+ }
32578
+ return pipeStreamWithIslandMarkerDetection(stream, markup);
32579
+ };
32580
+ var setCurrentIslandManifest = (manifest) => {
32581
+ globalThis.__absoluteManifest = manifest;
32582
+ };
32583
+
32530
32584
  // src/core/pageHandlers.ts
32585
+ init_browserTranslation();
32531
32586
  var finalizeStaticMobilePage = (framework, pagePath, metadata2) => {
32532
32587
  const pageId = metadata2?.pageId ?? `${framework}:${pagePath}`;
32533
32588
  const contract = metadata2?.contract ?? `${framework}:${pageId}:${ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION}`;
@@ -32545,7 +32600,8 @@ var finalizeStaticMobilePage = (framework, pagePath, metadata2) => {
32545
32600
  var handleStaticPageRequest = async (pagePath, options = {}, settings = {}) => {
32546
32601
  const html = await file(pagePath).text();
32547
32602
  const transformedHtml = await transformCurrentStaticPageHtml(html, settings);
32548
- return withPageCacheHeaders(await withStreamingSlots(new Response(injectIslandPageContext(transformedHtml), {
32603
+ const htmlWithTranslationBaseline = htmlContainsIslands(transformedHtml) ? injectBrowserTranslationBaseline(transformedHtml) : transformedHtml;
32604
+ return withPageCacheHeaders(await withStreamingSlots(new Response(injectIslandPageContext(htmlWithTranslationBaseline), {
32549
32605
  headers: { "Content-Type": "text/html" }
32550
32606
  }), {
32551
32607
  ...options,
@@ -41114,5 +41170,5 @@ export {
41114
41170
  wrapPageHandlerWithStreamingSlots
41115
41171
  };
41116
41172
 
41117
- //# debugId=B3A531CE0B0E139B64756E2164756E21
41173
+ //# debugId=76612B71C292527964756E2164756E21
41118
41174
  //# sourceMappingURL=index.js.map