@absolutejs/absolute 0.20.0-beta.133 → 0.20.0-beta.135

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 (30) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/changelog.json +35 -0
  3. package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
  4. package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
  5. package/dist/build.js +25 -4
  6. package/dist/build.js.map +5 -5
  7. package/dist/cli/{compile-nf4qsqyd.js → compile-c7798g5y.js} +4 -3
  8. package/dist/cli/{config-3te1fbry.js → config-hy5dkexz.js} +1 -1
  9. package/dist/cli/{dev-j3dhb396.js → dev-cjq9rdeq.js} +2 -2
  10. package/dist/cli/{expoProject-zy02tbfg.js → expoProject-4x9q22xw.js} +1 -1
  11. package/dist/cli/{index-c3tqbpkq.js → index-djme2zmz.js} +2 -2
  12. package/dist/cli/{index-5sjk7daj.js → index-g407dg4f.js} +2 -2
  13. package/dist/cli/{index-hfvxsgf4.js → index-s9374tcg.js} +200 -65
  14. package/dist/cli/{index-rrxeqrbn.js → index-t7yf3vxs.js} +8 -0
  15. package/dist/cli/index.js +5 -5
  16. package/dist/cli/{mobile-m0cdh8cf.js → mobile-ma7sfttv.js} +4 -4
  17. package/dist/cli/{start-3z3gtgm0.js → start-7qsbfdxf.js} +4 -4
  18. package/dist/dev/serverBootstrap.js +1 -1
  19. package/dist/index.js +25 -4
  20. package/dist/index.js.map +5 -5
  21. package/dist/mobile/index.js +48 -16
  22. package/dist/mobile/index.js.map +8 -8
  23. package/dist/mobile/remoteMacAgentEntry.js +66 -66
  24. package/dist/mobile/shellBootstrap.js +23 -0
  25. package/dist/src/mobile/artifactStore.d.ts +4 -0
  26. package/dist/src/mobile/config.d.ts +4 -0
  27. package/dist/src/mobile/nativePackages.d.ts +2 -2
  28. package/dist/src/mobile/pushDeepLinks.d.ts +16 -0
  29. package/dist/types/build.d.ts +11 -0
  30. package/package.json +3 -3
@@ -13,11 +13,11 @@ import {
13
13
  createElysiaOpenApiTypeboxPlugin,
14
14
  createOptionalPeerPlugin,
15
15
  resolveServerBundleExternals
16
- } from "./index-hfvxsgf4.js";
16
+ } from "./index-s9374tcg.js";
17
17
  import {
18
18
  normalizeAbsoluteMobileConfig2
19
- } from "./index-rrxeqrbn.js";
20
- import"./index-5sjk7daj.js";
19
+ } from "./index-t7yf3vxs.js";
20
+ import"./index-g407dg4f.js";
21
21
  import {
22
22
  ABSOLUTE_NATIVE_AUTH_CLIENTS_ENV2,
23
23
  installAbsoluteMobileAuthEnvironment2
@@ -701,6 +701,7 @@ const MIME: Record<string, string> = {
701
701
  ".json": "application/json",
702
702
  ".xml": "application/xml",
703
703
  ".txt": "text/plain; charset=utf-8",
704
+ ".pdf": "application/pdf",
704
705
  ".png": "image/png",
705
706
  ".jpg": "image/jpeg",
706
707
  ".svg": "image/svg+xml",
@@ -1,7 +1,7 @@
1
1
  // @bun
2
2
  import {
3
3
  normalizeAbsoluteMobileConfig2
4
- } from "./index-rrxeqrbn.js";
4
+ } from "./index-t7yf3vxs.js";
5
5
  export {
6
6
  normalizeAbsoluteMobileConfig2 as normalizeAbsoluteMobileConfig
7
7
  };
@@ -1313,8 +1313,8 @@ var loadAbsoluteMobileDevModules = async () => {
1313
1313
  iosNativeWatcher,
1314
1314
  expoNativeWatcher
1315
1315
  ] = await Promise.all([
1316
- import("./config-3te1fbry.js"),
1317
- import("./expoProject-zy02tbfg.js"),
1316
+ import("./config-hy5dkexz.js"),
1317
+ import("./expoProject-4x9q22xw.js"),
1318
1318
  import("./expoDevController-s70fj7vf.js"),
1319
1319
  import("./nativeAuth-ysv0x5dy.js"),
1320
1320
  import("./androidEmulatorController-j73a1br6.js"),
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  writeAbsoluteExpoProject2,
4
4
  syncAbsoluteExpoWebAssets2
5
- } from "./index-5sjk7daj.js";
5
+ } from "./index-g407dg4f.js";
6
6
  import"./index-pch0v1z6.js";
7
7
  export {
8
8
  syncAbsoluteExpoWebAssets2 as syncAbsoluteExpoWebAssets,
@@ -20,10 +20,10 @@ import {
20
20
  createElysiaOpenApiTypeboxPlugin,
21
21
  createOptionalPeerPlugin,
22
22
  resolveServerBundleExternals
23
- } from "./index-hfvxsgf4.js";
23
+ } from "./index-s9374tcg.js";
24
24
  import {
25
25
  normalizeAbsoluteMobileConfig2
26
- } from "./index-rrxeqrbn.js";
26
+ } from "./index-t7yf3vxs.js";
27
27
  import {
28
28
  installAbsoluteMobileAuthEnvironment2
29
29
  } from "./index-pch0v1z6.js";
