@ardrive/turbo-sdk 1.30.0 → 1.31.0-alpha.1
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/bundles/web.bundle.min.js +404 -16
- package/lib/cjs/cli/commands/uploadFile.js +1 -0
- package/lib/cjs/cli/commands/uploadFolder.js +4 -1
- package/lib/cjs/cli/options.js +17 -1
- package/lib/cjs/cli/types.js +0 -15
- package/lib/cjs/cli/utils.js +13 -0
- package/lib/cjs/common/chunked.js +359 -0
- package/lib/cjs/common/http.js +1 -0
- package/lib/cjs/common/turbo.js +10 -2
- package/lib/cjs/common/upload.js +39 -9
- package/lib/cjs/types.js +2 -1
- package/lib/cjs/version.js +1 -1
- package/lib/esm/cli/commands/uploadFile.js +2 -1
- package/lib/esm/cli/commands/uploadFolder.js +4 -1
- package/lib/esm/cli/options.js +17 -1
- package/lib/esm/cli/types.js +0 -15
- package/lib/esm/cli/utils.js +12 -0
- package/lib/esm/common/chunked.js +352 -0
- package/lib/esm/common/http.js +1 -0
- package/lib/esm/common/turbo.js +10 -2
- package/lib/esm/common/upload.js +39 -9
- package/lib/esm/types.js +1 -0
- package/lib/esm/version.js +1 -1
- package/lib/types/cli/commands/uploadFile.d.ts.map +1 -1
- package/lib/types/cli/commands/uploadFolder.d.ts.map +1 -1
- package/lib/types/cli/options.d.ts +45 -2
- package/lib/types/cli/options.d.ts.map +1 -1
- package/lib/types/cli/types.d.ts +4 -0
- package/lib/types/cli/types.d.ts.map +1 -1
- package/lib/types/cli/utils.d.ts +9 -1
- package/lib/types/cli/utils.d.ts.map +1 -1
- package/lib/types/common/chunked.d.ts +44 -0
- package/lib/types/common/chunked.d.ts.map +1 -0
- package/lib/types/common/http.d.ts +1 -1
- package/lib/types/common/http.d.ts.map +1 -1
- package/lib/types/common/turbo.d.ts +2 -2
- package/lib/types/common/turbo.d.ts.map +1 -1
- package/lib/types/common/upload.d.ts +3 -3
- package/lib/types/common/upload.d.ts.map +1 -1
- package/lib/types/types.d.ts +16 -4
- package/lib/types/types.d.ts.map +1 -1
- package/lib/types/version.d.ts +1 -1
- package/lib/types/version.d.ts.map +1 -1
- package/package.json +9 -5
|
@@ -197377,7 +197377,7 @@ var require_axios = __commonJS({
|
|
|
197377
197377
|
kind === "object" && isFunction4(thing.toString) && thing.toString() === "[object FormData]"));
|
|
197378
197378
|
};
|
|
197379
197379
|
var isURLSearchParams2 = kindOfTest2("URLSearchParams");
|
|
197380
|
-
var [
|
|
197380
|
+
var [isReadableStream3, isRequest2, isResponse2, isHeaders2] = ["ReadableStream", "Request", "Response", "Headers"].map(kindOfTest2);
|
|
197381
197381
|
var trim2 = (str) => str.trim ? str.trim() : str.replace(/^[\s\uFEFF\xA0]+|[\s\uFEFF\xA0]+$/g, "");
|
|
197382
197382
|
function forEach3(obj, fn2, { allOwnKeys = false } = {}) {
|
|
197383
197383
|
if (obj === null || typeof obj === "undefined") {
|
|
@@ -197662,7 +197662,7 @@ var require_axios = __commonJS({
|
|
|
197662
197662
|
isBoolean: isBoolean4,
|
|
197663
197663
|
isObject: isObject5,
|
|
197664
197664
|
isPlainObject: isPlainObject2,
|
|
197665
|
-
isReadableStream:
|
|
197665
|
+
isReadableStream: isReadableStream3,
|
|
197666
197666
|
isRequest: isRequest2,
|
|
197667
197667
|
isResponse: isResponse2,
|
|
197668
197668
|
isHeaders: isHeaders2,
|
|
@@ -220948,6 +220948,7 @@ function isSolanaWalletAdapter(walletAdapter) {
|
|
|
220948
220948
|
function isEthereumWalletAdapter(walletAdapter) {
|
|
220949
220949
|
return "getSigner" in walletAdapter;
|
|
220950
220950
|
}
|
|
220951
|
+
var validChunkingModes = ["force", "disabled", "auto"];
|
|
220951
220952
|
|
|
220952
220953
|
// src/common/logger.ts
|
|
220953
220954
|
init_dirname();
|
|
@@ -220959,7 +220960,7 @@ var import_winston = __toESM(require_winston(), 1);
|
|
|
220959
220960
|
init_dirname();
|
|
220960
220961
|
init_buffer2();
|
|
220961
220962
|
init_process2();
|
|
220962
|
-
var version21 = "1.30.0
|
|
220963
|
+
var version21 = "1.30.0";
|
|
220963
220964
|
|
|
220964
220965
|
// src/common/logger.ts
|
|
220965
220966
|
var TurboWinstonLogger = class _TurboWinstonLogger {
|
|
@@ -225543,6 +225544,7 @@ var TurboHTTPService = class {
|
|
|
225543
225544
|
}
|
|
225544
225545
|
const { body, duplex } = await toFetchBody(data);
|
|
225545
225546
|
try {
|
|
225547
|
+
this.logger.debug("Posting data via fetch", { endpoint, headers });
|
|
225546
225548
|
const res = await fetch(this.axios.defaults.baseURL + endpoint, {
|
|
225547
225549
|
method: "POST",
|
|
225548
225550
|
headers,
|
|
@@ -274373,6 +274375,11 @@ function pLimit(concurrency) {
|
|
|
274373
274375
|
return generator;
|
|
274374
274376
|
}
|
|
274375
274377
|
|
|
274378
|
+
// src/common/chunked.ts
|
|
274379
|
+
init_dirname();
|
|
274380
|
+
init_buffer2();
|
|
274381
|
+
init_process2();
|
|
274382
|
+
|
|
274376
274383
|
// src/common/events.ts
|
|
274377
274384
|
init_dirname();
|
|
274378
274385
|
init_buffer2();
|
|
@@ -274595,6 +274602,340 @@ function createStreamWithSigningEvents({
|
|
|
274595
274602
|
});
|
|
274596
274603
|
}
|
|
274597
274604
|
|
|
274605
|
+
// src/common/chunked.ts
|
|
274606
|
+
var fiveMiB = 5 * 1024 * 1024;
|
|
274607
|
+
var fiveHundredMiB = fiveMiB * 100;
|
|
274608
|
+
var defaultMaxChunkConcurrency = 5;
|
|
274609
|
+
var minChunkByteCount = fiveMiB;
|
|
274610
|
+
var defaultChunkByteCount = minChunkByteCount;
|
|
274611
|
+
var backlogQueueFactor = 2;
|
|
274612
|
+
var chunkingHeader = { "x-chunking-version": "2" };
|
|
274613
|
+
var ChunkedUploader = class {
|
|
274614
|
+
constructor({
|
|
274615
|
+
http,
|
|
274616
|
+
token,
|
|
274617
|
+
maxChunkConcurrency = defaultMaxChunkConcurrency,
|
|
274618
|
+
chunkByteCount = defaultChunkByteCount,
|
|
274619
|
+
logger: logger19 = TurboWinstonLogger.default,
|
|
274620
|
+
chunkingMode = "auto",
|
|
274621
|
+
dataItemByteCount
|
|
274622
|
+
}) {
|
|
274623
|
+
this.chunkByteCount = chunkByteCount;
|
|
274624
|
+
this.maxChunkConcurrency = maxChunkConcurrency;
|
|
274625
|
+
this.http = http;
|
|
274626
|
+
this.token = token;
|
|
274627
|
+
this.logger = logger19;
|
|
274628
|
+
this.assertChunkParams({
|
|
274629
|
+
chunkByteCount,
|
|
274630
|
+
chunkingMode,
|
|
274631
|
+
maxChunkConcurrency
|
|
274632
|
+
});
|
|
274633
|
+
this.shouldUseChunkUploader = this.shouldChunkUpload({
|
|
274634
|
+
chunkByteCount,
|
|
274635
|
+
chunkingMode,
|
|
274636
|
+
dataItemByteCount
|
|
274637
|
+
});
|
|
274638
|
+
this.maxBacklogQueue = this.maxChunkConcurrency * backlogQueueFactor;
|
|
274639
|
+
}
|
|
274640
|
+
shouldChunkUpload({
|
|
274641
|
+
chunkByteCount,
|
|
274642
|
+
chunkingMode,
|
|
274643
|
+
dataItemByteCount
|
|
274644
|
+
}) {
|
|
274645
|
+
if (chunkingMode === "disabled") {
|
|
274646
|
+
return false;
|
|
274647
|
+
}
|
|
274648
|
+
if (chunkingMode === "force") {
|
|
274649
|
+
return true;
|
|
274650
|
+
}
|
|
274651
|
+
const isMoreThanTwoChunksOfData = dataItemByteCount > chunkByteCount * 2;
|
|
274652
|
+
return isMoreThanTwoChunksOfData;
|
|
274653
|
+
}
|
|
274654
|
+
assertChunkParams({
|
|
274655
|
+
chunkByteCount,
|
|
274656
|
+
chunkingMode,
|
|
274657
|
+
maxChunkConcurrency
|
|
274658
|
+
}) {
|
|
274659
|
+
if (Number.isNaN(maxChunkConcurrency) || !Number.isInteger(maxChunkConcurrency) || maxChunkConcurrency < 1) {
|
|
274660
|
+
throw new Error(
|
|
274661
|
+
"Invalid max chunk concurrency. Must be an integer of at least 1."
|
|
274662
|
+
);
|
|
274663
|
+
}
|
|
274664
|
+
if (Number.isNaN(chunkByteCount) || !Number.isInteger(chunkByteCount) || chunkByteCount < fiveMiB || chunkByteCount > fiveHundredMiB) {
|
|
274665
|
+
throw new Error(
|
|
274666
|
+
"Invalid chunk size. Must be an integer between 5 MiB and 500 MiB."
|
|
274667
|
+
);
|
|
274668
|
+
}
|
|
274669
|
+
if (typeof chunkingMode !== "string" || !validChunkingModes.includes(chunkingMode)) {
|
|
274670
|
+
throw new Error(
|
|
274671
|
+
`Invalid chunking mode. Must be one of: ${validChunkingModes.join(
|
|
274672
|
+
", "
|
|
274673
|
+
)}`
|
|
274674
|
+
);
|
|
274675
|
+
}
|
|
274676
|
+
}
|
|
274677
|
+
/**
|
|
274678
|
+
* Initialize or resume an upload session, returning the upload ID.
|
|
274679
|
+
*/
|
|
274680
|
+
async initUpload() {
|
|
274681
|
+
const res = await this.http.get({
|
|
274682
|
+
endpoint: `/chunks/${this.token}/-1/-1?chunkSize=${this.chunkByteCount}`,
|
|
274683
|
+
headers: chunkingHeader
|
|
274684
|
+
});
|
|
274685
|
+
if (res.chunkSize !== this.chunkByteCount) {
|
|
274686
|
+
this.logger.warn("Chunk size mismatch! Overriding with server value.", {
|
|
274687
|
+
expected: this.chunkByteCount,
|
|
274688
|
+
actual: res.chunkSize
|
|
274689
|
+
});
|
|
274690
|
+
this.chunkByteCount = res.chunkSize;
|
|
274691
|
+
}
|
|
274692
|
+
return res.id;
|
|
274693
|
+
}
|
|
274694
|
+
async upload({
|
|
274695
|
+
dataItemSizeFactory,
|
|
274696
|
+
dataItemStreamFactory,
|
|
274697
|
+
dataItemOpts,
|
|
274698
|
+
signal,
|
|
274699
|
+
events
|
|
274700
|
+
}) {
|
|
274701
|
+
const uploadId = await this.initUpload();
|
|
274702
|
+
const dataItemByteCount = dataItemSizeFactory();
|
|
274703
|
+
const emitter = new TurboEventEmitter(events);
|
|
274704
|
+
const { stream: stream2, resume } = createStreamWithUploadEvents({
|
|
274705
|
+
data: dataItemStreamFactory(),
|
|
274706
|
+
dataSize: dataItemByteCount,
|
|
274707
|
+
emitter
|
|
274708
|
+
});
|
|
274709
|
+
this.logger.debug(`Starting chunked upload`, {
|
|
274710
|
+
token: this.token,
|
|
274711
|
+
uploadId,
|
|
274712
|
+
totalSize: dataItemByteCount,
|
|
274713
|
+
chunkByteCount: this.chunkByteCount,
|
|
274714
|
+
maxChunkConcurrency: this.maxChunkConcurrency,
|
|
274715
|
+
inputStreamType: isReadableStream2(stream2) ? "ReadableStream" : "Readable"
|
|
274716
|
+
});
|
|
274717
|
+
const inFlight = /* @__PURE__ */ new Set();
|
|
274718
|
+
const internalAbort = new AbortController();
|
|
274719
|
+
const combinedSignal = combineAbortSignals([internalAbort.signal, signal]);
|
|
274720
|
+
const limit = pLimit(this.maxChunkConcurrency);
|
|
274721
|
+
let currentOffset = 0;
|
|
274722
|
+
let currentChunkPartNumber = 0;
|
|
274723
|
+
let firstError;
|
|
274724
|
+
let uploadedBytes = 0;
|
|
274725
|
+
const chunks = splitIntoChunks(stream2, this.chunkByteCount);
|
|
274726
|
+
resume();
|
|
274727
|
+
for await (const chunk of chunks) {
|
|
274728
|
+
if (combinedSignal?.aborted) {
|
|
274729
|
+
internalAbort.abort();
|
|
274730
|
+
await Promise.allSettled(inFlight);
|
|
274731
|
+
firstError ??= new CanceledError2();
|
|
274732
|
+
break;
|
|
274733
|
+
}
|
|
274734
|
+
const chunkPartNumber = ++currentChunkPartNumber;
|
|
274735
|
+
const chunkByteCount = chunk.length;
|
|
274736
|
+
const chunkOffset = currentOffset;
|
|
274737
|
+
currentOffset += chunkByteCount;
|
|
274738
|
+
this.logger.debug("Queueing chunk", {
|
|
274739
|
+
chunkPartNumber,
|
|
274740
|
+
chunkOffset,
|
|
274741
|
+
chunkByteCount
|
|
274742
|
+
});
|
|
274743
|
+
const promise = limit(async () => {
|
|
274744
|
+
if (firstError !== void 0) {
|
|
274745
|
+
return;
|
|
274746
|
+
}
|
|
274747
|
+
this.logger.debug("Uploading chunk", {
|
|
274748
|
+
chunkPartNumber,
|
|
274749
|
+
chunkOffset,
|
|
274750
|
+
chunkByteCount
|
|
274751
|
+
});
|
|
274752
|
+
await this.http.post({
|
|
274753
|
+
endpoint: `/chunks/${this.token}/${uploadId}/${chunkOffset}`,
|
|
274754
|
+
data: chunk,
|
|
274755
|
+
headers: {
|
|
274756
|
+
"Content-Type": "application/octet-stream",
|
|
274757
|
+
...chunkingHeader
|
|
274758
|
+
},
|
|
274759
|
+
signal: combinedSignal
|
|
274760
|
+
});
|
|
274761
|
+
uploadedBytes += chunkByteCount;
|
|
274762
|
+
this.logger.debug("Chunk uploaded", {
|
|
274763
|
+
chunkPartNumber,
|
|
274764
|
+
chunkOffset,
|
|
274765
|
+
chunkByteCount
|
|
274766
|
+
});
|
|
274767
|
+
emitter.emit("upload-progress", {
|
|
274768
|
+
processedBytes: uploadedBytes,
|
|
274769
|
+
totalBytes: dataItemByteCount
|
|
274770
|
+
});
|
|
274771
|
+
}).catch((err) => {
|
|
274772
|
+
this.logger.error("Chunk upload failed", {
|
|
274773
|
+
id: chunkPartNumber,
|
|
274774
|
+
offset: chunkOffset,
|
|
274775
|
+
size: chunkByteCount,
|
|
274776
|
+
err
|
|
274777
|
+
});
|
|
274778
|
+
emitter.emit("upload-error", err);
|
|
274779
|
+
internalAbort.abort(err);
|
|
274780
|
+
firstError = firstError ?? err;
|
|
274781
|
+
});
|
|
274782
|
+
inFlight.add(promise);
|
|
274783
|
+
promise.finally(() => inFlight.delete(promise));
|
|
274784
|
+
if (inFlight.size >= this.maxBacklogQueue) {
|
|
274785
|
+
await Promise.race(inFlight);
|
|
274786
|
+
if (combinedSignal?.aborted) {
|
|
274787
|
+
internalAbort.abort();
|
|
274788
|
+
await Promise.allSettled(inFlight);
|
|
274789
|
+
firstError ??= new CanceledError2();
|
|
274790
|
+
break;
|
|
274791
|
+
}
|
|
274792
|
+
}
|
|
274793
|
+
}
|
|
274794
|
+
await Promise.all(inFlight);
|
|
274795
|
+
if (firstError !== void 0) {
|
|
274796
|
+
throw firstError;
|
|
274797
|
+
}
|
|
274798
|
+
const paidByHeader = {};
|
|
274799
|
+
if (dataItemOpts?.paidBy !== void 0) {
|
|
274800
|
+
paidByHeader["x-paid-by"] = Array.isArray(dataItemOpts.paidBy) ? dataItemOpts.paidBy.join(",") : dataItemOpts.paidBy;
|
|
274801
|
+
}
|
|
274802
|
+
const finalizeResponse = await this.http.post({
|
|
274803
|
+
endpoint: `/chunks/${this.token}/${uploadId}/-1`,
|
|
274804
|
+
data: Buffer2.alloc(0),
|
|
274805
|
+
headers: {
|
|
274806
|
+
"Content-Type": "application/octet-stream",
|
|
274807
|
+
...paidByHeader,
|
|
274808
|
+
...chunkingHeader
|
|
274809
|
+
},
|
|
274810
|
+
signal: combinedSignal
|
|
274811
|
+
});
|
|
274812
|
+
emitter.emit("upload-success");
|
|
274813
|
+
return finalizeResponse;
|
|
274814
|
+
}
|
|
274815
|
+
};
|
|
274816
|
+
async function* splitIntoChunks(source, chunkByteCount) {
|
|
274817
|
+
if (isReadableStream2(source)) {
|
|
274818
|
+
yield* splitReadableStreamIntoChunks(source, chunkByteCount);
|
|
274819
|
+
} else {
|
|
274820
|
+
yield* splitReadableIntoChunks(source, chunkByteCount);
|
|
274821
|
+
}
|
|
274822
|
+
}
|
|
274823
|
+
async function* splitReadableIntoChunks(source, chunkByteCount) {
|
|
274824
|
+
const queue2 = [];
|
|
274825
|
+
let total = 0;
|
|
274826
|
+
let encoder;
|
|
274827
|
+
for await (const piece of source) {
|
|
274828
|
+
const u82 = piece instanceof Uint8Array ? new Uint8Array(piece.buffer, piece.byteOffset, piece.byteLength) : (encoder ??= new TextEncoder()).encode(String(piece));
|
|
274829
|
+
queue2.push(u82);
|
|
274830
|
+
total += u82.length;
|
|
274831
|
+
while (total >= chunkByteCount) {
|
|
274832
|
+
const out = new Uint8Array(chunkByteCount);
|
|
274833
|
+
let remaining = out.length;
|
|
274834
|
+
let off2 = 0;
|
|
274835
|
+
while (remaining > 0) {
|
|
274836
|
+
const head = queue2[0];
|
|
274837
|
+
const take = Math.min(remaining, head.length);
|
|
274838
|
+
out.set(head.subarray(0, take), off2);
|
|
274839
|
+
off2 += take;
|
|
274840
|
+
remaining -= take;
|
|
274841
|
+
if (take === head.length) {
|
|
274842
|
+
queue2.shift();
|
|
274843
|
+
} else {
|
|
274844
|
+
queue2[0] = head.subarray(take);
|
|
274845
|
+
}
|
|
274846
|
+
}
|
|
274847
|
+
total -= chunkByteCount;
|
|
274848
|
+
yield Buffer2.from(out.buffer, out.byteOffset, out.byteLength);
|
|
274849
|
+
}
|
|
274850
|
+
}
|
|
274851
|
+
if (total > 0) {
|
|
274852
|
+
const out = new Uint8Array(total);
|
|
274853
|
+
let off2 = 0;
|
|
274854
|
+
while (queue2.length > 0) {
|
|
274855
|
+
const head = queue2.shift();
|
|
274856
|
+
out.set(head, off2);
|
|
274857
|
+
off2 += head.length;
|
|
274858
|
+
}
|
|
274859
|
+
yield Buffer2.from(out.buffer, out.byteOffset, out.byteLength);
|
|
274860
|
+
}
|
|
274861
|
+
}
|
|
274862
|
+
async function* splitReadableStreamIntoChunks(source, chunkByteCount) {
|
|
274863
|
+
const reader = source.getReader();
|
|
274864
|
+
const queue2 = [];
|
|
274865
|
+
let total = 0;
|
|
274866
|
+
try {
|
|
274867
|
+
while (true) {
|
|
274868
|
+
const { value, done } = await reader.read();
|
|
274869
|
+
if (done)
|
|
274870
|
+
break;
|
|
274871
|
+
const u82 = new Uint8Array(
|
|
274872
|
+
value.buffer,
|
|
274873
|
+
value.byteOffset,
|
|
274874
|
+
value.byteLength
|
|
274875
|
+
);
|
|
274876
|
+
queue2.push(u82);
|
|
274877
|
+
total += u82.length;
|
|
274878
|
+
while (total >= chunkByteCount) {
|
|
274879
|
+
const out = new Uint8Array(chunkByteCount);
|
|
274880
|
+
let remaining = out.length;
|
|
274881
|
+
let off2 = 0;
|
|
274882
|
+
while (remaining > 0) {
|
|
274883
|
+
const head = queue2[0];
|
|
274884
|
+
const take = Math.min(remaining, head.length);
|
|
274885
|
+
out.set(head.subarray(0, take), off2);
|
|
274886
|
+
off2 += take;
|
|
274887
|
+
remaining -= take;
|
|
274888
|
+
if (take === head.length) {
|
|
274889
|
+
queue2.shift();
|
|
274890
|
+
} else {
|
|
274891
|
+
queue2[0] = head.subarray(take);
|
|
274892
|
+
}
|
|
274893
|
+
}
|
|
274894
|
+
total -= chunkByteCount;
|
|
274895
|
+
yield Buffer2.from(out.buffer, out.byteOffset, out.byteLength);
|
|
274896
|
+
}
|
|
274897
|
+
}
|
|
274898
|
+
if (total > 0) {
|
|
274899
|
+
const out = new Uint8Array(total);
|
|
274900
|
+
let off2 = 0;
|
|
274901
|
+
while (queue2.length > 0) {
|
|
274902
|
+
const head = queue2.shift();
|
|
274903
|
+
out.set(head, off2);
|
|
274904
|
+
off2 += head.length;
|
|
274905
|
+
}
|
|
274906
|
+
yield Buffer2.from(out.buffer, out.byteOffset, out.byteLength);
|
|
274907
|
+
}
|
|
274908
|
+
} finally {
|
|
274909
|
+
reader.releaseLock();
|
|
274910
|
+
}
|
|
274911
|
+
}
|
|
274912
|
+
function isReadableStream2(source) {
|
|
274913
|
+
if (typeof ReadableStream !== "undefined" && source instanceof ReadableStream) {
|
|
274914
|
+
return true;
|
|
274915
|
+
}
|
|
274916
|
+
return source !== null && typeof source === "object" && "getReader" in source && typeof source.getReader === "function";
|
|
274917
|
+
}
|
|
274918
|
+
function combineAbortSignals(signals) {
|
|
274919
|
+
const real = signals.filter(Boolean);
|
|
274920
|
+
if (real.length === 0)
|
|
274921
|
+
return void 0;
|
|
274922
|
+
const anyFn = AbortSignal.any;
|
|
274923
|
+
if (typeof anyFn === "function") {
|
|
274924
|
+
return anyFn(real);
|
|
274925
|
+
}
|
|
274926
|
+
const controller = new AbortController();
|
|
274927
|
+
for (const s7 of real) {
|
|
274928
|
+
const sig = s7;
|
|
274929
|
+
if (sig.aborted) {
|
|
274930
|
+
controller.abort(sig.reason);
|
|
274931
|
+
break;
|
|
274932
|
+
}
|
|
274933
|
+
const onAbort = () => controller.abort(sig.reason);
|
|
274934
|
+
s7.addEventListener("abort", onAbort, { once: true });
|
|
274935
|
+
}
|
|
274936
|
+
return controller.signal;
|
|
274937
|
+
}
|
|
274938
|
+
|
|
274598
274939
|
// src/common/upload.ts
|
|
274599
274940
|
function isTurboUploadFileWithStreamFactoryParams(params) {
|
|
274600
274941
|
return "fileStreamFactory" in params;
|
|
@@ -274679,7 +275020,10 @@ var TurboAuthenticatedBaseUploadService = class extends TurboUnauthenticatedUplo
|
|
|
274679
275020
|
data,
|
|
274680
275021
|
dataItemOpts,
|
|
274681
275022
|
signal,
|
|
274682
|
-
events
|
|
275023
|
+
events,
|
|
275024
|
+
chunkByteCount,
|
|
275025
|
+
chunkingMode,
|
|
275026
|
+
maxChunkConcurrency
|
|
274683
275027
|
}) {
|
|
274684
275028
|
if (isBlob2(data)) {
|
|
274685
275029
|
const streamFactory = () => data.stream();
|
|
@@ -274705,7 +275049,10 @@ var TurboAuthenticatedBaseUploadService = class extends TurboUnauthenticatedUplo
|
|
|
274705
275049
|
fileSizeFactory: () => dataBuffer.byteLength,
|
|
274706
275050
|
signal,
|
|
274707
275051
|
dataItemOpts,
|
|
274708
|
-
events
|
|
275052
|
+
events,
|
|
275053
|
+
chunkByteCount,
|
|
275054
|
+
chunkingMode,
|
|
275055
|
+
maxChunkConcurrency
|
|
274709
275056
|
});
|
|
274710
275057
|
}
|
|
274711
275058
|
resolveUploadFileConfig(params) {
|
|
@@ -274737,17 +275084,37 @@ var TurboAuthenticatedBaseUploadService = class extends TurboUnauthenticatedUplo
|
|
|
274737
275084
|
let lastError = void 0;
|
|
274738
275085
|
let lastStatusCode = void 0;
|
|
274739
275086
|
const emitter = new TurboEventEmitter(events);
|
|
274740
|
-
const { dataItemStreamFactory, dataItemSizeFactory } = await this.signer.signDataItem({
|
|
274741
|
-
fileStreamFactory,
|
|
274742
|
-
fileSizeFactory,
|
|
274743
|
-
dataItemOpts,
|
|
274744
|
-
emitter
|
|
274745
|
-
});
|
|
274746
275087
|
while (retries < maxRetries) {
|
|
274747
275088
|
if (signal?.aborted) {
|
|
274748
275089
|
throw new CanceledError2();
|
|
274749
275090
|
}
|
|
275091
|
+
const { dataItemStreamFactory, dataItemSizeFactory } = await this.signer.signDataItem({
|
|
275092
|
+
fileStreamFactory,
|
|
275093
|
+
fileSizeFactory,
|
|
275094
|
+
dataItemOpts,
|
|
275095
|
+
emitter
|
|
275096
|
+
});
|
|
274750
275097
|
try {
|
|
275098
|
+
const { chunkByteCount, maxChunkConcurrency } = params;
|
|
275099
|
+
const chunkedUploader = new ChunkedUploader({
|
|
275100
|
+
http: this.httpService,
|
|
275101
|
+
token: this.token,
|
|
275102
|
+
maxChunkConcurrency,
|
|
275103
|
+
chunkByteCount,
|
|
275104
|
+
logger: this.logger,
|
|
275105
|
+
dataItemByteCount: dataItemSizeFactory(),
|
|
275106
|
+
chunkingMode: params.chunkingMode
|
|
275107
|
+
});
|
|
275108
|
+
if (chunkedUploader.shouldUseChunkUploader) {
|
|
275109
|
+
const response2 = await chunkedUploader.upload({
|
|
275110
|
+
dataItemStreamFactory,
|
|
275111
|
+
dataItemSizeFactory,
|
|
275112
|
+
dataItemOpts,
|
|
275113
|
+
signal,
|
|
275114
|
+
events
|
|
275115
|
+
});
|
|
275116
|
+
return response2;
|
|
275117
|
+
}
|
|
274751
275118
|
const response = await this.uploadSignedDataItem({
|
|
274752
275119
|
dataItemStreamFactory,
|
|
274753
275120
|
dataItemSizeFactory,
|
|
@@ -274847,7 +275214,10 @@ ${lastError instanceof Error ? lastError.message : lastError}`;
|
|
|
274847
275214
|
signal,
|
|
274848
275215
|
manifestOptions = {},
|
|
274849
275216
|
maxConcurrentUploads = 1,
|
|
274850
|
-
throwOnFailure = true
|
|
275217
|
+
throwOnFailure = true,
|
|
275218
|
+
maxChunkConcurrency,
|
|
275219
|
+
chunkByteCount,
|
|
275220
|
+
chunkingMode
|
|
274851
275221
|
} = params;
|
|
274852
275222
|
const { disableManifest, indexFile, fallbackFile } = manifestOptions;
|
|
274853
275223
|
const paths = {};
|
|
@@ -274873,7 +275243,10 @@ ${lastError instanceof Error ? lastError.message : lastError}`;
|
|
|
274873
275243
|
fileStreamFactory: () => this.getFileStreamForFile(file),
|
|
274874
275244
|
fileSizeFactory: () => this.getFileSize(file),
|
|
274875
275245
|
signal,
|
|
274876
|
-
dataItemOpts: dataItemOptsWithContentType
|
|
275246
|
+
dataItemOpts: dataItemOptsWithContentType,
|
|
275247
|
+
chunkByteCount,
|
|
275248
|
+
maxChunkConcurrency,
|
|
275249
|
+
chunkingMode
|
|
274877
275250
|
});
|
|
274878
275251
|
const relativePath = this.getRelativePath(file, params);
|
|
274879
275252
|
paths[relativePath] = { id: result2.id };
|
|
@@ -274916,7 +275289,10 @@ ${lastError instanceof Error ? lastError.message : lastError}`;
|
|
|
274916
275289
|
fileStreamFactory: () => this.createManifestStream(manifestBuffer),
|
|
274917
275290
|
fileSizeFactory: () => manifestBuffer.byteLength,
|
|
274918
275291
|
signal,
|
|
274919
|
-
dataItemOpts: { ...dataItemOpts, tags: tagsWithManifestContentType }
|
|
275292
|
+
dataItemOpts: { ...dataItemOpts, tags: tagsWithManifestContentType },
|
|
275293
|
+
chunkByteCount,
|
|
275294
|
+
maxChunkConcurrency,
|
|
275295
|
+
chunkingMode
|
|
274920
275296
|
});
|
|
274921
275297
|
return {
|
|
274922
275298
|
...response,
|
|
@@ -275164,9 +275540,20 @@ var TurboAuthenticatedClient = class extends TurboUnauthenticatedClient {
|
|
|
275164
275540
|
data,
|
|
275165
275541
|
dataItemOpts,
|
|
275166
275542
|
signal,
|
|
275167
|
-
events
|
|
275543
|
+
events,
|
|
275544
|
+
chunkByteCount,
|
|
275545
|
+
chunkingMode,
|
|
275546
|
+
maxChunkConcurrency
|
|
275168
275547
|
}) {
|
|
275169
|
-
return this.uploadService.upload({
|
|
275548
|
+
return this.uploadService.upload({
|
|
275549
|
+
data,
|
|
275550
|
+
dataItemOpts,
|
|
275551
|
+
signal,
|
|
275552
|
+
events,
|
|
275553
|
+
chunkByteCount,
|
|
275554
|
+
chunkingMode,
|
|
275555
|
+
maxChunkConcurrency
|
|
275556
|
+
});
|
|
275170
275557
|
}
|
|
275171
275558
|
uploadFile(params) {
|
|
275172
275559
|
return this.uploadService.uploadFile(params);
|
|
@@ -275952,6 +276339,7 @@ export {
|
|
|
275952
276339
|
tokenToBaseMap,
|
|
275953
276340
|
tokenTypes,
|
|
275954
276341
|
ukyveToTokenAmount,
|
|
276342
|
+
validChunkingModes,
|
|
275955
276343
|
weiToTokenAmount
|
|
275956
276344
|
};
|
|
275957
276345
|
/*! Bundled license information:
|
|
@@ -32,6 +32,7 @@ async function uploadFile(options) {
|
|
|
32
32
|
fileStreamFactory: () => (0, fs_1.createReadStream)(filePath),
|
|
33
33
|
fileSizeFactory: () => fileSize,
|
|
34
34
|
dataItemOpts: { tags: [...constants_js_1.turboCliTags, ...customTags], paidBy },
|
|
35
|
+
...(0, utils_js_1.getChunkingOptions)(options),
|
|
35
36
|
});
|
|
36
37
|
console.log('Uploaded file:', JSON.stringify(result, null, 2));
|
|
37
38
|
}
|
|
@@ -21,7 +21,7 @@ const utils_js_1 = require("../utils.js");
|
|
|
21
21
|
async function uploadFolder(options) {
|
|
22
22
|
const turbo = await (0, utils_js_1.turboFromOptions)(options);
|
|
23
23
|
const paidBy = await (0, utils_js_1.paidByFromOptions)(options, turbo);
|
|
24
|
-
const { disableManifest, fallbackFile, folderPath, indexFile, maxConcurrentUploads, } = (0, utils_js_1.getUploadFolderOptions)(options);
|
|
24
|
+
const { disableManifest, fallbackFile, folderPath, indexFile, maxConcurrentUploads, chunkByteCount, chunkingMode, maxChunkConcurrency, } = (0, utils_js_1.getUploadFolderOptions)(options);
|
|
25
25
|
const customTags = (0, utils_js_1.getTagsFromOptions)(options);
|
|
26
26
|
const result = await turbo.uploadFolder({
|
|
27
27
|
folderPath: folderPath,
|
|
@@ -32,6 +32,9 @@ async function uploadFolder(options) {
|
|
|
32
32
|
fallbackFile,
|
|
33
33
|
},
|
|
34
34
|
maxConcurrentUploads,
|
|
35
|
+
chunkByteCount,
|
|
36
|
+
chunkingMode,
|
|
37
|
+
maxChunkConcurrency,
|
|
35
38
|
});
|
|
36
39
|
console.log('Uploaded folder:', JSON.stringify(result, null, 2));
|
|
37
40
|
}
|
package/lib/cjs/cli/options.js
CHANGED
|
@@ -134,7 +134,7 @@ exports.optionMap = {
|
|
|
134
134
|
},
|
|
135
135
|
maxConcurrency: {
|
|
136
136
|
alias: '--max-concurrency <maxConcurrency>',
|
|
137
|
-
description: 'Maximum number of concurrent uploads',
|
|
137
|
+
description: 'Maximum number of concurrent file uploads',
|
|
138
138
|
},
|
|
139
139
|
paidBy: {
|
|
140
140
|
alias: '--paid-by <paidBy...>',
|
|
@@ -159,6 +159,19 @@ exports.optionMap = {
|
|
|
159
159
|
alias: '--byte-count <byteCount>',
|
|
160
160
|
description: 'Number of bytes to use for the action',
|
|
161
161
|
},
|
|
162
|
+
maxChunkConcurrency: {
|
|
163
|
+
alias: '--max-chunk-concurrency <maxChunkConcurrency>',
|
|
164
|
+
description: 'Maximum number of concurrent chunks to upload per file',
|
|
165
|
+
},
|
|
166
|
+
chunkByteCount: {
|
|
167
|
+
alias: '--chunk-byte-count <chunkByteCount>',
|
|
168
|
+
description: 'Size of each chunk in bytes',
|
|
169
|
+
},
|
|
170
|
+
chunkingMode: {
|
|
171
|
+
alias: '--chunking-mode <chunkingMode>',
|
|
172
|
+
description: 'Chunking mode to use for the upload. Can be "auto", "force" or "disabled". Defaults to "auto".',
|
|
173
|
+
default: 'auto',
|
|
174
|
+
},
|
|
162
175
|
};
|
|
163
176
|
exports.walletOptions = [
|
|
164
177
|
exports.optionMap.walletFile,
|
|
@@ -182,6 +195,9 @@ exports.uploadOptions = [
|
|
|
182
195
|
exports.optionMap.ignoreApprovals,
|
|
183
196
|
exports.optionMap.useSignerBalanceFirst,
|
|
184
197
|
exports.optionMap.tags,
|
|
198
|
+
exports.optionMap.maxChunkConcurrency,
|
|
199
|
+
exports.optionMap.chunkByteCount,
|
|
200
|
+
exports.optionMap.chunkingMode,
|
|
185
201
|
];
|
|
186
202
|
exports.uploadFolderOptions = [
|
|
187
203
|
...exports.uploadOptions,
|
package/lib/cjs/cli/types.js
CHANGED
|
@@ -1,17 +1,2 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
-
/**
|
|
3
|
-
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
4
|
-
*
|
|
5
|
-
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
-
* you may not use this file except in compliance with the License.
|
|
7
|
-
* You may obtain a copy of the License at
|
|
8
|
-
*
|
|
9
|
-
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
-
*
|
|
11
|
-
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
-
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
-
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
-
* See the License for the specific language governing permissions and
|
|
15
|
-
* limitations under the License.
|
|
16
|
-
*/
|
|
17
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
package/lib/cjs/cli/utils.js
CHANGED
|
@@ -20,6 +20,7 @@ exports.parseTags = parseTags;
|
|
|
20
20
|
exports.getTagsFromOptions = getTagsFromOptions;
|
|
21
21
|
exports.currencyFromOptions = currencyFromOptions;
|
|
22
22
|
exports.requiredByteCountFromOptions = requiredByteCountFromOptions;
|
|
23
|
+
exports.getChunkingOptions = getChunkingOptions;
|
|
23
24
|
/**
|
|
24
25
|
* Copyright (C) 2022-2024 Permanent Data Solutions, Inc.
|
|
25
26
|
*
|
|
@@ -236,6 +237,7 @@ function getUploadFolderOptions(options) {
|
|
|
236
237
|
fallbackFile: options.fallbackFile,
|
|
237
238
|
disableManifest: !options.manifest,
|
|
238
239
|
maxConcurrentUploads: +(options.maxConcurrency ?? 1),
|
|
240
|
+
...getChunkingOptions(options),
|
|
239
241
|
};
|
|
240
242
|
}
|
|
241
243
|
/**
|
|
@@ -283,3 +285,14 @@ function requiredByteCountFromOptions({ byteCount, }) {
|
|
|
283
285
|
}
|
|
284
286
|
return byteCountValue;
|
|
285
287
|
}
|
|
288
|
+
function getChunkingOptions(options) {
|
|
289
|
+
return {
|
|
290
|
+
chunkingMode: options.chunkingMode,
|
|
291
|
+
chunkByteCount: options.chunkByteCount !== undefined
|
|
292
|
+
? +options.chunkByteCount
|
|
293
|
+
: undefined,
|
|
294
|
+
maxChunkConcurrency: options.maxChunkConcurrency !== undefined
|
|
295
|
+
? +options.maxChunkConcurrency
|
|
296
|
+
: undefined,
|
|
297
|
+
};
|
|
298
|
+
}
|