@salesforce/lds-runtime-mobile 1.100.2 → 1.100.4
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/main.js +187 -145
- package/package.json +15 -15
- package/sfdc/main.js +187 -145
package/dist/main.js
CHANGED
|
@@ -4344,6 +4344,44 @@ function makeStoreEval(preconditioner, objectInfoService, userId, contextProvide
|
|
|
4344
4344
|
return wrapStartEndEvents(storeEval);
|
|
4345
4345
|
}
|
|
4346
4346
|
|
|
4347
|
+
/**
|
|
4348
|
+
* Copyright (c) 2022, Salesforce, Inc.,
|
|
4349
|
+
* All rights reserved.
|
|
4350
|
+
* For full license text, see the LICENSE.txt file
|
|
4351
|
+
*/
|
|
4352
|
+
|
|
4353
|
+
class AsyncWorkerPool {
|
|
4354
|
+
constructor(concurrency) {
|
|
4355
|
+
this.queue = [];
|
|
4356
|
+
this.activeWorkers = 0;
|
|
4357
|
+
this.concurrency = concurrency;
|
|
4358
|
+
}
|
|
4359
|
+
push(workFn) {
|
|
4360
|
+
return new Promise((resolve, reject) => {
|
|
4361
|
+
this.queue.push(async () => {
|
|
4362
|
+
return workFn().then(resolve).catch(reject);
|
|
4363
|
+
});
|
|
4364
|
+
this.work();
|
|
4365
|
+
});
|
|
4366
|
+
}
|
|
4367
|
+
cancel() {
|
|
4368
|
+
this.queue = [];
|
|
4369
|
+
// TODO [W-12513105]: thread cancellation through to active workers
|
|
4370
|
+
}
|
|
4371
|
+
work() {
|
|
4372
|
+
while (this.queue.length > 0 && this.activeWorkers < this.concurrency) {
|
|
4373
|
+
this.activeWorkers += 1;
|
|
4374
|
+
const next = this.queue.shift();
|
|
4375
|
+
if (next) {
|
|
4376
|
+
next().finally(() => {
|
|
4377
|
+
this.activeWorkers -= 1;
|
|
4378
|
+
this.work();
|
|
4379
|
+
});
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
4382
|
+
}
|
|
4383
|
+
}
|
|
4384
|
+
|
|
4347
4385
|
/**
|
|
4348
4386
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
4349
4387
|
* All rights reserved.
|
|
@@ -4762,6 +4800,7 @@ class DurableDraftQueue {
|
|
|
4762
4800
|
this.timeoutHandler = undefined;
|
|
4763
4801
|
this.handlers = {};
|
|
4764
4802
|
this.draftStore = draftStore;
|
|
4803
|
+
this.workerPool = new AsyncWorkerPool(1);
|
|
4765
4804
|
}
|
|
4766
4805
|
addHandler(handler) {
|
|
4767
4806
|
const id = handler.handlerId;
|
|
@@ -4861,20 +4900,22 @@ class DurableDraftQueue {
|
|
|
4861
4900
|
});
|
|
4862
4901
|
}
|
|
4863
4902
|
async enqueue(handlerId, data) {
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4903
|
+
return this.workerPool.push(async () => {
|
|
4904
|
+
let queue = await this.getQueueActions();
|
|
4905
|
+
const handler = this.getHandler(handlerId);
|
|
4906
|
+
const pendingAction = (await handler.buildPendingAction(data, queue));
|
|
4907
|
+
await this.draftStore.writeAction(pendingAction);
|
|
4908
|
+
queue = await this.getQueueActions();
|
|
4909
|
+
await this.notifyChangedListeners({
|
|
4910
|
+
type: DraftQueueEventType.ActionAdded,
|
|
4911
|
+
action: pendingAction,
|
|
4912
|
+
});
|
|
4913
|
+
await handler.handleActionEnqueued(pendingAction, queue);
|
|
4914
|
+
if (this.state === DraftQueueState.Started) {
|
|
4915
|
+
this.processNextAction();
|
|
4916
|
+
}
|
|
4917
|
+
return pendingAction;
|
|
4872
4918
|
});
|
|
4873
|
-
await handler.handleActionEnqueued(pendingAction, queue);
|
|
4874
|
-
if (this.state === DraftQueueState.Started) {
|
|
4875
|
-
this.processNextAction();
|
|
4876
|
-
}
|
|
4877
|
-
return pendingAction;
|
|
4878
4919
|
}
|
|
4879
4920
|
registerOnChangedListener(listener) {
|
|
4880
4921
|
this.draftQueueChangedListeners.push(listener);
|
|
@@ -4886,27 +4927,29 @@ class DurableDraftQueue {
|
|
|
4886
4927
|
};
|
|
4887
4928
|
}
|
|
4888
4929
|
async actionCompleted(action) {
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4930
|
+
return this.workerPool.push(async () => {
|
|
4931
|
+
const handler = this.getHandler(action.handler);
|
|
4932
|
+
let queue = await this.getQueueActions();
|
|
4933
|
+
const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
|
|
4934
|
+
const idAndKeyMappings = handler.getRedirectMappings(action);
|
|
4935
|
+
const keyMappings = idAndKeyMappings === undefined
|
|
4936
|
+
? undefined
|
|
4937
|
+
: idAndKeyMappings.map((m) => {
|
|
4938
|
+
return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
|
|
4939
|
+
});
|
|
4940
|
+
await this.draftStore.completeAction(queueOperations, keyMappings);
|
|
4941
|
+
queue = await this.getQueueActions();
|
|
4942
|
+
this.retryIntervalMilliseconds = 0;
|
|
4943
|
+
this.uploadingActionId = undefined;
|
|
4944
|
+
await handler.handleActionCompleted(action, queueOperations, queue, values$1(this.handlers));
|
|
4945
|
+
await this.notifyChangedListeners({
|
|
4946
|
+
type: DraftQueueEventType.ActionCompleted,
|
|
4947
|
+
action,
|
|
4897
4948
|
});
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
this.uploadingActionId = undefined;
|
|
4902
|
-
await handler.handleActionCompleted(action, queueOperations, queue, values$1(this.handlers));
|
|
4903
|
-
await this.notifyChangedListeners({
|
|
4904
|
-
type: DraftQueueEventType.ActionCompleted,
|
|
4905
|
-
action,
|
|
4949
|
+
if (this.state === DraftQueueState.Started) {
|
|
4950
|
+
this.processNextAction();
|
|
4951
|
+
}
|
|
4906
4952
|
});
|
|
4907
|
-
if (this.state === DraftQueueState.Started) {
|
|
4908
|
-
this.processNextAction();
|
|
4909
|
-
}
|
|
4910
4953
|
}
|
|
4911
4954
|
async actionFailed(action, retry) {
|
|
4912
4955
|
this.uploadingActionId = undefined;
|
|
@@ -5356,6 +5399,13 @@ class AbstractResourceRequestActionHandler {
|
|
|
5356
5399
|
this.draftQueue = draftQueue;
|
|
5357
5400
|
this.networkAdapter = networkAdapter;
|
|
5358
5401
|
this.getLuvio = getLuvio;
|
|
5402
|
+
// NOTE[W-12567340]: This property stores in-memory mappings between draft
|
|
5403
|
+
// ids and canonical ids for the current session. Having a local copy of
|
|
5404
|
+
// these mappings is necessary to avoid a race condition between publishing
|
|
5405
|
+
// new mappings to the durable store and those mappings being loaded into
|
|
5406
|
+
// the luvio store redirect table, during which a new draft might be enqueued
|
|
5407
|
+
// which would not see a necessary mapping.
|
|
5408
|
+
this.ephemeralRedirects = {};
|
|
5359
5409
|
}
|
|
5360
5410
|
enqueue(data) {
|
|
5361
5411
|
return this.draftQueue.enqueue(this.handlerId, data);
|
|
@@ -5423,7 +5473,8 @@ class AbstractResourceRequestActionHandler {
|
|
|
5423
5473
|
}
|
|
5424
5474
|
getQueueOperationsForCompletingDrafts(queue, action) {
|
|
5425
5475
|
const queueOperations = [];
|
|
5426
|
-
|
|
5476
|
+
const redirects = this.getRedirectMappings(action);
|
|
5477
|
+
if (redirects !== undefined) {
|
|
5427
5478
|
const { length } = queue;
|
|
5428
5479
|
for (let i = 0; i < length; i++) {
|
|
5429
5480
|
const queueAction = queue[i];
|
|
@@ -5433,69 +5484,64 @@ class AbstractResourceRequestActionHandler {
|
|
|
5433
5484
|
continue;
|
|
5434
5485
|
}
|
|
5435
5486
|
if (isResourceRequestAction(queueAction)) {
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
basePath = basePath.replace(draftId, canonicalId);
|
|
5450
|
-
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
5451
|
-
queueOperationMutated = true;
|
|
5452
|
-
}
|
|
5453
|
-
// if the action is performed on a previous draft id, we need to replace the action
|
|
5454
|
-
// with a new one at the updated canonical key
|
|
5455
|
-
if (queueActionTag === draftKey) {
|
|
5456
|
-
updatedActionTag = canonicalKey;
|
|
5457
|
-
updatedActionTargetId = canonicalId;
|
|
5458
|
-
}
|
|
5487
|
+
let queueOperationMutated = false;
|
|
5488
|
+
let updatedActionTag = undefined;
|
|
5489
|
+
let updatedActionTargetId = undefined;
|
|
5490
|
+
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
5491
|
+
let { basePath, body } = queueActionRequest;
|
|
5492
|
+
let stringifiedBody = stringify$4(body);
|
|
5493
|
+
// for each redirected ID/key we loop over the operation to see if it needs
|
|
5494
|
+
// to be updated
|
|
5495
|
+
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
5496
|
+
if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
|
|
5497
|
+
basePath = basePath.replace(draftId, canonicalId);
|
|
5498
|
+
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
5499
|
+
queueOperationMutated = true;
|
|
5459
5500
|
}
|
|
5460
|
-
if
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
}
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5501
|
+
// if the action is performed on a previous draft id, we need to replace the action
|
|
5502
|
+
// with a new one at the updated canonical key
|
|
5503
|
+
if (queueActionTag === draftKey) {
|
|
5504
|
+
updatedActionTag = canonicalKey;
|
|
5505
|
+
updatedActionTargetId = canonicalId;
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
if (queueOperationMutated) {
|
|
5509
|
+
if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
|
|
5510
|
+
const updatedAction = {
|
|
5511
|
+
...queueAction,
|
|
5512
|
+
tag: updatedActionTag,
|
|
5513
|
+
targetId: updatedActionTargetId,
|
|
5514
|
+
data: {
|
|
5515
|
+
...queueActionRequest,
|
|
5516
|
+
basePath: basePath,
|
|
5517
|
+
body: parse$4(stringifiedBody),
|
|
5518
|
+
},
|
|
5519
|
+
};
|
|
5520
|
+
// item needs to be replaced with a new item at the new record key
|
|
5521
|
+
queueOperations.push({
|
|
5522
|
+
type: QueueOperationType.Delete,
|
|
5523
|
+
id: queueActionId,
|
|
5524
|
+
});
|
|
5525
|
+
queueOperations.push({
|
|
5526
|
+
type: QueueOperationType.Add,
|
|
5527
|
+
action: updatedAction,
|
|
5528
|
+
});
|
|
5529
|
+
}
|
|
5530
|
+
else {
|
|
5531
|
+
const updatedAction = {
|
|
5532
|
+
...queueAction,
|
|
5533
|
+
data: {
|
|
5534
|
+
...queueActionRequest,
|
|
5535
|
+
basePath: basePath,
|
|
5536
|
+
body: parse$4(stringifiedBody),
|
|
5537
|
+
},
|
|
5538
|
+
};
|
|
5539
|
+
// item needs to be updated
|
|
5540
|
+
queueOperations.push({
|
|
5541
|
+
type: QueueOperationType.Update,
|
|
5542
|
+
id: queueActionId,
|
|
5543
|
+
action: updatedAction,
|
|
5544
|
+
});
|
|
5499
5545
|
}
|
|
5500
5546
|
}
|
|
5501
5547
|
}
|
|
@@ -5515,6 +5561,9 @@ class AbstractResourceRequestActionHandler {
|
|
|
5515
5561
|
const body = action.response.body;
|
|
5516
5562
|
const canonicalId = this.getIdFromResponseBody(body);
|
|
5517
5563
|
const draftId = action.targetId;
|
|
5564
|
+
if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
|
|
5565
|
+
this.ephemeralRedirects[draftId] = canonicalId;
|
|
5566
|
+
}
|
|
5518
5567
|
return [
|
|
5519
5568
|
{
|
|
5520
5569
|
draftId,
|
|
@@ -10220,7 +10269,8 @@ const assignedToMeFragmentSelections = [
|
|
|
10220
10269
|
},
|
|
10221
10270
|
];
|
|
10222
10271
|
function removeSyntheticFields(result, query) {
|
|
10223
|
-
|
|
10272
|
+
// It is possible that there are multiple record query.
|
|
10273
|
+
const connectionSelections = query.definitions
|
|
10224
10274
|
.filter(isOperationDefinitionNode)
|
|
10225
10275
|
.reduce((accu, definition) => {
|
|
10226
10276
|
return accu.concat(definition.selectionSet.selections);
|
|
@@ -10231,10 +10281,12 @@ function removeSyntheticFields(result, query) {
|
|
|
10231
10281
|
.filter(isFieldNode)
|
|
10232
10282
|
.filter(nodeIsNamed('query'))
|
|
10233
10283
|
.reduce(extractSelections, [])
|
|
10234
|
-
.filter(isFieldNode)
|
|
10284
|
+
.filter(isFieldNode);
|
|
10235
10285
|
// queries that are not RecordQuery will be undefined here.
|
|
10236
|
-
// we need to also check that
|
|
10237
|
-
if (!
|
|
10286
|
+
// we need to also check that connectionSelections are not undefined. If any connectionSelection has no `selectionSet` defined, that is a malformed query.
|
|
10287
|
+
if (!connectionSelections ||
|
|
10288
|
+
connectionSelections.length === 0 ||
|
|
10289
|
+
connectionSelections.some((connection) => connection.selectionSet === undefined)) {
|
|
10238
10290
|
return result;
|
|
10239
10291
|
}
|
|
10240
10292
|
const nodeJson = result.data.uiapi.query;
|
|
@@ -10243,10 +10295,15 @@ function removeSyntheticFields(result, query) {
|
|
|
10243
10295
|
const output = { ...result };
|
|
10244
10296
|
const outputApiParent = output.data.uiapi.query;
|
|
10245
10297
|
const keys$1 = keys$3(nodeJson);
|
|
10246
|
-
keys$1.forEach((
|
|
10298
|
+
keys$1.forEach((recordName) => {
|
|
10247
10299
|
const outputApi = {};
|
|
10248
|
-
|
|
10249
|
-
|
|
10300
|
+
// Each connectionSelection's maps its name or alias to one of returned records. The record name could be `apiName' or alias
|
|
10301
|
+
const targetConnection = connectionSelections.find((connection) => connection.name.value === recordName ||
|
|
10302
|
+
(connection.alias !== undefined && connection.alias.value === recordName));
|
|
10303
|
+
if (targetConnection !== undefined) {
|
|
10304
|
+
createUserJsonOutput(targetConnection, nodeJson[recordName], outputApi);
|
|
10305
|
+
outputApiParent[recordName] = outputApi;
|
|
10306
|
+
}
|
|
10250
10307
|
});
|
|
10251
10308
|
return output;
|
|
10252
10309
|
}
|
|
@@ -11288,12 +11345,18 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
|
|
|
11288
11345
|
const fieldName = fieldNames[i];
|
|
11289
11346
|
const fieldValue = bodyFields[fieldName];
|
|
11290
11347
|
if (typeof fieldValue === 'string' && this.isDraftId(fieldValue)) {
|
|
11291
|
-
const
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11348
|
+
const canonicalId = this.ephemeralRedirects[fieldValue];
|
|
11349
|
+
if (canonicalId !== undefined) {
|
|
11350
|
+
bodyFields[fieldName] = canonicalId;
|
|
11351
|
+
}
|
|
11352
|
+
else {
|
|
11353
|
+
const draftKey = this.buildTagForTargetId(fieldValue);
|
|
11354
|
+
const canonicalKey = this.getLuvio().storeGetCanonicalKey(draftKey);
|
|
11355
|
+
if (draftKey !== canonicalKey) {
|
|
11356
|
+
const canonicalId = extractRecordIdFromStoreKey(canonicalKey);
|
|
11357
|
+
if (canonicalId !== undefined) {
|
|
11358
|
+
bodyFields[fieldName] = canonicalId;
|
|
11359
|
+
}
|
|
11297
11360
|
}
|
|
11298
11361
|
}
|
|
11299
11362
|
}
|
|
@@ -11301,17 +11364,24 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
|
|
|
11301
11364
|
}
|
|
11302
11365
|
if (request.method === 'patch' || request.method === 'delete') {
|
|
11303
11366
|
const recordId = request.urlParams['recordId'];
|
|
11304
|
-
const
|
|
11305
|
-
|
|
11306
|
-
if (recordKey !== canonicalKey) {
|
|
11307
|
-
const canonicalId = extractRecordIdFromStoreKey(canonicalKey);
|
|
11308
|
-
if (canonicalId === undefined) {
|
|
11309
|
-
// could not resolve id from request -- return the request un-modified
|
|
11310
|
-
return request;
|
|
11311
|
-
}
|
|
11367
|
+
const canonicalId = this.ephemeralRedirects[recordId];
|
|
11368
|
+
if (canonicalId !== undefined) {
|
|
11312
11369
|
resolvedBasePath = resolvedBasePath.replace(recordId, canonicalId);
|
|
11313
11370
|
resolvedUrlParams = { ...resolvedUrlParams, recordId: canonicalId };
|
|
11314
11371
|
}
|
|
11372
|
+
else {
|
|
11373
|
+
const recordKey = this.buildTagForTargetId(recordId);
|
|
11374
|
+
const canonicalKey = this.getLuvio().storeGetCanonicalKey(recordKey);
|
|
11375
|
+
if (recordKey !== canonicalKey) {
|
|
11376
|
+
const canonicalId = extractRecordIdFromStoreKey(canonicalKey);
|
|
11377
|
+
if (canonicalId === undefined) {
|
|
11378
|
+
// could not resolve id from request -- return the request un-modified
|
|
11379
|
+
return request;
|
|
11380
|
+
}
|
|
11381
|
+
resolvedBasePath = resolvedBasePath.replace(recordId, canonicalId);
|
|
11382
|
+
resolvedUrlParams = { ...resolvedUrlParams, recordId: canonicalId };
|
|
11383
|
+
}
|
|
11384
|
+
}
|
|
11315
11385
|
}
|
|
11316
11386
|
return {
|
|
11317
11387
|
...request,
|
|
@@ -14659,34 +14729,6 @@ function setupInspection(luvio) {
|
|
|
14659
14729
|
* For full license text, see the LICENSE.txt file
|
|
14660
14730
|
*/
|
|
14661
14731
|
|
|
14662
|
-
class AsyncWorkerPool {
|
|
14663
|
-
constructor(concurrency) {
|
|
14664
|
-
this.queue = [];
|
|
14665
|
-
this.activeWorkers = 0;
|
|
14666
|
-
this.concurrency = concurrency;
|
|
14667
|
-
}
|
|
14668
|
-
push(workFn) {
|
|
14669
|
-
this.queue.push(workFn);
|
|
14670
|
-
this.work();
|
|
14671
|
-
}
|
|
14672
|
-
cancel() {
|
|
14673
|
-
this.queue = [];
|
|
14674
|
-
// TODO [W-12513105]: thread cancellation through to active workers
|
|
14675
|
-
}
|
|
14676
|
-
work() {
|
|
14677
|
-
while (this.queue.length > 0 && this.activeWorkers < this.concurrency) {
|
|
14678
|
-
this.activeWorkers += 1;
|
|
14679
|
-
const next = this.queue.shift();
|
|
14680
|
-
if (next) {
|
|
14681
|
-
next().finally(() => {
|
|
14682
|
-
this.activeWorkers -= 1;
|
|
14683
|
-
this.work();
|
|
14684
|
-
});
|
|
14685
|
-
}
|
|
14686
|
-
}
|
|
14687
|
-
}
|
|
14688
|
-
}
|
|
14689
|
-
|
|
14690
14732
|
class EventEmitter {
|
|
14691
14733
|
constructor() {
|
|
14692
14734
|
// @ts-ignore typescript doesn't like us setting this to an empty object for some reason
|
|
@@ -15239,4 +15281,4 @@ register({
|
|
|
15239
15281
|
});
|
|
15240
15282
|
|
|
15241
15283
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
15242
|
-
// version: 1.100.
|
|
15284
|
+
// version: 1.100.4-ce1be23b7
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-mobile",
|
|
3
|
-
"version": "1.100.
|
|
3
|
+
"version": "1.100.4",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for mobile/hybrid environments.",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -32,10 +32,10 @@
|
|
|
32
32
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-mobile"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@salesforce/lds-adapters-uiapi": "^1.100.
|
|
36
|
-
"@salesforce/lds-bindings": "^1.100.
|
|
37
|
-
"@salesforce/lds-instrumentation": "^1.100.
|
|
38
|
-
"@salesforce/lds-priming": "^1.100.
|
|
35
|
+
"@salesforce/lds-adapters-uiapi": "^1.100.4",
|
|
36
|
+
"@salesforce/lds-bindings": "^1.100.4",
|
|
37
|
+
"@salesforce/lds-instrumentation": "^1.100.4",
|
|
38
|
+
"@salesforce/lds-priming": "^1.100.4",
|
|
39
39
|
"@salesforce/user": "0.0.12",
|
|
40
40
|
"o11y": "244.0.0"
|
|
41
41
|
},
|
|
@@ -43,16 +43,16 @@
|
|
|
43
43
|
"@luvio/engine": "0.135.4",
|
|
44
44
|
"@luvio/environments": "0.135.4",
|
|
45
45
|
"@luvio/graphql-parser": "0.135.4",
|
|
46
|
-
"@salesforce/lds-adapters-graphql": "^1.100.
|
|
47
|
-
"@salesforce/lds-drafts": "^1.100.
|
|
48
|
-
"@salesforce/lds-drafts-adapters-uiapi": "^1.100.
|
|
49
|
-
"@salesforce/lds-graphql-eval": "^1.100.
|
|
50
|
-
"@salesforce/lds-network-adapter": "^1.100.
|
|
51
|
-
"@salesforce/lds-network-nimbus": "^1.100.
|
|
52
|
-
"@salesforce/lds-store-binary": "^1.100.
|
|
53
|
-
"@salesforce/lds-store-sql": "^1.100.
|
|
54
|
-
"@salesforce/lds-utils-adapters": "^1.100.
|
|
55
|
-
"@salesforce/nimbus-plugin-lds": "^1.100.
|
|
46
|
+
"@salesforce/lds-adapters-graphql": "^1.100.4",
|
|
47
|
+
"@salesforce/lds-drafts": "^1.100.4",
|
|
48
|
+
"@salesforce/lds-drafts-adapters-uiapi": "^1.100.4",
|
|
49
|
+
"@salesforce/lds-graphql-eval": "^1.100.4",
|
|
50
|
+
"@salesforce/lds-network-adapter": "^1.100.4",
|
|
51
|
+
"@salesforce/lds-network-nimbus": "^1.100.4",
|
|
52
|
+
"@salesforce/lds-store-binary": "^1.100.4",
|
|
53
|
+
"@salesforce/lds-store-sql": "^1.100.4",
|
|
54
|
+
"@salesforce/lds-utils-adapters": "^1.100.4",
|
|
55
|
+
"@salesforce/nimbus-plugin-lds": "^1.100.4",
|
|
56
56
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
57
57
|
"wait-for-expect": "^3.0.2"
|
|
58
58
|
},
|
package/sfdc/main.js
CHANGED
|
@@ -4344,6 +4344,44 @@ function makeStoreEval(preconditioner, objectInfoService, userId, contextProvide
|
|
|
4344
4344
|
return wrapStartEndEvents(storeEval);
|
|
4345
4345
|
}
|
|
4346
4346
|
|
|
4347
|
+
/**
|
|
4348
|
+
* Copyright (c) 2022, Salesforce, Inc.,
|
|
4349
|
+
* All rights reserved.
|
|
4350
|
+
* For full license text, see the LICENSE.txt file
|
|
4351
|
+
*/
|
|
4352
|
+
|
|
4353
|
+
class AsyncWorkerPool {
|
|
4354
|
+
constructor(concurrency) {
|
|
4355
|
+
this.queue = [];
|
|
4356
|
+
this.activeWorkers = 0;
|
|
4357
|
+
this.concurrency = concurrency;
|
|
4358
|
+
}
|
|
4359
|
+
push(workFn) {
|
|
4360
|
+
return new Promise((resolve, reject) => {
|
|
4361
|
+
this.queue.push(async () => {
|
|
4362
|
+
return workFn().then(resolve).catch(reject);
|
|
4363
|
+
});
|
|
4364
|
+
this.work();
|
|
4365
|
+
});
|
|
4366
|
+
}
|
|
4367
|
+
cancel() {
|
|
4368
|
+
this.queue = [];
|
|
4369
|
+
// TODO [W-12513105]: thread cancellation through to active workers
|
|
4370
|
+
}
|
|
4371
|
+
work() {
|
|
4372
|
+
while (this.queue.length > 0 && this.activeWorkers < this.concurrency) {
|
|
4373
|
+
this.activeWorkers += 1;
|
|
4374
|
+
const next = this.queue.shift();
|
|
4375
|
+
if (next) {
|
|
4376
|
+
next().finally(() => {
|
|
4377
|
+
this.activeWorkers -= 1;
|
|
4378
|
+
this.work();
|
|
4379
|
+
});
|
|
4380
|
+
}
|
|
4381
|
+
}
|
|
4382
|
+
}
|
|
4383
|
+
}
|
|
4384
|
+
|
|
4347
4385
|
/**
|
|
4348
4386
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
4349
4387
|
* All rights reserved.
|
|
@@ -4762,6 +4800,7 @@ class DurableDraftQueue {
|
|
|
4762
4800
|
this.timeoutHandler = undefined;
|
|
4763
4801
|
this.handlers = {};
|
|
4764
4802
|
this.draftStore = draftStore;
|
|
4803
|
+
this.workerPool = new AsyncWorkerPool(1);
|
|
4765
4804
|
}
|
|
4766
4805
|
addHandler(handler) {
|
|
4767
4806
|
const id = handler.handlerId;
|
|
@@ -4861,20 +4900,22 @@ class DurableDraftQueue {
|
|
|
4861
4900
|
});
|
|
4862
4901
|
}
|
|
4863
4902
|
async enqueue(handlerId, data) {
|
|
4864
|
-
|
|
4865
|
-
|
|
4866
|
-
|
|
4867
|
-
|
|
4868
|
-
|
|
4869
|
-
|
|
4870
|
-
|
|
4871
|
-
|
|
4903
|
+
return this.workerPool.push(async () => {
|
|
4904
|
+
let queue = await this.getQueueActions();
|
|
4905
|
+
const handler = this.getHandler(handlerId);
|
|
4906
|
+
const pendingAction = (await handler.buildPendingAction(data, queue));
|
|
4907
|
+
await this.draftStore.writeAction(pendingAction);
|
|
4908
|
+
queue = await this.getQueueActions();
|
|
4909
|
+
await this.notifyChangedListeners({
|
|
4910
|
+
type: DraftQueueEventType.ActionAdded,
|
|
4911
|
+
action: pendingAction,
|
|
4912
|
+
});
|
|
4913
|
+
await handler.handleActionEnqueued(pendingAction, queue);
|
|
4914
|
+
if (this.state === DraftQueueState.Started) {
|
|
4915
|
+
this.processNextAction();
|
|
4916
|
+
}
|
|
4917
|
+
return pendingAction;
|
|
4872
4918
|
});
|
|
4873
|
-
await handler.handleActionEnqueued(pendingAction, queue);
|
|
4874
|
-
if (this.state === DraftQueueState.Started) {
|
|
4875
|
-
this.processNextAction();
|
|
4876
|
-
}
|
|
4877
|
-
return pendingAction;
|
|
4878
4919
|
}
|
|
4879
4920
|
registerOnChangedListener(listener) {
|
|
4880
4921
|
this.draftQueueChangedListeners.push(listener);
|
|
@@ -4886,27 +4927,29 @@ class DurableDraftQueue {
|
|
|
4886
4927
|
};
|
|
4887
4928
|
}
|
|
4888
4929
|
async actionCompleted(action) {
|
|
4889
|
-
|
|
4890
|
-
|
|
4891
|
-
|
|
4892
|
-
|
|
4893
|
-
|
|
4894
|
-
|
|
4895
|
-
|
|
4896
|
-
|
|
4930
|
+
return this.workerPool.push(async () => {
|
|
4931
|
+
const handler = this.getHandler(action.handler);
|
|
4932
|
+
let queue = await this.getQueueActions();
|
|
4933
|
+
const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
|
|
4934
|
+
const idAndKeyMappings = handler.getRedirectMappings(action);
|
|
4935
|
+
const keyMappings = idAndKeyMappings === undefined
|
|
4936
|
+
? undefined
|
|
4937
|
+
: idAndKeyMappings.map((m) => {
|
|
4938
|
+
return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
|
|
4939
|
+
});
|
|
4940
|
+
await this.draftStore.completeAction(queueOperations, keyMappings);
|
|
4941
|
+
queue = await this.getQueueActions();
|
|
4942
|
+
this.retryIntervalMilliseconds = 0;
|
|
4943
|
+
this.uploadingActionId = undefined;
|
|
4944
|
+
await handler.handleActionCompleted(action, queueOperations, queue, values$1(this.handlers));
|
|
4945
|
+
await this.notifyChangedListeners({
|
|
4946
|
+
type: DraftQueueEventType.ActionCompleted,
|
|
4947
|
+
action,
|
|
4897
4948
|
});
|
|
4898
|
-
|
|
4899
|
-
|
|
4900
|
-
|
|
4901
|
-
this.uploadingActionId = undefined;
|
|
4902
|
-
await handler.handleActionCompleted(action, queueOperations, queue, values$1(this.handlers));
|
|
4903
|
-
await this.notifyChangedListeners({
|
|
4904
|
-
type: DraftQueueEventType.ActionCompleted,
|
|
4905
|
-
action,
|
|
4949
|
+
if (this.state === DraftQueueState.Started) {
|
|
4950
|
+
this.processNextAction();
|
|
4951
|
+
}
|
|
4906
4952
|
});
|
|
4907
|
-
if (this.state === DraftQueueState.Started) {
|
|
4908
|
-
this.processNextAction();
|
|
4909
|
-
}
|
|
4910
4953
|
}
|
|
4911
4954
|
async actionFailed(action, retry) {
|
|
4912
4955
|
this.uploadingActionId = undefined;
|
|
@@ -5356,6 +5399,13 @@ class AbstractResourceRequestActionHandler {
|
|
|
5356
5399
|
this.draftQueue = draftQueue;
|
|
5357
5400
|
this.networkAdapter = networkAdapter;
|
|
5358
5401
|
this.getLuvio = getLuvio;
|
|
5402
|
+
// NOTE[W-12567340]: This property stores in-memory mappings between draft
|
|
5403
|
+
// ids and canonical ids for the current session. Having a local copy of
|
|
5404
|
+
// these mappings is necessary to avoid a race condition between publishing
|
|
5405
|
+
// new mappings to the durable store and those mappings being loaded into
|
|
5406
|
+
// the luvio store redirect table, during which a new draft might be enqueued
|
|
5407
|
+
// which would not see a necessary mapping.
|
|
5408
|
+
this.ephemeralRedirects = {};
|
|
5359
5409
|
}
|
|
5360
5410
|
enqueue(data) {
|
|
5361
5411
|
return this.draftQueue.enqueue(this.handlerId, data);
|
|
@@ -5423,7 +5473,8 @@ class AbstractResourceRequestActionHandler {
|
|
|
5423
5473
|
}
|
|
5424
5474
|
getQueueOperationsForCompletingDrafts(queue, action) {
|
|
5425
5475
|
const queueOperations = [];
|
|
5426
|
-
|
|
5476
|
+
const redirects = this.getRedirectMappings(action);
|
|
5477
|
+
if (redirects !== undefined) {
|
|
5427
5478
|
const { length } = queue;
|
|
5428
5479
|
for (let i = 0; i < length; i++) {
|
|
5429
5480
|
const queueAction = queue[i];
|
|
@@ -5433,69 +5484,64 @@ class AbstractResourceRequestActionHandler {
|
|
|
5433
5484
|
continue;
|
|
5434
5485
|
}
|
|
5435
5486
|
if (isResourceRequestAction(queueAction)) {
|
|
5436
|
-
|
|
5437
|
-
|
|
5438
|
-
|
|
5439
|
-
|
|
5440
|
-
|
|
5441
|
-
|
|
5442
|
-
|
|
5443
|
-
|
|
5444
|
-
|
|
5445
|
-
|
|
5446
|
-
|
|
5447
|
-
|
|
5448
|
-
|
|
5449
|
-
basePath = basePath.replace(draftId, canonicalId);
|
|
5450
|
-
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
5451
|
-
queueOperationMutated = true;
|
|
5452
|
-
}
|
|
5453
|
-
// if the action is performed on a previous draft id, we need to replace the action
|
|
5454
|
-
// with a new one at the updated canonical key
|
|
5455
|
-
if (queueActionTag === draftKey) {
|
|
5456
|
-
updatedActionTag = canonicalKey;
|
|
5457
|
-
updatedActionTargetId = canonicalId;
|
|
5458
|
-
}
|
|
5487
|
+
let queueOperationMutated = false;
|
|
5488
|
+
let updatedActionTag = undefined;
|
|
5489
|
+
let updatedActionTargetId = undefined;
|
|
5490
|
+
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
5491
|
+
let { basePath, body } = queueActionRequest;
|
|
5492
|
+
let stringifiedBody = stringify$4(body);
|
|
5493
|
+
// for each redirected ID/key we loop over the operation to see if it needs
|
|
5494
|
+
// to be updated
|
|
5495
|
+
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
5496
|
+
if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
|
|
5497
|
+
basePath = basePath.replace(draftId, canonicalId);
|
|
5498
|
+
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
5499
|
+
queueOperationMutated = true;
|
|
5459
5500
|
}
|
|
5460
|
-
if
|
|
5461
|
-
|
|
5462
|
-
|
|
5463
|
-
|
|
5464
|
-
|
|
5465
|
-
|
|
5466
|
-
|
|
5467
|
-
|
|
5468
|
-
|
|
5469
|
-
|
|
5470
|
-
|
|
5471
|
-
|
|
5472
|
-
|
|
5473
|
-
|
|
5474
|
-
|
|
5475
|
-
|
|
5476
|
-
|
|
5477
|
-
}
|
|
5478
|
-
|
|
5479
|
-
|
|
5480
|
-
|
|
5481
|
-
|
|
5482
|
-
|
|
5483
|
-
|
|
5484
|
-
|
|
5485
|
-
|
|
5486
|
-
|
|
5487
|
-
|
|
5488
|
-
|
|
5489
|
-
|
|
5490
|
-
|
|
5491
|
-
|
|
5492
|
-
|
|
5493
|
-
|
|
5494
|
-
|
|
5495
|
-
|
|
5496
|
-
|
|
5497
|
-
|
|
5498
|
-
|
|
5501
|
+
// if the action is performed on a previous draft id, we need to replace the action
|
|
5502
|
+
// with a new one at the updated canonical key
|
|
5503
|
+
if (queueActionTag === draftKey) {
|
|
5504
|
+
updatedActionTag = canonicalKey;
|
|
5505
|
+
updatedActionTargetId = canonicalId;
|
|
5506
|
+
}
|
|
5507
|
+
}
|
|
5508
|
+
if (queueOperationMutated) {
|
|
5509
|
+
if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
|
|
5510
|
+
const updatedAction = {
|
|
5511
|
+
...queueAction,
|
|
5512
|
+
tag: updatedActionTag,
|
|
5513
|
+
targetId: updatedActionTargetId,
|
|
5514
|
+
data: {
|
|
5515
|
+
...queueActionRequest,
|
|
5516
|
+
basePath: basePath,
|
|
5517
|
+
body: parse$4(stringifiedBody),
|
|
5518
|
+
},
|
|
5519
|
+
};
|
|
5520
|
+
// item needs to be replaced with a new item at the new record key
|
|
5521
|
+
queueOperations.push({
|
|
5522
|
+
type: QueueOperationType.Delete,
|
|
5523
|
+
id: queueActionId,
|
|
5524
|
+
});
|
|
5525
|
+
queueOperations.push({
|
|
5526
|
+
type: QueueOperationType.Add,
|
|
5527
|
+
action: updatedAction,
|
|
5528
|
+
});
|
|
5529
|
+
}
|
|
5530
|
+
else {
|
|
5531
|
+
const updatedAction = {
|
|
5532
|
+
...queueAction,
|
|
5533
|
+
data: {
|
|
5534
|
+
...queueActionRequest,
|
|
5535
|
+
basePath: basePath,
|
|
5536
|
+
body: parse$4(stringifiedBody),
|
|
5537
|
+
},
|
|
5538
|
+
};
|
|
5539
|
+
// item needs to be updated
|
|
5540
|
+
queueOperations.push({
|
|
5541
|
+
type: QueueOperationType.Update,
|
|
5542
|
+
id: queueActionId,
|
|
5543
|
+
action: updatedAction,
|
|
5544
|
+
});
|
|
5499
5545
|
}
|
|
5500
5546
|
}
|
|
5501
5547
|
}
|
|
@@ -5515,6 +5561,9 @@ class AbstractResourceRequestActionHandler {
|
|
|
5515
5561
|
const body = action.response.body;
|
|
5516
5562
|
const canonicalId = this.getIdFromResponseBody(body);
|
|
5517
5563
|
const draftId = action.targetId;
|
|
5564
|
+
if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
|
|
5565
|
+
this.ephemeralRedirects[draftId] = canonicalId;
|
|
5566
|
+
}
|
|
5518
5567
|
return [
|
|
5519
5568
|
{
|
|
5520
5569
|
draftId,
|
|
@@ -10220,7 +10269,8 @@ const assignedToMeFragmentSelections = [
|
|
|
10220
10269
|
},
|
|
10221
10270
|
];
|
|
10222
10271
|
function removeSyntheticFields(result, query) {
|
|
10223
|
-
|
|
10272
|
+
// It is possible that there are multiple record query.
|
|
10273
|
+
const connectionSelections = query.definitions
|
|
10224
10274
|
.filter(isOperationDefinitionNode)
|
|
10225
10275
|
.reduce((accu, definition) => {
|
|
10226
10276
|
return accu.concat(definition.selectionSet.selections);
|
|
@@ -10231,10 +10281,12 @@ function removeSyntheticFields(result, query) {
|
|
|
10231
10281
|
.filter(isFieldNode)
|
|
10232
10282
|
.filter(nodeIsNamed('query'))
|
|
10233
10283
|
.reduce(extractSelections, [])
|
|
10234
|
-
.filter(isFieldNode)
|
|
10284
|
+
.filter(isFieldNode);
|
|
10235
10285
|
// queries that are not RecordQuery will be undefined here.
|
|
10236
|
-
// we need to also check that
|
|
10237
|
-
if (!
|
|
10286
|
+
// we need to also check that connectionSelections are not undefined. If any connectionSelection has no `selectionSet` defined, that is a malformed query.
|
|
10287
|
+
if (!connectionSelections ||
|
|
10288
|
+
connectionSelections.length === 0 ||
|
|
10289
|
+
connectionSelections.some((connection) => connection.selectionSet === undefined)) {
|
|
10238
10290
|
return result;
|
|
10239
10291
|
}
|
|
10240
10292
|
const nodeJson = result.data.uiapi.query;
|
|
@@ -10243,10 +10295,15 @@ function removeSyntheticFields(result, query) {
|
|
|
10243
10295
|
const output = { ...result };
|
|
10244
10296
|
const outputApiParent = output.data.uiapi.query;
|
|
10245
10297
|
const keys$1 = keys$3(nodeJson);
|
|
10246
|
-
keys$1.forEach((
|
|
10298
|
+
keys$1.forEach((recordName) => {
|
|
10247
10299
|
const outputApi = {};
|
|
10248
|
-
|
|
10249
|
-
|
|
10300
|
+
// Each connectionSelection's maps its name or alias to one of returned records. The record name could be `apiName' or alias
|
|
10301
|
+
const targetConnection = connectionSelections.find((connection) => connection.name.value === recordName ||
|
|
10302
|
+
(connection.alias !== undefined && connection.alias.value === recordName));
|
|
10303
|
+
if (targetConnection !== undefined) {
|
|
10304
|
+
createUserJsonOutput(targetConnection, nodeJson[recordName], outputApi);
|
|
10305
|
+
outputApiParent[recordName] = outputApi;
|
|
10306
|
+
}
|
|
10250
10307
|
});
|
|
10251
10308
|
return output;
|
|
10252
10309
|
}
|
|
@@ -11288,12 +11345,18 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
|
|
|
11288
11345
|
const fieldName = fieldNames[i];
|
|
11289
11346
|
const fieldValue = bodyFields[fieldName];
|
|
11290
11347
|
if (typeof fieldValue === 'string' && this.isDraftId(fieldValue)) {
|
|
11291
|
-
const
|
|
11292
|
-
|
|
11293
|
-
|
|
11294
|
-
|
|
11295
|
-
|
|
11296
|
-
|
|
11348
|
+
const canonicalId = this.ephemeralRedirects[fieldValue];
|
|
11349
|
+
if (canonicalId !== undefined) {
|
|
11350
|
+
bodyFields[fieldName] = canonicalId;
|
|
11351
|
+
}
|
|
11352
|
+
else {
|
|
11353
|
+
const draftKey = this.buildTagForTargetId(fieldValue);
|
|
11354
|
+
const canonicalKey = this.getLuvio().storeGetCanonicalKey(draftKey);
|
|
11355
|
+
if (draftKey !== canonicalKey) {
|
|
11356
|
+
const canonicalId = extractRecordIdFromStoreKey(canonicalKey);
|
|
11357
|
+
if (canonicalId !== undefined) {
|
|
11358
|
+
bodyFields[fieldName] = canonicalId;
|
|
11359
|
+
}
|
|
11297
11360
|
}
|
|
11298
11361
|
}
|
|
11299
11362
|
}
|
|
@@ -11301,17 +11364,24 @@ class UiApiActionHandler extends AbstractResourceRequestActionHandler {
|
|
|
11301
11364
|
}
|
|
11302
11365
|
if (request.method === 'patch' || request.method === 'delete') {
|
|
11303
11366
|
const recordId = request.urlParams['recordId'];
|
|
11304
|
-
const
|
|
11305
|
-
|
|
11306
|
-
if (recordKey !== canonicalKey) {
|
|
11307
|
-
const canonicalId = extractRecordIdFromStoreKey(canonicalKey);
|
|
11308
|
-
if (canonicalId === undefined) {
|
|
11309
|
-
// could not resolve id from request -- return the request un-modified
|
|
11310
|
-
return request;
|
|
11311
|
-
}
|
|
11367
|
+
const canonicalId = this.ephemeralRedirects[recordId];
|
|
11368
|
+
if (canonicalId !== undefined) {
|
|
11312
11369
|
resolvedBasePath = resolvedBasePath.replace(recordId, canonicalId);
|
|
11313
11370
|
resolvedUrlParams = { ...resolvedUrlParams, recordId: canonicalId };
|
|
11314
11371
|
}
|
|
11372
|
+
else {
|
|
11373
|
+
const recordKey = this.buildTagForTargetId(recordId);
|
|
11374
|
+
const canonicalKey = this.getLuvio().storeGetCanonicalKey(recordKey);
|
|
11375
|
+
if (recordKey !== canonicalKey) {
|
|
11376
|
+
const canonicalId = extractRecordIdFromStoreKey(canonicalKey);
|
|
11377
|
+
if (canonicalId === undefined) {
|
|
11378
|
+
// could not resolve id from request -- return the request un-modified
|
|
11379
|
+
return request;
|
|
11380
|
+
}
|
|
11381
|
+
resolvedBasePath = resolvedBasePath.replace(recordId, canonicalId);
|
|
11382
|
+
resolvedUrlParams = { ...resolvedUrlParams, recordId: canonicalId };
|
|
11383
|
+
}
|
|
11384
|
+
}
|
|
11315
11385
|
}
|
|
11316
11386
|
return {
|
|
11317
11387
|
...request,
|
|
@@ -14659,34 +14729,6 @@ function setupInspection(luvio) {
|
|
|
14659
14729
|
* For full license text, see the LICENSE.txt file
|
|
14660
14730
|
*/
|
|
14661
14731
|
|
|
14662
|
-
class AsyncWorkerPool {
|
|
14663
|
-
constructor(concurrency) {
|
|
14664
|
-
this.queue = [];
|
|
14665
|
-
this.activeWorkers = 0;
|
|
14666
|
-
this.concurrency = concurrency;
|
|
14667
|
-
}
|
|
14668
|
-
push(workFn) {
|
|
14669
|
-
this.queue.push(workFn);
|
|
14670
|
-
this.work();
|
|
14671
|
-
}
|
|
14672
|
-
cancel() {
|
|
14673
|
-
this.queue = [];
|
|
14674
|
-
// TODO [W-12513105]: thread cancellation through to active workers
|
|
14675
|
-
}
|
|
14676
|
-
work() {
|
|
14677
|
-
while (this.queue.length > 0 && this.activeWorkers < this.concurrency) {
|
|
14678
|
-
this.activeWorkers += 1;
|
|
14679
|
-
const next = this.queue.shift();
|
|
14680
|
-
if (next) {
|
|
14681
|
-
next().finally(() => {
|
|
14682
|
-
this.activeWorkers -= 1;
|
|
14683
|
-
this.work();
|
|
14684
|
-
});
|
|
14685
|
-
}
|
|
14686
|
-
}
|
|
14687
|
-
}
|
|
14688
|
-
}
|
|
14689
|
-
|
|
14690
14732
|
class EventEmitter {
|
|
14691
14733
|
constructor() {
|
|
14692
14734
|
// @ts-ignore typescript doesn't like us setting this to an empty object for some reason
|
|
@@ -15239,4 +15281,4 @@ register({
|
|
|
15239
15281
|
});
|
|
15240
15282
|
|
|
15241
15283
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
15242
|
-
// version: 1.100.
|
|
15284
|
+
// version: 1.100.4-ce1be23b7
|