@@ -29,8 +29,8 @@ import { readFile } from "fs/promises";
29
29
  import { dirname, join, resolve } from "path";
30
30
  var ABSOLUTE_CAPACITOR_DEVICES_VERSION = "0.8.0";
31
31
  var ABSOLUTE_CAPACITOR_SYNC_VERSION = "0.9.3";
32
- var ABSOLUTE_DEVICES_VERSION = "0.7.0";
33
- var ABSOLUTE_EXPO_DEVICES_VERSION = "0.0.11";
32
+ var ABSOLUTE_DEVICES_VERSION = "0.7.1";
33
+ var ABSOLUTE_EXPO_DEVICES_VERSION = "0.0.12";
34
34
  var ABSOLUTE_NATIVE_EXACT_PACKAGES = new Set([
35
35
  "@absolutejs/devices",
36
36
  "@absolutejs/devices-capacitor",
@@ -1,13 +1,13 @@
1
1
  // @bun
2
2
  import {
3
3
  normalizeAbsoluteMobileConfig2
4
- } from "./index-rrxeqrbn.js";
4
+ } from "./index-t7yf3vxs.js";
5
5
  import {
6
6
  assertAbsoluteDeviceCapabilityPackages,
7
7
  resolveAbsoluteMobileUpdateRuntime,
8
8
  writeAbsoluteExpoProject2,
9
9
  syncAbsoluteExpoWebAssets2
10
- } from "./index-5sjk7daj.js";
10
+ } from "./index-g407dg4f.js";
11
11
  import {
12
12
  toPascal
13
13
  } from "./index-92g14j47.js";
