@absolutejs/absolute 0.20.0-beta.0 → 0.20.0-beta.10

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 (118) hide show
  1. package/README.md +45 -0
  2. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  3. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  4. package/dist/angular/index.js +354 -22
  5. package/dist/angular/index.js.map +9 -6
  6. package/dist/angular/server.js +354 -22
  7. package/dist/angular/server.js.map +9 -6
  8. package/dist/build.js +742 -359
  9. package/dist/build.js.map +26 -24
  10. package/dist/cli/config/server.js +2 -2
  11. package/dist/cli/index.js +16105 -8429
  12. package/dist/dev/client/cssUtils.ts +112 -41
  13. package/dist/dev/client/handlers/html.ts +75 -15
  14. package/dist/dev/client/handlers/htmx.ts +43 -8
  15. package/dist/dev/client/handlers/react.ts +114 -32
  16. package/dist/dev/client/handlers/rebuild.ts +38 -8
  17. package/dist/dev/client/handlers/svelte.ts +33 -50
  18. package/dist/dev/client/handlers/vue.ts +36 -45
  19. package/dist/dev/client/hmrClient.ts +38 -6
  20. package/dist/dev/client/hmrTiming.ts +148 -0
  21. package/dist/dev/serverBootstrap.js +20 -11
  22. package/dist/index.js +1728 -864
  23. package/dist/index.js.map +38 -33
  24. package/dist/mobile/browser.js +14 -1
  25. package/dist/mobile/browser.js.map +3 -3
  26. package/dist/mobile/index.js +4853 -279
  27. package/dist/mobile/index.js.map +34 -7
  28. package/dist/mobile/remoteMacAgentEntry.js +29 -0
  29. package/dist/mobile/shellAuth.js +43 -0
  30. package/dist/mobile/shellBootstrap.js +581 -0
  31. package/dist/mobile/shellSync.js +74 -0
  32. package/dist/react/index.js +16 -3
  33. package/dist/react/index.js.map +4 -4
  34. package/dist/react/jsxDevRuntimeCompat.js +22 -2
  35. package/dist/react/jsxDevRuntimeCompat.js.map +5 -4
  36. package/dist/react/jsxRuntimeCompat.js +90 -0
  37. package/dist/react/jsxRuntimeCompat.js.map +10 -0
  38. package/dist/react/server.js +16 -3
  39. package/dist/react/server.js.map +4 -4
  40. package/dist/src/angular/pageHandler.d.ts +3 -0
  41. package/dist/src/build/compileVue.d.ts +1 -1
  42. package/dist/src/build/pwa.d.ts +15 -0
  43. package/dist/src/build/resolveBuildMode.d.ts +7 -0
  44. package/dist/src/cli/config/server.d.ts +1 -1
  45. package/dist/src/cli/scripts/dev.d.ts +4 -1
  46. package/dist/src/cli/scripts/mobile.d.ts +1 -0
  47. package/dist/src/cli/utils.d.ts +2 -2
  48. package/dist/src/core/build.d.ts +1 -1
  49. package/dist/src/core/pageHandlers.d.ts +11 -2
  50. package/dist/src/core/prepare.d.ts +6 -0
  51. package/dist/src/dev/clientManager.d.ts +9 -0
  52. package/dist/src/dev/configResolver.d.ts +2 -0
  53. package/dist/src/dev/moduleMapper.d.ts +1 -1
  54. package/dist/src/dev/moduleServer.d.ts +2 -1
  55. package/dist/src/dev/pathUtils.d.ts +1 -1
  56. package/dist/src/dev/reactComponentClassifier.d.ts +1 -1
  57. package/dist/src/mobile/androidConformance.d.ts +42 -0
  58. package/dist/src/mobile/androidEmulatorController.d.ts +105 -0
  59. package/dist/src/mobile/androidNativeWatcher.d.ts +19 -0
  60. package/dist/src/mobile/androidRelease.d.ts +51 -0
  61. package/dist/src/mobile/androidWebView.d.ts +46 -0
  62. package/dist/src/mobile/associationFiles.d.ts +49 -0
  63. package/dist/src/mobile/buildMetadata.d.ts +10 -0
  64. package/dist/src/mobile/buildPipeline.d.ts +9 -0
  65. package/dist/src/mobile/buildRelease.d.ts +24 -0
  66. package/dist/src/mobile/capacitorBundle.d.ts +42 -0
  67. package/dist/src/mobile/capacitorProject.d.ts +9 -0
  68. package/dist/src/mobile/client.d.ts +5 -1
  69. package/dist/src/mobile/config.d.ts +17 -0
  70. package/dist/src/mobile/emulatorDoctor.d.ts +25 -0
  71. package/dist/src/mobile/emulatorInstaller.d.ts +41 -0
  72. package/dist/src/mobile/index.d.ts +19 -0
  73. package/dist/src/mobile/iosConformance.d.ts +15 -0
  74. package/dist/src/mobile/iosNativeWatcher.d.ts +19 -0
  75. package/dist/src/mobile/iosRelease.d.ts +61 -0
  76. package/dist/src/mobile/iosSimulatorController.d.ts +89 -0
  77. package/dist/src/mobile/materializedBundle.d.ts +14 -0
  78. package/dist/src/mobile/nativeAuth.d.ts +17 -0
  79. package/dist/src/mobile/nativeBackgroundSync.d.ts +4 -0
  80. package/dist/src/mobile/nativeDeepLinks.d.ts +5 -0
  81. package/dist/src/mobile/releaseArtifact.d.ts +3 -0
  82. package/dist/src/mobile/releaseDoctor.d.ts +13 -0
  83. package/dist/src/mobile/releasePublisher.d.ts +130 -0
  84. package/dist/src/mobile/remoteMacAgent.d.ts +2 -0
  85. package/dist/src/mobile/remoteMacAgentEntry.d.ts +1 -0
  86. package/dist/src/mobile/remoteMacProtocol.d.ts +114 -0
  87. package/dist/src/mobile/remoteMacWire.d.ts +2 -0
  88. package/dist/src/mobile/routeMatcher.d.ts +3 -0
  89. package/dist/src/mobile/routeMetadataTransform.d.ts +13 -0
  90. package/dist/src/mobile/shellAuth.d.ts +13 -0
  91. package/dist/src/mobile/shellBootstrap.d.ts +18 -0
  92. package/dist/src/mobile/shellSync.d.ts +19 -0
  93. package/dist/src/mobile/staticDocument.d.ts +5 -0
  94. package/dist/src/mobile/transport.d.ts +43 -0
  95. package/dist/src/plugins/hmr.d.ts +3 -0
  96. package/dist/src/plugins/imageOptimizer.d.ts +1 -1
  97. package/dist/src/react/hooks/useMediaQuery.d.ts +1 -1
  98. package/dist/src/react/jsxDevRuntimeCompat.d.ts +1 -1
  99. package/dist/src/react/jsxRuntimeCompat.d.ts +7 -0
  100. package/dist/src/react/pageHandler.d.ts +3 -0
  101. package/dist/src/svelte/pageHandler.d.ts +3 -0
  102. package/dist/src/utils/loadConfig.d.ts +2 -0
  103. package/dist/src/utils/logger.d.ts +2 -0
  104. package/dist/src/utils/userAgentFunctions.d.ts +1 -1
  105. package/dist/src/vue/pageHandler.d.ts +3 -0
  106. package/dist/svelte/index.js +325 -23
  107. package/dist/svelte/index.js.map +8 -5
  108. package/dist/svelte/server.js +320 -18
  109. package/dist/svelte/server.js.map +8 -5
  110. package/dist/types/build.d.ts +59 -0
  111. package/dist/types/cli.d.ts +2 -0
  112. package/dist/types/globals.d.ts +14 -0
  113. package/dist/types/messages.d.ts +12 -0
  114. package/dist/vue/index.js +325 -23
  115. package/dist/vue/index.js.map +8 -5
  116. package/dist/vue/server.js +320 -18
  117. package/dist/vue/server.js.map +8 -5
  118. package/package.json +52 -8
