@lossless.org/client 1.7.0 → 1.8.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.
- package/dist_ts/00_commitinfo_data.js +1 -1
- package/dist_ts/nosqldb/classes.atomicdelete.d.ts +1 -0
- package/dist_ts/nosqldb/classes.atomicdelete.js +10 -7
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.d.ts +2 -0
- package/dist_ts/nosqldb/classes.atomicfindoneandupdate.js +9 -5
- package/dist_ts/nosqldb/classes.atomicupdate.d.ts +2 -0
- package/dist_ts/nosqldb/classes.atomicupdate.js +13 -8
- package/dist_ts/nosqldb/classes.collection.d.ts +13 -4
- package/dist_ts/nosqldb/classes.collection.js +57 -64
- package/dist_ts/nosqldb/classes.db.d.ts +1 -1
- package/dist_ts/nosqldb/classes.doc.d.ts +60 -3
- package/dist_ts/nosqldb/classes.doc.js +68 -26
- package/dist_ts/nosqldb/classes.exactpersistence.d.ts +36 -7
- package/dist_ts/nosqldb/classes.exactpersistence.js +92 -81
- package/dist_ts/nosqldb/classes.operationdeadline.d.ts +61 -0
- package/dist_ts/nosqldb/classes.operationdeadline.js +149 -0
- package/dist_ts/nosqldb/classes.persistence.d.ts +16 -1
- package/dist_ts/nosqldb/classes.persistence.js +20 -1
- package/dist_ts/nosqldb/classes.session.d.ts +73 -2
- package/dist_ts/nosqldb/classes.session.js +164 -38
- package/dist_ts/objectstorage/classes.bucket.d.ts +8 -3
- package/dist_ts/objectstorage/classes.bucket.js +83 -131
- package/dist_ts/objectstorage/classes.directory.js +17 -28
- package/dist_ts/objectstorage/classes.smartbucket.d.ts +13 -6
- package/dist_ts/objectstorage/classes.smartbucket.js +18 -12
- package/dist_ts/objectstorage/classes.watcher.js +1 -2
- package/dist_ts/objectstorage/interfaces.d.ts +8 -0
- package/dist_ts/objectstorage/internal.bucketrequests.d.ts +14 -0
- package/dist_ts/objectstorage/internal.bucketrequests.js +53 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.d.ts +12 -0
- package/dist_ts/objectstorage/internal.exactupload.capability.js +46 -17
- package/package.json +1 -1
- package/readme.md +6 -1
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/nosqldb/classes.atomicdelete.ts +10 -6
- package/ts/nosqldb/classes.atomicfindoneandupdate.ts +10 -4
- package/ts/nosqldb/classes.atomicupdate.ts +14 -7
- package/ts/nosqldb/classes.collection.ts +82 -73
- package/ts/nosqldb/classes.db.ts +1 -1
- package/ts/nosqldb/classes.doc.ts +162 -33
- package/ts/nosqldb/classes.exactpersistence.ts +131 -93
- package/ts/nosqldb/classes.operationdeadline.ts +179 -0
- package/ts/nosqldb/classes.persistence.ts +36 -1
- package/ts/nosqldb/classes.session.ts +221 -39
- package/ts/objectstorage/classes.bucket.ts +111 -158
- package/ts/objectstorage/classes.directory.ts +18 -27
- package/ts/objectstorage/classes.smartbucket.ts +21 -11
- package/ts/objectstorage/classes.watcher.ts +0 -1
- package/ts/objectstorage/interfaces.ts +9 -0
- package/ts/objectstorage/internal.bucketrequests.ts +70 -0
- package/ts/objectstorage/internal.exactupload.capability.ts +105 -24
|
@@ -23,6 +23,8 @@ interface IOwnedIndependentAbort {
|
|
|
23
23
|
|
|
24
24
|
interface IActiveCapabilityOperation {
|
|
25
25
|
abortController: AbortController;
|
|
26
|
+
/** Abort cause when the SmartBucket closes while the operation is active. */
|
|
27
|
+
closedDuringMessage: string;
|
|
26
28
|
ownedIndependentAborts: Set<IOwnedIndependentAbort>;
|
|
27
29
|
settlement: Promise<void>;
|
|
28
30
|
settle: () => void;
|
|
@@ -38,14 +40,29 @@ interface ICapabilityLifecycleRecord {
|
|
|
38
40
|
clientMutationReserved: boolean;
|
|
39
41
|
}
|
|
40
42
|
|
|
41
|
-
interface
|
|
42
|
-
bucketRef: IBucketCapabilityRef;
|
|
43
|
-
bucketName: string;
|
|
43
|
+
interface ILifecycleBinding {
|
|
44
44
|
smartbucketRef: ISmartBucketCapabilityRef;
|
|
45
45
|
storageClient: plugins.s3.S3Client;
|
|
46
46
|
lifecycleGeneration: number;
|
|
47
47
|
}
|
|
48
48
|
|
|
49
|
+
interface IExactCapabilityBinding extends ILifecycleBinding {
|
|
50
|
+
bucketRef: IBucketCapabilityRef;
|
|
51
|
+
bucketName: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* What an operation is bound to beyond its lifecycle: a bucket reference that
|
|
56
|
+
* must keep its name and parent, or nothing for an account-scoped request.
|
|
57
|
+
* The messages describe the operation kind in lifecycle errors.
|
|
58
|
+
*/
|
|
59
|
+
interface IOperationIdentity {
|
|
60
|
+
isCurrent(): boolean;
|
|
61
|
+
staleMessage: string;
|
|
62
|
+
detachedMessage: string;
|
|
63
|
+
closedDuringMessage: string;
|
|
64
|
+
}
|
|
65
|
+
|
|
49
66
|
interface IExactPathPurgeCapabilityBinding extends IExactCapabilityBinding {
|
|
50
67
|
versioningMode: TExactPathPurgeVersioningMode;
|
|
51
68
|
}
|
|
@@ -76,6 +93,12 @@ export interface IExactPathPurgeOperation extends IExactUploadOperation {
|
|
|
76
93
|
readonly versioningMode: TExactPathPurgeVersioningMode;
|
|
77
94
|
}
|
|
78
95
|
|
|
96
|
+
/**
|
|
97
|
+
* A lifecycle-managed provider request that addresses the storage account
|
|
98
|
+
* rather than one bucket reference, such as a bucket lookup or creation.
|
|
99
|
+
*/
|
|
100
|
+
export interface IAccountOperation extends Omit<IBasicBucketOperation, 'bucketName'> {}
|
|
101
|
+
|
|
79
102
|
const lifecycleRecords = new WeakMap<
|
|
80
103
|
ISmartBucketCapabilityRef,
|
|
81
104
|
ICapabilityLifecycleRecord
|
|
@@ -102,14 +125,15 @@ const abortAndDisposeIndependentWork = (
|
|
|
102
125
|
activeOperationArg.ownedIndependentAborts.clear();
|
|
103
126
|
};
|
|
104
127
|
|
|
128
|
+
const bucketDetachedMessage = 'The Bucket is not attached to a lifecycle-managed SmartBucket.';
|
|
129
|
+
|
|
105
130
|
const getLifecycleRecord = (
|
|
106
131
|
smartbucketRefArg: ISmartBucketCapabilityRef,
|
|
132
|
+
detachedMessageArg = bucketDetachedMessage,
|
|
107
133
|
): ICapabilityLifecycleRecord => {
|
|
108
134
|
const lifecycleRecord = lifecycleRecords.get(smartbucketRefArg);
|
|
109
135
|
if (!lifecycleRecord) {
|
|
110
|
-
throw new Error(
|
|
111
|
-
'The Bucket is not attached to a lifecycle-managed SmartBucket.',
|
|
112
|
-
);
|
|
136
|
+
throw new Error(detachedMessageArg);
|
|
113
137
|
}
|
|
114
138
|
return lifecycleRecord;
|
|
115
139
|
};
|
|
@@ -189,11 +213,11 @@ export const beginOperationLifecycleClose = (
|
|
|
189
213
|
}
|
|
190
214
|
lifecycleRecord.state = 'closing';
|
|
191
215
|
lifecycleRecord.generation++;
|
|
192
|
-
const
|
|
193
|
-
'The SmartBucket lifecycle closed during an object operation.',
|
|
194
|
-
);
|
|
216
|
+
const lifecycleAbortCauses = new Map<IActiveCapabilityOperation, Error>();
|
|
195
217
|
const activeSettlements: Promise<void>[] = [];
|
|
196
218
|
for (const activeOperation of lifecycleRecord.activeOperations) {
|
|
219
|
+
const lifecycleAbortCause = new Error(activeOperation.closedDuringMessage);
|
|
220
|
+
lifecycleAbortCauses.set(activeOperation, lifecycleAbortCause);
|
|
197
221
|
activeSettlements.push(activeOperation.settlement);
|
|
198
222
|
activeOperation.abortController.abort(lifecycleAbortCause);
|
|
199
223
|
}
|
|
@@ -206,7 +230,10 @@ export const beginOperationLifecycleClose = (
|
|
|
206
230
|
return new Promise<void>((resolveArg) => {
|
|
207
231
|
const settlementDeadline = setTimeout(() => {
|
|
208
232
|
for (const activeOperation of lifecycleRecord.activeOperations) {
|
|
209
|
-
activeOperation.forceFinish(
|
|
233
|
+
activeOperation.forceFinish(
|
|
234
|
+
lifecycleAbortCauses.get(activeOperation)
|
|
235
|
+
?? new Error(activeOperation.closedDuringMessage),
|
|
236
|
+
);
|
|
210
237
|
}
|
|
211
238
|
resolveArg();
|
|
212
239
|
}, operationCloseSettlementTimeoutMs);
|
|
@@ -230,28 +257,51 @@ export const completeOperationLifecycleClose = (
|
|
|
230
257
|
lifecycleRecords.delete(smartbucketRefArg);
|
|
231
258
|
};
|
|
232
259
|
|
|
260
|
+
const bucketIdentity = (bindingArg: IExactCapabilityBinding): IOperationIdentity => ({
|
|
261
|
+
isCurrent: () =>
|
|
262
|
+
bindingArg.bucketRef.smartbucketRef === bindingArg.smartbucketRef &&
|
|
263
|
+
bindingArg.bucketRef.name === bindingArg.bucketName,
|
|
264
|
+
staleMessage: 'The exact upload capability is invalid or stale.',
|
|
265
|
+
detachedMessage: bucketDetachedMessage,
|
|
266
|
+
closedDuringMessage: 'The SmartBucket lifecycle closed during an object operation.',
|
|
267
|
+
});
|
|
268
|
+
|
|
269
|
+
const accountIdentity: IOperationIdentity = {
|
|
270
|
+
isCurrent: () => true,
|
|
271
|
+
staleMessage: 'The bucket request is stale.',
|
|
272
|
+
detachedMessage: 'The SmartBucket is closed; the bucket request was not sent.',
|
|
273
|
+
closedDuringMessage: 'The SmartBucket lifecycle closed during a bucket request.',
|
|
274
|
+
};
|
|
275
|
+
|
|
233
276
|
const assertBindingCurrent = (
|
|
234
|
-
bindingArg:
|
|
277
|
+
bindingArg: ILifecycleBinding,
|
|
278
|
+
identityArg: IOperationIdentity,
|
|
235
279
|
): void => {
|
|
236
|
-
const lifecycleRecord = getLifecycleRecord(
|
|
280
|
+
const lifecycleRecord = getLifecycleRecord(
|
|
281
|
+
bindingArg.smartbucketRef,
|
|
282
|
+
identityArg.detachedMessage,
|
|
283
|
+
);
|
|
237
284
|
assertOpenLifecycle(lifecycleRecord);
|
|
238
285
|
if (
|
|
239
|
-
|
|
240
|
-
bindingArg.bucketRef.name !== bindingArg.bucketName ||
|
|
286
|
+
!identityArg.isCurrent() ||
|
|
241
287
|
lifecycleRecord.generation !== bindingArg.lifecycleGeneration ||
|
|
242
288
|
lifecycleRecord.storageClient !== bindingArg.storageClient ||
|
|
243
289
|
bindingArg.smartbucketRef.storageClient !== bindingArg.storageClient
|
|
244
290
|
) {
|
|
245
|
-
throw new Error(
|
|
291
|
+
throw new Error(identityArg.staleMessage);
|
|
246
292
|
}
|
|
247
293
|
};
|
|
248
294
|
|
|
249
|
-
const
|
|
250
|
-
bindingArg:
|
|
295
|
+
const beginLifecycleOperation = (
|
|
296
|
+
bindingArg: ILifecycleBinding,
|
|
297
|
+
identityArg: IOperationIdentity,
|
|
251
298
|
callerSignalArg?: AbortSignal,
|
|
252
|
-
):
|
|
253
|
-
assertBindingCurrent(bindingArg);
|
|
254
|
-
const lifecycleRecord = getLifecycleRecord(
|
|
299
|
+
): IAccountOperation => {
|
|
300
|
+
assertBindingCurrent(bindingArg, identityArg);
|
|
301
|
+
const lifecycleRecord = getLifecycleRecord(
|
|
302
|
+
bindingArg.smartbucketRef,
|
|
303
|
+
identityArg.detachedMessage,
|
|
304
|
+
);
|
|
255
305
|
const operationAbortController = new AbortController();
|
|
256
306
|
let settleOperation!: () => void;
|
|
257
307
|
const operationSettlement = new Promise<void>((resolveArg) => {
|
|
@@ -284,6 +334,7 @@ const beginOperation = (
|
|
|
284
334
|
};
|
|
285
335
|
const activeOperation: IActiveCapabilityOperation = {
|
|
286
336
|
abortController: operationAbortController,
|
|
337
|
+
closedDuringMessage: identityArg.closedDuringMessage,
|
|
287
338
|
ownedIndependentAborts: new Set(),
|
|
288
339
|
settlement: operationSettlement,
|
|
289
340
|
settle: settleOperation,
|
|
@@ -306,7 +357,6 @@ const beginOperation = (
|
|
|
306
357
|
}
|
|
307
358
|
|
|
308
359
|
return {
|
|
309
|
-
bucketName: bindingArg.bucketName,
|
|
310
360
|
client: bindingArg.storageClient,
|
|
311
361
|
signal: operationAbortController.signal,
|
|
312
362
|
registerOwnedIndependentAbort(
|
|
@@ -332,8 +382,7 @@ const beginOperation = (
|
|
|
332
382
|
if (
|
|
333
383
|
lifecycleRecord.state === 'closed' ||
|
|
334
384
|
!lifecycleRecord.activeOperations.has(activeOperation) ||
|
|
335
|
-
|
|
336
|
-
bindingArg.bucketRef.name !== bindingArg.bucketName ||
|
|
385
|
+
!identityArg.isCurrent() ||
|
|
337
386
|
lifecycleRecord.storageClient !== bindingArg.storageClient ||
|
|
338
387
|
bindingArg.smartbucketRef.storageClient !== bindingArg.storageClient
|
|
339
388
|
) {
|
|
@@ -346,7 +395,7 @@ const beginOperation = (
|
|
|
346
395
|
if (operationAbortController.signal.aborted) {
|
|
347
396
|
throw operationAbortController.signal.reason;
|
|
348
397
|
}
|
|
349
|
-
assertBindingCurrent(bindingArg);
|
|
398
|
+
assertBindingCurrent(bindingArg, identityArg);
|
|
350
399
|
},
|
|
351
400
|
runProvider<T>(
|
|
352
401
|
sendArg: () => Promise<T>,
|
|
@@ -456,6 +505,38 @@ const beginOperation = (
|
|
|
456
505
|
};
|
|
457
506
|
};
|
|
458
507
|
|
|
508
|
+
const beginOperation = (
|
|
509
|
+
bindingArg: IExactCapabilityBinding,
|
|
510
|
+
callerSignalArg?: AbortSignal,
|
|
511
|
+
): IBasicBucketOperation => Object.assign(
|
|
512
|
+
beginLifecycleOperation(bindingArg, bucketIdentity(bindingArg), callerSignalArg),
|
|
513
|
+
{ bucketName: bindingArg.bucketName },
|
|
514
|
+
);
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Begins an account-scoped request under the SmartBucket lifecycle: the
|
|
518
|
+
* caller's signal and `SmartBucket.close()` both abort it, close waits for it,
|
|
519
|
+
* and the storage client cannot change while it is active.
|
|
520
|
+
*/
|
|
521
|
+
export const beginAccountOperation = (
|
|
522
|
+
smartbucketRefArg: ISmartBucketCapabilityRef,
|
|
523
|
+
callerSignalArg?: AbortSignal,
|
|
524
|
+
): IAccountOperation => {
|
|
525
|
+
const lifecycleRecord = getLifecycleRecord(
|
|
526
|
+
smartbucketRefArg,
|
|
527
|
+
accountIdentity.detachedMessage,
|
|
528
|
+
);
|
|
529
|
+
return beginLifecycleOperation(
|
|
530
|
+
{
|
|
531
|
+
smartbucketRef: smartbucketRefArg,
|
|
532
|
+
storageClient: lifecycleRecord.storageClient,
|
|
533
|
+
lifecycleGeneration: lifecycleRecord.generation,
|
|
534
|
+
},
|
|
535
|
+
accountIdentity,
|
|
536
|
+
callerSignalArg,
|
|
537
|
+
);
|
|
538
|
+
};
|
|
539
|
+
|
|
459
540
|
export const beginBasicBucketOperation = (
|
|
460
541
|
bucketRefArg: IBucketCapabilityRef,
|
|
461
542
|
callerSignalArg?: AbortSignal,
|