@@ -294,38 +294,9 @@ var createBunStringRawUnicodePlugin = () => ({
294
294
  import { readFile as readFile4 } from "fs/promises";
295
295
  import { join as join4, resolve as resolve3 } from "path";
296
296
 
297
- // src/mobile/buildRelease.ts
297
+ // src/mobile/artifactStore.ts
298
298
  import { createHash as createHash2 } from "crypto";
299
- import { mkdir, readFile, writeFile } from "fs/promises";
300
- import { basename as basename2, dirname, extname as extname2, join, relative, resolve } from "path";
301
-
302
- // src/mobile/buildMetadata.ts
303
- var ABSOLUTE_MOBILE_ROUTE_DETAIL = "x-absolute-mobile";
304
- var frameworks = new Set([
305
- "angular",
306
- "ember",
307
- "html",
308
- "htmx",
309
- "react",
310
- "svelte",
311
- "vue"
312
- ]);
313
- var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
314
- var isPageFramework = (value) => typeof value === "string" && frameworks.has(value);
315
- var parseAbsoluteMobileBuildPageMetadata = (value) => {
316
- if (!isRecord(value))
317
- return;
318
- if (typeof value.bundleKey !== "string" || typeof value.contract !== "string" || !isPageFramework(value.framework) || typeof value.pageId !== "string" || typeof value.propsSchemaHash !== "string") {
319
- return;
320
- }
321
- return {
322
- bundleKey: value.bundleKey,
323
- contract: value.contract,
324
- framework: value.framework,
325
- pageId: value.pageId,
326
- propsSchemaHash: value.propsSchemaHash
327
- };
328
- };
299
+ import { pathToFileURL } from "url";
329
300
 
330
301
  // src/mobile/releaseArtifact.ts
331
302
  import { createHash } from "crypto";
@@ -335,7 +306,7 @@ var SHA_256 = "sha256";
335
306
  var RELEASE_ID_PREFIX = "amc_";
336
307
  var MODULE_SEGMENT_PARENT = "..";
337
308
  var EXPORT_NAME_PATTERN = /^[A-Z_a-z]\w*$/;
338
- var frameworks2 = new Set([
309
+ var frameworks = new Set([
339
310
  "angular",
340
311
  "ember",
341
312
  "html",
@@ -393,7 +364,7 @@ var requireNonEmpty = (value, field) => {
393
364
  }
394
365
  return value;
395
366
  };
396
- var isPageFramework2 = (value) => typeof value === "string" && frameworks2.has(value);
367
+ var isPageFramework = (value) => typeof value === "string" && frameworks.has(value);
397
368
  var readString = (value, field) => {
398
369
  if (typeof value !== "string") {
399
370
  throw new TypeError(`${field} must be a string.`);
@@ -401,7 +372,7 @@ var readString = (value, field) => {
401
372
  return value;
402
373
  };
403
374
  var parseCompatibilityPage = (value) => {
404
- if (!isCanonicalRecord(value) || !isPageFramework2(value.framework)) {
375
+ if (!isCanonicalRecord(value) || !isPageFramework(value.framework)) {
405
376
  throw new TypeError("Compatibility artifact contains an invalid page.");
406
377
  }
407
378
  const styleBundleHash = typeof value.styleBundleHash === "string" ? value.styleBundleHash : undefined;
@@ -552,8 +523,183 @@ var retainAbsoluteMobileCompatibilityArtifacts = (artifacts) => {
552
523
  return [...artifacts].sort((left, right) => right.generation - left.generation).slice(0, ABSOLUTE_MOBILE_RETAINED_GENERATIONS);
553
524
  };
554
525
 
526
+ // src/mobile/artifactStore.ts
527
+ var DEFAULT_MAX_PRODUCER_BYTES = 134217728;
528
+ var SHA_2562 = "sha256";
529
+ var ARTIFACT_FILE = "artifact.json";
530
+ var RELEASE_ID_PATTERN = /^amc_[a-f0-9]{64}$/;
531
+ var DEFAULT_BLOB_PREFIX = "absolutejs/mobile-compatibility";
532
+ var hashBlob = async (blob) => {
533
+ const bytes = new Uint8Array(await blob.arrayBuffer());
534
+ return createHash2(SHA_2562).update(bytes).digest("hex");
535
+ };
536
+ var blobFromBytes = (bytes) => {
537
+ const buffer = new ArrayBuffer(bytes.byteLength);
538
+ new Uint8Array(buffer).set(bytes);
539
+ return new Blob([buffer]);
540
+ };
541
+ var appDirectoryName = (appId) => createHash2(SHA_2562).update(appId).digest("hex");
542
+ var requireReleaseId = (releaseId) => {
543
+ if (!RELEASE_ID_PATTERN.test(releaseId)) {
544
+ throw new TypeError("Invalid mobile compatibility release id.");
545
+ }
546
+ return releaseId;
547
+ };
548
+ var validateStoredIdentity = (artifact, appId, releaseId) => {
549
+ if (artifact.appId !== appId || artifact.releaseId !== releaseId) {
550
+ throw new TypeError("Stored mobile compatibility identity does not match.");
551
+ }
552
+ return artifact;
553
+ };
554
+ var listBlobKeys = async (store, prefix, cursor, keys = []) => {
555
+ const result = await store.list({ cursor, prefix });
556
+ const collected = [...keys, ...result.objects.map(({ key }) => key)];
557
+ if (!result.truncated)
558
+ return collected;
559
+ if (!result.cursor) {
560
+ throw new TypeError("Truncated blob listing did not provide a cursor.");
561
+ }
562
+ return listBlobKeys(store, prefix, result.cursor, collected);
563
+ };
564
+ var normalizeBlobPrefix = (prefix) => {
565
+ const normalized = prefix.replace(/^\/+|\/+$/g, "");
566
+ if (!normalized || normalized.split("/").includes("..")) {
567
+ throw new TypeError("Mobile compatibility blob prefix is invalid.");
568
+ }
569
+ return normalized;
570
+ };
571
+ var carryForwardAbsoluteMobileCompatibilityReleases = async (input) => {
572
+ await verifyAbsoluteMobileCompatibilityProducer(input.current);
573
+ await input.store.write(input.current);
574
+ const available = await input.store.list(input.current.artifact.appId);
575
+ const retained = retainAbsoluteMobileCompatibilityArtifacts(available);
576
+ if (retained[0]?.releaseId !== input.current.artifact.releaseId) {
577
+ throw new TypeError("Current mobile release generation must be newer than stored history.");
578
+ }
579
+ const releases = await Promise.all(retained.map(({ releaseId }) => input.store.read(input.current.artifact.appId, releaseId)));
580
+ return Promise.all(releases.map((release) => {
581
+ if (!release) {
582
+ throw new TypeError("Compatibility store listed a release it could not read.");
583
+ }
584
+ return verifyAbsoluteMobileCompatibilityProducer(release);
585
+ }));
586
+ };
587
+ var createAbsoluteMobileBlobArtifactStore = (options) => {
588
+ const prefix = normalizeBlobPrefix(options.prefix ?? DEFAULT_BLOB_PREFIX);
589
+ const maxProducerBytes = options.maxProducerBytes ?? DEFAULT_MAX_PRODUCER_BYTES;
590
+ const appPrefix = (appId) => `${prefix}/${appDirectoryName(appId)}/releases`;
591
+ const releasePrefix = (appId, releaseId) => `${appPrefix(appId)}/${requireReleaseId(releaseId)}`;
592
+ const artifactKey = (appId, releaseId) => `${releasePrefix(appId, releaseId)}/${ARTIFACT_FILE}`;
593
+ const producerKey = (artifact) => `${releasePrefix(artifact.appId, artifact.releaseId)}/${artifact.producer.module}`;
594
+ const readArtifact = async (appId, releaseId) => {
595
+ const bytes = await options.store.get(artifactKey(appId, releaseId));
596
+ if (!bytes)
597
+ return null;
598
+ const parsed = JSON.parse(new TextDecoder().decode(bytes));
599
+ return validateStoredIdentity(parseAbsoluteMobileCompatibilityArtifact(parsed), appId, releaseId);
600
+ };
601
+ return {
602
+ delete: async (appId, releaseId) => {
603
+ const artifact = await readArtifact(appId, releaseId);
604
+ if (artifact)
605
+ await options.store.delete(producerKey(artifact));
606
+ await options.store.delete(artifactKey(appId, releaseId));
607
+ },
608
+ list: async (appId) => {
609
+ const releaseRoot = `${appPrefix(appId)}/`;
610
+ const keys = await listBlobKeys(options.store, releaseRoot);
611
+ const releaseIds = keys.filter((key) => key.endsWith(`/${ARTIFACT_FILE}`)).map((key) => key.slice(releaseRoot.length).split("/")[0]).filter((releaseId) => typeof releaseId === "string" && RELEASE_ID_PATTERN.test(releaseId));
612
+ const artifacts = await Promise.all([...new Set(releaseIds)].map((releaseId) => readArtifact(appId, releaseId)));
613
+ return artifacts.filter((artifact) => artifact !== null).sort((left, right) => right.generation - left.generation);
614
+ },
615
+ read: async (appId, releaseId) => {
616
+ const artifact = await readArtifact(appId, releaseId);
617
+ if (!artifact)
618
+ return null;
619
+ const bytes = await options.store.get(producerKey(artifact));
620
+ if (!bytes) {
621
+ throw new TypeError("Mobile compatibility artifact is missing its producer.");
622
+ }
623
+ return { artifact, producer: blobFromBytes(bytes) };
624
+ },
625
+ write: async (release) => {
626
+ const artifact = parseAbsoluteMobileCompatibilityArtifact(release.artifact);
627
+ const validated = await verifyAbsoluteMobileCompatibilityProducer({ artifact, producer: release.producer }, maxProducerBytes);
628
+ await options.store.put(producerKey(validated.artifact), validated.producer.stream(), {
629
+ contentType: "text/javascript; charset=utf-8",
630
+ maxBytes: maxProducerBytes,
631
+ metadata: {
632
+ appId: validated.artifact.appId,
633
+ releaseId: validated.artifact.releaseId,
634
+ sha256: validated.artifact.producer.bundleHash
635
+ }
636
+ });
637
+ await options.store.put(artifactKey(validated.artifact.appId, validated.artifact.releaseId), `${JSON.stringify(validated.artifact, null, "\t")}
638
+ `, { contentType: "application/json" });
639
+ }
640
+ };
641
+ };
642
+ var isFunctionRecord = (value, keys) => typeof value === "object" && value !== null && keys.every((key) => typeof Reflect.get(value, key) === "function");
643
+ var isArtifactStore = (value) => isFunctionRecord(value, ["delete", "list", "read", "write"]);
644
+ var isBlobStore = (value) => isFunctionRecord(value, ["delete", "get", "list", "put"]);
645
+ var loadAbsoluteMobileCompatibilityStore = async (options) => {
646
+ const loaded = await import(pathToFileURL(options.modulePath).href);
647
+ const exported = typeof loaded === "object" && loaded !== null ? Reflect.get(loaded, "default") ?? Reflect.get(loaded, "store") : undefined;
648
+ if (isArtifactStore(exported))
649
+ return exported;
650
+ if (isBlobStore(exported))
651
+ return createAbsoluteMobileBlobArtifactStore({
652
+ ...options.prefix === undefined ? {} : { prefix: options.prefix },
653
+ store: exported
654
+ });
655
+ throw new TypeError(`mobile.compatibility.store (${options.modulePath}) must export a blob store with get, put, list and delete.`);
656
+ };
657
+ var verifyAbsoluteMobileCompatibilityProducer = async (release, maxProducerBytes = DEFAULT_MAX_PRODUCER_BYTES) => {
658
+ const { artifact, producer } = release;
659
+ if (producer.size !== artifact.producer.bytes || producer.size > maxProducerBytes) {
660
+ throw new TypeError("Mobile compatibility producer size does not match its artifact.");
661
+ }
662
+ if (await hashBlob(producer) !== artifact.producer.bundleHash) {
663
+ throw new TypeError("Mobile compatibility producer hash does not match its artifact.");
664
+ }
665
+ return release;
666
+ };
667
+
668
+ // src/mobile/buildRelease.ts
669
+ import { createHash as createHash3 } from "crypto";
670
+ import { mkdir, readFile, writeFile } from "fs/promises";
671
+ import { basename as basename2, dirname, extname as extname2, join, relative, resolve } from "path";
672
+
673
+ // src/mobile/buildMetadata.ts
674
+ var ABSOLUTE_MOBILE_ROUTE_DETAIL = "x-absolute-mobile";
675
+ var frameworks2 = new Set([
676
+ "angular",
677
+ "ember",
678
+ "html",
679
+ "htmx",
680
+ "react",
681
+ "svelte",
682
+ "vue"
683
+ ]);
684
+ var isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
685
+ var isPageFramework2 = (value) => typeof value === "string" && frameworks2.has(value);
686
+ var parseAbsoluteMobileBuildPageMetadata = (value) => {
687
+ if (!isRecord(value))
688
+ return;
689
+ if (typeof value.bundleKey !== "string" || typeof value.contract !== "string" || !isPageFramework2(value.framework) || typeof value.pageId !== "string" || typeof value.propsSchemaHash !== "string") {
690
+ return;
691
+ }
692
+ return {
693
+ bundleKey: value.bundleKey,
694
+ contract: value.contract,
695
+ framework: value.framework,
696
+ pageId: value.pageId,
697
+ propsSchemaHash: value.propsSchemaHash
698
+ };
699
+ };
700
+
555
701
  // src/mobile/buildRelease.ts
556
- var sha256 = (bytes) => createHash2("sha256").update(bytes).digest("hex");
702
+ var sha256 = (bytes) => createHash3("sha256").update(bytes).digest("hex");
557
703
  var STATIC_SCRIPT_PATTERN = /(<script\b[^>]*?\bsrc\s*=\s*["'])(\/[^"']+\.(?:js|ts))(["'][^>]*>)/giu;
558
704
  var rewriteStaticScriptPaths = (source, manifest) => source.replace(STATIC_SCRIPT_PATTERN, (match, prefix, path, suffix) => {
559
705
  if (path.endsWith("/htmx.min.js"))
@@ -1189,31 +1335,10 @@ import {
1189
1335
  writeFile as writeFile3
1190
1336
  } from "fs/promises";
1191
1337
  import { dirname as dirname3, join as join3, resolve as resolvePath } from "path";
1192
-
1193
- // src/mobile/artifactStore.ts
1194
- import { createHash as createHash3 } from "crypto";
1195
- var DEFAULT_MAX_PRODUCER_BYTES = 134217728;
1196
- var SHA_2562 = "sha256";
1197
- var hashBlob = async (blob) => {
1198
- const bytes = new Uint8Array(await blob.arrayBuffer());
1199
- return createHash3(SHA_2562).update(bytes).digest("hex");
1200
- };
1201
- var verifyAbsoluteMobileCompatibilityProducer = async (release, maxProducerBytes = DEFAULT_MAX_PRODUCER_BYTES) => {
1202
- const { artifact, producer } = release;
1203
- if (producer.size !== artifact.producer.bytes || producer.size > maxProducerBytes) {
1204
- throw new TypeError("Mobile compatibility producer size does not match its artifact.");
1205
- }
1206
- if (await hashBlob(producer) !== artifact.producer.bundleHash) {
1207
- throw new TypeError("Mobile compatibility producer hash does not match its artifact.");
1208
- }
1209
- return release;
1210
- };
1211
-
1212
- // src/mobile/materializedBundle.ts
1213
1338
  var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1;
1214
1339
  var CURRENT_BUNDLE_FILE = "current.json";
1215
1340
  var BUNDLES_DIRECTORY = "bundles";
1216
- var ARTIFACT_FILE = "artifact.json";
1341
+ var ARTIFACT_FILE2 = "artifact.json";
1217
1342
  var BUNDLE_ID_PATTERN = /^amb_[a-f0-9]{64}$/;
1218
1343
  var isRecord2 = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
1219
1344
  var errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code;
@@ -1252,7 +1377,7 @@ var writeRelease = async (root, release) => {
1252
1377
  const producerPath = join3(directory, release.artifact.producer.module);
1253
1378
  await mkdir3(dirname3(producerPath), { recursive: true });
1254
1379
  await Promise.all([
1255
- writeFile3(join3(directory, ARTIFACT_FILE), `${JSON.stringify(release.artifact, null, "\t")}
1380
+ writeFile3(join3(directory, ARTIFACT_FILE2), `${JSON.stringify(release.artifact, null, "\t")}
1256
1381
  `),
1257
1382
  writeFile3(producerPath, new Uint8Array(await release.producer.arrayBuffer()))
1258
1383
  ]);
@@ -1396,12 +1521,19 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
1396
1521
  restoreEnvironmentVariable("ABSOLUTE_COMPILED_RUNTIME", previousCompiledRuntime);
1397
1522
  restoreEnvironmentVariable("ABSOLUTE_CONFIG", previousConfigPath);
1398
1523
  }
1524
+ const compatibilityStore = mobile.compatibilityStore ? await loadAbsoluteMobileCompatibilityStore(mobile.compatibilityStore) : undefined;
1525
+ const storedArtifacts = compatibilityStore ? await compatibilityStore.list(mobile.appId) : [];
1526
+ const storedReleaseIds = new Set(storedArtifacts.map(({ releaseId }) => releaseId));
1527
+ const localOnly = previous.filter(({ artifact }) => !storedReleaseIds.has(artifact.releaseId));
1399
1528
  const current = await buildAbsoluteMobileCompatibilityRelease({
1400
1529
  app: loaded.app,
1401
1530
  appId: mobile.appId,
1402
1531
  buildDirectory,
1403
1532
  manifest,
1404
- previousArtifacts: previous.map(({ artifact }) => artifact),
1533
+ previousArtifacts: [
1534
+ ...storedArtifacts,
1535
+ ...localOnly.map(({ artifact }) => artifact)
1536
+ ],
1405
1537
  producerExport: loaded.exportName,
1406
1538
  producerPath: resolve3(options.producerPath),
1407
1539
  runtime: String(ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION)
@@ -1424,10 +1556,13 @@ var finalizeAbsoluteMobileCompatibilityBuild = async (options) => {
1424
1556
  if (auth && !loaded.app.routes.some((route) => route.path === "/.well-known/openid-configuration")) {
1425
1557
  throw new TypeError("@absolutejs/auth is installed, but its OIDC provider is not mounted. Native authentication requires the auth oidc configuration so AbsoluteJS can provision a public PKCE client.");
1426
1558
  }
1427
- const releasesById = new Map([current, ...previous].map((release) => [
1428
- release.artifact.releaseId,
1429
- release
1430
- ]));
1559
+ if (compatibilityStore)
1560
+ await Promise.all(localOnly.map((release) => compatibilityStore.write(release)));
1561
+ const candidates = compatibilityStore ? await carryForwardAbsoluteMobileCompatibilityReleases({
1562
+ current,
1563
+ store: compatibilityStore
1564
+ }) : [current, ...previous];
1565
+ const releasesById = new Map(candidates.map((release) => [release.artifact.releaseId, release]));
1431
1566
  const retained = retainAbsoluteMobileCompatibilityArtifacts([...releasesById.values()].map(({ artifact }) => artifact));
1432
1567
  await materializeAbsoluteMobileCompatibilityBundle({
1433
1568
  currentReleaseId: current.artifact.releaseId,
@@ -506,6 +506,14 @@ var normalizeAbsoluteMobileConfig2 = (config, projectRoot) => {
506
506
  appName: requireText(config.appName, "mobile.appName"),
507
507
  ...branding ? { branding } : {},
508
508
  bundleDirectory: resolveProjectPath(projectRoot, config.bundleDirectory ?? ".absolutejs/mobile/web", "mobile.bundleDirectory"),
509
+ ...config.compatibility ? {
510
+ compatibilityStore: {
511
+ modulePath: resolveProjectPath(projectRoot, requireText(config.compatibility.store, "mobile.compatibility.store"), "mobile.compatibility.store"),
512
+ ...config.compatibility.prefix === undefined ? {} : {
513
+ prefix: requireText(config.compatibility.prefix, "mobile.compatibility.prefix")
514
+ }
515
+ }
516
+ } : {},
509
517
  deepLinkHosts: normalizeHosts(config.deepLinks?.hosts, productionOrigin),
510
518
  deepLinkScheme,
511
519
  engine: config.engine ?? "capacitor",
package/dist/cli/index.js CHANGED
@@ -54,7 +54,7 @@ if (command === "dev") {
54
54
  }
55
55
  const positionalArgs = stripNamedArgs("--config", "--android-device", "--ios-device").filter((arg) => arg !== "--no-mobile" && arg !== "--eager");
56
56
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
57
- const { dev } = await import("./dev-j3dhb396.js");
57
+ const { dev } = await import("./dev-cjq9rdeq.js");
58
58
  await dev(serverEntry, configPath, {
59
59
  androidDevice,
60
60
  eager: args.includes("--eager"),
@@ -70,7 +70,7 @@ if (command === "dev") {
70
70
  const configPath = parseNamedArg("--config");
71
71
  const positionalArgs = stripNamedArgs("--outdir", "--config").filter((arg) => arg !== "--prebuilt");
72
72
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
73
- const { start } = await import("./start-3z3gtgm0.js");
73
+ const { start } = await import("./start-7qsbfdxf.js");
74
74
  await start(serverEntry, outdir, configPath, {
75
75
  prebuilt: args.includes("--prebuilt")
76
76
  });
@@ -80,7 +80,7 @@ if (command === "dev") {
80
80
  const configPath = parseNamedArg("--config");
81
81
  const positionalArgs = stripNamedArgs("--outdir", "--config");
82
82
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
83
- const { start } = await import("./start-3z3gtgm0.js");
83
+ const { start } = await import("./start-7qsbfdxf.js");
84
84
  await start(serverEntry, outdir, configPath, { prepareOnly: true });
85
85
  } else if (command === "build") {
86
86
  sendTelemetryEvent("cli:command", { command });
@@ -201,13 +201,13 @@ if (command === "dev") {
201
201
  const configPath = parseNamedArg("--config");
202
202
  const positionalArgs = stripNamedArgs("--outdir", "--outfile", "--config");
203
203
  const serverEntry = positionalArgs[0] ?? DEFAULT_SERVER_ENTRY;
204
- const { compile } = await import("./compile-nf4qsqyd.js");
204
+ const { compile } = await import("./compile-c7798g5y.js");
205
205
  await compile(serverEntry, outdir, outfile, configPath);
206
206
  } else if (command === "mobile") {
207
207
  sendTelemetryEvent("cli:command", {
208
208
  command: `mobile:${workspaceCommand ?? "unknown"}`
209
209
  });
210
- const { runMobile } = await import("./mobile-m0cdh8cf.js");
210
+ const { runMobile } = await import("./mobile-ma7sfttv.js");
211
211
  try {
212
212
  await runMobile(args);
213
213
  } catch (error) {
@@ -22,14 +22,14 @@ import {
22
22
  renderAbsoluteMobileBrandingPreview,
23
23
  writeAbsoluteExpoProject2,
24
24
  syncAbsoluteExpoWebAssets2
25
- } from "./index-5sjk7daj.js";
25
+ } from "./index-g407dg4f.js";
26
26
  import {
27
27
  projectUsesAbsoluteAuth2,
28
28
  projectUsesAbsoluteSync2
29
29
  } from "./index-pch0v1z6.js";
30
30
  import {
31
31
  normalizeAbsoluteMobileConfig2
32
- } from "./index-rrxeqrbn.js";
32
+ } from "./index-t7yf3vxs.js";
33
33
  import"./index-hxqprc80.js";
34
34
  import {
35
35
  ABSOLUTE_ANDROID_AVD_NAME2,
@@ -58,7 +58,7 @@ import {
58
58
  resolveAbsoluteMobileRoute,
59
59
  ABSOLUTE_MOBILE_PAGE_PROTOCOL_VERSION,
60
60
  ABSOLUTE_MOBILE_CLIENT_MANIFEST_FORMAT
61
- } from "./index-hfvxsgf4.js";
61
+ } from "./index-s9374tcg.js";
62
62
  import {
63
63
  buildAbsoluteExpoAndroidWslBundle2
64
64
  } from "./index-jcjwsdqt.js";
@@ -75,7 +75,7 @@ import {
75
75
  import"./index-e6ysp900.js";
76
76
  import {
77
77
  start2
78
- } from "./index-c3tqbpkq.js";
78
+ } from "./index-djme2zmz.js";
79
79
  import {
80
80
  captureAbsoluteRemoteMacCommand2,
81
81
  getAbsoluteRemoteMacProfile2,
@@ -1,15 +1,15 @@
1
1
  // @bun
2
2
  import {
3
3
  start2
4
- } from "./index-c3tqbpkq.js";
5
- import"./index-hfvxsgf4.js";
4
+ } from "./index-djme2zmz.js";
5
+ import"./index-s9374tcg.js";
6
6
  import"./index-e6ysp900.js";
7
7
  import"./index-71gchbzt.js";
8
8
  import"./index-h7qhz02e.js";
9
9
  import"./index-qyxd5n9a.js";
10
10
  import"./index-43a1vvb7.js";
11
- import"./index-rrxeqrbn.js";
12
- import"./index-5sjk7daj.js";
11
+ import"./index-t7yf3vxs.js";
12
+ import"./index-g407dg4f.js";
13
13
  import"./index-pch0v1z6.js";
14
14
  import"./index-k4t9k1xk.js";
15
15
  import"./index-92hmw204.js";
@@ -3810,7 +3810,7 @@ var require_source_map_support = __commonJS(function(exports, module) {
3810
3810
 
3811
3811
  // node_modules/typescript/lib/typescript.js
3812
3812
  var require_typescript = __commonJS(function(exports, module) {
3813
- var __dirname = "/tmp/claude-1000/-home-alexkahn-abs-PAAS/9b0057a2-5737-48f9-9dbe-dcb83ea02b04/scratchpad/abs-release/node_modules/typescript/lib", __filename = "/tmp/claude-1000/-home-alexkahn-abs-PAAS/9b0057a2-5737-48f9-9dbe-dcb83ea02b04/scratchpad/abs-release/node_modules/typescript/lib/typescript.js";
3813
+ var __dirname = "/home/runner/work/absolutejs/absolutejs/node_modules/typescript/lib", __filename = "/home/runner/work/absolutejs/absolutejs/node_modules/typescript/lib/typescript.js";
3814
3814
  /*! *****************************************************************************
3815
3815
  Copyright (c) Microsoft Corporation. All rights reserved.
3816
3816
  Licensed under the Apache License, Version 2.0 (the "License"); you may not use
package/dist/index.js CHANGED
@@ -11130,6 +11130,14 @@ var APP_ID_PATTERN, SCHEME_PATTERN, APPLE_APP_ID_PREFIX_PATTERN, CERTIFICATE_FIN
11130
11130
  appName: requireText(config.appName, "mobile.appName"),
11131
11131
  ...branding ? { branding } : {},
11132
11132
  bundleDirectory: resolveProjectPath(projectRoot, config.bundleDirectory ?? ".absolutejs/mobile/web", "mobile.bundleDirectory"),
11133
+ ...config.compatibility ? {
11134
+ compatibilityStore: {
11135
+ modulePath: resolveProjectPath(projectRoot, requireText(config.compatibility.store, "mobile.compatibility.store"), "mobile.compatibility.store"),
11136
+ ...config.compatibility.prefix === undefined ? {} : {
11137
+ prefix: requireText(config.compatibility.prefix, "mobile.compatibility.prefix")
11138
+ }
11139
+ }
11140
+ } : {},
11133
11141
  deepLinkHosts: normalizeHosts(config.deepLinks?.hosts, productionOrigin),
11134
11142
  deepLinkScheme,
11135
11143
  engine: config.engine ?? "capacitor",
@@ -24667,7 +24675,7 @@ var init_compileAngular = __esm(() => {
24667
24675
 
24668
24676
  // node_modules/content-tag/pkg/node/content_tag.cjs
24669
24677
  var require_content_tag = __commonJS(function(exports, module) {
24670
- var __dirname = "/tmp/claude-1000/-home-alexkahn-abs-PAAS/9b0057a2-5737-48f9-9dbe-dcb83ea02b04/scratchpad/abs-release/node_modules/content-tag/pkg/node";
24678
+ var __dirname = "/home/runner/work/absolutejs/absolutejs/node_modules/content-tag/pkg/node";
24671
24679
  var imports = {};
24672
24680
  imports["__wbindgen_placeholder__"] = exports;
24673
24681
  var wasm;
@@ -28794,6 +28802,7 @@ var init_assetStore = __esm(() => {
28794
28802
  ".map": "application/json",
28795
28803
  ".mjs": "application/javascript",
28796
28804
  ".otf": "font/otf",
28805
+ ".pdf": "application/pdf",
28797
28806
  ".png": "image/png",
28798
28807
  ".svg": "image/svg+xml",
28799
28808
  ".ttf": "font/ttf",
@@ -36499,6 +36508,7 @@ import {
36499
36508
  writeFile as writeFile12
36500
36509
  } from "fs/promises";
36501
36510
  import { join as join62, resolve as resolvePath2 } from "path";
36511
+ import { pathToFileURL as pathToFileURL4 } from "url";
36502
36512
  var DEFAULT_MAX_PRODUCER_BYTES = 134217728, SHA_2562 = "sha256", ARTIFACT_FILE = "artifact.json", RELEASE_ID_PATTERN, DEFAULT_BLOB_PREFIX = "absolutejs/mobile-compatibility", hashBlob = async (blob) => {
36503
36513
  const bytes = new Uint8Array(await blob.arrayBuffer());
36504
36514
  return createHash9(SHA_2562).update(bytes).digest("hex");
@@ -36677,6 +36687,17 @@ var DEFAULT_MAX_PRODUCER_BYTES = 134217728, SHA_2562 = "sha256", ARTIFACT_FILE =
36677
36687
  }
36678
36688
  }
36679
36689
  };
36690
+ }, isFunctionRecord = (value, keys) => typeof value === "object" && value !== null && keys.every((key) => typeof Reflect.get(value, key) === "function"), isArtifactStore = (value) => isFunctionRecord(value, ["delete", "list", "read", "write"]), isBlobStore = (value) => isFunctionRecord(value, ["delete", "get", "list", "put"]), loadAbsoluteMobileCompatibilityStore = async (options) => {
36691
+ const loaded = await import(pathToFileURL4(options.modulePath).href);
36692
+ const exported = typeof loaded === "object" && loaded !== null ? Reflect.get(loaded, "default") ?? Reflect.get(loaded, "store") : undefined;
36693
+ if (isArtifactStore(exported))
36694
+ return exported;
36695
+ if (isBlobStore(exported))
36696
+ return createAbsoluteMobileBlobArtifactStore({
36697
+ ...options.prefix === undefined ? {} : { prefix: options.prefix },
36698
+ store: exported
36699
+ });
36700
+ throw new TypeError(`mobile.compatibility.store (${options.modulePath}) must export a blob store with get, put, list and delete.`);
36680
36701
  }, verifyAbsoluteMobileCompatibilityProducer = async (release, maxProducerBytes = DEFAULT_MAX_PRODUCER_BYTES) => {
36681
36702
  const { artifact, producer } = release;
36682
36703
  if (producer.size !== artifact.producer.bytes || producer.size > maxProducerBytes) {
@@ -36711,7 +36732,7 @@ import {
36711
36732
  writeFile as writeFile13
36712
36733
  } from "fs/promises";
36713
36734
  import { dirname as dirname39, join as join63, resolve as resolvePath3 } from "path";
36714
- import { pathToFileURL as pathToFileURL4 } from "url";
36735
+ import { pathToFileURL as pathToFileURL5 } from "url";
36715
36736
  var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "current.json", BUNDLES_DIRECTORY = "bundles", ARTIFACT_FILE2 = "artifact.json", BUNDLE_ID_PATTERN, isRecord10 = (value) => typeof value === "object" && value !== null && !Array.isArray(value), errorHasCode2 = (error, code) => typeof error === "object" && error !== null && Reflect.get(error, "code") === code, bundleIdFor = (currentReleaseId, releases) => {
36716
36737
  const identity = JSON.stringify({
36717
36738
  currentReleaseId,
@@ -36770,7 +36791,7 @@ var ABSOLUTE_MOBILE_MATERIALIZED_BUNDLE_FORMAT = 1, CURRENT_BUNDLE_FILE = "curre
36770
36791
  throw error;
36771
36792
  }
36772
36793
  return destination;
36773
- }, readCompatibilityModule = (modulePath) => import(pathToFileURL4(modulePath).href), resolveProducerHandler = (loaded, exportName) => {
36794
+ }, readCompatibilityModule = (modulePath) => import(pathToFileURL5(modulePath).href), resolveProducerHandler = (loaded, exportName) => {
36774
36795
  const value = loaded[exportName];
36775
36796
  if (!isRecord10(value) || typeof value.handle !== "function") {
36776
36797
  throw new TypeError(`Compatibility producer export ${exportName} must expose handle(request).`);
@@ -43800,5 +43821,5 @@ export {
43800
43821
  wrapPageHandlerWithStreamingSlots
43801
43822
  };
43802
43823
 
43803
- //# debugId=6F1E1785E74A52C164756E2164756E21
43824
+ //# debugId=CF052FF52214E05F64756E2164756E21
43804
43825
  //# sourceMappingURL=index.js.map