@@ -3281,7 +3281,7 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
3281
3281
  getStreamingSlotsRuntimeScript()
3282
3282
  ].filter(Boolean).join(";");
3283
3283
  return `<script${createNonceAttr(nonce)}>${escapeScriptContent(runtimeBody)}</script>`;
3284
- }, toUint8 = (value, encoder) => encoder.encode(value), isRecord4 = (value) => Boolean(value) && typeof value === "object", isSafeHtmlLike = (value) => isRecord4(value) && typeof value.changingThisBreaksApplicationSecurity === "string", normalizeSafeHtml = (value) => {
3284
+ }, toUint8 = (value, encoder) => encoder.encode(value), isRecord5 = (value) => Boolean(value) && typeof value === "object", isSafeHtmlLike = (value) => isRecord5(value) && typeof value.changingThisBreaksApplicationSecurity === "string", normalizeSafeHtml = (value) => {
3285
3285
  if (isSafeHtmlLike(value)) {
3286
3286
  return value.changingThisBreaksApplicationSecurity;
3287
3287
  }
@@ -3342,7 +3342,7 @@ var SLOT_ID_PREFIX = "abs-slot-", CLOSING_BODY_TAG = "</body>", CLOSING_HEAD_TAG
3342
3342
  }, createTimeoutError = (slot, timeoutMs) => {
3343
3343
  const error = Object.assign(new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`), { __absTimeout: true });
3344
3344
  return error;
3345
- }, isSlotPatchPayloadObject = (value) => isRecord4(value) && ("html" in value), isTimeoutError = (error) => isRecord4(error) && error.__absTimeout === true, toStreamingSlot = (slot, policy) => ({
3345
+ }, isSlotPatchPayloadObject = (value) => isRecord5(value) && ("html" in value), isTimeoutError = (error) => isRecord5(error) && error.__absTimeout === true, toStreamingSlot = (slot, policy) => ({
3346
3346
  errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
3347
3347
  fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
3348
3348
  id: slot.id ?? createStreamingSlotId(),
@@ -3924,6 +3924,19 @@ var colors2, frameworkColors, formatPath = (filePath) => {
3924
3924
  const errorMsg = error instanceof Error ? error.message : error;
3925
3925
  const fullMessage = `${colors2.red}error${colors2.reset} ${message}${errorMsg ? `: ${errorMsg}` : ""}`;
3926
3926
  console.error(`${timestamp} ${tag} ${fullMessage}`);
3927
+ }, logHmrClientUpdate = (path, framework, duration, target, serverMs, clientMs, outcome = "applied", kind) => {
3928
+ const timestamp = `${colors2.dim}${formatTimestamp()}${colors2.reset}`;
3929
+ const targetLabel = target.startsWith("capacitor-") ? target.slice("capacitor-".length) : target;
3930
+ const tag = `${colors2.cyan}[hmr:${targetLabel}]${colors2.reset}`;
3931
+ const pathColor = framework ? getFrameworkColor(framework) : colors2.white;
3932
+ const breakdown = serverMs === undefined || clientMs === undefined ? "" : `; server ${serverMs}ms, client ${clientMs}ms`;
3933
+ let action = "failed after";
3934
+ if (outcome === "applied")
3935
+ action = "applied in";
3936
+ else if (outcome === "reloaded")
3937
+ action = "falling back to reload after";
3938
+ const kindLabel = kind ? `${kind} ` : "";
3939
+ console.log(`${timestamp} ${tag} ${framework ?? "update"} ${kindLabel}${pathColor}${formatPath(path)}${colors2.reset} ${colors2.dim}${action} ${duration}ms${breakdown}${colors2.reset}`);
3927
3940
  }, logHmrUpdate = (path, framework, duration) => {
3928
3941
  log("hmr update", { duration, framework, path });
3929
3942
  }, logInfo = (message) => {
@@ -5654,6 +5667,7 @@ var requestContext = Object.prototype.hasOwnProperty.call(window, '__ABS_ANGULAR
5654
5667
  var pageHasIslands = Boolean(pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__) || Boolean(document.querySelector('[data-island="true"]'));
5655
5668
  var pageHasRawStreamingSlots = Boolean(document.querySelector('[data-absolute-raw-slot="true"]'));
5656
5669
  var pageHasStreamingSlots = Boolean(document.querySelector('[data-absolute-slot="true"]'));
5670
+ var isClientRender = window.__ABSOLUTE_PAGE_RENDER_MODE__ === 'client';
5657
5671
  var contextProviders = [{ provide: REQUEST_CONTEXT, useValue: requestContext }];
5658
5672
  // Page-level providers are injected directly into the page module's
5659
5673
  // server output by \`compileAngular\`'s providers-injection step
@@ -5704,13 +5718,14 @@ if (!document.querySelector(_sel)) {
5704
5718
  }
5705
5719
 
5706
5720
  var providers = [provideZonelessChangeDetection()];
5707
- if (!window.__HMR_SKIP_HYDRATION__ && !pageHasIslands) {
5721
+ if (!isClientRender && !window.__HMR_SKIP_HYDRATION__ && !pageHasIslands) {
5708
5722
  providers.push(provideClientHydration(withHttpTransferCacheOptions(absoluteHttpTransferCacheOptions)));
5709
5723
  }
5710
5724
  delete window.__HMR_SKIP_HYDRATION__;
5711
5725
  providers.push.apply(providers, pageProviders);
5712
5726
  providers.push.apply(providers, contextProviders);
5713
5727
  window.__ABS_SLOT_HYDRATION_PENDING__ = pageHasRawStreamingSlots;
5728
+ var absolutePageReady = Promise.resolve();
5714
5729
 
5715
5730
  if (pageHasRawStreamingSlots) {
5716
5731
  window.__ABS_SLOT_HYDRATION_PENDING__ = false;
@@ -5720,7 +5735,7 @@ if (pageHasRawStreamingSlots) {
5720
5735
  });
5721
5736
  }
5722
5737
  } else {
5723
- bootstrapApplication(${componentClassName}, {
5738
+ absolutePageReady = bootstrapApplication(${componentClassName}, {
5724
5739
  providers: providers
5725
5740
  }).then(function (appRef) {
5726
5741
  window.__ANGULAR_APP__ = appRef;
@@ -5730,8 +5745,17 @@ if (pageHasRawStreamingSlots) {
5730
5745
  window.__ABS_SLOT_FLUSH__();
5731
5746
  });
5732
5747
  }
5748
+ return appRef;
5733
5749
  });
5734
5750
  }
5751
+ window.__ABSOLUTE_PAGE_READY__ = absolutePageReady;
5752
+ window.__ABSOLUTE_PAGE_DISPOSE__ = async function() {
5753
+ await absolutePageReady;
5754
+ if (window.__ANGULAR_APP__) {
5755
+ window.__ANGULAR_APP__.destroy();
5756
+ window.__ANGULAR_APP__ = null;
5757
+ }
5758
+ };
5735
5759
  `.trim() : `
5736
5760
  import '@angular/compiler';
5737
5761
  import { bootstrapApplication } from '@angular/platform-browser';
@@ -5750,6 +5774,7 @@ var requestContext = Object.prototype.hasOwnProperty.call(window, '__ABS_ANGULAR
5750
5774
  var pageHasIslands = Boolean(pageModule.__ABSOLUTE_PAGE_HAS_ISLANDS__) || Boolean(document.querySelector('[data-island="true"]'));
5751
5775
  var pageHasRawStreamingSlots = Boolean(document.querySelector('[data-absolute-raw-slot="true"]'));
5752
5776
  var pageHasStreamingSlots = Boolean(document.querySelector('[data-absolute-slot="true"]'));
5777
+ var isClientRender = window.__ABSOLUTE_PAGE_RENDER_MODE__ === 'client';
5753
5778
  var contextProviders = [{ provide: REQUEST_CONTEXT, useValue: requestContext }];
5754
5779
  // Page-level providers are injected directly into the page module's
5755
5780
  // server output by \`compileAngular\`'s providers-injection step
@@ -5769,11 +5794,21 @@ var absoluteHttpTransferCacheOptions = {
5769
5794
 
5770
5795
  enableProdMode();
5771
5796
 
5797
+ // Production mobile/client-only activation starts from AbsoluteJS's empty
5798
+ // #root shell rather than server-rendered Angular markup. Create the page's
5799
+ // actual Angular host from its compiled selector so application authors do
5800
+ // not need framework-specific mobile configuration.
5801
+ var _sel = ${componentClassName}.\u0275cmp?.selectors?.[0]?.[0] || 'ng-app';
5802
+ if (!document.querySelector(_sel)) {
5803
+ (document.getElementById('root') || document.body).appendChild(document.createElement(_sel));
5804
+ }
5805
+
5772
5806
  var providers = [provideZonelessChangeDetection()].concat(pageProviders).concat(contextProviders);
5773
- if (!pageHasIslands) {
5807
+ if (!isClientRender && !pageHasIslands) {
5774
5808
  providers.unshift(provideClientHydration(withHttpTransferCacheOptions(absoluteHttpTransferCacheOptions)));
5775
5809
  }
5776
5810
  window.__ABS_SLOT_HYDRATION_PENDING__ = pageHasRawStreamingSlots;
5811
+ var absolutePageReady = Promise.resolve();
5777
5812
 
5778
5813
  if (pageHasRawStreamingSlots) {
5779
5814
  window.__ABS_SLOT_HYDRATION_PENDING__ = false;
@@ -5783,7 +5818,7 @@ if (pageHasRawStreamingSlots) {
5783
5818
  });
5784
5819
  }
5785
5820
  } else {
5786
- bootstrapApplication(${componentClassName}, {
5821
+ absolutePageReady = bootstrapApplication(${componentClassName}, {
5787
5822
  providers: providers
5788
5823
  }).then(function (appRef) {
5789
5824
  window.__ANGULAR_APP__ = appRef;
@@ -5793,8 +5828,17 @@ if (pageHasRawStreamingSlots) {
5793
5828
  window.__ABS_SLOT_FLUSH__();
5794
5829
  });
5795
5830
  }
5831
+ return appRef;
5796
5832
  });
5797
5833
  }
5834
+ window.__ABSOLUTE_PAGE_READY__ = absolutePageReady;
5835
+ window.__ABSOLUTE_PAGE_DISPOSE__ = async function() {
5836
+ await absolutePageReady;
5837
+ if (window.__ANGULAR_APP__) {
5838
+ window.__ANGULAR_APP__.destroy();
5839
+ window.__ANGULAR_APP__ = null;
5840
+ }
5841
+ };
5798
5842
  `.trim();
5799
5843
  const indexHash = Bun.hash(hydration).toString(BASE_36_RADIX);
5800
5844
  const indexUnchanged = cachedWrapper?.indexHash === indexHash;
@@ -5995,7 +6039,7 @@ var provideDeterministicEnv = (options = {}) => {
5995
6039
  };
5996
6040
  // src/angular/pageHandler.ts
5997
6041
  init_constants();
5998
- import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
6042
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "async_hooks";
5999
6043
  import { lstat, mkdir as mkdir4, readlink, symlink } from "fs/promises";
6000
6044
  import { basename as basename5, dirname as dirname6, join as join10, resolve as resolve8 } from "path";
6001
6045
  import { pathToFileURL as pathToFileURL2 } from "url";
@@ -6388,6 +6432,276 @@ var lowerAngularServerIslands = async (html) => {
6388
6432
  // src/angular/pageHandler.ts
6389
6433
  init_devRouteRegistrationCallsite();
6390
6434
 
6435
+ // src/core/requestContext.ts
6436
+ import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
6437
+ import { Elysia as Elysia2 } from "elysia";
6438
+ var REQUEST_STORAGE_KEY = Symbol.for("absolutejs.requestAsyncLocalStorage");
6439
+ var isAbsoluteRequestStorage = (value) => typeof value === "object" && value !== null && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
6440
+ var getRequestStorage = () => {
6441
+ const value = Reflect.get(globalThis, REQUEST_STORAGE_KEY);
6442
+ return isAbsoluteRequestStorage(value) ? value : undefined;
6443
+ };
6444
+ var ensureRequestStorage = () => {
6445
+ const existing = getRequestStorage();
6446
+ if (existing)
6447
+ return existing;
6448
+ const storage = new AsyncLocalStorage2;
6449
+ Reflect.set(globalThis, REQUEST_STORAGE_KEY, storage);
6450
+ return storage;
6451
+ };
6452
+ var absoluteRequestContext = new Elysia2({
6453
+ name: "absolutejs-request-context"
6454
+ }).request(({ request }) => {
6455
+ ensureRequestStorage().enterWith({ request });
6456
+ }).as("global");
6457
+ var getCurrentAbsoluteRequest = () => getRequestStorage()?.getStore()?.request;
6458
+ var runWithAbsoluteRequest = (request, callback) => ensureRequestStorage().run({ request }, callback);
6459
+
6460
+ // src/mobile/producerContextState.ts
6461
+ var ABSOLUTE_MOBILE_PRODUCER_STORAGE_KEY = Symbol.for("absolutejs.mobileProducerAsyncLocalStorage");
6462
+ var frameworks = new Set([
6463
+ "angular",
6464
+ "ember",
6465
+ "html",
6466
+ "htmx",
6467
+ "react",
6468
+ "svelte",
6469
+ "vue"
6470
+ ]);
6471
+ var isCompatibilityPage = (value) => typeof value === "object" && value !== null && ("bundleHash" in value) && typeof value.bundleHash === "string" && ("contract" in value) && typeof value.contract === "string" && ("framework" in value) && typeof value.framework === "string" && frameworks.has(value.framework) && ("pageId" in value) && typeof value.pageId === "string" && ("propsSchemaHash" in value) && typeof value.propsSchemaHash === "string";
6472
+ var getCurrentAbsoluteMobileProducerContext = () => {
6473
+ const value = Reflect.get(globalThis, ABSOLUTE_MOBILE_PRODUCER_STORAGE_KEY);
6474
+ if (typeof value !== "object" || value === null || !("getStore" in value) || typeof value.getStore !== "function") {
6475
+ return;
6476
+ }
6477
+ const context = value.getStore();
6478
+ if (typeof context !== "object" || context === null || !("page" in context) || !isCompatibilityPage(context.page) || !("releaseId" in context) || typeof context.releaseId !== "string") {
6479
+ return;
6480
+ }
6481
+ return { page: context.page, releaseId: context.releaseId };
6482
+ };
6483
+
6484
+ // src/mobile/pageProtocol.ts
6485
+ var ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE = "application/vnd.absolute.page+json";
6486
+ var ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION = 1;
6487
+ var BAD_REQUEST_STATUS = 400;
6488
+ var OK_STATUS = 200;
6489
+ var SERVER_ERROR_STATUS = 500;
6490
+ var UPGRADE_REQUIRED_STATUS = 426;
6491
+ var MOBILE_PAGE_REQUEST_HEADERS = {
6492
+ appBuild: "x-absolute-mobile-app-build",
6493
+ pageBundle: "x-absolute-mobile-page-bundle",
6494
+ pageContracts: "x-absolute-mobile-page-contracts",
6495
+ pageId: "x-absolute-mobile-page-id",
6496
+ protocol: "x-absolute-mobile-protocol",
6497
+ runtime: "x-absolute-mobile-runtime"
6498
+ };
6499
+ var parseMediaType = (value) => value.split(";", 1)[0]?.trim().toLowerCase();
6500
+ var acceptsAbsoluteMobilePage = (request) => {
6501
+ if (!request)
6502
+ return false;
6503
+ return (request.headers.get("accept") ?? "").split(",").some((value) => parseMediaType(value) === ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE);
6504
+ };
6505
+ var readRequiredHeader = (request, name) => {
6506
+ const value = request.headers.get(name)?.trim();
6507
+ return value ? value : undefined;
6508
+ };
6509
+ var parseAbsoluteMobilePageRequest = (request) => {
6510
+ if (!request || !acceptsAbsoluteMobilePage(request)) {
6511
+ return { kind: "not-mobile" };
6512
+ }
6513
+ const protocolValue = readRequiredHeader(request, MOBILE_PAGE_REQUEST_HEADERS.protocol);
6514
+ const runtime = readRequiredHeader(request, MOBILE_PAGE_REQUEST_HEADERS.runtime);
6515
+ const appBuild = readRequiredHeader(request, MOBILE_PAGE_REQUEST_HEADERS.appBuild);
6516
+ const pageBundle = readRequiredHeader(request, MOBILE_PAGE_REQUEST_HEADERS.pageBundle);
6517
+ const pageContractsValue = readRequiredHeader(request, MOBILE_PAGE_REQUEST_HEADERS.pageContracts);
6518
+ const pageId = readRequiredHeader(request, MOBILE_PAGE_REQUEST_HEADERS.pageId);
6519
+ if (!protocolValue || !/^\d+$/.test(protocolValue)) {
6520
+ return {
6521
+ kind: "invalid",
6522
+ message: `Missing or invalid ${MOBILE_PAGE_REQUEST_HEADERS.protocol} header.`
6523
+ };
6524
+ }
6525
+ if (!runtime) {
6526
+ return {
6527
+ kind: "invalid",
6528
+ message: `Missing ${MOBILE_PAGE_REQUEST_HEADERS.runtime} header.`
6529
+ };
6530
+ }
6531
+ if (!appBuild) {
6532
+ return {
6533
+ kind: "invalid",
6534
+ message: `Missing ${MOBILE_PAGE_REQUEST_HEADERS.appBuild} header.`
6535
+ };
6536
+ }
6537
+ if (!pageBundle) {
6538
+ return {
6539
+ kind: "invalid",
6540
+ message: `Missing ${MOBILE_PAGE_REQUEST_HEADERS.pageBundle} header.`
6541
+ };
6542
+ }
6543
+ if (!pageContractsValue) {
6544
+ return {
6545
+ kind: "invalid",
6546
+ message: `Missing ${MOBILE_PAGE_REQUEST_HEADERS.pageContracts} header.`
6547
+ };
6548
+ }
6549
+ if (!pageId) {
6550
+ return {
6551
+ kind: "invalid",
6552
+ message: `Missing ${MOBILE_PAGE_REQUEST_HEADERS.pageId} header.`
6553
+ };
6554
+ }
6555
+ const pageContracts = [
6556
+ ...new Set(pageContractsValue.split(",").map((value) => value.trim()).filter(Boolean))
6557
+ ];
6558
+ if (pageContracts.length === 0) {
6559
+ return {
6560
+ kind: "invalid",
6561
+ message: `${MOBILE_PAGE_REQUEST_HEADERS.pageContracts} must contain at least one contract.`
6562
+ };
6563
+ }
6564
+ return {
6565
+ client: {
6566
+ appBuild,
6567
+ pageBundle,
6568
+ pageContracts,
6569
+ pageId,
6570
+ protocol: Number(protocolValue),
6571
+ runtime
6572
+ },
6573
+ kind: "mobile"
6574
+ };
6575
+ };
6576
+ var responseHeaders = () => {
6577
+ const headers = new Headers({
6578
+ "cache-control": "no-store",
6579
+ "content-type": `${ABSOLUTE_MOBILE_PAGE_MEDIA_TYPE}; version=${ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION}`
6580
+ });
6581
+ headerVaryValues.forEach((value) => headers.append("vary", value));
6582
+ return headers;
6583
+ };
6584
+ var headerVaryValues = [
6585
+ "Accept",
6586
+ MOBILE_PAGE_REQUEST_HEADERS.protocol,
6587
+ MOBILE_PAGE_REQUEST_HEADERS.runtime,
6588
+ MOBILE_PAGE_REQUEST_HEADERS.appBuild,
6589
+ MOBILE_PAGE_REQUEST_HEADERS.pageBundle,
6590
+ MOBILE_PAGE_REQUEST_HEADERS.pageContracts,
6591
+ MOBILE_PAGE_REQUEST_HEADERS.pageId
6592
+ ];
6593
+ var envelopeResponse = (response, status) => new Response(JSON.stringify({
6594
+ protocol: ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
6595
+ response
6596
+ }), { headers: responseHeaders(), status });
6597
+ var isRecord4 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
6598
+ var normalizeJsonValue = (value) => {
6599
+ const serialized = JSON.stringify(value);
6600
+ if (serialized === undefined) {
6601
+ throw new TypeError("Mobile page props must be JSON-serializable.");
6602
+ }
6603
+ const parsed = JSON.parse(serialized);
6604
+ if (!isRecord4(parsed)) {
6605
+ throw new TypeError("Mobile page props must serialize to an object.");
6606
+ }
6607
+ return parsed;
6608
+ };
6609
+ var finalizeArchivedMobilePage = (context, input) => {
6610
+ const { page } = context;
6611
+ if (page.pageId !== input.compatibility.pageId || page.framework !== input.compatibility.framework) {
6612
+ return envelopeResponse({
6613
+ kind: "invalid-request",
6614
+ message: "Archived producer page identity does not match its release artifact."
6615
+ }, BAD_REQUEST_STATUS);
6616
+ }
6617
+ try {
6618
+ const [currentRepresentation] = input.compatibility.representations;
6619
+ if (!currentRepresentation) {
6620
+ throw new TypeError("Mobile page has no current representation.");
6621
+ }
6622
+ return envelopeResponse({
6623
+ contract: page.contract,
6624
+ framework: page.framework,
6625
+ kind: "page",
6626
+ pageId: page.pageId,
6627
+ props: normalizeJsonValue(currentRepresentation.mapProps(input.props)),
6628
+ status: input.status ?? OK_STATUS
6629
+ }, input.status ?? OK_STATUS);
6630
+ } catch (error) {
6631
+ console.error(`[Mobile] Archived producer ${context.releaseId} failed for ${page.pageId}:`, error);
6632
+ return createAbsoluteMobilePageErrorResponse(page.pageId);
6633
+ }
6634
+ };
6635
+ var createAbsoluteMobileInvalidRequestResponse = (message) => envelopeResponse({ kind: "invalid-request", message }, BAD_REQUEST_STATUS);
6636
+ var createAbsoluteMobilePageErrorResponse = (pageId) => envelopeResponse({
6637
+ code: "representation-failed",
6638
+ kind: "error",
6639
+ pageId,
6640
+ status: SERVER_ERROR_STATUS
6641
+ }, SERVER_ERROR_STATUS);
6642
+ var createAbsoluteMobileUpgradeResponse = (result) => envelopeResponse(result, UPGRADE_REQUIRED_STATUS);
6643
+ var finalizeAbsoluteMobilePage = (input) => {
6644
+ const parsed = parseAbsoluteMobilePageRequest(input.request);
6645
+ if (parsed.kind === "not-mobile")
6646
+ return;
6647
+ if (parsed.kind === "invalid") {
6648
+ return envelopeResponse({ kind: "invalid-request", message: parsed.message }, BAD_REQUEST_STATUS);
6649
+ }
6650
+ const { client } = parsed;
6651
+ if (client.pageId !== input.compatibility.pageId) {
6652
+ return envelopeResponse({
6653
+ kind: "invalid-request",
6654
+ message: `Requested mobile page ${client.pageId} does not match ${input.compatibility.pageId}.`
6655
+ }, BAD_REQUEST_STATUS);
6656
+ }
6657
+ const producerContext = getCurrentAbsoluteMobileProducerContext();
6658
+ if (producerContext)
6659
+ return finalizeArchivedMobilePage(producerContext, input);
6660
+ if (client.protocol !== ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION) {
6661
+ return envelopeResponse({
6662
+ kind: "upgrade-required",
6663
+ pageId: input.compatibility.pageId,
6664
+ reason: "protocol"
6665
+ }, UPGRADE_REQUIRED_STATUS);
6666
+ }
6667
+ if (!input.compatibility.runtimes.includes(client.runtime)) {
6668
+ return envelopeResponse({
6669
+ kind: "upgrade-required",
6670
+ pageId: input.compatibility.pageId,
6671
+ reason: "runtime",
6672
+ supportedRuntimes: [...input.compatibility.runtimes]
6673
+ }, UPGRADE_REQUIRED_STATUS);
6674
+ }
6675
+ const clientContracts = new Set(client.pageContracts);
6676
+ const representation = input.compatibility.representations.find(({ contract }) => clientContracts.has(contract));
6677
+ if (!representation) {
6678
+ return envelopeResponse({
6679
+ kind: "upgrade-required",
6680
+ pageId: input.compatibility.pageId,
6681
+ reason: "page-contract",
6682
+ supportedContracts: input.compatibility.representations.map(({ contract }) => contract)
6683
+ }, UPGRADE_REQUIRED_STATUS);
6684
+ }
6685
+ try {
6686
+ return envelopeResponse({
6687
+ contract: representation.contract,
6688
+ framework: input.compatibility.framework,
6689
+ kind: "page",
6690
+ pageId: input.compatibility.pageId,
6691
+ props: normalizeJsonValue(representation.mapProps(input.props)),
6692
+ status: input.status ?? OK_STATUS
6693
+ }, input.status ?? OK_STATUS);
6694
+ } catch (error) {
6695
+ console.error(`[Mobile] Failed to produce ${input.compatibility.pageId} representation ${representation.contract}:`, error);
6696
+ return envelopeResponse({
6697
+ code: "representation-failed",
6698
+ kind: "error",
6699
+ pageId: input.compatibility.pageId,
6700
+ status: SERVER_ERROR_STATUS
6701
+ }, SERVER_ERROR_STATUS);
6702
+ }
6703
+ };
6704
+
6391
6705
  // src/angular/ssrSanitizer.ts
6392
6706
  var escapeHtml2 = (str) => String(str).replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;");
6393
6707
  var bypassValue = (value) => ({
@@ -6499,7 +6813,7 @@ var withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
6499
6813
 
6500
6814
  // src/core/streamingSlotWarningScope.ts
6501
6815
  init_logger();
6502
- import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
6816
+ import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
6503
6817
  var STREAMING_SLOT_WARNING_STORAGE_KEY2 = Symbol.for("absolutejs.streamingSlotWarningAsyncLocalStorage");
6504
6818
  var isObjectRecord4 = (value) => Boolean(value) && typeof value === "object";
6505
6819
  var isAsyncLocalStorage3 = (value) => isObjectRecord4(value) && ("getStore" in value) && typeof value.getStore === "function" && ("run" in value) && typeof value.run === "function";
@@ -6515,7 +6829,7 @@ var ensureWarningStorage = () => {
6515
6829
  if (existing) {
6516
6830
  return existing;
6517
6831
  }
6518
- const storage = new AsyncLocalStorage2;
6832
+ const storage = new AsyncLocalStorage3;
6519
6833
  Reflect.set(globalThis, STREAMING_SLOT_WARNING_STORAGE_KEY2, storage);
6520
6834
  return storage;
6521
6835
  };
@@ -6557,11 +6871,11 @@ var runWithStreamingSlotWarningScope = (task, metadata) => ensureWarningStorage(
6557
6871
 
6558
6872
  // src/angular/pageHandler.ts
6559
6873
  init_ssrRender();
6560
- var isRecord5 = (value) => typeof value === "object" && value !== null;
6874
+ var isRecord6 = (value) => typeof value === "object" && value !== null;
6561
6875
  var isAngularComponent2 = (value) => typeof value === "function";
6562
6876
  var componentHostsRouterOutlet = (component) => {
6563
6877
  const componentDef = Reflect.get(component, "\u0275cmp");
6564
- if (!isRecord5(componentDef))
6878
+ if (!isRecord6(componentDef))
6565
6879
  return false;
6566
6880
  const rawDependencies = componentDef.dependencies;
6567
6881
  const dependencies = typeof rawDependencies === "function" ? Reflect.apply(rawDependencies, undefined, []) : rawDependencies;
@@ -6571,7 +6885,7 @@ var componentHostsRouterOutlet = (component) => {
6571
6885
  if (dependency === null || typeof dependency !== "object" && typeof dependency !== "function")
6572
6886
  return false;
6573
6887
  const directiveDef = Reflect.get(dependency, "\u0275dir") ?? dependency;
6574
- if (!isRecord5(directiveDef))
6888
+ if (!isRecord6(directiveDef))
6575
6889
  return false;
6576
6890
  const { selectors } = directiveDef;
6577
6891
  return Array.isArray(selectors) && JSON.stringify(selectors).includes("router-outlet");
@@ -6601,7 +6915,7 @@ var ensureAngularCompiler = () => {
6601
6915
  }
6602
6916
  return compilerImportPromise;
6603
6917
  };
6604
- var readAngularPageModule = (value) => isRecord5(value) ? value : null;
6918
+ var readAngularPageModule = (value) => isRecord6(value) ? value : null;
6605
6919
  var resolveAngularSsrOutDir = (projectRoot = process.cwd(), configuredOutDir = process.env.ABSOLUTE_ANGULAR_SSR_OUTDIR) => configuredOutDir ?? join10(projectRoot, ".absolutejs", "runtime", "angular-ssr");
6606
6920
  var createAngularRuntimeCacheBuster = () => `${Date.now().toString(BASE_36_RADIX)}.${Math.random().toString(BASE_36_RADIX).substring(2, RANDOM_ID_END_INDEX)}`;
6607
6921
  var existingNodeModulesLinkMatches = async (nodeModulesLink, expectedTarget) => {
@@ -6702,14 +7016,32 @@ var resolveRequestRenderUrl = (request) => {
6702
7016
  return "/";
6703
7017
  }
6704
7018
  };
6705
- var angularSsrContext = new AsyncLocalStorage3;
7019
+ var angularSsrContext = new AsyncLocalStorage4;
6706
7020
  setSsrContextGetter(() => angularSsrContext.getStore());
6707
7021
  var handleAngularPageRequest = async (input) => {
6708
7022
  const requestId = `angular_${Date.now()}_${Math.random().toString(BASE_36_RADIX).substring(2, RANDOM_ID_END_INDEX)}`;
7023
+ const request = input.request ?? getCurrentAbsoluteRequest();
7024
+ const pageId = input.__absoluteMobile?.pageId ?? derivePageName(input.pagePath);
7025
+ const currentContract = input.__absoluteMobile?.contract ?? `angular:${pageId}:${ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION}`;
7026
+ const mobileResponse = finalizeAbsoluteMobilePage({
7027
+ compatibility: {
7028
+ framework: "angular",
7029
+ pageId,
7030
+ representations: [
7031
+ { contract: currentContract, mapProps: (props) => props }
7032
+ ],
7033
+ runtimes: [String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)]
7034
+ },
7035
+ props: isRecord6(input.requestContext) ? input.requestContext : Object.create(null),
7036
+ request,
7037
+ status: input.responseInit?.status
7038
+ });
7039
+ if (mobileResponse)
7040
+ return mobileResponse;
6709
7041
  return angularSsrContext.run(requestId, async () => {
6710
- const spaNotFound = await renderSpaNotFound("angular", derivePageName(input.pagePath), input.request);
7042
+ const spaNotFound = await renderSpaNotFound("angular", derivePageName(input.pagePath), request);
6711
7043
  if (spaNotFound)
6712
- return withPageCacheHeaders(spaNotFound, input.request);
7044
+ return withPageCacheHeaders(spaNotFound, request);
6713
7045
  await ensureAngularCompiler();
6714
7046
  const userHeadTag = input.headTag ?? "<head></head>";
6715
7047
  const resolvedIndexPath = input.indexPath;
@@ -6717,7 +7049,7 @@ var handleAngularPageRequest = async (input) => {
6717
7049
  const resolvedPagePath = input.pagePath;
6718
7050
  const maybeRequestContext = input.requestContext;
6719
7051
  const responseInit = input.responseInit ?? {};
6720
- const resolvedUrl = resolveRequestRenderUrl(input.request);
7052
+ const resolvedUrl = resolveRequestRenderUrl(request);
6721
7053
  const siblingCss = await readSiblingCss(resolvedPagePath);
6722
7054
  const resolvedHeadTag = injectInlineCss(userHeadTag, siblingCss);
6723
7055
  cacheRouteData(resolvedPagePath, {
@@ -6754,7 +7086,7 @@ var handleAngularPageRequest = async (input) => {
6754
7086
  ...handlerCallProviders,
6755
7087
  ...await buildServerAnimationProviders(usesLegacyAnimations)
6756
7088
  ];
6757
- const providers = buildProviders(deps, sanitizer, input.request, maybeRequestContext, responseInit, combinedProviders);
7089
+ const providers = buildProviders(deps, sanitizer, request, maybeRequestContext, responseInit, combinedProviders);
6758
7090
  const rawHtml = await renderAngularApp(deps, PageComponent, providers, htmlString, resolvedUrl);
6759
7091
  const shouldProcessIslands = hasIslands || rawHtml.includes("<absolute-island");
6760
7092
  const htmlWithLoweredIslands = shouldProcessIslands ? await lowerAngularServerIslands(rawHtml) : rawHtml;
@@ -6762,18 +7094,18 @@ var handleAngularPageRequest = async (input) => {
6762
7094
  return new Response(html, withHtmlContentType(responseInit));
6763
7095
  };
6764
7096
  const pageResponse = await runWithStreamingSlotWarningScope(() => options?.collectStreamingSlots === true ? withRegisteredStreamingSlots(renderPageResponse, options) : renderPageResponse(), { handlerCallsite });
6765
- return withPageCacheHeaders(pageResponse, input.request);
7097
+ return withPageCacheHeaders(pageResponse, request);
6766
7098
  } catch (error) {
6767
7099
  console.error("[SSR] Angular render error:", error);
6768
7100
  const pageName = derivePageName(resolvedPagePath);
6769
7101
  const conventionResponse = await renderConventionError("angular", pageName, error);
6770
7102
  if (conventionResponse) {
6771
- return withPageCacheHeaders(conventionResponse, input.request);
7103
+ return withPageCacheHeaders(conventionResponse, request);
6772
7104
  }
6773
7105
  return withPageCacheHeaders(new Response(ssrErrorPage("angular", error), {
6774
7106
  headers: { "Content-Type": "text/html" },
6775
7107
  status: 500
6776
- }), input.request);
7108
+ }), request);
6777
7109
  }
6778
7110
  });
6779
7111
  };
@@ -6799,5 +7131,5 @@ export {
6799
7131
  ABSOLUTE_HTTP_TRANSFER_CACHE_SKIP_HEADER
6800
7132
  };
6801
7133
 
6802
- //# debugId=0B6150AC19AC9D1364756E2164756E21
7134
+ //# debugId=4F398A37606C42FD64756E2164756E21
6803
7135
  //# sourceMappingURL=server.js.map