@lossless.org/client 2.1.0 → 2.3.0

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.
@@ -60,4 +60,33 @@ export const planMultipartUpload = (optionsArg) => {
60
60
  maximumBufferedBytes: Math.min(optionsArg.objectSize, partSize * concurrency) + Math.min(optionsArg.objectSize, partSize),
61
61
  };
62
62
  };
63
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwubXVsdGlwYXJ0LnBsYW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9vYmplY3RzdG9yYWdlL2ludGVybmFsLm11bHRpcGFydC5wbGFubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUtBLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3ZELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUM5RCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLENBQUM7QUFDL0MsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN2RSxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7QUFDL0MsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsRUFBRSxDQUFDO0FBRTVDLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxRQUFnQixFQUFFLE9BQWUsRUFBUSxFQUFFO0lBQ2hGLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNwRCxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsT0FBTyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLDBCQUEwQixHQUFHLENBQUMsb0JBQXdDLEVBQVUsRUFBRTtJQUN0RixJQUFJLG9CQUFvQixLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLE9BQU8sdUJBQXVCLENBQUM7SUFDakMsQ0FBQztJQUNELElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLElBQUksb0JBQW9CLElBQUksQ0FBQyxF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
63
+ /**
64
+ * Plans an upload of undeclared length that must not exceed
65
+ * `maxObjectSize`. The part size grows with the maximum so that the largest
66
+ * allowed source still fits into the multipart part limit.
67
+ */
68
+ export const planBoundedMultipartUpload = (optionsArg) => {
69
+ if (!Number.isSafeInteger(optionsArg.maxObjectSize) || optionsArg.maxObjectSize < 1) {
70
+ throw new TypeError('maxObjectSize must be a positive safe integer.');
71
+ }
72
+ if (optionsArg.maxObjectSize > MULTIPART_MAX_OBJECT_SIZE) {
73
+ throw new RangeError(`maxObjectSize exceeds the ${MULTIPART_MAX_OBJECT_SIZE} byte multipart limit.`);
74
+ }
75
+ const requestedConcurrency = normalizeRequestedConcurrency(optionsArg.requestedConcurrency);
76
+ const preferredPartSize = normalizeRequestedPartSize(optionsArg.requestedPartSize);
77
+ const partSize = Math.max(preferredPartSize, Math.ceil(optionsArg.maxObjectSize / MULTIPART_MAX_PART_COUNT));
78
+ if (partSize > MULTIPART_MAX_PART_SIZE) {
79
+ throw new RangeError('The maximum cannot be represented by legal multipart parts.');
80
+ }
81
+ const maxPartCount = Math.ceil(optionsArg.maxObjectSize / partSize);
82
+ const concurrency = Math.min(requestedConcurrency, maxPartCount);
83
+ return {
84
+ classification: 'bounded',
85
+ maxObjectSize: optionsArg.maxObjectSize,
86
+ partSize,
87
+ maxPartCount,
88
+ concurrency,
89
+ maximumBufferedBytes: Math.min(optionsArg.maxObjectSize, partSize * concurrency) + Math.min(optionsArg.maxObjectSize, partSize),
90
+ };
91
+ };
92
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwubXVsdGlwYXJ0LnBsYW5uZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi90cy9vYmplY3RzdG9yYWdlL2ludGVybmFsLm11bHRpcGFydC5wbGFubmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQU9BLE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3ZELE1BQU0sQ0FBQyxNQUFNLHVCQUF1QixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUM5RCxNQUFNLENBQUMsTUFBTSx3QkFBd0IsR0FBRyxNQUFNLENBQUM7QUFDL0MsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsQ0FBQyxHQUFHLElBQUksR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN2RSxNQUFNLENBQUMsTUFBTSw2QkFBNkIsR0FBRyxDQUFDLENBQUM7QUFDL0MsTUFBTSxDQUFDLE1BQU0seUJBQXlCLEdBQUcsRUFBRSxDQUFDO0FBRTVDLE1BQU0sNkJBQTZCLEdBQUcsQ0FBQyxRQUFnQixFQUFFLE9BQWUsRUFBUSxFQUFFO0lBQ2hGLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxJQUFJLFFBQVEsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUNwRCxNQUFNLElBQUksU0FBUyxDQUFDLEdBQUcsT0FBTyx1Q0FBdUMsQ0FBQyxDQUFDO0lBQ3pFLENBQUM7QUFDSCxDQUFDLENBQUM7QUFFRixNQUFNLDBCQUEwQixHQUFHLENBQUMsb0JBQXdDLEVBQVUsRUFBRTtJQUN0RixJQUFJLG9CQUFvQixLQUFLLFNBQVMsRUFBRSxDQUFDO1FBQ3ZDLE9BQU8sdUJBQXVCLENBQUM7SUFDakMsQ0FBQztJQUNELElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLG9CQUFvQixDQUFDLElBQUksb0JBQW9CLElBQUksQ0FBQyxF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
@@ -6,6 +6,7 @@ const failureMessages = {
6
6
  'source-empty-chunk-limit': 'The multipart source emitted too many consecutive empty chunks.',
7
7
  'source-short': 'The multipart source ended before the declared content length.',
8
8
  'source-extra': 'The multipart source exceeded the declared content length.',
9
+ 'source-over-maximum': 'The multipart source exceeded the maximum content length.',
9
10
  'part-callback': 'A multipart part callback failed.',
10
11
  };
11
12
  const failureSettlementMaximumTimeoutMs = 30_000;
@@ -33,16 +34,33 @@ export class MultipartStreamConsumptionError extends Error {
33
34
  }
34
35
  }
