@absolutejs/absolute 0.20.0-beta.30 → 0.20.0-beta.32

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 (43) 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 +5 -1
  4. package/dist/angular/index.js.map +3 -3
  5. package/dist/angular/server.js +5 -1
  6. package/dist/angular/server.js.map +3 -3
  7. package/dist/build.js +7 -1
  8. package/dist/build.js.map +4 -4
  9. package/dist/cli/config/server.js +4 -0
  10. package/dist/cli/index.js +9 -0
  11. package/dist/dev/client/hmrClient.ts +5 -2
  12. package/dist/dev/client/hmrTiming.ts +2 -0
  13. package/dist/index.js +284 -204
  14. package/dist/index.js.map +10 -9
  15. package/dist/mobile/index.js +394 -31
  16. package/dist/mobile/index.js.map +11 -6
  17. package/dist/mobile/remoteMacAgentEntry.js +5 -5
  18. package/dist/mobile/shellBootstrap.js +205 -0
  19. package/dist/react/index.js +5 -1
  20. package/dist/react/index.js.map +3 -3
  21. package/dist/react/server.js +5 -1
  22. package/dist/react/server.js.map +3 -3
  23. package/dist/src/cli/config/server.d.ts +1 -1
  24. package/dist/src/core/prepare.d.ts +340 -0
  25. package/dist/src/mobile/index.d.ts +2 -0
  26. package/dist/src/mobile/mobilePreview.d.ts +174 -0
  27. package/dist/src/mobile/mobilePreviewClient.d.ts +1 -0
  28. package/dist/src/mobile/shellHttp.d.ts +2 -0
  29. package/dist/src/plugins/imageOptimizer.d.ts +1 -1
  30. package/dist/src/react/hooks/useMediaQuery.d.ts +1 -1
  31. package/dist/src/utils/logger.d.ts +1 -0
  32. package/dist/src/utils/startupBanner.d.ts +1 -0
  33. package/dist/src/utils/userAgentFunctions.d.ts +1 -1
  34. package/dist/svelte/index.js +5 -1
  35. package/dist/svelte/index.js.map +3 -3
  36. package/dist/svelte/server.js +5 -1
  37. package/dist/svelte/server.js.map +3 -3
  38. package/dist/types/messages.d.ts +1 -1
  39. package/dist/vue/index.js +5 -1
  40. package/dist/vue/index.js.map +3 -3
  41. package/dist/vue/server.js +5 -1
  42. package/dist/vue/server.js.map +3 -3
  43. package/package.json +2 -1
package/dist/index.js CHANGED
@@ -9028,11 +9028,92 @@ var init_loadConfig = __esm(() => {
9028
9028
  ]);
9029
9029
  });
9030
9030
 
9031
+ // src/cli/scripts/telemetry.ts
9032
+ import { existsSync as existsSync9, mkdirSync as mkdirSync2, readFileSync as readFileSync10, writeFileSync as writeFileSync4 } from "fs";
9033
+ import { homedir } from "os";
9034
+ import { join as join13 } from "path";
9035
+ var configDir, configPath, getTelemetryConfig = () => {
9036
+ try {
9037
+ if (!existsSync9(configPath))
9038
+ return null;
9039
+ const raw = readFileSync10(configPath, "utf-8");
9040
+ const config = JSON.parse(raw);
9041
+ return config;
9042
+ } catch {
9043
+ return null;
9044
+ }
9045
+ };
9046
+ var init_telemetry = __esm(() => {
9047
+ configDir = join13(homedir(), ".absolutejs");
9048
+ configPath = join13(configDir, "telemetry.json");
9049
+ });
9050
+
9051
+ // src/cli/telemetryEvent.ts
9052
+ import { existsSync as existsSync10, readFileSync as readFileSync11 } from "fs";
9053
+ import { arch as arch2, platform as platform2 } from "os";
9054
+ import { dirname as dirname9, join as join14, parse } from "path";
9055
+ var checkCandidate = (candidate) => {
9056
+ if (!existsSync10(candidate)) {
9057
+ return null;
9058
+ }
9059
+ const pkg = JSON.parse(readFileSync11(candidate, "utf-8"));
9060
+ if (pkg.name === "@absolutejs/absolute") {
9061
+ const ver = pkg.version;
9062
+ return ver;
9063
+ }
9064
+ return null;
9065
+ }, getVersion = () => {
9066
+ try {
9067
+ return findPackageVersion();
9068
+ } catch {
9069
+ return "unknown";
9070
+ }
9071
+ }, findPackageVersion = () => {
9072
+ let { dir } = import.meta;
9073
+ while (dir !== parse(dir).root) {
9074
+ const candidate = join14(dir, "package.json");
9075
+ const version = checkCandidate(candidate);
9076
+ if (version) {
9077
+ return version;
9078
+ }
9079
+ dir = dirname9(dir);
9080
+ }
9081
+ return "unknown";
9082
+ }, sendTelemetryEvent = (event, payload) => {
9083
+ try {
9084
+ if (process.env.TELEMETRY_OFF === "1")
9085
+ return;
9086
+ const config = getTelemetryConfig();
9087
+ if (!config?.enabled)
9088
+ return;
9089
+ const body = {
9090
+ anonymousId: config.anonymousId,
9091
+ arch: arch2(),
9092
+ bunVersion: Bun.version,
9093
+ event,
9094
+ os: platform2(),
9095
+ payload,
9096
+ timestamp: new Date().toISOString(),
9097
+ version: getVersion()
9098
+ };
9099
+ fetch("https://absolutejs.com/api/telemetry", {
9100
+ body: JSON.stringify(body),
9101
+ headers: { "Content-Type": "application/json" },
9102
+ method: "POST"
9103
+ }).catch(() => {
9104
+ return;
9105
+ });
9106
+ } catch {}
9107
+ };
9108
+ var init_telemetryEvent = __esm(() => {
9109
+ init_telemetry();
9110
+ });
9111
+
9031
9112
  // src/build/scanEntryPoints.ts
9032
- import { existsSync as existsSync9 } from "fs";
9113
+ import { existsSync as existsSync11 } from "fs";
9033
9114
  var {Glob } = globalThis.Bun;
