@absolutejs/absolute 0.20.0-beta.84 → 0.20.0-beta.85
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 +39 -7
- package/dist/build.js.map +3 -3
- package/dist/cli/{compile-t73ac1zb.js → compile-d7g2fvqe.js} +1 -1
- package/dist/cli/index.js +1 -1
- package/dist/index.js +39 -7
- package/dist/index.js.map +3 -3
- package/dist/mobile/index.js +212 -52
- package/dist/mobile/index.js.map +4 -4
- package/dist/mobile/shellUpdate.js +280 -47
- package/dist/src/mobile/updateClient.d.ts +20 -0
- package/package.json +2 -2
package/dist/mobile/index.js
CHANGED
|
@@ -20760,14 +20760,18 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20760
20760
|
const expoCodeSigning = resolveExpoCodeSigning(options.expoCodeSigning);
|
|
20761
20761
|
return async (request) => {
|
|
20762
20762
|
const origin = request.headers.get("origin");
|
|
20763
|
-
const cors = origin && allowedOrigins.has(origin) ? {
|
|
20763
|
+
const cors = origin && allowedOrigins.has(origin) ? {
|
|
20764
|
+
"access-control-allow-origin": origin,
|
|
20765
|
+
"access-control-expose-headers": "content-range,etag",
|
|
20766
|
+
vary: "Origin"
|
|
20767
|
+
} : {};
|
|
20764
20768
|
if (request.method === "OPTIONS") {
|
|
20765
20769
|
if (!origin || !allowedOrigins.has(origin))
|
|
20766
20770
|
return new Response(null, { status: 403 });
|
|
20767
20771
|
return new Response(null, {
|
|
20768
20772
|
headers: {
|
|
20769
20773
|
...cors,
|
|
20770
|
-
"access-control-allow-headers": "x-absolute-mobile-app,x-absolute-mobile-channel,x-absolute-mobile-installation,x-absolute-mobile-release,x-absolute-mobile-runtime",
|
|
20774
|
+
"access-control-allow-headers": "if-range,range,x-absolute-mobile-app,x-absolute-mobile-channel,x-absolute-mobile-installation,x-absolute-mobile-release,x-absolute-mobile-runtime",
|
|
20771
20775
|
"access-control-allow-methods": "GET,OPTIONS",
|
|
20772
20776
|
"access-control-max-age": "600"
|
|
20773
20777
|
},
|
|
@@ -20895,14 +20899,42 @@ var MOBILE_UPDATE_REGISTRY_FORMAT = 1, DEFAULT_PREFIX = "absolutejs/mobile-updat
|
|
|
20895
20899
|
});
|
|
20896
20900
|
if (!file)
|
|
20897
20901
|
return new Response(null, { status: 404 });
|
|
20898
|
-
|
|
20902
|
+
const etag = `"${file.file.sha256}"`;
|
|
20903
|
+
const range = request.headers.get("range");
|
|
20904
|
+
const useRange = range !== null && (!request.headers.has("if-range") || request.headers.get("if-range") === etag);
|
|
20905
|
+
let contents = file.bytes;
|
|
20906
|
+
let status = 200;
|
|
20907
|
+
let contentRange;
|
|
20908
|
+
if (useRange) {
|
|
20909
|
+
const parsed = /^bytes=(\d+)-(\d*)$/.exec(range);
|
|
20910
|
+
const start = parsed?.[1] === undefined ? NaN : Number(parsed[1]);
|
|
20911
|
+
const requestedEnd = parsed?.[2] === undefined || parsed[2] === "" ? file.bytes.byteLength - 1 : Number(parsed[2]);
|
|
20912
|
+
if (!Number.isSafeInteger(start) || !Number.isSafeInteger(requestedEnd) || start < 0 || start >= file.bytes.byteLength || requestedEnd < start)
|
|
20913
|
+
return new Response(null, {
|
|
20914
|
+
headers: {
|
|
20915
|
+
...cors,
|
|
20916
|
+
"accept-ranges": "bytes",
|
|
20917
|
+
"content-range": `bytes */${file.bytes.byteLength}`,
|
|
20918
|
+
etag
|
|
20919
|
+
},
|
|
20920
|
+
status: 416
|
|
20921
|
+
});
|
|
20922
|
+
const end = Math.min(requestedEnd, file.bytes.byteLength - 1);
|
|
20923
|
+
contents = file.bytes.slice(start, end + 1);
|
|
20924
|
+
status = 206;
|
|
20925
|
+
contentRange = `bytes ${start}-${end}/${file.bytes.byteLength}`;
|
|
20926
|
+
}
|
|
20927
|
+
return new Response(new Blob([new Uint8Array(contents).buffer]), {
|
|
20899
20928
|
headers: {
|
|
20900
20929
|
...cors,
|
|
20930
|
+
"accept-ranges": "bytes",
|
|
20901
20931
|
"cache-control": "public, max-age=31536000, immutable",
|
|
20902
|
-
"content-length": String(
|
|
20932
|
+
"content-length": String(contents.byteLength),
|
|
20933
|
+
...contentRange ? { "content-range": contentRange } : {},
|
|
20903
20934
|
"content-type": expoContentType(file.file.path.includes(".") ? file.file.path.slice(file.file.path.lastIndexOf(".") + 1) : undefined, false),
|
|
20904
|
-
etag
|
|
20905
|
-
}
|
|
20935
|
+
etag
|
|
20936
|
+
},
|
|
20937
|
+
status
|
|
20906
20938
|
});
|
|
20907
20939
|
};
|
|
20908
20940
|
};
|
|
@@ -38705,17 +38737,18 @@ var fileUrl = (manifestUrl, releaseId, path) => {
|
|
|
38705
38737
|
throw new TypeError("Mobile update asset escaped its signed release origin.");
|
|
38706
38738
|
return result;
|
|
38707
38739
|
};
|
|
38708
|
-
var readChunks = async (reader, maximum2, chunks = [], received = 0) => {
|
|
38740
|
+
var readChunks = async (reader, maximum2, onChunk, chunks = [], received = 0) => {
|
|
38709
38741
|
const result = await reader.read();
|
|
38710
38742
|
if (result.done)
|
|
38711
38743
|
return { chunks, received };
|
|
38712
38744
|
const total = received + result.value.byteLength;
|
|
38713
38745
|
if (total > maximum2)
|
|
38714
38746
|
throw new TypeError("Mobile update response exceeds its signed size.");
|
|
38747
|
+
await onChunk?.(result.value, received);
|
|
38715
38748
|
chunks.push(result.value);
|
|
38716
|
-
return readChunks(reader, maximum2, chunks, total);
|
|
38749
|
+
return readChunks(reader, maximum2, onChunk, chunks, total);
|
|
38717
38750
|
};
|
|
38718
|
-
var readBounded = async (response, maximum2) => {
|
|
38751
|
+
var readBounded = async (response, maximum2, onChunk) => {
|
|
38719
38752
|
const declared = Number(response.headers.get("content-length"));
|
|
38720
38753
|
if (Number.isFinite(declared) && declared > maximum2)
|
|
38721
38754
|
throw new TypeError("Mobile update response exceeds its signed size.");
|
|
@@ -38723,8 +38756,9 @@ var readBounded = async (response, maximum2) => {
|
|
|
38723
38756
|
return new Uint8Array;
|
|
38724
38757
|
const reader = response.body.getReader();
|
|
38725
38758
|
let result;
|
|
38759
|
+
const chunks = [];
|
|
38726
38760
|
try {
|
|
38727
|
-
result = await readChunks(reader, maximum2);
|
|
38761
|
+
result = await readChunks(reader, maximum2, onChunk, chunks);
|
|
38728
38762
|
} catch (error) {
|
|
38729
38763
|
await reader.cancel().catch(() => {
|
|
38730
38764
|
return;
|
|
@@ -38733,7 +38767,7 @@ var readBounded = async (response, maximum2) => {
|
|
|
38733
38767
|
}
|
|
38734
38768
|
const contents = new Uint8Array(result.received);
|
|
38735
38769
|
let offset = 0;
|
|
38736
|
-
for (const chunk of
|
|
38770
|
+
for (const chunk of chunks) {
|
|
38737
38771
|
contents.set(chunk, offset);
|
|
38738
38772
|
offset += chunk.byteLength;
|
|
38739
38773
|
}
|
|
@@ -38754,49 +38788,172 @@ var requireCompatible = (manifest, config) => {
|
|
|
38754
38788
|
if (manifest.runtimeFingerprint !== config.runtimeFingerprint)
|
|
38755
38789
|
throw new TypeError("Mobile update requires a different native runtime.");
|
|
38756
38790
|
};
|
|
38791
|
+
var networkConcurrency = (requested) => {
|
|
38792
|
+
const bounded = Math.max(1, Math.min(6, Math.floor(requested ?? 3)));
|
|
38793
|
+
const navigatorValue = Reflect.get(globalThis, "navigator");
|
|
38794
|
+
const connection = typeof navigatorValue === "object" && navigatorValue !== null ? Reflect.get(navigatorValue, "connection") : undefined;
|
|
38795
|
+
if (typeof connection !== "object" || connection === null)
|
|
38796
|
+
return bounded;
|
|
38797
|
+
if (Reflect.get(connection, "saveData") === true)
|
|
38798
|
+
return 1;
|
|
38799
|
+
const effectiveType = Reflect.get(connection, "effectiveType");
|
|
38800
|
+
if (effectiveType === "slow-2g" || effectiveType === "2g")
|
|
38801
|
+
return 1;
|
|
38802
|
+
if (effectiveType === "3g")
|
|
38803
|
+
return Math.min(2, bounded);
|
|
38804
|
+
return bounded;
|
|
38805
|
+
};
|
|
38806
|
+
var combine = (prefix, suffix) => {
|
|
38807
|
+
const result = new Uint8Array(prefix.byteLength + suffix.byteLength);
|
|
38808
|
+
result.set(prefix);
|
|
38809
|
+
result.set(suffix, prefix.byteLength);
|
|
38810
|
+
return result;
|
|
38811
|
+
};
|
|
38812
|
+
var validContentRange = (value, start, total) => value === `bytes ${start}-${total - 1}/${total}`;
|
|
38813
|
+
var combineSignals = (signals) => {
|
|
38814
|
+
const nativeAny = Reflect.get(AbortSignal, "any");
|
|
38815
|
+
if (typeof nativeAny === "function")
|
|
38816
|
+
return Reflect.apply(nativeAny, AbortSignal, [signals]);
|
|
38817
|
+
const controller = new AbortController;
|
|
38818
|
+
const abort = () => controller.abort();
|
|
38819
|
+
if (signals.some((signal) => signal.aborted))
|
|
38820
|
+
abort();
|
|
38821
|
+
else
|
|
38822
|
+
signals.forEach((signal) => signal.addEventListener("abort", abort, { once: true }));
|
|
38823
|
+
return controller.signal;
|
|
38824
|
+
};
|
|
38757
38825
|
var createAbsoluteMobileUpdateClient = (options) => {
|
|
38758
38826
|
const manifestUrl = exactManifestUrl(options.config.manifestUrl);
|
|
38759
38827
|
const request = options.fetch ?? globalThis.fetch;
|
|
38760
|
-
const downloadFiles = async (manifest
|
|
38761
|
-
|
|
38762
|
-
|
|
38763
|
-
|
|
38764
|
-
|
|
38765
|
-
|
|
38766
|
-
|
|
38767
|
-
|
|
38768
|
-
|
|
38769
|
-
|
|
38770
|
-
|
|
38771
|
-
|
|
38772
|
-
|
|
38773
|
-
|
|
38774
|
-
|
|
38775
|
-
|
|
38776
|
-
|
|
38777
|
-
|
|
38828
|
+
const downloadFiles = async (manifest) => {
|
|
38829
|
+
const startedAt = performance.now();
|
|
38830
|
+
const transfer = {
|
|
38831
|
+
avoidedBytes: 0,
|
|
38832
|
+
completedFiles: 0,
|
|
38833
|
+
downloadedBytes: 0,
|
|
38834
|
+
downloadedFiles: 0,
|
|
38835
|
+
durationMs: 0,
|
|
38836
|
+
resumedBytes: 0,
|
|
38837
|
+
resumedFiles: 0,
|
|
38838
|
+
reusedBytes: 0,
|
|
38839
|
+
reusedFiles: 0,
|
|
38840
|
+
throughputBytesPerSecond: 0,
|
|
38841
|
+
totalBytes: manifest.files.reduce((total, file) => total + file.bytes, 0),
|
|
38842
|
+
totalFiles: manifest.files.length
|
|
38843
|
+
};
|
|
38844
|
+
const updateTiming = () => {
|
|
38845
|
+
transfer.durationMs = Math.max(0, performance.now() - startedAt);
|
|
38846
|
+
transfer.avoidedBytes = transfer.reusedBytes + transfer.resumedBytes;
|
|
38847
|
+
transfer.throughputBytesPerSecond = transfer.durationMs > 0 ? Math.round(transfer.downloadedBytes * 1000 / transfer.durationMs) : transfer.downloadedBytes;
|
|
38848
|
+
};
|
|
38849
|
+
const progress = () => {
|
|
38850
|
+
updateTiming();
|
|
38851
|
+
try {
|
|
38852
|
+
options.onProgress?.({
|
|
38853
|
+
...transfer,
|
|
38854
|
+
kind: "download-progress"
|
|
38855
|
+
});
|
|
38856
|
+
} catch {}
|
|
38857
|
+
};
|
|
38858
|
+
const controller = new AbortController;
|
|
38859
|
+
let next = 0;
|
|
38860
|
+
let firstError;
|
|
38861
|
+
const downloadFile = async (file) => {
|
|
38862
|
+
const staged = await options.store.readStaged?.(file);
|
|
38863
|
+
if (staged?.byteLength === file.bytes && await options.verifier.digest(staged) === file.sha256) {
|
|
38864
|
+
transfer.resumedBytes += staged.byteLength;
|
|
38865
|
+
transfer.resumedFiles += 1;
|
|
38866
|
+
transfer.completedFiles += 1;
|
|
38867
|
+
progress();
|
|
38868
|
+
return;
|
|
38869
|
+
}
|
|
38870
|
+
const reusable = await options.store.readReusable?.(file);
|
|
38871
|
+
if (reusable?.byteLength === file.bytes && await options.verifier.digest(reusable) === file.sha256) {
|
|
38872
|
+
await options.store.write(file, reusable);
|
|
38873
|
+
transfer.reusedBytes += reusable.byteLength;
|
|
38874
|
+
transfer.reusedFiles += 1;
|
|
38875
|
+
transfer.completedFiles += 1;
|
|
38876
|
+
progress();
|
|
38877
|
+
return;
|
|
38878
|
+
}
|
|
38879
|
+
const candidate = await options.store.readPartial?.(file);
|
|
38880
|
+
if (candidate?.byteLength === file.bytes && await options.verifier.digest(candidate) === file.sha256) {
|
|
38881
|
+
await options.store.write(file, candidate);
|
|
38882
|
+
transfer.resumedBytes += candidate.byteLength;
|
|
38883
|
+
transfer.resumedFiles += 1;
|
|
38884
|
+
transfer.completedFiles += 1;
|
|
38885
|
+
progress();
|
|
38886
|
+
return;
|
|
38887
|
+
}
|
|
38888
|
+
const partial = candidate && candidate.byteLength > 0 && candidate.byteLength < file.bytes ? candidate : new Uint8Array;
|
|
38889
|
+
const headers = new Headers;
|
|
38890
|
+
if (partial.byteLength > 0) {
|
|
38891
|
+
headers.set("if-range", `"${file.sha256}"`);
|
|
38892
|
+
headers.set("range", `bytes=${partial.byteLength}-`);
|
|
38893
|
+
}
|
|
38894
|
+
const asset2 = await request(fileUrl(manifestUrl, manifest.releaseId, file.path), {
|
|
38895
|
+
cache: "no-store",
|
|
38896
|
+
credentials: "omit",
|
|
38897
|
+
headers,
|
|
38898
|
+
redirect: "error",
|
|
38899
|
+
signal: combineSignals([
|
|
38900
|
+
controller.signal,
|
|
38901
|
+
AbortSignal.timeout(30000)
|
|
38902
|
+
])
|
|
38778
38903
|
});
|
|
38779
|
-
|
|
38780
|
-
|
|
38781
|
-
|
|
38782
|
-
|
|
38783
|
-
|
|
38784
|
-
|
|
38785
|
-
|
|
38786
|
-
|
|
38787
|
-
|
|
38788
|
-
|
|
38789
|
-
|
|
38790
|
-
|
|
38791
|
-
|
|
38792
|
-
|
|
38793
|
-
|
|
38794
|
-
|
|
38795
|
-
|
|
38796
|
-
|
|
38797
|
-
|
|
38798
|
-
|
|
38799
|
-
|
|
38904
|
+
if (!asset2.ok)
|
|
38905
|
+
throw new TypeError(`Mobile update asset ${file.path} failed with HTTP ${asset2.status}.`);
|
|
38906
|
+
const ranged = asset2.status === 206;
|
|
38907
|
+
if (ranged && (partial.byteLength === 0 || !validContentRange(asset2.headers.get("content-range"), partial.byteLength, file.bytes)))
|
|
38908
|
+
throw new TypeError(`Mobile update asset ${file.path} returned an invalid byte range.`);
|
|
38909
|
+
const prefix = ranged ? partial : new Uint8Array;
|
|
38910
|
+
if (ranged) {
|
|
38911
|
+
transfer.resumedBytes += partial.byteLength;
|
|
38912
|
+
transfer.resumedFiles += 1;
|
|
38913
|
+
}
|
|
38914
|
+
const downloaded = await readBounded(asset2, file.bytes - prefix.byteLength, options.store.appendPartial ? async (chunk, offset) => {
|
|
38915
|
+
await options.store.appendPartial?.(file, chunk, prefix.byteLength + offset);
|
|
38916
|
+
transfer.downloadedBytes += chunk.byteLength;
|
|
38917
|
+
progress();
|
|
38918
|
+
} : undefined);
|
|
38919
|
+
if (!options.store.appendPartial) {
|
|
38920
|
+
transfer.downloadedBytes += downloaded.byteLength;
|
|
38921
|
+
progress();
|
|
38922
|
+
}
|
|
38923
|
+
if (transfer.downloadedBytes > ABSOLUTE_MOBILE_UPDATE_MAX_TOTAL_BYTES)
|
|
38924
|
+
throw new TypeError("Mobile update exceeds the maximum transfer size.");
|
|
38925
|
+
const contents = combine(prefix, downloaded);
|
|
38926
|
+
if (contents.byteLength !== file.bytes)
|
|
38927
|
+
throw new TypeError(`Mobile update asset ${file.path} has an invalid size.`);
|
|
38928
|
+
if (await options.verifier.digest(contents) !== file.sha256)
|
|
38929
|
+
throw new TypeError(`Mobile update asset ${file.path} failed integrity verification.`);
|
|
38930
|
+
await options.store.write(file, contents);
|
|
38931
|
+
transfer.downloadedFiles += 1;
|
|
38932
|
+
transfer.completedFiles += 1;
|
|
38933
|
+
progress();
|
|
38934
|
+
};
|
|
38935
|
+
const worker = async () => {
|
|
38936
|
+
if (firstError)
|
|
38937
|
+
return;
|
|
38938
|
+
const index = next++;
|
|
38939
|
+
const file = manifest.files[index];
|
|
38940
|
+
if (!file)
|
|
38941
|
+
return;
|
|
38942
|
+
try {
|
|
38943
|
+
await downloadFile(file);
|
|
38944
|
+
} catch (error) {
|
|
38945
|
+
firstError ??= error;
|
|
38946
|
+
controller.abort();
|
|
38947
|
+
}
|
|
38948
|
+
await worker();
|
|
38949
|
+
};
|
|
38950
|
+
await Promise.all(Array.from({
|
|
38951
|
+
length: Math.min(networkConcurrency(options.concurrency), manifest.files.length)
|
|
38952
|
+
}, () => worker()));
|
|
38953
|
+
if (firstError)
|
|
38954
|
+
throw firstError;
|
|
38955
|
+
updateTiming();
|
|
38956
|
+
return transfer;
|
|
38800
38957
|
};
|
|
38801
38958
|
const check = async (download = false) => {
|
|
38802
38959
|
const response = await request(manifestUrl, {
|
|
@@ -38833,7 +38990,10 @@ var createAbsoluteMobileUpdateClient = (options) => {
|
|
|
38833
38990
|
transfer = await downloadFiles(manifest);
|
|
38834
38991
|
await options.store.commit(manifest);
|
|
38835
38992
|
} catch (error) {
|
|
38836
|
-
|
|
38993
|
+
if (options.store.suspend)
|
|
38994
|
+
await options.store.suspend(manifest.releaseId);
|
|
38995
|
+
else
|
|
38996
|
+
await options.store.abort(manifest.releaseId);
|
|
38837
38997
|
throw error;
|
|
38838
38998
|
}
|
|
38839
38999
|
return { kind: "downloaded", manifest, transfer };
|
|
@@ -39333,5 +39493,5 @@ export {
|
|
|
39333
39493
|
writeAbsoluteMobileUpdateRegistry
|
|
39334
39494
|
};
|
|
39335
39495
|
|
|
39336
|
-
//# debugId=
|
|
39496
|
+
//# debugId=B713A6D1CA49D10364756E2164756E21
|
|
39337
39497
|
//# sourceMappingURL=index.js.map
|