35
36
  const validatePlan = (planArg) => {
36
- if (!Number.isSafeInteger(planArg.objectSize) ||
37
- planArg.objectSize < 0 ||
38
- planArg.objectSize > MULTIPART_MAX_OBJECT_SIZE) {
39
- throw new TypeError('plan.objectSize is invalid.');
40
- }
41
37
  if (!Number.isSafeInteger(planArg.concurrency) ||
42
38
  planArg.concurrency < 1 ||
43
39
  planArg.concurrency > MULTIPART_MAX_CONCURRENCY) {
44
40
  throw new TypeError('plan.concurrency is invalid.');
45
41
  }
42
+ if (planArg.classification === 'bounded') {
43
+ if (!Number.isSafeInteger(planArg.maxObjectSize) ||
44
+ planArg.maxObjectSize < 1 ||
45
+ planArg.maxObjectSize > MULTIPART_MAX_OBJECT_SIZE ||
46
+ !Number.isSafeInteger(planArg.partSize) ||
47
+ planArg.partSize < MULTIPART_MIN_PART_SIZE ||
48
+ planArg.partSize > MULTIPART_MAX_PART_SIZE ||
49
+ planArg.maxPartCount !== Math.ceil(planArg.maxObjectSize / planArg.partSize) ||
50
+ planArg.maxPartCount > MULTIPART_MAX_PART_COUNT ||
51
+ planArg.concurrency > planArg.maxPartCount ||
52
+ planArg.maximumBufferedBytes !==
53
+ Math.min(planArg.maxObjectSize, planArg.partSize * planArg.concurrency) +
54
+ Math.min(planArg.maxObjectSize, planArg.partSize)) {
55
+ throw new TypeError('The bounded multipart plan is inconsistent.');
56
+ }
57
+ return;
58
+ }
59
+ if (!Number.isSafeInteger(planArg.objectSize) ||
60
+ planArg.objectSize < 0 ||
61
+ planArg.objectSize > MULTIPART_MAX_OBJECT_SIZE) {
62
+ throw new TypeError('plan.objectSize is invalid.');
63
+ }
46
64
  if (planArg.classification === 'zero') {
47
65
  if (planArg.objectSize !== 0 ||
48
66
  planArg.partSize !== 0 ||
@@ -82,6 +100,14 @@ export const consumeExactMultipartStream = async (optionsArg) => {
82
100
  failureSettlementTimeoutMs > failureSettlementMaximumTimeoutMs) {
83
101
  throw new TypeError(`failureSettlementTimeoutMs must be a positive safe integer no greater than ${failureSettlementMaximumTimeoutMs}.`);
84
102
  }
103
+ const plan = optionsArg.plan;
104
+ // A bounded plan reads parts until the source ends and refuses more than
105
+ // its maximum; an exact plan reads exactly the declared length.
106
+ const bounded = plan.classification === 'bounded';
107
+ const sizeLimit = bounded ? plan.maxObjectSize : plan.objectSize;
108
+ const overLimitKind = bounded
109
+ ? 'source-over-maximum'
110
+ : 'source-extra';
85
111
  const reader = optionsArg.readableStream.getReader();
86
112
  const callbackAbortController = new AbortController();
87
113
  const inFlightParts = new Map();
@@ -187,7 +213,7 @@ export const consumeExactMultipartStream = async (optionsArg) => {
187
213
  return outcome.result;
188
214
  }
189
215
  };
190
- const dispatchPart = (dataArg, partNumberArg) => {
216
+ const dispatchPart = (dataArg, partNumberArg, isLastPartArg) => {
191
217
  const token = Symbol(`multipart-part-${partNumberArg}`);
192
218
  partCallbacksStarted++;
193
219
  currentPartBytes = 0;
@@ -196,8 +222,8 @@ export const consumeExactMultipartStream = async (optionsArg) => {
196
222
  const outcome = Promise.resolve()
197
223
  .then(() => optionsArg.onPart({
198
224
  partNumber: partNumberArg,
199
- byteOffset: (partNumberArg - 1) * optionsArg.plan.partSize,
200
- isLastPart: partNumberArg === optionsArg.plan.partCount,
225
+ byteOffset: (partNumberArg - 1) * plan.partSize,
226
+ isLastPart: isLastPartArg,
201
227
  data: dataArg,
202
228
  signal: callbackAbortController.signal,
203
229
  }))
@@ -233,10 +259,14 @@ export const consumeExactMultipartStream = async (optionsArg) => {
233
259
  try {
234
260
  let pendingChunk;
235
261
  let pendingChunkOffset = 0;
236
- for (let partNumber = 1; partNumber <= optionsArg.plan.partCount; partNumber++) {
262
+ for (let partNumber = 1; bounded ? !sourceClosed : partNumber <= plan.partCount; partNumber++) {
237
263
  await waitForCapacity();
238
- const partByteLength = Math.min(optionsArg.plan.partSize, optionsArg.plan.objectSize -
239
- (partNumber - 1) * optionsArg.plan.partSize);
264
+ const partByteLength = Math.min(plan.partSize, sizeLimit - (partNumber - 1) * plan.partSize);
265
+ if (partByteLength <= 0) {
266
+ // A bounded source filled its maximum, which ends at or inside the
267
+ // previous part; the trailing read below refuses any further byte.
268
+ break;
269
+ }
240
270
  if (inFlightBytes + partByteLength >
241
271
  optionsArg.plan.maximumBufferedBytes) {
242
272
  throw new Error('The multipart plan cannot honor its buffering bound.');
@@ -262,6 +292,9 @@ export const consumeExactMultipartStream = async (optionsArg) => {
262
292
  const readResult = await readWhileObservingCallbacks();
263
293
  if (readResult.done) {
264
294
  sourceClosed = true;
295
+ if (bounded) {
296
+ break;
297
+ }
265
298
  throw {
266
299
  kind: 'source-short',
267
300
  };
@@ -276,22 +309,36 @@ export const consumeExactMultipartStream = async (optionsArg) => {
276
309
  continue;
277
310
  }
278
311
  observedBytes += readResult.value.byteLength;
279
- if (observedBytes > optionsArg.plan.objectSize) {
312
+ if (observedBytes > sizeLimit) {
280
313
  throw {
281
- kind: 'source-extra',
314
+ kind: overLimitKind,
282
315
  };
283
316
  }
284
- if (readResult.value.byteLength > optionsArg.plan.partSize) {
317
+ if (readResult.value.byteLength > plan.partSize) {
285
318
  throw {
286
319
  kind: 'source-buffer-limit',
287
- cause: new RangeError(`Source chunks must not exceed ${optionsArg.plan.partSize} bytes.`),
320
+ cause: new RangeError(`Source chunks must not exceed ${plan.partSize} bytes.`),
288
321
  };
289
322
  }
290
323
  pendingChunk = readResult.value;
291
324
  pendingChunkBytes = readResult.value.byteLength;
292
325
  observeBufferedBytes();
293
326
  }
294
- dispatchPart(partData, partNumber);
327
+ if (partOffset === 0) {
328
+ // A bounded source ended at a part boundary.
329
+ currentPartBytes = 0;
330
+ break;
331
+ }
332
+ if (partOffset < partByteLength) {
333
+ // Only a bounded source ends inside a part; its last part keeps the
334
+ // bytes read, as an exact copy.
335
+ dispatchPart(partData.slice(0, partOffset), partNumber, true);
336
+ }
337
+ else {
338
+ dispatchPart(partData, partNumber, bounded
339
+ ? sourceClosed || observedBytes === sizeLimit
340
+ : partNumber === plan.partCount);
341
+ }
295
342
  }
296
343
  while (!sourceClosed) {
297
344
  const readResult = await readWhileObservingCallbacks();
@@ -310,7 +357,7 @@ export const consumeExactMultipartStream = async (optionsArg) => {
310
357
  }
311
358
  observedBytes += readResult.value.byteLength;
312
359
  throw {
313
- kind: 'source-extra',
360
+ kind: overLimitKind,
314
361
  };
315
362
  }
316
363
  while (inFlightParts.size > 0) {
@@ -407,7 +454,9 @@ export const consumeExactMultipartStream = async (optionsArg) => {
407
454
  completionAuthorized: false,
408
455
  kind: failure.kind,
409
456
  cause: failure.cause,
410
- expectedBytes: optionsArg.plan.objectSize,
457
+ ...(bounded
458
+ ? { maxBytes: plan.maxObjectSize }
459
+ : { expectedBytes: plan.objectSize }),
411
460
  observedBytes,
412
461
  partCallbacksStarted,
413
462
  completedPartNumbers: [...completedPartNumbers].sort((leftArg, rightArg) => {
@@ -437,4 +486,4 @@ export const consumeExactMultipartStream = async (optionsArg) => {
437
486
  }
438
487
  }
439
488
  };
440
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwubXVsdGlwYXJ0LnN0cmVhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL29iamVjdHN0b3JhZ2UvaW50ZXJuYWwubXVsdGlwYXJ0LnN0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLHlCQUF5QixFQUN6Qix3QkFBd0IsRUFDeEIsdUJBQXVCLEVBQ3ZCLHVCQUF1QixHQUN4QixNQUFNLGlDQUFpQyxDQUFDO0FBZ0R6QyxNQUFNLGVBQWUsR0FBZ0Q7SUFDbkUsT0FBTyxFQUFFLDJDQUEyQztJQUNwRCxhQUFhLEVBQUUsc0RBQXNEO0lBQ3JFLHFCQUFxQixFQUFFLG9FQUFvRTtJQUMzRiwwQkFBMEIsRUFDeEIsaUVBQWlFO0lBQ25FLGNBQWMsRUFBRSxnRUFBZ0U7SUFDaEYsY0FBYyxFQUFFLDREQUE0RDtJQUM1RSxlQUFlLEVBQUUsbUNBQW1DO0NBQ3JELENBQUM7QUFDRixNQUFNLGlDQUFpQyxHQUFHLE1BQU0sQ0FBQztBQUNqRCxNQUFNLDZCQUE2QixHQUFHLEtBQUssQ0FBQztBQUU1QyxNQUFNLE9BQU8sK0JBQWdDLFNBQVEsS0FBSztJQUN4QyxLQUFLLENBQStCO0lBQ3BEOztPQUVHO0lBQ2Esa0JBQWtCLENBQWdCO0lBQ2xEOztPQUVHO0lBQ2EsZUFBZSxDQUFnQjtJQUUvQyxZQUNFLFFBQXNDLEVBQ3RDLGNBR0M7UUFFRCxLQUFLLENBQUMsZUFBZSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRTtZQUNwQyxLQUFLLEVBQUUsUUFBUSxDQUFDLEtBQUs7U0FDdEIsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxDQUFDLElBQUksR0FBRyxpQ0FBaUMsQ0FBQztRQUM5QyxJQUFJLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQztRQUN0QixJQUFJLENBQUMsa0JBQWtCO1lBQ3JCLGNBQWMsRUFBRSxrQkFBa0IsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7UUFDMUQsSUFBSSxDQUFDLGVBQWU7WUFDbEIsY0FBYyxFQUFFLGVBQWUsSUFBSSxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDekQsQ0FBQztDQUNGO0FBRUQsTUFBTSxZQUFZLEdBQUcsQ0FBQyxPQUE2QixFQUFRLEVBQUU7SUFDM0QsSUFDRSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztRQUN6QyxPQUFPLENBQUMsVUFBVSxHQUFHLENBQUM7UUFDdEIsT0FBTyxDQUFDLFVBQVUsR0FBRyx5QkFBeUIsRUFDOUMsQ0FBQztRQUNELE1BQU0sSUFBSSxTQUFTLENBQUMsNkJBQTZCLENBQUMsQ0FBQztJQUNyRCxDQUFDO0lBQ0QsSUFDRSxDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLFdBQVcsQ0FBQztRQUMxQyxPQUFPLENBQUMsV0FBVyxHQUFHLENBQUM7UUFDdkIsT0FBTyxDQUFDLFdBQVcsR0FBRyx5QkFBeUIsRUFDL0MsQ0FBQztRQUNELE1BQU0sSUFBSSxTQUFTLENBQUMsOEJBQThCLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBQ0QsSUFBSSxPQUFPLENBQUMsY0FBYyxLQUFLLE1BQU0sRUFBRSxDQUFDO1FBQ3RDLElBQ0UsT0FBTyxDQUFDLFVBQVUsS0FBSyxDQUFDO1lBQ3hCLE9BQU8sQ0FBQyxRQUFRLEtBQUssQ0FBQztZQUN0QixPQUFPLENBQUMsU0FBUyxLQUFLLENBQUM7WUFDdkIsT0FBTyxDQUFDLG9CQUFvQixLQUFLLENBQUMsRUFDbEMsQ0FBQztZQUNELE1BQU0sSUFBSSxTQUFTLENBQUMsK0NBQStDLENBQUMsQ0FBQztRQUN2RSxDQUFDO1FBQ0QsT0FBTztJQUNULENBQUM7SUFFRCxJQUNFLE9BQU8sQ0FBQyxVQUFVLEtBQUssQ0FBQztRQUN4QixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQztRQUN2QyxPQUFPLENBQUMsUUFBUSxHQUFHLHVCQUF1QjtRQUMxQyxPQUFPLENBQUMsUUFBUSxHQUFHLHVCQUF1QjtRQUMxQyxPQUFPLENBQUMsU0FBUyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsUUFBUSxDQUFDO1FBQ3RFLE9BQU8sQ0FBQyxTQUFTLEdBQUcsQ0FBQztRQUNyQixPQUFPLENBQUMsU0FBUyxHQUFHLHdCQUF3QjtRQUM1QyxPQUFPLENBQUMsV0FBVyxHQUFHLE9BQU8sQ0FBQyxTQUFTO1FBQ3ZDLE9BQU8sQ0FBQyxvQkFBb0I7WUFDMUIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxRQUFRLEdBQUcsT0FBTyxDQUFDLFdBQVcsQ0FBQztnQkFDbEUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFDbEQsQ0FBQztRQUNELE1BQU0sSUFBSSxTQUFTLENBQUMscUNBQXFDLENBQUMsQ0FBQztJQUM3RCxDQUFDO0FBQ0gsQ0FBQyxDQUFDO0FBRUYsTUFBTSxDQUFDLE1BQU0sMkJBQTJCLEdBQUcsS0FBSyxFQUM5QyxVQUErQyxFQUNILEVBQUU7SUFDOUMsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUM5QixJQUNFLENBQUMsVUFBVSxDQUFDLGNBQWM7UUFDMUIsT0FBTyxVQUFVLENBQUMsY0FBYyxDQUFDLFNBQVMsS0FBSyxVQUFVLEVBQ3pELENBQUM7UUFDRCxNQUFNLElBQUksU0FBUyxDQUFDLDhDQUE4QyxDQUFDLENBQUM7SUFDdEUsQ0FBQztJQUNELElBQUksT0FBTyxVQUFVLENBQUMsTUFBTSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQzVDLE1BQU0sSUFBSSxTQUFTLENBQUMsNEJBQTRCLENBQUMsQ0FBQztJQUNwRCxDQUFDO0lBQ0QsTUFBTSwwQkFBMEIsR0FDOUIsVUFBVSxDQUFDLDBCQUEwQjtRQUNyQyxpQ0FBaUMsQ0FBQztJQUNwQyxJQUNFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQywwQkFBMEIsQ0FBQztRQUNqRCwwQkFBMEIsSUFBSSxDQUFDO1FBQy9CLDBCQUEwQixHQUFHLGlDQUFpQyxFQUM5RCxDQUFDO1FBQ0QsTUFBTSxJQUFJLFNBQVMsQ0FDakIsOEVBQThFLGlDQUFpQyxHQUFHLENBQ25ILENBQUM7SUFDSixDQUFDO0lBRUQsTUFBTSxNQUFNLEdBQUcsVUFBVSxDQUFDLGNBQWMsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUNyRCxNQUFNLHVCQUF1QixHQUFHLElBQUksZUFBZSxFQUFFLENBQUM7SUFDdEQsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLEVBQXlCLENBQUM7SUFDdkQsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQy9DLElBQUksYUFBYSxHQUFHLENBQUMsQ0FBQztJQUN0QixJQUFJLGdCQUFnQixHQUFHLENBQUMsQ0FBQztJQUN6QixJQUFJLGlCQUFpQixHQUFHLENBQUMsQ0FBQztJQUMxQixJQUFJLGlCQUFpQixHQUFHLENBQUMsQ0FBQztJQUMxQixJQUFJLGFBQWEsR0FBRyxDQUFDLENBQUM7SUFDdEIsSUFBSSxvQkFBb0IsR0FBRyxDQUFDLENBQUM7SUFDN0IsSUFBSSxZQUFZLEdBQUcsS0FBSyxDQUFDO0lBQ3pCLElBQUksc0JBQXNCLEdBQUcsQ0FBQyxDQUFDO0lBRS9CLElBQUksWUFBa0QsQ0FBQztJQUN2RCxNQUFNLFlBQVksR0FBRyxJQUFJLE9BQU8sQ0FBZ0IsQ0FBQyxVQUFVLEVBQUUsRUFBRTtRQUM3RCxZQUFZLEdBQUcsVUFBVSxDQUFDO0lBQzVCLENBQUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxXQUFXLEdBQUcsR0FBUyxFQUFFO1FBQzdCLE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxNQUFNLEVBQUUsTUFBTSxJQUFJLElBQUksS0FBSyxDQUFDLDJCQUEyQixDQUFDLENBQUM7UUFDbEYsdUJBQXVCLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JDLFlBQVksQ0FBQztZQUNYLElBQUksRUFBRSxPQUFPO1lBQ2IsS0FBSztTQUNOLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUNGLFVBQVUsQ0FBQyxNQUFNLEVBQUUsZ0JBQWdCLENBQUMsT0FBTyxFQUFFLFdBQVcsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDO0lBQzFFLElBQUksVUFBVSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUMvQixXQUFXLEVBQUUsQ0FBQztJQUNoQixDQUFDO0lBRUQsTUFBTSxrQkFBa0IsR0FBRyxDQUFDLFVBQXdCLEVBQVEsRUFBRTtRQUM1RCxNQUFNLFlBQVksR0FBRyxhQUFhLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN6RCxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7WUFDbEIsT0FBTztRQUNULENBQUM7UUFDRCxhQUFhLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUN2QyxhQUFhLElBQUksWUFBWSxDQUFDLFVBQVUsQ0FBQztRQUN6QyxJQUFJLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUN6QixvQkFBb0IsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQ2hELE9BQU87UUFDVCxDQUFDO1FBQ0QsTUFBTTtZQUNKLElBQUksRUFBRSxlQUFlO1lBQ3JCLEtBQUssRUFBRSxVQUFVLENBQUMsS0FBSztTQUNFLENBQUM7SUFDOUIsQ0FBQyxDQUFDO0lBRUYsTUFBTSxvQkFBb0IsR0FBRyxHQUFTLEVBQUU7UUFDdEMsTUFBTSxhQUFhLEdBQUcsYUFBYSxHQUFHLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDO1FBQzNFLElBQUksYUFBYSxHQUFHLFVBQVUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztZQUN6RCxNQUFNO2dCQUNKLElBQUksRUFBRSxxQkFBcUI7Z0JBQzNCLEtBQUssRUFBRSxJQUFJLFVBQVUsQ0FBQyxpREFBaUQsQ0FBQzthQUMvQyxDQUFDO1FBQzlCLENBQUM7UUFDRCxpQkFBaUIsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLGFBQWEsQ0FBQyxDQUFDO0lBQ2pFLENBQUMsQ0FBQztJQUVGLE1BQU0sY0FBYyxHQUFHLEtBQUssSUFBbUIsRUFBRTtRQUMvQyxNQUFNLE9BQU8sR0FBRyxNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQ2hDO1lBQ0UsWUFBWTtZQUNaLEdBQUcsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FDaEMsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQzdDO1NBQ0YsQ0FDRixDQUFDO1FBQ0YsSUFBSSxDQUFDLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxFQUFFLENBQUM7WUFDMUIsTUFBTTtnQkFDSixJQUFJLEVBQUUsU0FBUztnQkFDZixLQUFLLEVBQUUsT0FBTyxDQUFDLEtBQUs7YUFDSyxDQUFDO1FBQzlCLENBQUM7UUFDRCxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUM5QixDQUFDLENBQUM7SUFFRixNQUFNLGVBQWUsR0FBRyxLQUFLLElBQW1CLEVBQUU7UUFDaEQsT0FBTyxhQUFhLENBQUMsSUFBSSxJQUFJLFVBQVUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDekQsTUFBTSxjQUFjLEVBQUUsQ0FBQztRQUN6QixDQUFDO0lBQ0gsQ0FBQyxDQUFDO0lBRUYsTUFBTSwyQkFBMkIsR0FBRyxLQUFLLElBRXZDLEVBQUU7UUFDRixNQUFNLFdBQVcsR0FBMEIsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDLElBQUksQ0FDM0QsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDZCxJQUFJLEVBQUUsTUFBTTtZQUNaLE1BQU0sRUFBRSxTQUFTO1NBQ2xCLENBQUMsRUFDRixDQUFDLFFBQWlCLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEIsSUFBSSxFQUFFLFlBQVk7WUFDbEIsS0FBSyxFQUFFLFFBQVE7U0FDaEIsQ0FBQyxDQUNILENBQUM7UUFFRixPQUFPLElBQUksRUFBRSxDQUFDO1lBQ1osTUFBTSxPQUFPLEdBQUcsTUFBTSxPQUFPLENBQUMsSUFBSSxDQUFDO2dCQUNqQyxXQUFXO2dCQUNYLFlBQVk7Z0JBQ1osR0FBRyxDQUFDLEdBQUcsYUFBYSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsR0FBRyxDQUNoQyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUMsZUFBZSxDQUFDLE9BQU8sQ0FDN0M7YUFDRixDQUFDLENBQUM7WUFDSCxJQUFJLE9BQU8sSUFBSSxPQUFPLEVBQUUsQ0FBQztnQkFDdkIsa0JBQWtCLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBQzVCLFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUM3QixNQUFNO29CQUNKLElBQUksRUFBRSxTQUFTO29CQUNmLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztpQkFDSyxDQUFDO1lBQzlCLENBQUM7WUFDRCxJQUFJLE9BQU8sQ0FBQyxJQUFJLEtBQUssWUFBWSxFQUFFLENBQUM7Z0JBQ2xDLE1BQU07b0JBQ0osSUFBSSxFQUFFLGFBQWE7b0JBQ25CLEtBQUssRUFBRSxPQUFPLENBQUMsS0FBSztpQkFDSyxDQUFDO1lBQzlCLENBQUM7WUFDRCxPQUFPLE9BQU8sQ0FBQyxNQUFNLENBQUM7UUFDeEIsQ0FBQztJQUNILENBQUMsQ0FBQztJQUVGLE1BQU0sWUFBWSxHQUFHLENBQUMsT0FBbUIsRUFBRSxhQUFxQixFQUFRLEVBQUU7UUFDeEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLGtCQUFrQixhQUFhLEVBQUUsQ0FBQyxDQUFDO1FBQ3hELG9CQUFvQixFQUFFLENBQUM7UUFDdkIsZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO1FBQ3JCLGFBQWEsSUFBSSxPQUFPLENBQUMsVUFBVSxDQUFDO1FBQ3BDLG9CQUFvQixFQUFFLENBQUM7UUFDdkIsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRTthQUM5QixJQUFJLENBQUMsR0FBRyxFQUFFLENBQ1QsVUFBVSxDQUFDLE1BQU0sQ0FBQztZQUNoQixVQUFVLEVBQUUsYUFBYTtZQUN6QixVQUFVLEVBQUUsQ0FBQyxhQUFhLEdBQUcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRO1lBQzFELFVBQVUsRUFBRSxhQUFhLEtBQUssVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQ3ZELElBQUksRUFBRSxPQUFPO1lBQ2IsTUFBTSxFQUFFLHVCQUF1QixDQUFDLE1BQU07U0FDdkMsQ0FBQyxDQUNIO2FBQ0EsSUFBSSxDQUNILEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDTCxLQUFLO1lBQ0wsVUFBVSxFQUFFLGFBQWE7WUFDekIsU0FBUyxFQUFFLElBQUk7U0FDaEIsQ0FBQyxFQUNGLENBQUMsUUFBaUIsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QixLQUFLO1lBQ0wsVUFBVSxFQUFFLGFBQWE7WUFDekIsU0FBUyxFQUFFLEtBQUs7WUFDaEIsS0FBSyxFQUFFLFFBQVE7U0FDaEIsQ0FBQyxDQUNILENBQUM7UUFDSixhQUFhLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRTtZQUN2QixVQUFVLEVBQUUsT0FBTyxDQUFDLFVBQVU7WUFDOUIsT0FBTztTQUNSLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQztJQUVGLE1BQU0saUJBQWlCLEdBQUcsQ0FBQyxRQUFvQixFQUFXLEVBQUU7UUFDMUQsSUFBSSxRQUFRLENBQUMsVUFBVSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzVCLHNCQUFzQixHQUFHLENBQUMsQ0FBQztZQUMzQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxzQkFBc0IsRUFBRSxDQUFDO1FBQ3pCLElBQUksc0JBQXNCLEdBQUcsNkJBQTZCLEVBQUUsQ0FBQztZQUMzRCxNQUFNO2dCQUNKLElBQUksRUFBRSwwQkFBMEI7Z0JBQ2hDLEtBQUssRUFBRSxJQUFJLFVBQVUsQ0FDbkIsMENBQTBDLDZCQUE2Qiw0QkFBNEIsQ0FDcEc7YUFDd0IsQ0FBQztRQUM5QixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDLENBQUM7SUFFRixJQUFJLENBQUM7UUFDSCxJQUFJLFlBQW9DLENBQUM7UUFDekMsSUFBSSxrQkFBa0IsR0FBRyxDQUFDLENBQUM7UUFFM0IsS0FDRSxJQUFJLFVBQVUsR0FBRyxDQUFDLEVBQ2xCLFVBQVUsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFDdkMsVUFBVSxFQUFFLEVBQ1osQ0FBQztZQUNELE1BQU0sZUFBZSxFQUFFLENBQUM7WUFDeEIsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FDN0IsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQ3hCLFVBQVUsQ0FBQyxJQUFJLENBQUMsVUFBVTtnQkFDeEIsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxDQUFDLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQzlDLENBQUM7WUFDRixJQUNFLGFBQWEsR0FBRyxjQUFjO2dCQUM5QixVQUFVLENBQUMsSUFBSSxDQUFDLG9CQUFvQixFQUNwQyxDQUFDO2dCQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsc0RBQXNELENBQUMsQ0FBQztZQUMxRSxDQUFDO1lBQ0QsTUFBTSxRQUFRLEdBQUcsSUFBSSxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUM7WUFDaEQsZ0JBQWdCLEdBQUcsY0FBYyxDQUFDO1lBQ2xDLG9CQUFvQixFQUFFLENBQUM7WUFDdkIsSUFBSSxVQUFVLEdBQUcsQ0FBQyxDQUFDO1lBRW5CLE9BQU8sVUFBVSxHQUFHLGNBQWMsRUFBRSxDQUFDO2dCQUNuQyxJQUNFLFlBQVk7b0JBQ1osa0JBQWtCLEdBQUcsWUFBWSxDQUFDLFVBQVUsRUFDNUMsQ0FBQztvQkFDRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUM3QixjQUFjLEdBQUcsVUFBVSxFQUMzQixZQUFZLENBQUMsVUFBVSxHQUFHLGtCQUFrQixDQUM3QyxDQUFDO29CQUNGLFFBQVEsQ0FBQyxHQUFHLENBQ1YsWUFBWSxDQUFDLFFBQVEsQ0FDbkIsa0JBQWtCLEVBQ2xCLGtCQUFrQixHQUFHLGNBQWMsQ0FDcEMsRUFDRCxVQUFVLENBQ1gsQ0FBQztvQkFDRixrQkFBa0IsSUFBSSxjQUFjLENBQUM7b0JBQ3JDLFVBQVUsSUFBSSxjQUFjLENBQUM7b0JBQzdCLElBQUksa0JBQWtCLEtBQUssWUFBWSxDQUFDLFVBQVUsRUFBRSxDQUFDO3dCQUNuRCxZQUFZLEdBQUcsU0FBUyxDQUFDO3dCQUN6QixrQkFBa0IsR0FBRyxDQUFDLENBQUM7d0JBQ3ZCLGlCQUFpQixHQUFHLENBQUMsQ0FBQztvQkFDeEIsQ0FBQztvQkFDRCxTQUFTO2dCQUNYLENBQUM7Z0JBRUQsTUFBTSxVQUFVLEdBQUcsTUFBTSwyQkFBMkIsRUFBRSxDQUFDO2dCQUN2RCxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDcEIsWUFBWSxHQUFHLElBQUksQ0FBQztvQkFDcEIsTUFBTTt3QkFDSixJQUFJLEVBQUUsY0FBYztxQkFDSyxDQUFDO2dCQUM5QixDQUFDO2dCQUNELElBQUksQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLFlBQVksVUFBVSxDQUFDLEVBQUUsQ0FBQztvQkFDOUMsTUFBTTt3QkFDSixJQUFJLEVBQUUsYUFBYTt3QkFDbkIsS0FBSyxFQUFFLElBQUksU0FBUyxDQUFDLHNEQUFzRCxDQUFDO3FCQUNuRCxDQUFDO2dCQUM5QixDQUFDO2dCQUNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztvQkFDekMsU0FBUztnQkFDWCxDQUFDO2dCQUNELGFBQWEsSUFBSSxVQUFVLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQztnQkFDN0MsSUFBSSxhQUFhLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztvQkFDL0MsTUFBTTt3QkFDSixJQUFJLEVBQUUsY0FBYztxQkFDSyxDQUFDO2dCQUM5QixDQUFDO2dCQUNELElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztvQkFDM0QsTUFBTTt3QkFDSixJQUFJLEVBQUUscUJBQXFCO3dCQUMzQixLQUFLLEVBQUUsSUFBSSxVQUFVLENBQ25CLGlDQUFpQyxVQUFVLENBQUMsSUFBSSxDQUFDLFFBQVEsU0FBUyxDQUNuRTtxQkFDd0IsQ0FBQztnQkFDOUIsQ0FBQztnQkFDRCxZQUFZLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQztnQkFDaEMsaUJBQWlCLEdBQUcsVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7Z0JBQ2hELG9CQUFvQixFQUFFLENBQUM7WUFDekIsQ0FBQztZQUVELFlBQVksQ0FBQyxRQUFRLEVBQUUsVUFBVSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUNyQixNQUFNLFVBQVUsR0FBRyxNQUFNLDJCQUEyQixFQUFFLENBQUM7WUFDdkQsSUFBSSxVQUFVLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3BCLFlBQVksR0FBRyxJQUFJLENBQUM7Z0JBQ3BCLE1BQU07WUFDUixDQUFDO1lBQ0QsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssWUFBWSxVQUFVLENBQUMsRUFBRSxDQUFDO2dCQUM5QyxNQUFNO29CQUNKLElBQUksRUFBRSxhQUFhO29CQUNuQixLQUFLLEVBQUUsSUFBSSxTQUFTLENBQUMsc0RBQXNELENBQUM7aUJBQ25ELENBQUM7WUFDOUIsQ0FBQztZQUNELElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDekMsU0FBUztZQUNYLENBQUM7WUFDRCxhQUFhLElBQUksVUFBVSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7WUFDN0MsTUFBTTtnQkFDSixJQUFJLEVBQUUsY0FBYzthQUNLLENBQUM7UUFDOUIsQ0FBQztRQUVELE9BQU8sYUFBYSxDQUFDLElBQUksR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUM5QixNQUFNLGNBQWMsRUFBRSxDQUFDO1FBQ3pCLENBQUM7UUFDRCxJQUFJLFVBQVUsQ0FBQyxNQUFNLEVBQUUsT0FBTyxFQUFFLENBQUM7WUFDL0IsTUFBTTtnQkFDSixJQUFJLEVBQUUsU0FBUztnQkFDZixLQUFLLEVBQUUsVUFBVSxDQUFDLE1BQU0sQ0FBQyxNQUFNO2FBQ04sQ0FBQztRQUM5QixDQUFDO1FBRUQsT0FBTztZQUNMLG9CQUFvQixFQUFFLElBQUk7WUFDMUIsYUFBYSxFQUFFLGFBQWE7WUFDNUIsYUFBYSxFQUFFLG9CQUFvQixDQUFDLElBQUk7WUFDeEMsaUJBQWlCO1lBQ2pCLG9CQUFvQixFQUFFLFVBQVUsQ0FBQyxJQUFJLENBQUMsb0JBQW9CO1NBQzNELENBQUM7SUFDSixDQUFDO0lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztRQUNmLE1BQU0sT0FBTyxHQUNYLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFDekIsS0FBSyxLQUFLLElBQUk7WUFDZCxNQUFNLElBQUksS0FBSztZQUNmLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxRQUFRO1lBQzVCLENBQUMsQ0FBRSxLQUF5QjtZQUM1QixDQUFDLENBQUU7Z0JBQ0MsSUFBSSxFQUFFLGFBQWE7Z0JBQ25CLEtBQUssRUFBRSxLQUFLO2FBQ2MsQ0FBQztRQUNuQyx1QkFBdUIsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEtBQUssSUFBSSxJQUFJLEtBQUssQ0FBQyxlQUFlLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUV6RixNQUFNLG9CQUFvQixHQUEwQyxZQUFZO1lBQzlFLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDO2dCQUNkLE1BQU0sRUFBRSxRQUFRO2FBQ2pCLENBQUM7WUFDSixDQUFDLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRTtpQkFDZCxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQ3hDLElBQUksQ0FDSCxHQUFHLEVBQUUsQ0FBQyxDQUFDO2dCQUNMLE1BQU0sRUFBRSxXQUFXO2FBQ3BCLENBQUMsRUFDRixDQUFDLFFBQWlCLEVBQUUsRUFBRSxDQUFDLENBQUM7Z0JBQ3RCLE1BQU0sRUFBRSxlQUFlO2dCQUN2QixLQUFLLEVBQUUsUUFBUTthQUNoQixDQUFDLENBQ0gsQ0FBQztRQUVSLElBQUksZ0JBQWdCLEdBQUcsS0FBSyxDQUFDO1FBQzdCLE1BQU0sa0JBQWtCLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FDcEMsQ0FBQyxHQUFHLGFBQWEsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FDN0IsQ0FBQyxlQUFlLEVBQUUsRUFBRSxDQUFDLGVBQWUsQ0FBQyxPQUFPLENBQzdDLENBQ0Y7YUFDRSxJQUFJLENBQUMsQ0FBQyxvQkFBb0IsRUFBRSxFQUFFO1lBQzdCLEtBQUssTUFBTSxPQUFPLElBQUksb0JBQW9CLEVBQUUsQ0FBQztnQkFDM0MsSUFBSSxPQUFPLENBQUMsU0FBUyxFQUFFLENBQUM7b0JBQ3RCLG9CQUFvQixDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBQy9DLENBQUM7WUFDSCxDQUFDO1lBQ0QsYUFBYSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQ3RCLGFBQWEsR0FBRyxDQUFDLENBQUM7UUFDcEIsQ0FBQyxDQUFDO2FBQ0QsSUFBSSxDQUNILEdBQUcsRUFBRSxDQUFDLFNBQVMsRUFDZixHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQ2hCLENBQUM7UUFDSixNQUFNLDBCQUEwQixHQUFHLGtCQUFrQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDOUQsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDO1FBQzFCLENBQUMsQ0FBQyxDQUFDO1FBQ0gsSUFBSSxhQUF1RCxDQUFDO1FBQzVELElBQUksb0JBQW9CLEdBQUcsS0FBSyxDQUFDO1FBQ2pDLE1BQU0scUJBQXFCLEdBQUcsb0JBQW9CLENBQUMsSUFBSSxDQUNyRCxDQUFDLGdCQUFnQixFQUFFLEVBQUU7WUFDbkIsYUFBYSxHQUFHLGdCQUFnQixDQUFDO1lBQ2pDLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUM5QixDQUFDLEVBQ0QsR0FBRyxFQUFFO1lBQ0gsYUFBYSxHQUFHO2dCQUNkLE1BQU0sRUFBRSxlQUFlO2dCQUN2QixLQUFLLEVBQUUsSUFBSSxLQUFLLENBQUMsNENBQTRDLENBQUM7YUFDL0QsQ0FBQztZQUNGLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUM5QixDQUFDLENBQ0YsQ0FBQztRQUNGLE1BQU0sZUFBZSxHQUFHLE9BQU8sQ0FBQyxVQUFVLENBQUM7WUFDekMsMEJBQTBCO1lBQzFCLHFCQUFxQjtTQUN0QixDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3pCLE1BQU0sdUJBQXVCLEdBQUcsTUFBTSxDQUNwQyx1Q0FBdUMsQ0FDeEMsQ0FBQztRQUNGLElBQUkseUJBRUssQ0FBQztRQUNWLE1BQU0seUJBQXlCLEdBQUcsSUFBSSxPQUFPLENBRTNDLENBQUMsVUFBVSxFQUFFLEVBQUU7WUFDZix5QkFBeUIsR0FBRyxVQUFVLENBQUM7UUFDekMsQ0FBQyxDQUFDLENBQUM7UUFDSCxNQUFNLGtCQUFrQixHQUFHLFVBQVUsQ0FBQyxHQUFHLEVBQUU7WUFDekMseUJBQXlCLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUNyRCxDQUFDLEVBQUUsMEJBQTBCLENBQUMsQ0FBQztRQUMvQixNQUFNLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxlQUFlLEVBQUUseUJBQXlCLENBQUMsQ0FBQyxDQUFDO1FBQ2pFLFlBQVksQ0FBQyxrQkFBa0IsQ0FBQyxDQUFDO1FBQ2pDLE1BQU0sS0FBSyxHQUNULG9CQUFvQixLQUFLLENBQUM7WUFDeEIsQ0FBQyxDQUFFO2dCQUNDLFdBQVcsRUFBRSxlQUFlO2dCQUM1QixzQkFBc0IsRUFBRSxLQUFLO2FBQ3BCO1lBQ2IsQ0FBQyxDQUFFO2dCQUNDLFdBQVcsRUFBRSx1QkFBdUI7Z0JBQ3BDLHNCQUFzQixFQUFFLElBQUk7YUFDbkIsQ0FBQztRQUVsQixNQUFNLElBQUksK0JBQStCLENBQ3ZDO1lBQ0Usb0JBQW9CLEVBQUUsS0FBSztZQUMzQixJQUFJLEVBQUUsT0FBTyxDQUFDLElBQUk7WUFDbEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxLQUFLO1lBQ3BCLGFBQWEsRUFBRSxVQUFVLENBQUMsSUFBSSxDQUFDLFVBQVU7WUFDekMsYUFBYTtZQUNiLG9CQUFvQjtZQUNwQixvQkFBb0IsRUFBRSxDQUFDLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxJQUFJLENBQ2xELENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxFQUFFO2dCQUNwQixPQUFPLE9BQU8sR0FBRyxRQUFRLENBQUM7WUFDNUIsQ0FBQyxDQUNGO1lBQ0QsT0FBTyxFQUFFO2dCQUNQLFNBQVMsRUFBRSxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxVQUFVO2dCQUNwRCxNQUFNLEVBQ0osb0JBQW9CLElBQUksYUFBYTtvQkFDbkMsQ0FBQyxDQUFDLGFBQWE7b0JBQ2YsQ0FBQyxDQUFDO3dCQUNFLE1BQU0sRUFBRSxpQkFBaUI7cUJBQzFCO2FBQ1I7WUFDRCxLQUFLO1NBQ04sRUFDRDtZQUNFLGtCQUFrQjtZQUNsQixlQUFlO1NBQ2hCLENBQ0YsQ0FBQztJQUNKLENBQUM7WUFBUyxDQUFDO1FBQ1QsVUFBVSxDQUFDLE1BQU0sRUFBRSxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsV0FBVyxDQUFDLENBQUM7UUFDN0QsSUFBSSxDQUFDO1lBQ0gsTUFBTSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ3ZCLENBQUM7UUFBQyxNQUFNLENBQUM7WUFDUCxtRUFBbUU7UUFDckUsQ0FBQztJQUNILENBQUM7QUFDSCxDQUFDLENBQUMifQ==
489
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwubXVsdGlwYXJ0LnN0cmVhbS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL29iamVjdHN0b3JhZ2UvaW50ZXJuYWwubXVsdGlwYXJ0LnN0cmVhbS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQ0wseUJBQXlCLEVBQ3pCLHlCQUF5QixFQUN6Qix3QkFBd0IsRUFDeEIsdUJBQXVCLEVBQ3ZCLHVCQUF1QixHQUN4QixNQUFNLGlDQUFpQyxDQUFDO0FBZ0R6QyxNQUFNLGVBQWUsR0FBZ0Q7SUFDbkUsT0FBTyxFQUFFLDJDQUEyQztJQUNwRCxhQUFhLEVBQUUsc0RBQXNEO0lBQ3JFLHFCQUFxQixFQUFFLG9FQUFvRTtJQUMzRiwwQkFBMEIsRUFDeEIsaUVBQWlFO0lBQ25FLGNBQWMsRUFBRSxnRUFBZ0U7SUFDaEYsY0FBYyxFQUFFLDREQUE0RDtJQUM1RSxxQkFBcUIsRUFBRSwyREFBMkQ7SUFDbEYsZUFBZSxFQUFFLG1DQUFtQztDQUNyRCxDQUFDO0FBQ0YsTUFBTSxpQ0FBaUMsR0FBRyxNQUFNLENBQUM7QUFDakQsTUFBTSw2QkFBNkIsR0FBRyxLQUFLLENBQUM7QUFFNUMsTUFBTSxPQUFPLCtCQUFnQyxTQUFRLEtBQUs7SUFDeEMsS0FBSyxDQUErQjtJQUNwRDs7T0FFRztJQUNhLGtCQUFrQixDQUFnQjtJQUNsRDs7T0FFRztJQUNhLGVBQWUsQ0FBZ0I7SUFFL0MsWUFDRSxRQUFzQyxFQUN0QyxjQUdDO1FBRUQsS0FBSyxDQUFDLGVBQWUsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDcEMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO1NBQ3RCLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxJQUFJLEdBQUcsaUNBQWlDLENBQUM7UUFDOUMsSUFBSSxDQUFDLEtBQUssR0FBRyxRQUFRLENBQUM7UUFDdEIsSUFBSSxDQUFDLGtCQUFrQjtZQUNyQixjQUFjLEVBQUUsa0JBQWtCLElBQUks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
@@ -3,6 +3,11 @@ export interface IMultipartPlanningOptions {
3
3
  requestedPartSize?: number;
4
4
  requestedConcurrency?: number;
5
5
  }
6
+ export interface IMultipartBoundedPlanningOptions {
7
+ maxObjectSize: number;
8
+ requestedPartSize?: number;
9
+ requestedConcurrency?: number;
10
+ }
6
11
  interface IMultipartUploadPlanBase {
7
12
  objectSize: number;
8
13
  concurrency: number;
@@ -20,10 +25,31 @@ export interface IMultipartDataUploadPlan extends IMultipartUploadPlanBase {
20
25
  partSize: number;
21
26
  partCount: number;
22
27
  }
23
- export type TMultipartUploadPlan = IMultipartZeroUploadPlan | IMultipartDataUploadPlan;
28
+ /**
29
+ * A plan for a source of undeclared length: full parts are read until the
30
+ * source ends, and a source longer than `maxObjectSize` fails. The part size
31
+ * is chosen so that `maxObjectSize` fits into the multipart part limit.
32
+ */
33
+ export interface IMultipartBoundedUploadPlan {
34
+ classification: 'bounded';
35
+ maxObjectSize: number;
36
+ partSize: number;
37
+ /** Parts that `maxObjectSize` needs; the source may need fewer. */
38
+ maxPartCount: number;
39
+ concurrency: number;
40
+ maximumBufferedBytes: number;
41
+ }
42
+ /** A plan for a source of declared length. */
43
+ export type TMultipartDeclaredUploadPlan = IMultipartZeroUploadPlan | IMultipartDataUploadPlan;
44
+ export type TMultipartUploadPlan = TMultipartDeclaredUploadPlan | IMultipartBoundedUploadPlan;
24
45
  export interface IMultipartStreamPart {
25
46
  partNumber: number;
26
47
  byteOffset: number;
48
+ /**
49
+ * Under a bounded plan a part is only known to be the last when the source
50
+ * ended inside it or it reached the maximum; a source that ends exactly at
51
+ * a part boundary leaves its last part marked false.
52
+ */
27
53
  isLastPart: boolean;
28
54
  /**
29
55
  * An exact, exclusively owned copy. The consumer never mutates or reuses it.
@@ -46,7 +72,7 @@ export interface IMultipartStreamConsumptionResult {
46
72
  peakBufferedBytes: number;
47
73
  maximumBufferedBytes: number;
48
74
  }
49
- export type TMultipartStreamFailureKind = 'aborted' | 'source-read' | 'source-buffer-limit' | 'source-empty-chunk-limit' | 'source-short' | 'source-extra' | 'part-callback';
75
+ export type TMultipartStreamFailureKind = 'aborted' | 'source-read' | 'source-buffer-limit' | 'source-empty-chunk-limit' | 'source-short' | 'source-extra' | 'source-over-maximum' | 'part-callback';
50
76
  export type TMultipartOwnedReaderCleanup = {
51
77
  status: 'closed';
52
78
  } | {
@@ -72,7 +98,10 @@ export interface IMultipartStreamFailureState {
72
98
  completionAuthorized: false;
73
99
  kind: TMultipartStreamFailureKind;
74
100
  cause?: unknown;
75
- expectedBytes: number;
101
+ /** The declared length; absent under a bounded plan. */
102
+ expectedBytes?: number;
103
+ /** The maximum length of a bounded plan. */
104
+ maxBytes?: number;
76
105
  observedBytes: number;
77
106
  partCallbacksStarted: number;
78
107
  completedPartNumbers: number[];
@@ -0,0 +1,38 @@
1
+ import * as plugins from './plugins.js';
2
+ import type { IBasicBucketOperation } from './internal.exactupload.capability.js';
3
+ /**
4
+ * Sources larger than this are copied with UploadPartCopy. It is the largest
5
+ * object one CopyObject may copy, so every copy that one CopyObject can do
6
+ * stays one. A capped MinIO (2 CPUs, 2 GiB) answered a single CopyObject after
7
+ * about 3 s per GiB, inside the default 60 s request timeout at this size.
8
+ */
9
+ export declare const multipartCopyThresholdBytes: number;
10
+ /** One 256 MiB UploadPartCopy answered within 0.9 s on the same MinIO. */
11
+ export declare const multipartCopyPartSizeBytes: number;
12
+ export interface IMultipartCopyPlan {
13
+ partSize: number;
14
+ partCount: number;
15
+ }
16
+ /**
17
+ * Grows the part size so the object fits in 10,000 parts and refuses objects
18
+ * that S3 cannot hold.
19
+ */
20
+ export declare const planMultipartCopy: (objectSizeArg: number, partSizeArg?: number) => IMultipartCopyPlan;
21
+ export interface IMultipartCopyOptions {
22
+ copySource: string;
23
+ sourceSize: number;
24
+ /** Every part copy requires the source to still carry this ETag. */
25
+ sourceEtag: string;
26
+ targetBucketName: string;
27
+ targetKey: string;
28
+ /** Object properties of the new object; a multipart upload copies none itself. */
29
+ objectProperties: Pick<plugins.s3.CreateMultipartUploadCommandInput, 'Metadata' | 'ContentType' | 'CacheControl' | 'ContentDisposition' | 'ContentEncoding' | 'ContentLanguage' | 'Expires'>;
30
+ partSize?: number;
31
+ /** Receives cleanup that outlived its deadline; the operation must not finish before it settles. */
32
+ onDeferredCleanup: (settlementArg: Promise<void>) => void;
33
+ }
34
+ /**
35
+ * Copies one object part by part. Any failure or abort aborts the multipart
36
+ * upload instead of completing it.
37
+ */
38
+ export declare const copyObjectMultipart: (operationArg: IBasicBucketOperation, optionsArg: IMultipartCopyOptions) => Promise<void>;
@@ -0,0 +1,98 @@
1
+ import * as plugins from './plugins.js';
2
+ import { abortMultipartUpload } from './internal.exactupload.operations.js';
3
+ const MiB = 1024 * 1024;
4
+ const GiB = 1024 * MiB;
5
+ /**
6
+ * Sources larger than this are copied with UploadPartCopy. It is the largest
7
+ * object one CopyObject may copy, so every copy that one CopyObject can do
8
+ * stays one. A capped MinIO (2 CPUs, 2 GiB) answered a single CopyObject after
9
+ * about 3 s per GiB, inside the default 60 s request timeout at this size.
10
+ */
11
+ export const multipartCopyThresholdBytes = 5 * GiB;
12
+ /** One 256 MiB UploadPartCopy answered within 0.9 s on the same MinIO. */
13
+ export const multipartCopyPartSizeBytes = 256 * MiB;
14
+ const maximumCopyPartSizeBytes = 5 * GiB;
15
+ const maximumCopyPartCount = 10_000;
16
+ const maximumCopyObjectSizeBytes = 5 * 1024 * GiB;
17
+ /**
18
+ * Grows the part size so the object fits in 10,000 parts and refuses objects
19
+ * that S3 cannot hold.
20
+ */
21
+ export const planMultipartCopy = (objectSizeArg, partSizeArg = multipartCopyPartSizeBytes) => {
22
+ if (!Number.isSafeInteger(objectSizeArg) ||
23
+ objectSizeArg <= 0 ||
24
+ objectSizeArg > maximumCopyObjectSizeBytes) {
25
+ throw new RangeError(`A multipart copy needs a source of 1 byte to ${maximumCopyObjectSizeBytes} bytes, not ${objectSizeArg}.`);
26
+ }
27
+ const partSize = Math.max(partSizeArg, Math.ceil(objectSizeArg / maximumCopyPartCount));
28
+ if (partSize > maximumCopyPartSizeBytes) {
29
+ throw new RangeError(`A multipart copy part cannot exceed ${maximumCopyPartSizeBytes} bytes.`);
30
+ }
31
+ return {
32
+ partSize,
33
+ partCount: Math.ceil(objectSizeArg / partSize),
34
+ };
35
+ };
36
+ /**
37
+ * Copies one object part by part. Any failure or abort aborts the multipart
38
+ * upload instead of completing it.
39
+ */
40
+ export const copyObjectMultipart = async (operationArg, optionsArg) => {
41
+ const plan = planMultipartCopy(optionsArg.sourceSize, optionsArg.partSize);
42
+ const abortUpload = (uploadIdArg) => abortMultipartUpload(operationArg, optionsArg.targetKey, uploadIdArg, optionsArg.targetBucketName);
43
+ const createOutput = await operationArg.runProvider(() => operationArg.client.send(new plugins.s3.CreateMultipartUploadCommand({
44
+ Bucket: optionsArg.targetBucketName,
45
+ Key: optionsArg.targetKey,
46
+ ...optionsArg.objectProperties,
47
+ }), { abortSignal: operationArg.signal }), {
48
+ // A create that ignored cancellation still owns an upload.
49
+ disposeLateResult: async (lateOutputArg) => {
50
+ if (lateOutputArg.UploadId) {
51
+ const abortResult = await abortUpload(lateOutputArg.UploadId);
52
+ await abortResult.settlement;
53
+ }
54
+ },
55
+ });
56
+ const uploadId = createOutput.UploadId;
57
+ if (typeof uploadId !== 'string' || uploadId.length === 0) {
58
+ throw new Error('CreateMultipartUpload returned no UploadId.');
59
+ }
60
+ try {
61
+ const parts = [];
62
+ for (let partNumber = 1; partNumber <= plan.partCount; partNumber++) {
63
+ const start = (partNumber - 1) * plan.partSize;
64
+ const end = Math.min(optionsArg.sourceSize, start + plan.partSize) - 1;
65
+ const partOutput = await operationArg.runProvider(() => operationArg.client.send(new plugins.s3.UploadPartCopyCommand({
66
+ Bucket: optionsArg.targetBucketName,
67
+ Key: optionsArg.targetKey,
68
+ UploadId: uploadId,
69
+ PartNumber: partNumber,
70
+ CopySource: optionsArg.copySource,
71
+ CopySourceRange: `bytes=${start}-${end}`,
72
+ CopySourceIfMatch: optionsArg.sourceEtag,
73
+ }), { abortSignal: operationArg.signal }));
74
+ const etag = partOutput.CopyPartResult?.ETag;
75
+ if (typeof etag !== 'string' || etag.length === 0) {
76
+ throw new Error('UploadPartCopy returned no ETag.');
77
+ }
78
+ parts.push({ PartNumber: partNumber, ETag: etag });
79
+ }
80
+ await operationArg.runProvider(() => operationArg.client.send(new plugins.s3.CompleteMultipartUploadCommand({
81
+ Bucket: optionsArg.targetBucketName,
82
+ Key: optionsArg.targetKey,
83
+ UploadId: uploadId,
84
+ MultipartUpload: { Parts: parts },
85
+ }), { abortSignal: operationArg.signal }));
86
+ }
87
+ catch (error) {
88
+ const abortResult = await abortUpload(uploadId);
89
+ if (abortResult.cleanup.status === 'abort-failed') {
90
+ throw new AggregateError([error, abortResult.cleanup.cause], `The multipart copy failed and its upload '${uploadId}' could not be aborted.`);
91
+ }
92
+ if (abortResult.timedOut) {
93
+ optionsArg.onDeferredCleanup(abortResult.settlement);
94
+ }
95
+ throw error;
96
+ }
97
+ };
98
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW50ZXJuYWwubXVsdGlwYXJ0Y29weS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3RzL29iamVjdHN0b3JhZ2UvaW50ZXJuYWwubXVsdGlwYXJ0Y29weS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEtBQUssT0FBTyxNQUFNLGNBQWMsQ0FBQztBQUV4QyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxzQ0FBc0MsQ0FBQztBQUU1RSxNQUFNLEdBQUcsR0FBRyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLE1BQU0sR0FBRyxHQUFHLElBQUksR0FBRyxHQUFHLENBQUM7QUFFdkI7Ozs7O0dBS0c7QUFDSCxNQUFNLENBQUMsTUFBTSwyQkFBMkIsR0FBRyxDQUFDLEdBQUcsR0FBRyxDQUFDO0FBQ25ELDBFQUEwRTtBQUMxRSxNQUFNLENBQUMsTUFBTSwwQkFBMEIsR0FBRyxHQUFHLEdBQUcsR0FBRyxDQUFDO0FBQ3BELE1BQU0sd0JBQXdCLEdBQUcsQ0FBQyxHQUFHLEdBQUcsQ0FBQztBQUN6QyxNQUFNLG9CQUFvQixHQUFHLE1BQU0sQ0FBQztBQUNwQyxNQUFNLDBCQUEwQixHQUFHLENBQUMsR0FBRyxJQUFJLEdBQUcsR0FBRyxDQUFDO0FBT2xEOzs7R0FHRztBQUNILE1BQU0sQ0FBQyxNQUFNLGlCQUFpQixHQUFHLENBQy9CLGFBQXFCLEVBQ3JCLFdBQVcsR0FBRywwQkFBMEIsRUFDcEIsRUFBRTtJQUN0QixJQUNFLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxhQUFhLENBQUM7UUFDcEMsYUFBYSxJQUFJLENBQUM7UUFDbEIsYUFBYSxHQUFHLDBCQUEwQixFQUMxQyxDQUFDO1FBQ0QsTUFBTSxJQUFJLFVBQVUsQ0FDbEIsZ0RBQWdELDBCQUEwQixlQUFlLGFBQWEsR0FBRyxDQUMxRyxDQUFDO0lBQ0osQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQ3ZCLFdBQVcsRUFDWCxJQUFJLENB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
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@lossless.org/client",
3
- "version": "2.1.0",
3
+ "version": "2.3.0",
4
4
  "private": false,
5
5
  "publishConfig": {
6
6
  "registry": "https://verdaccio.lossless.digital"
@@ -89,7 +89,7 @@
89
89
  "@git.zone/tstest": "7.2.1",
90
90
  "@lossless.org/nosqldb": "8.0.2",
91
91
  "@lossless.org/nosqldb-qualified": "npm:@lossless.org/nosqldb@10.9.0",
92
- "@lossless.org/objectstorage": "10.3.1",
92
+ "@lossless.org/objectstorage": "^10.7.0",
93
93
  "@lossless.org/sqldb": "0.2.3",
94
94
  "@push.rocks/qenv": "^6.1.3",
95
95
  "@types/node": "26.6.4",
package/readme.md CHANGED
@@ -140,6 +140,7 @@ Family imports preserve the established SmartData and SmartBucket names and cons
140
140
  | Reads of objects that may be missing | `bucket.fastGetIfPresent({ path, signal? })` — one GetObject resolving the object's bytes, or `null` when the key does not exist |
141
141
  | Bounded requests | `new SmartBucket(config, { connectionTimeoutMs?, requestTimeoutMs?, maxAttempts? })` and the same options on `new ObjectStorageConnection({ ... })` — every request of the client a SmartBucket builds ends within `smartBucket.requestBounds.requestDeadlineMs`, retries included, or rejects with `ObjectStorageRequestDeadlineError` |
142
142
  | Signals on writes, moves and listings | `bucket.fastPut({ ..., signal? })`, `bucket.fastMove({ ..., signal? })`, `bucket.listObjectKeysPage({ ..., signal? })`, `bucket.listAllObjects(prefix?, { signal? })` and `bucket.listAllObjectsArray(prefix?, { signal? })`; `fastGet`, `fastPutStream`, `fastCopy` and `fastRemove` already took one |
143
+ | Copies of large objects | `bucket.fastCopy({ sourcePath, destinationPath?, targetBucket?, nativeMetadata?, deleteExistingNativeMetadata?, signal? })` copies a source above 5 GiB, which one CopyObject cannot copy, part by part with UploadPartCopy |
143
144
 
144
145
  A bucket lookup sends one HeadBucket for the named bucket, never ListBuckets, so a credential scoped to its bucket can open it without the account-wide list permission, and a lookup does not depend on which buckets a listing returns. A missing bucket (404) keeps its answer: `getBucketByName()` rejects with `Bucket '<name>' not found.` and `bucketExists()` resolves `false`. A bucket the credentials may not access (403) rejects both with an error that names the denial and keeps the provider error as `cause`; S3 does not say whether such a bucket exists. Any other provider failure is rethrown unchanged. `signal` aborts the in-flight request and rejects with the signal's reason. Lookups, creations and removals run as lifecycle-managed operations: `SmartBucket.close()` aborts and awaits them, and the storage client cannot be replaced while one is active.
145
146
 
@@ -149,7 +150,9 @@ A bucket lookup sends one HeadBucket for the named bucket, never ListBuckets, so
149
150
 
150
151
  `fastGetIfPresent()` answers "read it, or tell me it is gone" with one GetObject, so an object removed between an existence check and a read can no longer turn into a failed read: a provider answer that the key does not exist — `NoSuchKey`, `NotFound` or any other HTTP 404 — resolves `null`. Every other failure rejects as `fastGet()` does, the provider error unchanged: a missing bucket (`NoSuchBucket`), a denied request, a failure while the body streams, and an abort through `signal` or `SmartBucket.close()`, which rejects with the abort reason even when the provider answers not-found after it. `fastExists()` and the create-only check of `fastPutStream()` classify a missing object the same way.
151
152
 
152
- Every request of the S3 client a `SmartBucket` builds is bounded. An attempt whose socket does not connect within `connectionTimeoutMs` (default 10 s, at most 60 s), or whose response headers do not arrive within `requestTimeoutMs` of its start (default 60 s, at most 1 h; the upload of the request body counts), fails with the SDK's `TimeoutError`; the SDK retries it up to `maxAttempts` attempts in all (default 3, at most 10, standard retry mode, `AWS_MAX_ATTEMPTS` and shared config files ignored). Each value must be a positive safe integer; anything else is refused with a `TypeError` before a client is built. `smartBucket.requestBounds` (and `connection.requestBounds`) reads the frozen bounds, including `requestDeadlineMs = maxAttempts × requestTimeoutMs + (maxAttempts − 1) × 20 000 ms + 1 000 ms` — the attempts, the longest wait the retry strategy takes before a retry (a provider's retry-after hint included), and a second for the client's own work. 221 000 ms with the defaults. A request still unsettled at that deadline, a stalled error body included, rejects with `ObjectStorageRequestDeadlineError`, its attempt in flight is destroyed and no further attempt of it starts, so a consumer can hold the client to an upper bound of its own (`requestDeadlineMs < bound`). The bound does not undo a request: a PutObject the provider received completely before the deadline or an abort may still take effect. It covers requests, not the time a caller takes to read a download it received: a response body streams at the caller's pace until it is consumed, the caller's signal aborts or the SmartBucket closes. While a client assigned through `storageClient` or `replaceStorageClient()` is in use, `requestBounds` is `undefined` and that client's own configuration applies. A single-request upload (`fastPut`, `fastPutStream`) must finish sending its body within `requestTimeoutMs`; for large objects raise it or use `fastPutStreamExact()`, whose parts are separate requests of 5 MiB each.
153
+ `fastCopy()` reads the source with one HeadObject. A source of up to 5 GiB, the largest object one CopyObject may copy, is copied with one CopyObject, as before. A larger source, which failed before, is copied with a multipart upload of 256 MiB parts (larger when the object needs more than 10,000 parts, up to the 5 TiB S3 maximum), each part an UploadPartCopy of its byte range that requires the source to still carry the ETag the HeadObject read, so a source replaced during the copy fails the copy with the provider's 412 instead of mixing two versions. Each part is one request with its own `requestTimeoutMs` bound. The new object gets the properties CopyObject gives it: the source's metadata and content headers with `deleteExistingNativeMetadata` unset, only the given metadata with it set. Object tags, the storage class, server-side encryption settings and a website redirect are not carried by a part-by-part copy; the new object takes the target bucket's defaults for them. Any failure or abort, `signal` and `SmartBucket.close()` included, sends AbortMultipartUpload and never completes the upload; a create that answered after cancellation has its upload aborted as well. A copy above 5 GiB needs a provider with UploadPartCopy and `x-amz-copy-source-if-match`; ObjectStorage has them from 10.7.0.
154
+
155
+ Every request of the S3 client a `SmartBucket` builds is bounded. An attempt whose socket does not connect within `connectionTimeoutMs` (default 10 s, at most 60 s), or whose response headers do not arrive within `requestTimeoutMs` of its start (default 60 s, at most 1 h; the upload of the request body counts), fails with the SDK's `TimeoutError`; the SDK retries it up to `maxAttempts` attempts in all (default 3, at most 10, standard retry mode, `AWS_MAX_ATTEMPTS` and shared config files ignored). Each value must be a positive safe integer; anything else is refused with a `TypeError` before a client is built. `smartBucket.requestBounds` (and `connection.requestBounds`) reads the frozen bounds, including `requestDeadlineMs = maxAttempts × requestTimeoutMs + (maxAttempts − 1) × 20 000 ms + 1 000 ms` — the attempts, the longest wait the retry strategy takes before a retry (a provider's retry-after hint included), and a second for the client's own work. 221 000 ms with the defaults. A request still unsettled at that deadline, a stalled error body included, rejects with `ObjectStorageRequestDeadlineError`, its attempt in flight is destroyed and no further attempt of it starts, so a consumer can hold the client to an upper bound of its own (`requestDeadlineMs < bound`). The bound does not undo a request: a PutObject the provider received completely before the deadline or an abort may still take effect. It covers requests, not the time a caller takes to read a download it received: a response body streams at the caller's pace until it is consumed, the caller's signal aborts or the SmartBucket closes. While a client assigned through `storageClient` or `replaceStorageClient()` is in use, `requestBounds` is `undefined` and that client's own configuration applies. A single-request upload (`fastPut`, `fastPutStream`) must finish sending its body within `requestTimeoutMs`; large or slow bodies use `fastPutStreamExact()`, whose parts are separate requests, each bounded on its own (5 MiB unless `requestedPartSize` asks for more or the length needs more than 10,000 parts).
153
156
 
154
157
  A `signal` aborts the request in flight, stops its retries and rejects with the signal's reason; an already aborted signal sends nothing. A signal of a bucket read, write, copy, move, removal, existence check or listing that is not an `AbortSignal`, a `Proxy` of one included, is refused with a `TypeError` before any request. A per-call time limit is a signal as well, `AbortSignal.timeout(ms)` or an own `AbortController`.
155
158
 
@@ -3,6 +3,6 @@
3
3
  */
4
4
  export const commitinfo = {
5
5
  name: '@lossless.org/client',
6
- version: '2.1.0',
6
+ version: '2.3.0',
7
7
  description: 'One typed client for NoSQLDB, MongoDB, SQLDB, MariaDB, ClickHouse and S3 object storage.'
8
8
  }