@absolutejs/absolute 0.20.0-beta.83 → 0.20.0-beta.84
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.
- package/dist/angular/components/core/streamingSlotRegistrar.js +1 -1
- package/dist/angular/components/core/streamingSlotRegistry.js +2 -2
- package/dist/build.js +66 -11
- package/dist/build.js.map +3 -3
- package/dist/cli/index.js +1 -1
- package/dist/cli/{mobile-9dx39bd3.js → mobile-pdck6a35.js} +17 -3
- package/dist/index.js +66 -11
- package/dist/index.js.map +3 -3
- package/dist/mobile/index.js +107 -21
- package/dist/mobile/index.js.map +5 -5
- package/dist/mobile/shellUpdate.js +46 -8
- package/dist/src/mobile/updateClient.d.ts +11 -0
- package/dist/src/mobile/updatePublisher.d.ts +4 -0
- package/package.json +2 -2
package/dist/mobile/index.js
CHANGED
|
@@ -20137,6 +20137,7 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20137
20137
|
const releaseRoot = (manifest) => `${root(manifest.appId)}/releases/${manifest.releaseId}`;
|
|
20138
20138
|
const manifestKey = (manifest) => `${releaseRoot(manifest)}/update.json`;
|
|
20139
20139
|
const fileKey = (manifest, file) => `${releaseRoot(manifest)}/files/${file.path}`;
|
|
20140
|
+
const contentBlobKey = (appId, sha2563) => `${root(appId)}/blobs/${sha2563}`;
|
|
20140
20141
|
const tombstoneKey = (appId, releaseId) => `${root(appId)}/gc/${releaseId}.json`;
|
|
20141
20142
|
const channelKey = (appId, channel) => {
|
|
20142
20143
|
if (!APP_ID.test(appId) || !NAME.test(channel))
|
|
@@ -20283,9 +20284,19 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20283
20284
|
const releasePrefix = `${appRoot}releases/`;
|
|
20284
20285
|
const channelPrefix = `${appRoot}channels/`;
|
|
20285
20286
|
const markerPrefix = `${appRoot}gc/`;
|
|
20287
|
+
const blobPrefix = `${appRoot}blobs/`;
|
|
20286
20288
|
const objectKeysByRelease = new Map;
|
|
20287
20289
|
const objectBytesByRelease = new Map;
|
|
20290
|
+
const objectKeysByDigest = new Map;
|
|
20291
|
+
const objectBytesByDigest = new Map;
|
|
20288
20292
|
for (const blobObject of objects) {
|
|
20293
|
+
if (blobObject.key.startsWith(blobPrefix)) {
|
|
20294
|
+
const sha2563 = blobObject.key.slice(blobPrefix.length);
|
|
20295
|
+
if (HASH.test(sha2563)) {
|
|
20296
|
+
objectKeysByDigest.set(sha2563, blobObject.key);
|
|
20297
|
+
objectBytesByDigest.set(sha2563, blobObject.size);
|
|
20298
|
+
}
|
|
20299
|
+
}
|
|
20289
20300
|
if (!blobObject.key.startsWith(releasePrefix))
|
|
20290
20301
|
continue;
|
|
20291
20302
|
const suffix = blobObject.key.slice(releasePrefix.length);
|
|
@@ -20364,20 +20375,28 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20364
20375
|
releaseId: manifest.releaseId
|
|
20365
20376
|
};
|
|
20366
20377
|
}).toSorted((left, right) => right.createdAt.localeCompare(left.createdAt));
|
|
20378
|
+
const protectedReleaseIds = new Set(releases.filter((release) => release.protectedBy.length > 0).map((release) => release.releaseId));
|
|
20379
|
+
const protectedDigests = new Set(manifests.filter((manifest) => protectedReleaseIds.has(manifest.releaseId)).flatMap((manifest) => manifest.files.map((file) => file.sha256)));
|
|
20380
|
+
const reclaimableContentBytes = [...objectBytesByDigest].filter(([sha2563]) => !protectedDigests.has(sha2563)).reduce((total, [, bytes]) => total + bytes, 0);
|
|
20381
|
+
const contentBlobBytes = [...objectBytesByDigest.values()].reduce((total, bytes) => total + bytes, 0);
|
|
20367
20382
|
const releaseBytes = releases.reduce((total, release) => total + release.bytes, 0);
|
|
20368
20383
|
const totalBytes = objects.reduce((total, object22) => total + object22.size, 0);
|
|
20369
20384
|
return {
|
|
20370
20385
|
objectKeysByRelease,
|
|
20386
|
+
objectKeysByDigest,
|
|
20371
20387
|
report: {
|
|
20372
20388
|
appId: input.appId,
|
|
20373
20389
|
channelCount: channels.length,
|
|
20374
|
-
|
|
20390
|
+
contentBlobBytes,
|
|
20391
|
+
contentBlobCount: objectKeysByDigest.size,
|
|
20392
|
+
reclaimableBytes: releases.filter((release) => release.protectedBy.length === 0).reduce((total, release) => total + release.bytes, 0) + reclaimableContentBytes,
|
|
20393
|
+
reclaimableContentBytes,
|
|
20375
20394
|
releaseBytes,
|
|
20376
20395
|
releaseCount: releases.length,
|
|
20377
20396
|
releases,
|
|
20378
20397
|
totalBytes,
|
|
20379
20398
|
totalObjectCount: objects.length,
|
|
20380
|
-
untrackedBytes: totalBytes - releaseBytes
|
|
20399
|
+
untrackedBytes: totalBytes - releaseBytes - contentBlobBytes
|
|
20381
20400
|
}
|
|
20382
20401
|
};
|
|
20383
20402
|
};
|
|
@@ -20389,7 +20408,8 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20389
20408
|
marked: [],
|
|
20390
20409
|
reclaimedBytes: 0,
|
|
20391
20410
|
restored: [],
|
|
20392
|
-
swept: []
|
|
20411
|
+
swept: [],
|
|
20412
|
+
sweptContentBlobs: []
|
|
20393
20413
|
};
|
|
20394
20414
|
if (input.apply !== true)
|
|
20395
20415
|
return result;
|
|
@@ -20447,6 +20467,21 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20447
20467
|
result.reclaimedBytes += candidate.bytes;
|
|
20448
20468
|
result.swept.push(release.releaseId);
|
|
20449
20469
|
}
|
|
20470
|
+
const afterReleaseSweep = await inventory(input);
|
|
20471
|
+
const referencedDigests = new Set;
|
|
20472
|
+
for (const release of afterReleaseSweep.report.releases) {
|
|
20473
|
+
const manifest = await readManifest(input.appId, release.releaseId);
|
|
20474
|
+
for (const file of manifest?.manifest.files ?? [])
|
|
20475
|
+
referencedDigests.add(file.sha256);
|
|
20476
|
+
}
|
|
20477
|
+
for (const [sha2563, key] of afterReleaseSweep.objectKeysByDigest) {
|
|
20478
|
+
if (referencedDigests.has(sha2563))
|
|
20479
|
+
continue;
|
|
20480
|
+
const head = await options.store.head(key);
|
|
20481
|
+
await remove(key);
|
|
20482
|
+
result.reclaimedBytes += head?.size ?? 0;
|
|
20483
|
+
result.sweptContentBlobs.push(sha2563);
|
|
20484
|
+
}
|
|
20450
20485
|
return result;
|
|
20451
20486
|
};
|
|
20452
20487
|
return {
|
|
@@ -20463,8 +20498,16 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20463
20498
|
throw new MobileUpdateRegistryError("Local mobile update manifest changed");
|
|
20464
20499
|
const existing = await readManifest(manifest.appId, manifest.releaseId);
|
|
20465
20500
|
let reused = existing !== null;
|
|
20501
|
+
let storedBytes = 0;
|
|
20502
|
+
let storedFiles = 0;
|
|
20503
|
+
let reusedBytes = 0;
|
|
20504
|
+
let reusedFiles = 0;
|
|
20466
20505
|
if (existing && JSON.stringify(existing.manifest) !== JSON.stringify(manifest))
|
|
20467
20506
|
throw new MobileUpdateRegistryError("Published mobile update is immutable");
|
|
20507
|
+
if (existing) {
|
|
20508
|
+
reusedBytes = manifest.files.reduce((total, file) => total + file.bytes, 0);
|
|
20509
|
+
reusedFiles = manifest.files.length;
|
|
20510
|
+
}
|
|
20468
20511
|
if (!existing) {
|
|
20469
20512
|
for (const file of manifest.files) {
|
|
20470
20513
|
const local = path.join(localRoot, "files", file.path);
|
|
@@ -20473,18 +20516,24 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20473
20516
|
throw new MobileUpdateRegistryError(`Mobile update file ${file.path} size changed`);
|
|
20474
20517
|
if (await fileDigest(Bun.file(local)) !== file.sha256)
|
|
20475
20518
|
throw new MobileUpdateRegistryError(`Mobile update file ${file.path} integrity failed`);
|
|
20476
|
-
const key =
|
|
20519
|
+
const key = contentBlobKey(manifest.appId, file.sha256);
|
|
20477
20520
|
const stored = await options.store.head(key);
|
|
20478
20521
|
if (!stored) {
|
|
20479
20522
|
await options.store.put(key, Bun.file(local).stream(), {
|
|
20480
20523
|
cacheControl: "public, max-age=31536000, immutable",
|
|
20481
20524
|
contentType: "application/octet-stream",
|
|
20482
20525
|
maxBytes: file.bytes,
|
|
20483
|
-
metadata: {
|
|
20526
|
+
metadata: { sha256: file.sha256 },
|
|
20484
20527
|
signal: input.signal
|
|
20485
20528
|
});
|
|
20486
|
-
|
|
20487
|
-
|
|
20529
|
+
storedBytes += file.bytes;
|
|
20530
|
+
storedFiles += 1;
|
|
20531
|
+
} else if (stored.size !== file.bytes || stored.metadata?.sha256 !== file.sha256)
|
|
20532
|
+
throw new MobileUpdateRegistryError("Stored mobile update content identity changed");
|
|
20533
|
+
else {
|
|
20534
|
+
reusedBytes += file.bytes;
|
|
20535
|
+
reusedFiles += 1;
|
|
20536
|
+
}
|
|
20488
20537
|
}
|
|
20489
20538
|
const bytes = json(manifest);
|
|
20490
20539
|
await options.store.put(manifestKey(manifest), bytes, {
|
|
@@ -20508,8 +20557,12 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20508
20557
|
return {
|
|
20509
20558
|
appId: manifest.appId,
|
|
20510
20559
|
channel: manifest.channel,
|
|
20560
|
+
storedBytes,
|
|
20561
|
+
storedFiles,
|
|
20511
20562
|
releaseId: manifest.releaseId,
|
|
20512
20563
|
reused,
|
|
20564
|
+
reusedBytes,
|
|
20565
|
+
reusedFiles,
|
|
20513
20566
|
rollout: input.rollout,
|
|
20514
20567
|
stage: "published"
|
|
20515
20568
|
};
|
|
@@ -20558,14 +20611,16 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20558
20611
|
const file = release.manifest.files.find((candidate) => candidate.path === requested);
|
|
20559
20612
|
if (!file)
|
|
20560
20613
|
return null;
|
|
20561
|
-
const
|
|
20614
|
+
const legacyKey = fileKey(release.manifest, file);
|
|
20615
|
+
const legacyHead = await options.store.head(legacyKey);
|
|
20616
|
+
const key = legacyHead ? legacyKey : contentBlobKey(release.manifest.appId, file.sha256);
|
|
20562
20617
|
const [bytes, head] = await Promise.all([
|
|
20563
20618
|
options.store.get(key),
|
|
20564
|
-
options.store.head(key)
|
|
20619
|
+
legacyHead ? Promise.resolve(legacyHead) : options.store.head(key)
|
|
20565
20620
|
]);
|
|
20566
20621
|
if (!bytes || !head)
|
|
20567
20622
|
return null;
|
|
20568
|
-
if (bytes.byteLength !== file.bytes || head.size !== file.bytes || head.metadata?.sha256 !== file.sha256 || (head.metadata?.releaseid ?? head.metadata?.releaseId) !== release.manifest.releaseId || digest(bytes) !== file.sha256)
|
|
20623
|
+
if (bytes.byteLength !== file.bytes || head.size !== file.bytes || head.metadata?.sha256 !== file.sha256 || legacyHead && (head.metadata?.releaseid ?? head.metadata?.releaseId) !== release.manifest.releaseId || digest(bytes) !== file.sha256)
|
|
20569
20624
|
throw new MobileUpdateRegistryError("Stored mobile update file integrity failed");
|
|
20570
20625
|
return { bytes, file };
|
|
20571
20626
|
}
|
|
@@ -38702,10 +38757,26 @@ var requireCompatible = (manifest, config) => {
|
|
|
38702
38757
|
var createAbsoluteMobileUpdateClient = (options) => {
|
|
38703
38758
|
const manifestUrl = exactManifestUrl(options.config.manifestUrl);
|
|
38704
38759
|
const request = options.fetch ?? globalThis.fetch;
|
|
38705
|
-
const downloadFiles = async (manifest, index = 0,
|
|
38760
|
+
const downloadFiles = async (manifest, index = 0, transfer = {
|
|
38761
|
+
downloadedBytes: 0,
|
|
38762
|
+
downloadedFiles: 0,
|
|
38763
|
+
reusedBytes: 0,
|
|
38764
|
+
reusedFiles: 0,
|
|
38765
|
+
totalBytes: manifest.files.reduce((total, file) => total + file.bytes, 0),
|
|
38766
|
+
totalFiles: manifest.files.length
|
|
38767
|
+
}) => {
|
|
38706
38768
|
const file = manifest.files[index];
|
|
38707
38769
|
if (!file)
|
|
38708
|
-
return
|
|
38770
|
+
return transfer;
|
|
38771
|
+
const reusable = await options.store.readReusable?.(file);
|
|
38772
|
+
if (reusable && reusable.byteLength === file.bytes && await options.verifier.digest(reusable) === file.sha256) {
|
|
38773
|
+
await options.store.write(file, reusable);
|
|
38774
|
+
return downloadFiles(manifest, index + 1, {
|
|
38775
|
+
...transfer,
|
|
38776
|
+
reusedBytes: transfer.reusedBytes + reusable.byteLength,
|
|
38777
|
+
reusedFiles: transfer.reusedFiles + 1
|
|
38778
|
+
});
|
|
38779
|
+
}
|
|
38709
38780
|
const asset2 = await request(fileUrl(manifestUrl, manifest.releaseId, file.path), {
|
|
38710
38781
|
cache: "no-store",
|
|
38711
38782
|
credentials: "omit",
|
|
@@ -38715,13 +38786,17 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
38715
38786
|
if (!asset2.ok)
|
|
38716
38787
|
throw new TypeError(`Mobile update asset ${file.path} failed with HTTP ${asset2.status}.`);
|
|
38717
38788
|
const contents = await readBounded(asset2, file.bytes);
|
|
38718
|
-
const
|
|
38719
|
-
if (contents.byteLength !== file.bytes ||
|
|
38789
|
+
const downloadedBytes = transfer.downloadedBytes + contents.byteLength;
|
|
38790
|
+
if (contents.byteLength !== file.bytes || downloadedBytes > ABSOLUTE_MOBILE_UPDATE_MAX_TOTAL_BYTES)
|
|
38720
38791
|
throw new TypeError(`Mobile update asset ${file.path} has an invalid size.`);
|
|
38721
38792
|
if (await options.verifier.digest(contents) !== file.sha256)
|
|
38722
38793
|
throw new TypeError(`Mobile update asset ${file.path} failed integrity verification.`);
|
|
38723
38794
|
await options.store.write(file, contents);
|
|
38724
|
-
return downloadFiles(manifest, index + 1,
|
|
38795
|
+
return downloadFiles(manifest, index + 1, {
|
|
38796
|
+
...transfer,
|
|
38797
|
+
downloadedBytes,
|
|
38798
|
+
downloadedFiles: transfer.downloadedFiles + 1
|
|
38799
|
+
});
|
|
38725
38800
|
};
|
|
38726
38801
|
const check = async (download = false) => {
|
|
38727
38802
|
const response = await request(manifestUrl, {
|
|
@@ -38753,14 +38828,15 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
38753
38828
|
if (!download)
|
|
38754
38829
|
return { kind: "update-available", manifest };
|
|
38755
38830
|
await options.store.begin(manifest);
|
|
38831
|
+
let transfer;
|
|
38756
38832
|
try {
|
|
38757
|
-
await downloadFiles(manifest);
|
|
38833
|
+
transfer = await downloadFiles(manifest);
|
|
38758
38834
|
await options.store.commit(manifest);
|
|
38759
38835
|
} catch (error) {
|
|
38760
38836
|
await options.store.abort(manifest.releaseId);
|
|
38761
38837
|
throw error;
|
|
38762
38838
|
}
|
|
38763
|
-
return { kind: "downloaded", manifest };
|
|
38839
|
+
return { kind: "downloaded", manifest, transfer };
|
|
38764
38840
|
};
|
|
38765
38841
|
return {
|
|
38766
38842
|
check,
|
|
@@ -38888,6 +38964,7 @@ var lifecycleMethod = (publisher, name) => {
|
|
|
38888
38964
|
throw new TypeError(`Mobile update registry does not support ${name}. Re-run \`absolute mobile update provision --force\` after upgrading @absolutejs/deploy.`);
|
|
38889
38965
|
return method;
|
|
38890
38966
|
};
|
|
38967
|
+
var validOptionalCounters = (values) => values.every((value) => value === undefined) || values.every((value) => Number.isSafeInteger(value) && (value ?? -1) >= 0);
|
|
38891
38968
|
var validateStorageIdentity = (result, appId) => {
|
|
38892
38969
|
if (!object5(result) || result.appId !== appId || !Array.isArray(result.releases) || ![
|
|
38893
38970
|
result.channelCount,
|
|
@@ -38897,7 +38974,11 @@ var validateStorageIdentity = (result, appId) => {
|
|
|
38897
38974
|
result.totalBytes,
|
|
38898
38975
|
result.totalObjectCount,
|
|
38899
38976
|
result.untrackedBytes
|
|
38900
|
-
].every((value) => Number.isSafeInteger(value) && value >= 0)
|
|
38977
|
+
].every((value) => Number.isSafeInteger(value) && value >= 0) || !validOptionalCounters([
|
|
38978
|
+
result.contentBlobBytes,
|
|
38979
|
+
result.contentBlobCount,
|
|
38980
|
+
result.reclaimableContentBytes
|
|
38981
|
+
]))
|
|
38901
38982
|
throw new TypeError("Mobile update registry returned an invalid storage report.");
|
|
38902
38983
|
return result;
|
|
38903
38984
|
};
|
|
@@ -38917,7 +38998,7 @@ var pruneAbsoluteMobileUpdates = async (options) => {
|
|
|
38917
38998
|
...options.signal ? { signal: options.signal } : {}
|
|
38918
38999
|
});
|
|
38919
39000
|
validateStorageIdentity(result, options.appId);
|
|
38920
|
-
if (!Array.isArray(result.marked) || !Array.isArray(result.restored) || !Array.isArray(result.swept) || typeof result.dryRun !== "boolean" || !Number.isSafeInteger(result.reclaimedBytes) || result.reclaimedBytes < 0)
|
|
39001
|
+
if (!Array.isArray(result.marked) || !Array.isArray(result.restored) || !Array.isArray(result.swept) || result.sweptContentBlobs !== undefined && !Array.isArray(result.sweptContentBlobs) || typeof result.dryRun !== "boolean" || !Number.isSafeInteger(result.reclaimedBytes) || result.reclaimedBytes < 0)
|
|
38921
39002
|
throw new TypeError("Mobile update registry returned an invalid collection report.");
|
|
38922
39003
|
return result;
|
|
38923
39004
|
};
|
|
@@ -38963,7 +39044,12 @@ var publishAbsoluteMobileUpdate = async (options) => {
|
|
|
38963
39044
|
rollout: options.rollout,
|
|
38964
39045
|
signal: options.signal
|
|
38965
39046
|
});
|
|
38966
|
-
if (result.appId !== manifest.appId || result.channel !== manifest.channel || result.releaseId !== manifest.releaseId || result.rollout !== options.rollout || result.stage !== "published" || typeof result.reused !== "boolean"
|
|
39047
|
+
if (result.appId !== manifest.appId || result.channel !== manifest.channel || result.releaseId !== manifest.releaseId || result.rollout !== options.rollout || result.stage !== "published" || typeof result.reused !== "boolean" || !validOptionalCounters([
|
|
39048
|
+
result.storedBytes,
|
|
39049
|
+
result.storedFiles,
|
|
39050
|
+
result.reusedBytes,
|
|
39051
|
+
result.reusedFiles
|
|
39052
|
+
]))
|
|
38967
39053
|
throw new TypeError("Mobile update registry returned a different publication identity.");
|
|
38968
39054
|
return result;
|
|
38969
39055
|
};
|
|
@@ -39247,5 +39333,5 @@ export {
|
|
|
39247
39333
|
writeAbsoluteMobileUpdateRegistry
|
|
39248
39334
|
};
|
|
39249
39335
|
|
|
39250
|
-
//# debugId=
|
|
39336
|
+
//# debugId=A051836D5390197D64756E2164756E21
|
|
39251
39337
|
//# sourceMappingURL=index.js.map
|