9034
9115
  var scanEntryPoints = async (dir, pattern) => {
9035
- if (!existsSync9(dir))
9116
+ if (!existsSync11(dir))
9036
9117
  return [];
9037
9118
  const entryPaths = [];
9038
9119
  const glob = new Glob(pattern);
@@ -9121,8 +9202,8 @@ var init_sourceMetadata = __esm(() => {
9121
9202
  });
9122
9203
 
9123
9204
  // src/islands/pageMetadata.ts
9124
- import { readFileSync as readFileSync10 } from "fs";
9125
- import { dirname as dirname10, resolve as resolve14 } from "path";
9205
+ import { readFileSync as readFileSync12 } from "fs";
9206
+ import { dirname as dirname11, resolve as resolve14 } from "path";
9126
9207
  var pagePatterns, getPageDirs = (config) => [
9127
9208
  { dir: config.angularDirectory, framework: "angular" },
9128
9209
  { dir: config.emberDirectory, framework: "ember" },
@@ -9142,7 +9223,7 @@ var pagePatterns, getPageDirs = (config) => [
9142
9223
  const source = definition.buildReference?.source;
9143
9224
  if (!source)
9144
9225
  continue;
9145
- const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve14(dirname10(buildInfo.resolvedRegistryPath), source);
9226
+ const resolvedSource = source.startsWith("file://") ? new URL(source).pathname : resolve14(dirname11(buildInfo.resolvedRegistryPath), source);
9146
9227
  lookup.set(`${definition.framework}:${definition.component}`, resolve14(resolvedSource));
9147
9228
  }
9148
9229
  return lookup;
@@ -9164,7 +9245,7 @@ var pagePatterns, getPageDirs = (config) => [
9164
9245
  return;
9165
9246
  const files = await scanEntryPoints(resolve14(entry.dir), pattern);
9166
9247
  for (const filePath of files) {
9167
- const source = readFileSync10(filePath, "utf-8");
9248
+ const source = readFileSync12(filePath, "utf-8");
9168
9249
  const islands = extractIslandUsagesFromSource(source);
9169
9250
  pageMetadata.set(resolve14(filePath), {
9170
9251
  islands: resolveIslandUsages(islands, islandSourceLookup),
@@ -9308,7 +9389,7 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
9308
9389
  headers: { "Content-Type": "text/html" },
9309
9390
  status: 500
9310
9391
  });
9311
- }, escapeHtml = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"), replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml(errorProps.stack) : ""), renderHtmlError = async (conventionPath, errorProps) => {
9392
+ }, escapeHtml2 = (value) => value.replace(/&/g, "&amp;").replace(/</g, "&lt;").replace(/>/g, "&gt;").replace(/"/g, "&quot;").replace(/'/g, "&#39;"), replaceErrorTokens = (template, errorProps) => template.replace(/\{\{\s*name\s*\}\}/g, escapeHtml2(errorProps.name)).replace(/\{\{\s*message\s*\}\}/g, escapeHtml2(errorProps.message)).replace(/\{\{\s*stack\s*\}\}/g, errorProps.stack ? escapeHtml2(errorProps.stack) : ""), renderHtmlError = async (conventionPath, errorProps) => {
9312
9393
  const template = await Bun.file(conventionPath).text();
9313
9394
  const html = replaceErrorTokens(template, errorProps);
9314
9395
  return new Response(html, {
@@ -9597,6 +9678,7 @@ var colors, MONTHS, formatTimestamp = () => {
9597
9678
  port,
9598
9679
  host,
9599
9680
  networkUrl,
9681
+ mobilePreviewUrl,
9600
9682
  protocol = "http"
9601
9683
  } = options;
9602
9684
  const name = `${colors.cyan}${colors.bold}ABSOLUTEJS${colors.reset}`;
@@ -9610,6 +9692,9 @@ var colors, MONTHS, formatTimestamp = () => {
9610
9692
  if (networkUrl) {
9611
9693
  console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Network:${colors.reset} ${networkUrl}`);
9612
9694
  }
9695
+ if (mobilePreviewUrl) {
9696
+ console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Mobile:${colors.reset} ${mobilePreviewUrl}`);
9697
+ }
9613
9698
  console.log("");
9614
9699
  };
9615
9700
  var init_startupBanner = __esm(() => {
@@ -9728,7 +9813,7 @@ __export(exports_devRouteRegistrationCallsite, {
9728
9813
  getCurrentRouteRegistrationCallsite: () => getCurrentRouteRegistrationCallsite
9729
9814
  });
9730
9815
  import { AsyncLocalStorage as AsyncLocalStorage3 } from "async_hooks";
9731
- import { Elysia as Elysia4 } from "elysia";
9816
+ import { Elysia as Elysia5 } from "elysia";
9732
9817
  var ROUTE_CALLSITE_STORAGE_KEY, ROUTE_CALLSITE_PATCHED_KEY, NODE_ENV_KEY = "NODE_ENV", ROUTE_METHOD_NAMES, PAGE_HANDLER_NAMES, pageHandlerWrappers, isPageHandlerFunction = (value) => typeof value === "function", handlerSourceMentionsPageHelper = (handler) => {
9733
9818
  const source = handler.toString();
9734
9819
  return PAGE_HANDLER_NAMES.some((name) => source.includes(name));
@@ -9795,7 +9880,7 @@ var ROUTE_CALLSITE_STORAGE_KEY, ROUTE_CALLSITE_PATCHED_KEY, NODE_ENV_KEY = "NODE
9795
9880
  if (Reflect.get(globalThis, ROUTE_CALLSITE_PATCHED_KEY) === true) {
9796
9881
  return;
9797
9882
  }
9798
- const { prototype } = Elysia4;
9883
+ const { prototype } = Elysia5;
9799
9884
  ROUTE_METHOD_NAMES.forEach((methodName) => {
9800
9885
  const originalMethod = Reflect.get(prototype, methodName);
9801
9886
  if (!isRouteMethod(originalMethod))
@@ -9993,23 +10078,23 @@ var init_verifyAngularCoreUniqueness = __esm(() => {
9993
10078
  });
9994
10079
 
9995
10080
  // src/build/generateReactIndexes.ts
9996
- import { existsSync as existsSync10, mkdirSync as mkdirSync2 } from "fs";
10081
+ import { existsSync as existsSync12, mkdirSync as mkdirSync3 } from "fs";
9997
10082
  import { readdir as readdir4, rm as rm4, writeFile as writeFile4 } from "fs/promises";
9998
- import { basename as basename4, join as join15, relative as relative6, resolve as resolve16, sep } from "path";
10083
+ import { basename as basename4, join as join17, relative as relative6, resolve as resolve16, sep } from "path";
9999
10084
  var {Glob: Glob2 } = globalThis.Bun;
10000
10085
  var indexContentCache, resolveDevClientDir = () => {
10001
10086
  const projectRoot = process.cwd();
10002
10087
  const fromSource = resolve16(import.meta.dir, "../dev/client");
10003
- if (existsSync10(fromSource) && fromSource.startsWith(projectRoot)) {
10088
+ if (existsSync12(fromSource) && fromSource.startsWith(projectRoot)) {
10004
10089
  return fromSource;
10005
10090
  }
10006
10091
  const fromNodeModules = resolve16(projectRoot, "node_modules/@absolutejs/absolute/dist/dev/client");
10007
- if (existsSync10(fromNodeModules))
10092
+ if (existsSync12(fromNodeModules))
10008
10093
  return fromNodeModules;
10009
10094
  return resolve16(import.meta.dir, "./dev/client");
10010
10095
  }, devClientDir, errorOverlayPath, hmrClientPath, refreshSetupPath, reactRefreshRuntimePath, generateReactIndexFiles = async (reactPagesDirectory, reactIndexesDirectory, isDev2 = false) => {
10011
- if (!existsSync10(reactIndexesDirectory)) {
10012
- mkdirSync2(reactIndexesDirectory, { recursive: true });
10096
+ if (!existsSync12(reactIndexesDirectory)) {
10097
+ mkdirSync3(reactIndexesDirectory, { recursive: true });
10013
10098
  }
10014
10099
  const CONVENTION_RE = /^(?:(.+)\.)?(error|loading|not-found)\.[^.]+$/;
10015
10100
  const pagesGlob = new Glob2("*.{jsx,tsx}");
@@ -10028,8 +10113,8 @@ var indexContentCache, resolveDevClientDir = () => {
10028
10113
  });
10029
10114
  if (staleIndexes.length > 0) {
10030
10115
  await Promise.all(staleIndexes.map((indexFile) => {
10031
- indexContentCache.delete(join15(reactIndexesDirectory, indexFile));
10032
- return rm4(join15(reactIndexesDirectory, indexFile), {
10116
+ indexContentCache.delete(join17(reactIndexesDirectory, indexFile));
10117
+ return rm4(join17(reactIndexesDirectory, indexFile), {
10033
10118
  force: true
10034
10119
  });
10035
10120
  }));
@@ -10338,11 +10423,11 @@ var indexContentCache, resolveDevClientDir = () => {
10338
10423
  ] : []
10339
10424
  ].join(`
10340
10425
  `);
10341
- const indexPath = join15(reactIndexesDirectory, `${componentName}.tsx`);
10426
+ const indexPath = join17(reactIndexesDirectory, `${componentName}.tsx`);
10342
10427
  const hasher = new Bun.CryptoHasher("md5");
10343
10428
  hasher.update(content);
10344
10429
  const contentHash = hasher.digest("hex");
10345
- if (indexContentCache.get(indexPath) === contentHash && existsSync10(indexPath)) {
10430
+ if (indexContentCache.get(indexPath) === contentHash && existsSync12(indexPath)) {
10346
10431
  return;
10347
10432
  }
10348
10433
  indexContentCache.set(indexPath, contentHash);
@@ -10352,8 +10437,8 @@ var indexContentCache, resolveDevClientDir = () => {
10352
10437
  if (!isDev2) {
10353
10438
  return;
10354
10439
  }
10355
- const refreshPath = join15(reactIndexesDirectory, "_refresh.tsx");
10356
- if (!existsSync10(refreshPath)) {
10440
+ const refreshPath = join17(reactIndexesDirectory, "_refresh.tsx");
10441
+ if (!existsSync12(refreshPath)) {
10357
10442
  await writeFile4(refreshPath, `import '${refreshSetupPath}';
10358
10443
  import 'react';
10359
10444
  import 'react-dom/client';
@@ -10363,10 +10448,10 @@ import 'react-dom/client';
10363
10448
  var init_generateReactIndexes = __esm(() => {
10364
10449
  indexContentCache = new Map;
10365
10450
  devClientDir = resolveDevClientDir();
10366
- errorOverlayPath = join15(devClientDir, "errorOverlay.ts").replace(/\\/g, "/");
10367
- hmrClientPath = join15(devClientDir, "hmrClient.ts").replace(/\\/g, "/");
10368
- refreshSetupPath = join15(devClientDir, "reactRefreshSetup.ts").replace(/\\/g, "/");
10369
- reactRefreshRuntimePath = join15(devClientDir, "vendor", "reactRefreshRuntime.js").replace(/\\/g, "/");
10451
+ errorOverlayPath = join17(devClientDir, "errorOverlay.ts").replace(/\\/g, "/");
10452
+ hmrClientPath = join17(devClientDir, "hmrClient.ts").replace(/\\/g, "/");
10453
+ refreshSetupPath = join17(devClientDir, "reactRefreshSetup.ts").replace(/\\/g, "/");
10454
+ reactRefreshRuntimePath = join17(devClientDir, "vendor", "reactRefreshRuntime.js").replace(/\\/g, "/");
10370
10455
  });
10371
10456
 
10372
10457
  // src/build/wrapHTMLScript.ts
@@ -10434,7 +10519,7 @@ var init_outputLogs = __esm(() => {
10434
10519
  // src/build/scanConventions.ts
10435
10520
  import { basename as basename5 } from "path";
10436
10521
  var {Glob: Glob3 } = globalThis.Bun;
10437
- import { existsSync as existsSync11 } from "fs";
10522
+ import { existsSync as existsSync13 } from "fs";
10438
10523
  var CONVENTION_RE, classifyFile = (file2, pageFiles, defaults, pages) => {
10439
10524
  const fileName = basename5(file2);
10440
10525
  const match = CONVENTION_RE.exec(fileName);
@@ -10459,7 +10544,7 @@ var CONVENTION_RE, classifyFile = (file2, pageFiles, defaults, pages) => {
10459
10544
  else if (kind === "loading")
10460
10545
  pages[pageName].loading = file2;
10461
10546
  }, scanConventions = async (pagesDir, pattern) => {
10462
- if (!existsSync11(pagesDir)) {
10547
+ if (!existsSync13(pagesDir)) {
10463
10548
  const pageFiles2 = [];
10464
10549
  return { conventions: undefined, pageFiles: pageFiles2 };
10465
10550
  }
@@ -10483,7 +10568,7 @@ var init_scanConventions = __esm(() => {
10483
10568
 
10484
10569
  // src/build/spaSideManifests.ts
10485
10570
  import { writeFile as writeFile5 } from "fs/promises";
10486
- import { basename as basename6, dirname as dirname11, relative as relative7, resolve as resolve17 } from "path";
10571
+ import { basename as basename6, dirname as dirname12, relative as relative7, resolve as resolve17 } from "path";
10487
10572
  var writeSpaSideManifests = async (spaRoutesBySource, resolveServerJsPath) => {
10488
10573
  const manifestEntries = {};
10489
10574
  await Promise.all([...spaRoutesBySource.entries()].map(async ([source, routes]) => {
@@ -10491,7 +10576,7 @@ var writeSpaSideManifests = async (spaRoutesBySource, resolveServerJsPath) => {
10491
10576
  const parentJsPath = resolveServerJsPath(parentName);
10492
10577
  if (!parentJsPath)
10493
10578
  return;
10494
- const sourceDir = dirname11(source);
10579
+ const sourceDir = dirname12(source);
10495
10580
  const entries = routes.flatMap(({ path, importPath }) => {
10496
10581
  const childSourcePath = resolve17(sourceDir, importPath);
10497
10582
  const childName = basename6(childSourcePath, ".vue");
@@ -10499,7 +10584,7 @@ var writeSpaSideManifests = async (spaRoutesBySource, resolveServerJsPath) => {
10499
10584
  if (!childJsPath)
10500
10585
  return [];
10501
10586
  const absoluteCssPath = childJsPath.replace(/\.js$/, ".css");
10502
- const cssPath = relative7(dirname11(parentJsPath), absoluteCssPath);
10587
+ const cssPath = relative7(dirname12(parentJsPath), absoluteCssPath);
10503
10588
  return [{ cssPath, path }];
10504
10589
  });
10505
10590
  if (entries.length === 0)
@@ -10537,8 +10622,8 @@ var buildServerBundleExternals = (angularVendorPaths) => {
10537
10622
  };
10538
10623
 
10539
10624
  // src/build/scanRouteRegistrations.ts
10540
- import { readdirSync, readFileSync as readFileSync11 } from "fs";
10541
- import { join as join16 } from "path";
10625
+ import { readdirSync, readFileSync as readFileSync13 } from "fs";
10626
+ import { join as join18 } from "path";
10542
10627
  import ts2 from "typescript";
10543
10628
  var ELYSIA_ROUTE_METHODS, SKIP_DIRS, SOURCE_EXTENSIONS, getScriptKind = (filePath) => {
10544
10629
  if (filePath.endsWith(".tsx"))
@@ -10575,9 +10660,9 @@ var ELYSIA_ROUTE_METHODS, SKIP_DIRS, SOURCE_EXTENSIONS, getScriptKind = (filePat
10575
10660
  continue;
10576
10661
  if (entry.name.startsWith("."))
10577
10662
  continue;
10578
- stack.push(join16(dir, entry.name));
10663
+ stack.push(join18(dir, entry.name));
10579
10664
  } else if (entry.isFile() && hasSourceExtension(entry.name)) {
10580
- out.push(join16(dir, entry.name));
10665
+ out.push(join18(dir, entry.name));
10581
10666
  }
10582
10667
  }
10583
10668
  }
@@ -10591,7 +10676,7 @@ var ELYSIA_ROUTE_METHODS, SKIP_DIRS, SOURCE_EXTENSIONS, getScriptKind = (filePat
10591
10676
  }, extractRoutesFromFile = (filePath, out) => {
10592
10677
  let source;
10593
10678
  try {
10594
- source = readFileSync11(filePath, "utf-8");
10679
+ source = readFileSync13(filePath, "utf-8");
10595
10680
  } catch {
10596
10681
  return;
10597
10682
  }
@@ -10664,8 +10749,8 @@ var exports_staticAnalyzeSpaRoutes = {};
10664
10749
  __export(exports_staticAnalyzeSpaRoutes, {
10665
10750
  analyzeAngularSpaRoutes: () => analyzeAngularSpaRoutes
10666
10751
  });
10667
- import { existsSync as existsSync12, promises as fs } from "fs";
10668
- import { join as join17 } from "path";
10752
+ import { existsSync as existsSync14, promises as fs } from "fs";
10753
+ import { join as join19 } from "path";
10669
10754
  import ts3 from "typescript";
10670
10755
  var DYNAMIC_SEGMENT_PATTERN, pathHasDynamic = (path) => path.split("/").some((seg) => DYNAMIC_SEGMENT_PATTERN.test(seg) || seg === "**"), importsSymbolFrom = (sourceFile, localName, moduleSpecifier) => {
10671
10756
  for (const statement of sourceFile.statements) {
@@ -10862,7 +10947,7 @@ var DYNAMIC_SEGMENT_PATTERN, pathHasDynamic = (path) => path.split("/").some((se
10862
10947
  continue;
10863
10948
  if (item.name.startsWith("."))
10864
10949
  continue;
10865
- const full = join17(dir, item.name);
10950
+ const full = join19(dir, item.name);
10866
10951
  if (item.isDirectory()) {
10867
10952
  directories.push(full);
10868
10953
  } else if (item.isFile() && item.name.endsWith(".ts") && !item.name.endsWith(".d.ts")) {
@@ -10871,7 +10956,7 @@ var DYNAMIC_SEGMENT_PATTERN, pathHasDynamic = (path) => path.split("/").some((se
10871
10956
  }
10872
10957
  await Promise.all(directories.map((directory) => walkTsFiles(directory, files)));
10873
10958
  }, analyzeAngularSpaRoutes = async (angularDirectory) => {
10874
- if (!existsSync12(angularDirectory))
10959
+ if (!existsSync14(angularDirectory))
10875
10960
  return [];
10876
10961
  const tsFiles = [];
10877
10962
  await walkTsFiles(angularDirectory, tsFiles);
@@ -10896,8 +10981,8 @@ var exports_staticAnalyzeSpaRoutes2 = {};
10896
10981
  __export(exports_staticAnalyzeSpaRoutes2, {
10897
10982
  analyzeReactSpaRoutes: () => analyzeReactSpaRoutes
10898
10983
  });
10899
- import { existsSync as existsSync13, promises as fs2 } from "fs";
10900
- import { join as join18 } from "path";
10984
+ import { existsSync as existsSync15, promises as fs2 } from "fs";
10985
+ import { join as join20 } from "path";
10901
10986
  import ts4 from "typescript";
10902
10987
  var DYNAMIC_SEGMENT_PATTERN2, pathHasDynamic2 = (path) => path.split("/").some((seg) => DYNAMIC_SEGMENT_PATTERN2.test(seg) || seg === "**"), readStringLiteral2 = (expression) => {
10903
10988
  if (ts4.isStringLiteral(expression) || ts4.isNoSubstitutionTemplateLiteral(expression)) {
@@ -11076,7 +11161,7 @@ var DYNAMIC_SEGMENT_PATTERN2, pathHasDynamic2 = (path) => path.split("/").some((
11076
11161
  for (const item of items) {
11077
11162
  if (item.name === "node_modules" || item.name.startsWith("."))
11078
11163
  continue;
11079
- const full = join18(dir, item.name);
11164
+ const full = join20(dir, item.name);
11080
11165
  if (item.isDirectory()) {
11081
11166
  directories.push(full);
11082
11167
  } else if (item.isFile() && (item.name.endsWith(".tsx") || item.name.endsWith(".ts") || item.name.endsWith(".jsx") || item.name.endsWith(".js")) && !item.name.endsWith(".d.ts")) {
@@ -11085,7 +11170,7 @@ var DYNAMIC_SEGMENT_PATTERN2, pathHasDynamic2 = (path) => path.split("/").some((
11085
11170
  }
11086
11171
  await Promise.all(directories.map((directory) => walkSourceFiles(directory, files)));
11087
11172
  }, analyzeReactSpaRoutes = async (reactDirectory) => {
11088
- if (!existsSync13(reactDirectory))
11173
+ if (!existsSync15(reactDirectory))
11089
11174
  return [];
11090
11175
  const files = [];
11091
11176
  await walkSourceFiles(reactDirectory, files);
@@ -11110,8 +11195,8 @@ var exports_staticAnalyzeSpaRoutes3 = {};
11110
11195
  __export(exports_staticAnalyzeSpaRoutes3, {
11111
11196
  analyzeSvelteSpaRoutes: () => analyzeSvelteSpaRoutes
11112
11197
  });
11113
- import { existsSync as existsSync14, promises as fs3 } from "fs";
11114
- import { join as join19 } from "path";
11198
+ import { existsSync as existsSync16, promises as fs3 } from "fs";
11199
+ import { join as join21 } from "path";
11115
11200
  var DYNAMIC_SEGMENT_PATTERN3, pathHasDynamic3 = (path) => path.split("/").some((seg) => DYNAMIC_SEGMENT_PATTERN3.test(seg) || seg === "**"), joinSegments3 = (parent, child) => {
11116
11201
  if (!child)
11117
11202
  return parent;
@@ -11184,7 +11269,7 @@ var DYNAMIC_SEGMENT_PATTERN3, pathHasDynamic3 = (path) => path.split("/").some((
11184
11269
  for (const item of items) {
11185
11270
  if (item.name === "node_modules" || item.name.startsWith("."))
11186
11271
  continue;
11187
- const full = join19(dir, item.name);
11272
+ const full = join21(dir, item.name);
11188
11273
  if (item.isDirectory()) {
11189
11274
  directories.push(full);
11190
11275
  } else if (item.isFile() && item.name.endsWith(".svelte")) {
@@ -11193,7 +11278,7 @@ var DYNAMIC_SEGMENT_PATTERN3, pathHasDynamic3 = (path) => path.split("/").some((
11193
11278
  }
11194
11279
  await Promise.all(directories.map((directory) => walkSvelteFiles(directory, files)));
11195
11280
  }, analyzeSvelteSpaRoutes = async (svelteDirectory) => {
11196
- if (!existsSync14(svelteDirectory))
11281
+ if (!existsSync16(svelteDirectory))
11197
11282
  return [];
11198
11283
  const files = [];
11199
11284
  await walkSvelteFiles(svelteDirectory, files);
@@ -11220,8 +11305,8 @@ var exports_staticAnalyzeSpaRoutes4 = {};
11220
11305
  __export(exports_staticAnalyzeSpaRoutes4, {
11221
11306
  analyzeVueSpaRoutes: () => analyzeVueSpaRoutes
11222
11307
  });
11223
- import { existsSync as existsSync15, promises as fs4 } from "fs";
11224
- import { join as join20 } from "path";
11308
+ import { existsSync as existsSync17, promises as fs4 } from "fs";
11309
+ import { join as join22 } from "path";
11225
11310
  import ts5 from "typescript";
11226
11311
  var DYNAMIC_SEGMENT_PATTERN4, pathHasDynamic4 = (path) => path.split("/").some((seg) => DYNAMIC_SEGMENT_PATTERN4.test(seg) || seg === "**"), readStringLiteral3 = (expression) => {
11227
11312
  if (ts5.isStringLiteral(expression) || ts5.isNoSubstitutionTemplateLiteral(expression)) {
@@ -11454,7 +11539,7 @@ var DYNAMIC_SEGMENT_PATTERN4, pathHasDynamic4 = (path) => path.split("/").some((
11454
11539
  for (const item of items) {
11455
11540
  if (item.name === "node_modules" || item.name.startsWith("."))
11456
11541
  continue;
11457
- const full = join20(dir, item.name);
11542
+ const full = join22(dir, item.name);
11458
11543
  if (item.isDirectory()) {
11459
11544
  directories.push(full);
11460
11545
  } else if (item.isFile() && (item.name.endsWith(".ts") || item.name.endsWith(".js") || item.name.endsWith(".vue")) && !item.name.endsWith(".d.ts")) {
@@ -11463,7 +11548,7 @@ var DYNAMIC_SEGMENT_PATTERN4, pathHasDynamic4 = (path) => path.split("/").some((
11463
11548
  }
11464
11549
  await Promise.all(directories.map((directory) => walkSourceFiles2(directory, files)));
11465
11550
  }, analyzeVueSpaRoutes = async (vueDirectory) => {
11466
- if (!existsSync15(vueDirectory))
11551
+ if (!existsSync17(vueDirectory))
11467
11552
  return [];
11468
11553
  const files = [];
11469
11554
  await walkSourceFiles2(vueDirectory, files);
@@ -11720,10 +11805,10 @@ var init_generateSitemap = __esm(() => {
11720
11805
  });
11721
11806
 
11722
11807
  // src/build/scanCssEntryPoints.ts
11723
- import { existsSync as existsSync16 } from "fs";
11808
+ import { existsSync as existsSync18 } from "fs";
11724
11809
  var {Glob: Glob4 } = globalThis.Bun;
11725
11810
  var scanCssEntryPoints = async (dir, ignore) => {
11726
- if (!existsSync16(dir))
11811
+ if (!existsSync18(dir))
11727
11812
  return [];
11728
11813
  const entryPaths = [];
11729
11814
  const glob = new Glob4("**/*.{css,scss,sass,less,styl,stylus}");
@@ -11740,8 +11825,8 @@ var init_scanCssEntryPoints = __esm(() => {
11740
11825
  });
11741
11826
 
11742
11827
  // src/utils/imageProcessing.ts
11743
- import { existsSync as existsSync17, mkdirSync as mkdirSync3, readFileSync as readFileSync12, writeFileSync as writeFileSync4 } from "fs";
11744
- import { join as join21, resolve as resolve18 } from "path";
11828
+ import { existsSync as existsSync19, mkdirSync as mkdirSync4, readFileSync as readFileSync14, writeFileSync as writeFileSync5 } from "fs";
11829
+ import { join as join23, resolve as resolve18 } from "path";
11745
11830
  var DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, DEFAULT_QUALITY, OPTIMIZATION_ENDPOINT = "/_absolute/image", BLUR_DEVIATION = 20, sharpModule = undefined, sharpLoaded = false, sharpWarned = false, snapToSize = (target, sizes) => {
11746
11831
  for (const size of sizes) {
11747
11832
  if (size >= target)
@@ -11798,9 +11883,9 @@ var DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, DEFAULT_QUALITY, OPTIMIZATION_END
11798
11883
  const image2 = config?.imageSizes ?? DEFAULT_IMAGE_SIZES;
11799
11884
  return [...device, ...image2].sort((left, right) => left - right);
11800
11885
  }, getCacheDir = (buildDir, cacheDirectory) => {
11801
- const dir = cacheDirectory ? resolve18(cacheDirectory) : join21(buildDir, ".cache", "images");
11802
- if (!existsSync17(dir))
11803
- mkdirSync3(dir, { recursive: true });
11886
+ const dir = cacheDirectory ? resolve18(cacheDirectory) : join23(buildDir, ".cache", "images");
11887
+ if (!existsSync19(dir))
11888
+ mkdirSync4(dir, { recursive: true });
11804
11889
  return dir;
11805
11890
  }, getCacheKey = (url, width, quality, format) => {
11806
11891
  const hasher = new Bun.CryptoHasher("sha256");
@@ -11889,13 +11974,13 @@ var DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, DEFAULT_QUALITY, OPTIMIZATION_END
11889
11974
  return optimizeUnsupportedAvif(err, input, width, quality, format);
11890
11975
  }
11891
11976
  }, readFromCache = (cacheDir, cacheKey) => {
11892
- const metaPath = join21(cacheDir, `${cacheKey}.meta`);
11893
- const dataPath = join21(cacheDir, `${cacheKey}.data`);
11894
- if (!existsSync17(metaPath) || !existsSync17(dataPath))
11977
+ const metaPath = join23(cacheDir, `${cacheKey}.meta`);
11978
+ const dataPath = join23(cacheDir, `${cacheKey}.data`);
11979
+ if (!existsSync19(metaPath) || !existsSync19(dataPath))
11895
11980
  return null;
11896
11981
  try {
11897
- const meta = JSON.parse(readFileSync12(metaPath, "utf-8"));
11898
- const buffer = readFileSync12(dataPath);
11982
+ const meta = JSON.parse(readFileSync14(metaPath, "utf-8"));
11983
+ const buffer = readFileSync14(dataPath);
11899
11984
  return { buffer, meta };
11900
11985
  } catch {
11901
11986
  return null;
@@ -11917,10 +12002,10 @@ var DEFAULT_DEVICE_SIZES, DEFAULT_IMAGE_SIZES, DEFAULT_QUALITY, OPTIMIZATION_END
11917
12002
  return null;
11918
12003
  }
11919
12004
  }, writeToCache = (cacheDir, cacheKey, buffer, meta) => {
11920
- const metaPath = join21(cacheDir, `${cacheKey}.meta`);
11921
- const dataPath = join21(cacheDir, `${cacheKey}.data`);
11922
- writeFileSync4(dataPath, buffer);
11923
- writeFileSync4(metaPath, JSON.stringify(meta));
12005
+ const metaPath = join23(cacheDir, `${cacheKey}.meta`);
12006
+ const dataPath = join23(cacheDir, `${cacheKey}.data`);
12007
+ writeFileSync5(dataPath, buffer);
12008
+ writeFileSync5(metaPath, JSON.stringify(meta));
11924
12009
  };
11925
12010
  var init_imageProcessing = __esm(() => {
11926
12011
  init_constants();
@@ -12003,87 +12088,6 @@ var init_optimizeHtmlImages = __esm(() => {
12003
12088
  IMG_REGEX = /<img\s+([^>]*?)data-optimized([^>]*?)\/?>/gi;
12004
12089
  });
12005
12090
 
12006
- // src/cli/scripts/telemetry.ts
12007
- import { existsSync as existsSync18, mkdirSync as mkdirSync4, readFileSync as readFileSync13, writeFileSync as writeFileSync5 } from "fs";
12008
- import { homedir } from "os";
12009
- import { join as join22 } from "path";
12010
- var configDir, configPath, getTelemetryConfig = () => {
12011
- try {
12012
- if (!existsSync18(configPath))
12013
- return null;
12014
- const raw = readFileSync13(configPath, "utf-8");
12015
- const config = JSON.parse(raw);
12016
- return config;
12017
- } catch {
12018
- return null;
12019
- }
12020
- };
12021
- var init_telemetry = __esm(() => {
12022
- configDir = join22(homedir(), ".absolutejs");
12023
- configPath = join22(configDir, "telemetry.json");
12024
- });
12025
-
12026
- // src/cli/telemetryEvent.ts
12027
- import { existsSync as existsSync19, readFileSync as readFileSync14 } from "fs";
12028
- import { arch as arch2, platform as platform2 } from "os";
12029
- import { dirname as dirname12, join as join23, parse } from "path";
12030
- var checkCandidate = (candidate) => {
12031
- if (!existsSync19(candidate)) {
12032
- return null;
12033
- }
12034
- const pkg = JSON.parse(readFileSync14(candidate, "utf-8"));
12035
- if (pkg.name === "@absolutejs/absolute") {
12036
- const ver = pkg.version;
12037
- return ver;
12038
- }
12039
- return null;
12040
- }, getVersion = () => {
12041
- try {
12042
- return findPackageVersion();
12043
- } catch {
12044
- return "unknown";
12045
- }
12046
- }, findPackageVersion = () => {
12047
- let { dir } = import.meta;
12048
- while (dir !== parse(dir).root) {
12049
- const candidate = join23(dir, "package.json");
12050
- const version = checkCandidate(candidate);
12051
- if (version) {
12052
- return version;
12053
- }
12054
- dir = dirname12(dir);
12055
- }
12056
- return "unknown";
12057
- }, sendTelemetryEvent = (event, payload) => {
12058
- try {
12059
- if (process.env.TELEMETRY_OFF === "1")
12060
- return;
12061
- const config = getTelemetryConfig();
12062
- if (!config?.enabled)
12063
- return;
12064
- const body = {
12065
- anonymousId: config.anonymousId,
12066
- arch: arch2(),
12067
- bunVersion: Bun.version,
12068
- event,
12069
- os: platform2(),
12070
- payload,
12071
- timestamp: new Date().toISOString(),
12072
- version: getVersion()
12073
- };
12074
- fetch("https://absolutejs.com/api/telemetry", {
12075
- body: JSON.stringify(body),
12076
- headers: { "Content-Type": "application/json" },
12077
- method: "POST"
12078
- }).catch(() => {
12079
- return;
12080
- });
12081
- } catch {}
12082
- };
12083
- var init_telemetryEvent = __esm(() => {
12084
- init_telemetry();
12085
- });
12086
-
12087
12091
  // src/build/updateAssetPaths.ts
12088
12092
  var exports_updateAssetPaths = {};
12089
12093
  __export(exports_updateAssetPaths, {
@@ -25522,6 +25526,8 @@ var MAX_RETAINED_HMR_UPDATES = 100, normalizedHmrTarget = (value) => {
25522
25526
  return value;
25523
25527
  if (value === "capacitor-native")
25524
25528
  return value;
25529
+ if (value === "mobile-preview")
25530
+ return value;
25525
25531
  return "web";
25526
25532
  }, hmrMessageMetadata = (state, message) => {
25527
25533
  const data = Reflect.get(message, "data");
@@ -30349,16 +30355,16 @@ var init_devBuild = __esm(() => {
30349
30355
  });
30350
30356
 
30351
30357
  // src/react/bridgeInternals.ts
30352
- var INTERNALS_KEYS, isRecord9 = (val) => typeof val === "object" && val !== null, findInternals = (mod) => {
30358
+ var INTERNALS_KEYS, isRecord10 = (val) => typeof val === "object" && val !== null, findInternals = (mod) => {
30353
30359
  for (const key of INTERNALS_KEYS) {
30354
30360
  const val = mod[key];
30355
- if (isRecord9(val))
30361
+ if (isRecord10(val))
30356
30362
  return val;
30357
30363
  }
30358
30364
  return;
30359
30365
  }, bridgeReactInternals = async () => {
30360
30366
  const pinnedRef = globalThis.__reactModuleRef;
30361
- if (!isRecord9(pinnedRef))
30367
+ if (!isRecord10(pinnedRef))
30362
30368
  return;
30363
30369
  const react = await import("react");
30364
30370
  if (pinnedRef === react)
@@ -30392,7 +30398,7 @@ var exports_hmr = {};
30392
30398
  __export(exports_hmr, {
30393
30399
  hmr: () => hmr
30394
30400
  });
30395
- import Elysia5 from "elysia";
30401
+ import Elysia6 from "elysia";
30396
30402
  import { websocket as websocket2 } from "elysia/websocket";
30397
30403
  var STORE_KEY = "__elysiaStore", restoredStores, getGlobalValue = (key) => Reflect.get(globalThis, key), restoreStore = (store) => {
30398
30404
  if (!store || typeof store !== "object")
@@ -30488,7 +30494,7 @@ var STORE_KEY = "__elysiaStore", restoredStores, getGlobalValue = (key) => Refle
30488
30494
  return candidate;
30489
30495
  }
30490
30496
  return null;
30491
- }, hmr = (hmrState2, manifest, moduleServerHandler) => new Elysia5({ name: "absolutejs-hmr" }).use(websocket2({
30497
+ }, hmr = (hmrState2, manifest, moduleServerHandler) => new Elysia6({ name: "absolutejs-hmr" }).use(websocket2({
30492
30498
  idleTimeout: DEFAULT_WEBSOCKET_IDLE_TIMEOUT_SECONDS,
30493
30499
  sendPings: true
30494
30500
  })).request(async ({ request, store }) => {
@@ -30567,7 +30573,7 @@ __export(exports_devtoolsJson, {
30567
30573
  });
30568
30574
  import { existsSync as existsSync37, mkdirSync as mkdirSync15, readFileSync as readFileSync33, writeFileSync as writeFileSync10 } from "fs";
30569
30575
  import { dirname as dirname32, join as join51, resolve as resolve48 } from "path";
30570
- import { Elysia as Elysia6 } from "elysia";
30576
+ import { Elysia as Elysia7 } from "elysia";
30571
30577
  var ENDPOINT = "/.well-known/appspecific/com.chrome.devtools.json", UUID_CACHE_KEY = "__absoluteDevtoolsWorkspaceUuid", getGlobalUuid = () => Reflect.get(globalThis, UUID_CACHE_KEY), setGlobalUuid = (uuid) => {
30572
30578
  Reflect.set(globalThis, UUID_CACHE_KEY, uuid);
30573
30579
  return uuid;
@@ -30600,7 +30606,7 @@ var ENDPOINT = "/.well-known/appspecific/com.chrome.devtools.json", UUID_CACHE_K
30600
30606
  const rootPath = resolve48(options.projectRoot ?? process.cwd());
30601
30607
  const root = options.normalizeForWindowsContainer === false ? rootPath : normalizeDevtoolsWorkspaceRoot(rootPath);
30602
30608
  const uuid = getOrCreateUuid(buildDir, options);
30603
- return new Elysia6({ name: "absolute-devtools-json" }).get(ENDPOINT, () => ({
30609
+ return new Elysia7({ name: "absolute-devtools-json" }).get(ENDPOINT, () => ({
30604
30610
  workspace: {
30605
30611
  root,
30606
30612
  uuid
@@ -30627,7 +30633,7 @@ __export(exports_imageOptimizer, {
30627
30633
  });
30628
30634
  import { existsSync as existsSync38 } from "fs";
30629
30635
  import { resolve as resolve49 } from "path";
30630
- import { Elysia as Elysia7 } from "elysia";
30636
+ import { Elysia as Elysia8 } from "elysia";
30631
30637
  var DEFAULT_CACHE_TTL_SECONDS = 60, MS_PER_SECOND = 1000, MAX_QUALITY = 100, avifInProgress, safeResolve = (path, baseDir) => {
30632
30638
  try {
30633
30639
  const resolved = validateSafePath(path, baseDir);
@@ -30740,7 +30746,7 @@ var DEFAULT_CACHE_TTL_SECONDS = 60, MS_PER_SECOND = 1000, MAX_QUALITY = 100, avi
30740
30746
  }
30741
30747
  });
30742
30748
  }, imageOptimizer = (config, buildDir) => {
30743
- const plugin = new Elysia7({ name: "image-optimizer" });
30749
+ const plugin = new Elysia8({ name: "image-optimizer" });
30744
30750
  if (!config && config !== undefined)
30745
30751
  return plugin;
30746
30752
  if (config?.unoptimized)
@@ -30841,7 +30847,7 @@ var exports_requestInspector = {};
30841
30847
  __export(exports_requestInspector, {
30842
30848
  requestInspector: () => requestInspector
30843
30849
  });
30844
- import { Elysia as Elysia8 } from "elysia";
30850
+ import { Elysia as Elysia9 } from "elysia";
30845
30851
  var RING_MAX = 200, DEFAULT_STATUS = 200, ASSET_EXTENSION, requestLog = () => {
30846
30852
  globalThis.__absoluteRequestLog ??= [];
30847
30853
  return globalThis.__absoluteRequestLog;
@@ -30877,7 +30883,7 @@ var RING_MAX = 200, DEFAULT_STATUS = 200, ASSET_EXTENSION, requestLog = () => {
30877
30883
  var init_requestInspector = __esm(() => {
30878
30884
  ASSET_EXTENSION = /\.(?:avif|css|gif|ico|jpe?g|js|json|map|mjs|otf|png|svg|ttf|txt|wasm|webp|woff2?)$/i;
30879
30885
  pending = new WeakMap;
30880
- requestInspector = new Elysia8({
30886
+ requestInspector = new Elysia9({
30881
30887
  name: "absolute-request-inspector"
30882
30888
  }).get("/__absolute/requests", () => requestLog()).request(({ request }) => {
30883
30889
  pending.set(request, {
@@ -32222,7 +32228,7 @@ var handleHTMXPageRequest = async (pagePath, options = {}) => {
32222
32228
  import { createHash as createHash8 } from "crypto";
32223
32229
  import { existsSync as existsSync39, readdirSync as readdirSync10, readFileSync as readFileSync35 } from "fs";
32224
32230
  import { basename as basename18, join as join54, relative as relative20, resolve as resolvePath4 } from "path";
32225
- import { Elysia as Elysia9, NotFound } from "elysia";
32231
+ import { Elysia as Elysia10, NotFound } from "elysia";
32226
32232
 
32227
32233
  // src/plugins/openApiPlugin.ts
32228
32234
  import { existsSync as existsSync7, readFileSync as readFileSync8 } from "fs";
@@ -33094,6 +33100,78 @@ var verifyAbsoluteMobileAssociationFiles = async (config, request = globalThis.f
33094
33100
  return { results };
33095
33101
  };
33096
33102
 
33103
+ // src/mobile/mobilePreview.ts
33104
+ init_telemetryEvent();
33105
+ import { Elysia as Elysia4 } from "elysia";
33106
+ var ABSOLUTE_MOBILE_PREVIEW_PATH = "/__absolute/mobile-preview";
33107
+ var escapeHtml = (value) => value.replaceAll("&", "&amp;").replaceAll("<", "&lt;").replaceAll(">", "&gt;").replaceAll('"', "&quot;");
33108
+ var isRecord7 = (value) => typeof value === "object" && value !== null;
33109
+ var normalizeEntry2 = (entry) => {
33110
+ const parsed = new URL(entry ?? "/", "https://absolute.invalid");
33111
+ return `${parsed.pathname}${parsed.search}${parsed.hash}`;
33112
+ };
33113
+ var absoluteMobilePreviewDocument = (mobile) => {
33114
+ const entry = normalizeEntry2(mobile.entry);
33115
+ const appName = mobile.appName?.trim() || "AbsoluteJS App";
33116
+ const boot = JSON.stringify({ appName, entry }).replaceAll("<", "\\u003c");
33117
+ return `<!doctype html>
33118
+ <html lang="en">
33119
+ <head>
33120
+ <meta charset="utf-8">
33121
+ <meta name="viewport" content="width=device-width,initial-scale=1">
33122
+ <meta name="color-scheme" content="dark">
33123
+ <link rel="icon" href="data:,">
33124
+ <title>${escapeHtml(appName)} \xB7 Mobile Preview</title>
33125
+ <style>
33126
+ :root{font-family:Inter,ui-sans-serif,system-ui,sans-serif;color:#e8ecf3;background:#080b12;color-scheme:dark}*{box-sizing:border-box}body{margin:0;min-height:100vh;background:radial-gradient(circle at 30% 0,#17213a 0,#080b12 42%)}button,input,select{font:inherit}.shell{display:grid;grid-template-columns:minmax(320px,1fr) 292px;gap:24px;min-height:100vh;padding:24px}.stage{display:grid;place-items:center;min-width:0}.device{position:relative;width:min(100%,430px);height:min(880px,calc(100vh - 48px));min-height:620px;padding:12px;border:1px solid #343c4d;border-radius:48px;background:#111620;box-shadow:0 35px 80px #0009,inset 0 0 0 1px #ffffff0d}.device.android{border-radius:30px}.screen{position:relative;width:100%;height:100%;overflow:hidden;border-radius:37px;background:#fff}.android .screen{border-radius:20px}.island{position:absolute;z-index:2;top:17px;left:50%;width:112px;height:30px;transform:translateX(-50%);border-radius:18px;background:#080b12;pointer-events:none}.android .island{width:9px;height:9px;top:10px}.app{width:100%;height:100%;border:0;background:#fff}.panel{align-self:start;position:sticky;top:24px;max-height:calc(100vh - 48px);overflow:auto;padding:18px;border:1px solid #262d3a;border-radius:20px;background:#0e131dcc;box-shadow:0 18px 50px #0005;backdrop-filter:blur(18px)}h1{font-size:18px;margin:0}.sub{margin:5px 0 18px;color:#8f9aae;font-size:12px}.status{display:flex;align-items:center;gap:8px;margin-bottom:18px;padding:9px 11px;border-radius:10px;background:#151c28;color:#aeb8ca;font-size:12px}.dot{width:8px;height:8px;border-radius:50%;background:#eab308}.ready .dot{background:#22c55e}.group{padding:14px 0;border-top:1px solid #252c39}.group:first-of-type{border-top:0}.label{display:block;margin-bottom:8px;color:#97a3b7;font-size:11px;font-weight:700;letter-spacing:.08em;text-transform:uppercase}.row{display:flex;gap:8px}.row>*{min-width:0}.grow{flex:1}button,select,input{border:1px solid #30394a;border-radius:9px;background:#171e2b;color:#e8ecf3;padding:9px 10px}button{cursor:pointer}button:hover{border-color:#64748b;background:#202a3a}button.active{border-color:#60a5fa;background:#172b48;color:#bfdbfe}input{width:100%}.events{height:84px;overflow:auto;margin-top:8px;padding:8px;border-radius:9px;background:#090d14;color:#8290a7;font:11px/1.5 ui-monospace,monospace}.hint{margin-top:12px;color:#64748b;font-size:11px;line-height:1.45}@media(max-width:840px){.shell{grid-template-columns:1fr;padding:12px}.device{height:720px}.panel{position:static;max-height:none}}
33127
+ </style>
33128
+ </head>
33129
+ <body>
33130
+ <main class="shell">
33131
+ <section class="stage"><div class="device" id="device"><div class="island"></div><div class="screen"><iframe class="app" id="app" title="${escapeHtml(appName)} mobile runtime"></iframe></div></div></section>
33132
+ <aside class="panel">
33133
+ <h1>${escapeHtml(appName)}</h1><p class="sub">AbsoluteJS mobile runtime preview</p>
33134
+ <div class="status" id="status"><span class="dot"></span><span id="statusText">Starting runtime\u2026</span></div>
33135
+ <div class="group"><span class="label">Device</span><div class="row"><button id="ios" class="grow active">iOS</button><button id="android" class="grow">Android</button></div></div>
33136
+ <div class="group"><label class="label" for="route">Route / deep link</label><div class="row"><input id="route" value="${escapeHtml(entry)}"><button id="go">Go</button></div><div class="row" style="margin-top:8px"><button id="deepLink" class="grow">Emit deep link</button><button id="back" class="grow">Hardware back</button></div></div>
33137
+ <div class="group"><span class="label">Connection</span><div class="row"><button id="online" class="grow active">Wi-Fi</button><button id="cellular" class="grow">Cellular</button><button id="offline" class="grow">Offline</button></div></div>
33138
+ <div class="group"><span class="label">Lifecycle</span><div class="row"><button id="active" class="grow active">Active</button><button id="background" class="grow">Background</button><button id="inactive" class="grow">Inactive</button></div></div>
33139
+ <div class="group"><span class="label">Keyboard</span><div class="row"><button id="keyboardShow" class="grow">Show</button><button id="keyboardHide" class="grow">Hide</button></div></div>
33140
+ <div class="group"><label class="label" for="permission">Permissions</label><div class="row"><select id="permission" class="grow"><option value="camera">Camera</option><option value="location">Location</option><option value="notifications">Notifications</option></select><select id="permissionState" class="grow"><option value="prompt">Prompt</option><option value="granted">Granted</option><option value="denied">Denied</option><option value="blocked">Blocked</option></select></div><button id="applyPermission" style="width:100%;margin-top:8px">Apply permission state</button></div>
33141
+ <div class="group"><span class="label">Runtime events</span><div class="events" id="events" aria-live="polite"></div><p class="hint">This runs the same development pages, HMR client, provider-neutral HTTP, and Devices contracts as an installed target. Native rendering, signing, push delivery, and OS scheduling still require a simulator or physical device.</p></div>
33142
+ </aside>
33143
+ </main>
33144
+ <script>const config=${boot};const frame=document.getElementById('app');const device=document.getElementById('device');const status=document.getElementById('status');const statusText=document.getElementById('statusText');const events=document.getElementById('events');let platform='ios';const event=(text)=>{const line=document.createElement('div');line.textContent=new Date().toLocaleTimeString()+' \xB7 '+text;events.prepend(line)};const routeUrl=()=>{const value=document.getElementById('route').value.trim()||config.entry;const url=new URL(value,location.origin);if(url.origin!==location.origin)throw new TypeError('Preview routes must stay on this dev server.');url.searchParams.set('__absolute_target','mobile-preview');url.searchParams.set('__absolute_preview_platform',platform);return url};const load=()=>{try{status.classList.remove('ready');statusText.textContent='Starting runtime\u2026';frame.src=routeUrl().href;event('loaded '+routeUrl().pathname)}catch(error){statusText.textContent=error.message}};const send=(message)=>{if(!frame.contentWindow)return;frame.contentWindow.postMessage(message,location.origin);event(message.type.replace('absolute-preview:',''))};const select=(ids,active)=>ids.forEach(id=>document.getElementById(id).classList.toggle('active',id===active));document.getElementById('ios').onclick=()=>{platform='ios';device.classList.remove('android');select(['ios','android'],'ios');load()};document.getElementById('android').onclick=()=>{platform='android';device.classList.add('android');select(['ios','android'],'android');load()};document.getElementById('go').onclick=load;document.getElementById('route').onkeydown=e=>{if(e.key==='Enter')load()};document.getElementById('deepLink').onclick=()=>send({type:'absolute-preview:deep-link',url:new URL(document.getElementById('route').value,location.origin).href});document.getElementById('back').onclick=()=>send({type:'absolute-preview:back'});[['online',true,'wifi'],['cellular',true,'cellular'],['offline',false,'none']].forEach(([id,connected,connectionType])=>document.getElementById(id).onclick=()=>{select(['online','cellular','offline'],id);send({type:'absolute-preview:network',connected,connectionType})});['active','background','inactive'].forEach(id=>document.getElementById(id).onclick=()=>{select(['active','background','inactive'],id);send({type:'absolute-preview:lifecycle',state:id})});document.getElementById('keyboardShow').onclick=()=>send({type:'absolute-preview:keyboard',visible:true,heightPx:320});document.getElementById('keyboardHide').onclick=()=>send({type:'absolute-preview:keyboard',visible:false,heightPx:0});document.getElementById('applyPermission').onclick=()=>send({type:'absolute-preview:permission',capability:document.getElementById('permission').value,state:document.getElementById('permissionState').value});addEventListener('message',e=>{if(e.origin!==location.origin||e.source!==frame.contentWindow||!e.data||typeof e.data.type!=='string'||!e.data.type.startsWith('absolute-preview:'))return;if(e.data.type==='absolute-preview:ready'){status.classList.add('ready');statusText.textContent=platform==='ios'?'iOS runtime connected':'Android runtime connected'}event(e.data.event||e.data.type.replace('absolute-preview:',''))});load();</script>
33145
+ </body>
33146
+ </html>`;
33147
+ };
33148
+ var createAbsoluteMobilePreviewPlugin = (mobile) => {
33149
+ if (!mobile)
33150
+ return new Elysia4({ name: "absolutejs-mobile-preview-disabled" });
33151
+ return new Elysia4({ name: "absolutejs-mobile-preview" }).get(ABSOLUTE_MOBILE_PREVIEW_PATH, () => new Response(absoluteMobilePreviewDocument(mobile), {
33152
+ headers: {
33153
+ "Cache-Control": "no-store",
33154
+ "Content-Security-Policy": "default-src 'self'; script-src 'unsafe-inline' 'self'; style-src 'unsafe-inline'; frame-src 'self'; img-src 'self' data: blob:; connect-src 'self' ws: wss:",
33155
+ "Content-Type": "text/html; charset=utf-8",
33156
+ "X-Robots-Tag": "noindex, nofollow"
33157
+ }
33158
+ })).post("/__absolute/mobile-preview-telemetry", ({ body, status }) => {
33159
+ const value = isRecord7(body) ? body : undefined;
33160
+ const durationMs = value?.durationMs;
33161
+ const platform3 = value?.platform;
33162
+ if (typeof durationMs !== "number" || !Number.isFinite(durationMs) || durationMs < 0 || durationMs > 300000 || platform3 !== "android" && platform3 !== "ios") {
33163
+ return status(400, { error: "invalid-preview-telemetry" });
33164
+ }
33165
+ sendTelemetryEvent("mobile:preview-ready", {
33166
+ durationMs: Math.round(durationMs),
33167
+ platform: platform3,
33168
+ provider: "capacitor",
33169
+ target: "mobile-preview"
33170
+ });
33171
+ return status(204);
33172
+ });
33173
+ };
33174
+
33097
33175
  // src/mobile/materializedBundle.ts
33098
33176
  import { createHash as createHash6 } from "crypto";
33099
33177
  import {
@@ -33105,7 +33183,7 @@ import {
33105
33183
  rm as rm3,
33106
33184
  writeFile as writeFile3
33107
33185
  } from "fs/promises";
33108
- import { dirname as dirname9, join as join14, resolve as resolvePath2 } from "path";
33186
+ import { dirname as dirname10, join as join16, resolve as resolvePath2 } from "path";
33109
33187
  import { pathToFileURL as pathToFileURL2 } from "url";
33110
33188
 
33111
33189
  // src/mobile/artifactStore.ts
@@ -33119,7 +33197,7 @@ import {
33119
33197
  rm as rm2,
33120
33198
  writeFile as writeFile2
33121
33199
  } from "fs/promises";
33122
- import { join as join13, resolve as resolvePath } from "path";
33200
+ import { join as join15, resolve as resolvePath } from "path";
33123
33201
  var DEFAULT_MAX_PRODUCER_BYTES = 134217728;
33124
33202
  var SHA_2562 = "sha256";
33125
33203
  var ARTIFACT_FILE = "artifact.json";
@@ -33143,7 +33221,7 @@ var requireReleaseId = (releaseId) => {
33143
33221
  return releaseId;
33144
33222
  };
33145
33223
  var readStoredArtifact = async (releaseDirectory) => {
33146
- const serialized = await readFile4(join13(releaseDirectory, ARTIFACT_FILE), "utf8");
33224
+ const serialized = await readFile4(join15(releaseDirectory, ARTIFACT_FILE), "utf8");
33147
33225
  const parsed = JSON.parse(serialized);
33148
33226
  return parseAbsoluteMobileCompatibilityArtifact(parsed);
33149
33227
  };
@@ -33244,8 +33322,8 @@ var createAbsoluteMobileBlobArtifactStore = (options) => {
33244
33322
  var createAbsoluteMobileFileArtifactStore = (options) => {
33245
33323
  const root = resolvePath(options.root);
33246
33324
  const maxProducerBytes = options.maxProducerBytes ?? DEFAULT_MAX_PRODUCER_BYTES;
33247
- const appDirectory = (appId) => join13(root, appDirectoryName(appId));
33248
- const releaseDirectory = (appId, releaseId) => join13(appDirectory(appId), requireReleaseId(releaseId));
33325
+ const appDirectory = (appId) => join15(root, appDirectoryName(appId));
33326
+ const releaseDirectory = (appId, releaseId) => join15(appDirectory(appId), requireReleaseId(releaseId));
33249
33327
  const acceptExistingRelease = async (error, artifact) => {
33250
33328
  if (!errorHasCode(error, "EEXIST") && !errorHasCode(error, "ENOTEMPTY")) {
33251
33329
  return false;
@@ -33286,7 +33364,7 @@ var createAbsoluteMobileFileArtifactStore = (options) => {
33286
33364
  }
33287
33365
  return {
33288
33366
  artifact,
33289
- producer: Bun.file(join13(directory, artifact.producer.module))
33367
+ producer: Bun.file(join15(directory, artifact.producer.module))
33290
33368
  };
33291
33369
  },
33292
33370
  write: async (release) => {
@@ -33294,14 +33372,14 @@ var createAbsoluteMobileFileArtifactStore = (options) => {
33294
33372
  const validated = await verifyAbsoluteMobileCompatibilityProducer({ artifact: validatedArtifact, producer: release.producer }, maxProducerBytes);
33295
33373
  const parent = appDirectory(validated.artifact.appId);
33296
33374
  await mkdir6(parent, { recursive: true });
33297
- const staging = await mkdtemp(join13(parent, ".stage-"));
33298
- const producerPath = join13(staging, validated.artifact.producer.module);
33375
+ const staging = await mkdtemp(join15(parent, ".stage-"));
33376
+ const producerPath = join15(staging, validated.artifact.producer.module);
33299
33377
  try {
33300
33378
  await mkdir6(resolvePath(producerPath, ".."), {
33301
33379
  recursive: true
33302
33380
  });
33303
33381
  await Promise.all([
33304
- writeFile2(join13(staging, ARTIFACT_FILE), `${JSON.stringify(validated.artifact, null, "\t")}
33382
+ writeFile2(join15(staging, ARTIFACT_FILE), `${JSON.stringify(validated.artifact, null, "\t")}
33305
33383
  `),
33306
33384
  writeFile2(producerPath, new Uint8Array(await validated.producer.arrayBuffer()))
33307
33385
  ]);
@@ -33332,7 +33410,7 @@ var CURRENT_BUNDLE_FILE = "current.json";
33332
33410
  var BUNDLES_DIRECTORY = "bundles";
33333
33411
  var ARTIFACT_FILE2 = "artifact.json";
33334
33412
  var BUNDLE_ID_PATTERN = /^amb_[a-f0-9]{64}$/;
33335
- var isRecord7 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
33413
+ var isRecord8 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
33336
33414
  var errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code;
33337
33415
  var bundleIdFor = (currentReleaseId, releases) => {
33338
33416
  const identity = JSON.stringify({
@@ -33342,7 +33420,7 @@ var bundleIdFor = (currentReleaseId, releases) => {
33342
33420
  return `amb_${createHash6("sha256").update(identity).digest("hex")}`;
33343
33421
  };
33344
33422
  var parseBundleIndex = (value) => {
33345
- if (!isRecord7(value) || value.format !== ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT || typeof value.bundleId !== "string" || !BUNDLE_ID_PATTERN.test(value.bundleId) || typeof value.currentReleaseId !== "string" || !Array.isArray(value.releases)) {
33423
+ if (!isRecord8(value) || value.format !== ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT || typeof value.bundleId !== "string" || !BUNDLE_ID_PATTERN.test(value.bundleId) || typeof value.currentReleaseId !== "string" || !Array.isArray(value.releases)) {
33346
33424
  throw new TypeError("Invalid materialized mobile compatibility bundle.");
33347
33425
  }
33348
33426
  const releases = value.releases.map(parseAbsoluteMobileCompatibilityArtifact);
@@ -33365,17 +33443,17 @@ var parseBundleIndex = (value) => {
33365
33443
  };
33366
33444
  };
33367
33445
  var writeRelease = async (root, release) => {
33368
- const directory = join14(root, release.artifact.releaseId);
33369
- const producerPath = join14(directory, release.artifact.producer.module);
33370
- await mkdir7(dirname9(producerPath), { recursive: true });
33446
+ const directory = join16(root, release.artifact.releaseId);
33447
+ const producerPath = join16(directory, release.artifact.producer.module);
33448
+ await mkdir7(dirname10(producerPath), { recursive: true });
33371
33449
  await Promise.all([
33372
- writeFile3(join14(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
33450
+ writeFile3(join16(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
33373
33451
  `),
33374
33452
  writeFile3(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
33375
33453
  ]);
33376
33454
  };
33377
33455
  var installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
33378
- const destination = join14(bundlesRoot, bundleId);
33456
+ const destination = join16(bundlesRoot, bundleId);
33379
33457
  try {
33380
33458
  await access2(destination);
33381
33459
  return destination;
@@ -33383,7 +33461,7 @@ var installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
33383
33461
  if (!errorHasCode2(error, "ENOENT"))
33384
33462
  throw error;
33385
33463
  }
33386
- const staging = await mkdtemp2(join14(bundlesRoot, ".stage-"));
33464
+ const staging = await mkdtemp2(join16(bundlesRoot, ".stage-"));
33387
33465
  try {
33388
33466
  await Promise.all(releases.map((release) => writeRelease(staging, release)));
33389
33467
  await rename3(staging, destination);
@@ -33399,7 +33477,7 @@ var installImmutableBundle = async (bundlesRoot, bundleId, releases) => {
33399
33477
  var readCompatibilityModule = (modulePath) => import(pathToFileURL2(modulePath).href);
33400
33478
  var resolveProducerHandler = (loaded, exportName) => {
33401
33479
  const value = loaded[exportName];
33402
- if (!isRecord7(value) || typeof value.handle !== "function") {
33480
+ if (!isRecord8(value) || typeof value.handle !== "function") {
33403
33481
  throw new TypeError(`Compatibility producer export ${exportName} must expose handle(request).`);
33404
33482
  }
33405
33483
  const { handle } = value;
@@ -33417,15 +33495,15 @@ var resolveProducerHandler = (loaded, exportName) => {
33417
33495
  };
33418
33496
  var loadAbsoluteMobileMaterializedBundle = async (root) => {
33419
33497
  const resolvedRoot = resolvePath2(root);
33420
- const serialized = await readFile5(join14(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
33498
+ const serialized = await readFile5(join16(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
33421
33499
  const parsed = JSON.parse(serialized);
33422
33500
  const index = parseBundleIndex(parsed);
33423
- const bundleRoot = join14(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
33501
+ const bundleRoot = join16(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
33424
33502
  return {
33425
33503
  artifacts: index.releases,
33426
33504
  currentReleaseId: index.currentReleaseId,
33427
33505
  loadProducer: async (artifact) => {
33428
- const modulePath = join14(bundleRoot, artifact.releaseId, artifact.producer.module);
33506
+ const modulePath = join16(bundleRoot, artifact.releaseId, artifact.producer.module);
33429
33507
  await verifyAbsoluteMobileCompatibilityProducer({
33430
33508
  artifact,
33431
33509
  producer: Bun.file(modulePath)
@@ -33452,7 +33530,7 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
33452
33530
  return release;
33453
33531
  });
33454
33532
  const root = resolvePath2(input.root);
33455
- const bundlesRoot = join14(root, BUNDLES_DIRECTORY);
33533
+ const bundlesRoot = join16(root, BUNDLES_DIRECTORY);
33456
33534
  await mkdir7(bundlesRoot, { recursive: true });
33457
33535
  const bundleId = bundleIdFor(input.currentReleaseId, artifacts);
33458
33536
  await installImmutableBundle(bundlesRoot, bundleId, orderedReleases);
@@ -33462,8 +33540,8 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
33462
33540
  format: ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT,
33463
33541
  releases: artifacts
33464
33542
  };
33465
- const pointerPath = join14(root, CURRENT_BUNDLE_FILE);
33466
- const temporaryPointerPath = join14(root, `.current-${crypto.randomUUID()}.json`);
33543
+ const pointerPath = join16(root, CURRENT_BUNDLE_FILE);
33544
+ const temporaryPointerPath = join16(root, `.current-${crypto.randomUUID()}.json`);
33467
33545
  await writeFile3(temporaryPointerPath, `${JSON.stringify(index, null, "\t")}
33468
33546
  `, { flag: "wx" });
33469
33547
  await rename3(temporaryPointerPath, pointerPath);
@@ -33472,12 +33550,12 @@ var materializeAbsoluteMobileCompatibilityBundle = async (input) => {
33472
33550
  var readAbsoluteMobileMaterializedReleases = async (root) => {
33473
33551
  const resolvedRoot = resolvePath2(root);
33474
33552
  try {
33475
- const serialized = await readFile5(join14(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
33553
+ const serialized = await readFile5(join16(resolvedRoot, CURRENT_BUNDLE_FILE), "utf8");
33476
33554
  const parsed = JSON.parse(serialized);
33477
33555
  const index = parseBundleIndex(parsed);
33478
- const bundleRoot = join14(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
33556
+ const bundleRoot = join16(resolvedRoot, BUNDLES_DIRECTORY, index.bundleId);
33479
33557
  return Promise.all(index.releases.map(async (artifact) => {
33480
- const producer = Bun.file(join14(bundleRoot, artifact.releaseId, artifact.producer.module));
33558
+ const producer = Bun.file(join16(bundleRoot, artifact.releaseId, artifact.producer.module));
33481
33559
  await verifyAbsoluteMobileCompatibilityProducer({
33482
33560
  artifact,
33483
33561
  producer
@@ -33494,16 +33572,16 @@ var readAbsoluteMobileMaterializedReleases = async (root) => {
33494
33572
  // src/core/loadIslandRegistry.ts
33495
33573
  init_islandEntries();
33496
33574
  import { resolve as resolve13 } from "path";
33497
- var isRecord8 = (value) => typeof value === "object" && value !== null;
33575
+ var isRecord9 = (value) => typeof value === "object" && value !== null;
33498
33576
  var resolveRegistryExport2 = (mod) => {
33499
- if (isRecord8(mod.islandRegistry))
33577
+ if (isRecord9(mod.islandRegistry))
33500
33578
  return mod.islandRegistry;
33501
- if (isRecord8(mod.default))
33579
+ if (isRecord9(mod.default))
33502
33580
  return mod.default;
33503
33581
  throw new Error("Island registry module must export `islandRegistry` or a default registry object.");
33504
33582
  };
33505
- var isRegistryModuleExport = (value) => isRecord8(value);
33506
- var isIslandRegistryInput = (value) => isRecord8(value);
33583
+ var isRegistryModuleExport = (value) => isRecord9(value);
33584
+ var isIslandRegistryInput = (value) => isRecord9(value);
33507
33585
  var loadIslandRegistry = async (registryPath) => {
33508
33586
  const resolvedRegistryPath = resolve13(registryPath);
33509
33587
  const buildInfo = await loadIslandRegistryBuildInfo(resolvedRegistryPath);
@@ -33539,7 +33617,7 @@ var retryStaticPlugin = async (createStaticPlugin, options) => {
33539
33617
  return await createStaticPlugin(options);
33540
33618
  } catch (error) {
33541
33619
  logWarn(`Static asset routes were skipped this cycle \u2014 a build file was unavailable mid-rebuild: ${error instanceof Error ? error.message : String(error)}`);
33542
- return new Elysia9({ name: "absolutejs-static-fallback" });
33620
+ return new Elysia10({ name: "absolutejs-static-fallback" });
33543
33621
  }
33544
33622
  };
33545
33623
  var mountStaticPlugin = async (createStaticPlugin, options) => {
@@ -33721,15 +33799,16 @@ var prepareDev = async (config, buildDir) => {
33721
33799
  const { requestInspector: requestInspector2 } = await Promise.resolve().then(() => (init_requestInspector(), exports_requestInspector));
33722
33800
  const { serverTiming } = await import("@elysia/server-timing");
33723
33801
  const mobileAssociationPlugin = createAbsoluteMobileAssociationPlugin(config.mobile, process.cwd());
33802
+ const mobilePreviewPlugin = createAbsoluteMobilePreviewPlugin(config.mobile);
33724
33803
  const nativeMobileConfig = config.mobile;
33725
33804
  let nativeDevAdapterBundle;
33726
33805
  const getNativeDevAdapterBundle = () => nativeDevAdapterBundle ??= nativeMobileConfig ? Promise.resolve().then(() => (init_devDeviceAdapter(), exports_devDeviceAdapter)).then(({ buildAbsoluteNativeDevAdapter: buildAbsoluteNativeDevAdapter2 }) => buildAbsoluteNativeDevAdapter2(process.cwd(), nativeMobileConfig)) : Promise.resolve("export {};");
33727
- const absolutejs = new Elysia9({ name: "absolutejs-runtime" }).use(requestInspector2).use(absoluteRequestContext).use(serverTiming()).use(devtoolsJson2(buildDir, {
33806
+ const absolutejs = new Elysia10({ name: "absolutejs-runtime" }).use(requestInspector2).use(absoluteRequestContext).use(serverTiming()).use(devtoolsJson2(buildDir, {
33728
33807
  normalizeForWindowsContainer: config.dev?.devtools?.normalizeForWindowsContainer,
33729
33808
  projectRoot: config.dev?.devtools?.projectRoot,
33730
33809
  uuid: config.dev?.devtools?.uuid,
33731
33810
  uuidCachePath: config.dev?.devtools?.uuidCachePath
33732
- })).use(imageOptimizer2(config.images, buildDir)).use(mobileAssociationPlugin).get("/__absolute/native-device-adapter.js", async () => new Response(await getNativeDevAdapterBundle(), {
33811
+ })).use(imageOptimizer2(config.images, buildDir)).use(mobileAssociationPlugin).use(mobilePreviewPlugin).get("/__absolute/native-device-adapter.js", async () => new Response(await getNativeDevAdapterBundle(), {
33733
33812
  headers: {
33734
33813
  "Cache-Control": "no-store",
33735
33814
  "Content-Type": "text/javascript; charset=utf-8"
@@ -33773,18 +33852,18 @@ var loadPrerenderMap = (prerenderDir) => {
33773
33852
  var loadMobileCompatibilityPlugin = async (buildDir) => {
33774
33853
  const root = join54(buildDir, ".absolutejs", "mobile-compatibility");
33775
33854
  if (!existsSync39(join54(root, "current.json"))) {
33776
- return new Elysia9({ name: "absolutejs-mobile-compatibility-empty" });
33855
+ return new Elysia10({ name: "absolutejs-mobile-compatibility-empty" });
33777
33856
  }
33778
33857
  const options = await loadAbsoluteMobileMaterializedBundle(root);
33779
33858
  return createAbsoluteMobileCompatibilityDispatcher(options);
33780
33859
  };
33781
- var createNotFoundPlugin = () => new Elysia9({ name: "absolutejs-not-found" }).error("global", NotFound, async () => {
33860
+ var createNotFoundPlugin = () => new Elysia10({ name: "absolutejs-not-found" }).error("global", NotFound, async () => {
33782
33861
  const response = await renderFirstNotFound();
33783
33862
  if (response)
33784
33863
  return response;
33785
33864
  return;
33786
33865
  });
33787
- var createBuildErrorRecoveryPlugin = () => new Elysia9({ name: "absolutejs-build-error-recovery" }).error("global", async ({ error }) => {
33866
+ var createBuildErrorRecoveryPlugin = () => new Elysia10({ name: "absolutejs-build-error-recovery" }).error("global", async ({ error }) => {
33788
33867
  const message = error instanceof Error ? error.message : String(error);
33789
33868
  const assetMatch = /^Asset "(.+)" not found in manifest\.$/.exec(message);
33790
33869
  if (!assetMatch)
@@ -33852,7 +33931,7 @@ var prepare = async (configOrPath) => {
33852
33931
  staticLimit: MAX_STATIC_ROUTE_COUNT
33853
33932
  });
33854
33933
  const generatedAssetsRoot = join54(buildDir, ".absolutejs");
33855
- const generatedAssetsPlugin = new Elysia9({
33934
+ const generatedAssetsPlugin = new Elysia10({
33856
33935
  name: "absolutejs-generated-assets"
33857
33936
  }).get("/.absolutejs/*", async ({ params, set }) => {
33858
33937
  const requestedPath = resolvePath4(generatedAssetsRoot, params["*"]);
@@ -33876,7 +33955,7 @@ var prepare = async (configOrPath) => {
33876
33955
  const hash = base.match(/[.-]([0-9a-z]{6,12})\.[0-9a-z]+$/i)?.[1];
33877
33956
  return hash ? /[0-9]/.test(hash) && /[a-z]/i.test(hash) : false;
33878
33957
  };
33879
- const assetCachePlugin = new Elysia9({
33958
+ const assetCachePlugin = new Elysia10({
33880
33959
  name: "absolutejs-asset-cache"
33881
33960
  }).afterHandle("global", ({ request, responseValue }) => {
33882
33961
  if (!(responseValue instanceof Response))
@@ -33899,7 +33978,7 @@ var prepare = async (configOrPath) => {
33899
33978
  const revalidateMs = config.static?.revalidate ? config.static.revalidate * MS_PER_SECOND2 : 0;
33900
33979
  const port = Number(process.env.PORT) || DEFAULT_PORT2;
33901
33980
  const rerendering = new Set;
33902
- const prerenderPlugin = new Elysia9({
33981
+ const prerenderPlugin = new Elysia10({
33903
33982
  name: "prerendered-pages"
33904
33983
  }).request(({ request }) => {
33905
33984
  const url = new URL(request.url);
@@ -33922,7 +34001,7 @@ var prepare = async (configOrPath) => {
33922
34001
  });
33923
34002
  stepStartedAt = performance.now();
33924
34003
  const { imageOptimizer: imageOptimizer3 } = await Promise.resolve().then(() => (init_imageOptimizer(), exports_imageOptimizer));
33925
- const absolutejs2 = new Elysia9({ name: "absolutejs-runtime" }).use(absoluteRequestContext).use(mobileAssociationPlugin).use(mobileCompatibilityPlugin).use(assetCachePlugin).use(imageOptimizer3(config.images, buildDir)).use(prerenderPlugin).use(staticFiles).use(generatedAssetsPlugin).use(createNotFoundPlugin());
34004
+ const absolutejs2 = new Elysia10({ name: "absolutejs-runtime" }).use(absoluteRequestContext).use(mobileAssociationPlugin).use(mobileCompatibilityPlugin).use(assetCachePlugin).use(imageOptimizer3(config.images, buildDir)).use(prerenderPlugin).use(staticFiles).use(generatedAssetsPlugin).use(createNotFoundPlugin());
33926
34005
  await withOpenApi(absolutejs2, config, process.cwd(), false);
33927
34006
  await withTelemetry(absolutejs2, config, process.cwd());
33928
34007
  recordStep("assemble production runtime", stepStartedAt);
@@ -33931,7 +34010,7 @@ var prepare = async (configOrPath) => {
33931
34010
  }
33932
34011
  stepStartedAt = performance.now();
33933
34012
  const { imageOptimizer: imageOptimizer2 } = await Promise.resolve().then(() => (init_imageOptimizer(), exports_imageOptimizer));
33934
- const absolutejs = new Elysia9({ name: "absolutejs-runtime" }).use(absoluteRequestContext).use(mobileAssociationPlugin).use(mobileCompatibilityPlugin).use(assetCachePlugin).use(imageOptimizer2(config.images, buildDir)).use(staticFiles).use(generatedAssetsPlugin).use(createNotFoundPlugin());
34013
+ const absolutejs = new Elysia10({ name: "absolutejs-runtime" }).use(absoluteRequestContext).use(mobileAssociationPlugin).use(mobileCompatibilityPlugin).use(assetCachePlugin).use(imageOptimizer2(config.images, buildDir)).use(staticFiles).use(generatedAssetsPlugin).use(createNotFoundPlugin());
33935
34014
  await withOpenApi(absolutejs, config, process.cwd(), false);
33936
34015
  await withTelemetry(absolutejs, config, process.cwd());
33937
34016
  recordStep("assemble production runtime", stepStartedAt);
@@ -34266,6 +34345,7 @@ var networking = (app) => {
34266
34345
  startupBanner({
34267
34346
  buildDuration,
34268
34347
  host: host2,
34348
+ mobilePreviewUrl: env4.ABSOLUTE_MOBILE_PREVIEW === "1" ? `${protocol}://${host2 === "0.0.0.0" ? "localhost" : host2}:${port}/__absolute/mobile-preview` : undefined,
34269
34349
  networkUrl: hostFlag ? `${protocol}://${localIP}:${port}/` : undefined,
34270
34350
  port,
34271
34351
  protocol,
@@ -40783,5 +40863,5 @@ export {
40783
40863
  ANGULAR_INIT_TIMEOUT_MS
40784
40864
  };
40785
40865
 
40786
- //# debugId=BA41AA624E4BADC564756E2164756E21
40866
+ //# debugId=C7F91C3EB54CEFC064756E2164756E21
40787
40867
  //# sourceMappingURL=index.js.map