@salesforce/lds-worker-api 1.156.0 → 1.157.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.
|
@@ -770,4 +770,4 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
770
770
|
}
|
|
771
771
|
|
|
772
772
|
export { createPrimingSession, draftManager, draftQueue, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, invokeAdapter, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, setMetadataTTL, setUiApiRecordTTL, subscribeToAdapter };
|
|
773
|
-
// version: 1.
|
|
773
|
+
// version: 1.157.0-4246d2656
|
|
@@ -3799,7 +3799,7 @@ function withDefaultLuvio(callback) {
|
|
|
3799
3799
|
}
|
|
3800
3800
|
callbacks.push(callback);
|
|
3801
3801
|
}
|
|
3802
|
-
// version: 1.
|
|
3802
|
+
// version: 1.157.0-4246d2656
|
|
3803
3803
|
|
|
3804
3804
|
// TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
|
|
3805
3805
|
function instrumentAdapter$1(createFunction, _metadata) {
|
|
@@ -15232,7 +15232,7 @@ function parseAndVisit(source) {
|
|
|
15232
15232
|
updateReferenceMapWithKnownKey(ast, luvioDocumentNode);
|
|
15233
15233
|
return luvioDocumentNode;
|
|
15234
15234
|
}
|
|
15235
|
-
// version: 1.
|
|
15235
|
+
// version: 1.157.0-4246d2656
|
|
15236
15236
|
|
|
15237
15237
|
function unwrap(data) {
|
|
15238
15238
|
// The lwc-luvio bindings import a function from lwc called "unwrap".
|
|
@@ -16145,7 +16145,7 @@ function createGraphQLWireAdapterConstructor(luvio, adapter, metadata, astResolv
|
|
|
16145
16145
|
const { apiFamily, name } = metadata;
|
|
16146
16146
|
return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
|
|
16147
16147
|
}
|
|
16148
|
-
// version: 1.
|
|
16148
|
+
// version: 1.157.0-4246d2656
|
|
16149
16149
|
|
|
16150
16150
|
/**
|
|
16151
16151
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -44016,7 +44016,7 @@ withDefaultLuvio((luvio) => {
|
|
|
44016
44016
|
dropFunction: instrumentation$2.notifyRecordUpdateAvailableDropped,
|
|
44017
44017
|
});
|
|
44018
44018
|
});
|
|
44019
|
-
// version: 1.
|
|
44019
|
+
// version: 1.157.0-612ff940a
|
|
44020
44020
|
|
|
44021
44021
|
var caseSensitiveUserId = '005B0000000GR4OIAW';
|
|
44022
44022
|
|
|
@@ -44118,6 +44118,15 @@ var eagerEvalDefaultCachePolicy = {
|
|
|
44118
44118
|
},
|
|
44119
44119
|
};
|
|
44120
44120
|
|
|
44121
|
+
var ldsPrimingGraphqlBatch = {
|
|
44122
|
+
isOpen: function (e) {
|
|
44123
|
+
return e.fallback;
|
|
44124
|
+
},
|
|
44125
|
+
hasError: function () {
|
|
44126
|
+
return !0;
|
|
44127
|
+
},
|
|
44128
|
+
};
|
|
44129
|
+
|
|
44121
44130
|
/**
|
|
44122
44131
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
44123
44132
|
* All rights reserved.
|
|
@@ -48132,38 +48141,32 @@ function recordQuery(selection, apiName, alias, predicates, input) {
|
|
|
48132
48141
|
const draftsField = { type: FieldType.Scalar, extract, path: 'node._drafts' };
|
|
48133
48142
|
const idExtract = { type: ValueType.Extract, jsonAlias: alias, field: 'Id' };
|
|
48134
48143
|
const idField = { type: FieldType.Scalar, extract: idExtract, path: 'node.Id' };
|
|
48135
|
-
// When the exclude stale records gate is open
|
|
48136
|
-
//
|
|
48137
|
-
//
|
|
48138
|
-
|
|
48139
|
-
|
|
48140
|
-
const
|
|
48141
|
-
|
|
48142
|
-
|
|
48143
|
-
|
|
48144
|
-
|
|
48145
|
-
|
|
48146
|
-
|
|
48147
|
-
|
|
48148
|
-
|
|
48149
|
-
|
|
48150
|
-
|
|
48151
|
-
|
|
48152
|
-
|
|
48153
|
-
|
|
48154
|
-
|
|
48155
|
-
|
|
48156
|
-
|
|
48157
|
-
|
|
48158
|
-
|
|
48159
|
-
|
|
48160
|
-
|
|
48161
|
-
predicates.push({
|
|
48162
|
-
type: PredicateType$1.compound,
|
|
48163
|
-
operator: CompoundOperator.or,
|
|
48164
|
-
children: [timestampCheck, isDraft],
|
|
48165
|
-
});
|
|
48166
|
-
}
|
|
48144
|
+
// When the exclude stale records gate is open and there is a root timestamp
|
|
48145
|
+
// in the parser input, inject an additional predicate to limit the search
|
|
48146
|
+
// to records that either have drafts associated to them or were ingested at
|
|
48147
|
+
// least as recently as the query.
|
|
48148
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false }) && input.rootTimestamp !== undefined) {
|
|
48149
|
+
const timestampCheck = {
|
|
48150
|
+
type: PredicateType$1.comparison,
|
|
48151
|
+
left: {
|
|
48152
|
+
type: ValueType.Extract,
|
|
48153
|
+
jsonAlias: alias,
|
|
48154
|
+
field: 'ingestionTimestamp',
|
|
48155
|
+
metadata: true,
|
|
48156
|
+
},
|
|
48157
|
+
operator: ComparisonOperator.gte,
|
|
48158
|
+
right: { type: ValueType.IntLiteral, value: input.rootTimestamp },
|
|
48159
|
+
};
|
|
48160
|
+
const isDraft = {
|
|
48161
|
+
type: PredicateType$1.nullComparison,
|
|
48162
|
+
left: { type: ValueType.Extract, jsonAlias: alias, field: 'drafts' },
|
|
48163
|
+
operator: NullComparisonOperator.isNot,
|
|
48164
|
+
};
|
|
48165
|
+
predicates.push({
|
|
48166
|
+
type: PredicateType$1.compound,
|
|
48167
|
+
operator: CompoundOperator.or,
|
|
48168
|
+
children: [timestampCheck, isDraft],
|
|
48169
|
+
});
|
|
48167
48170
|
}
|
|
48168
48171
|
return queryContainer(internalFields, alias, apiName, predicates).map((result) => {
|
|
48169
48172
|
const { fields, predicates } = result;
|
|
@@ -48213,6 +48216,20 @@ function rootRecordQuery(selection, input) {
|
|
|
48213
48216
|
if (input.objectInfoMap[alias] === undefined) {
|
|
48214
48217
|
return failure([missingObjectInfo(apiName)]);
|
|
48215
48218
|
}
|
|
48219
|
+
// When the exclude stale records gate is open and the query has an
|
|
48220
|
+
// ingestion timestamp in its cache metadata, associate that with the input
|
|
48221
|
+
// so it can later be used to limit the search to records were ingested at
|
|
48222
|
+
// least as recently as the query.
|
|
48223
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false })) {
|
|
48224
|
+
const key = input.connectionKeyBuilder(selection, input.config.variables);
|
|
48225
|
+
const queryMetadata = input.metadata[key];
|
|
48226
|
+
// If there is no metadata for this query or it somehow lacks a timestamp
|
|
48227
|
+
// skip setting the root timestamp
|
|
48228
|
+
if (queryMetadata !== undefined && queryMetadata.ingestionTimestamp !== undefined) {
|
|
48229
|
+
// subtract 10ms from timestamp to account for ingestion processing time
|
|
48230
|
+
input.rootTimestamp = queryMetadata.ingestionTimestamp - 10;
|
|
48231
|
+
}
|
|
48232
|
+
}
|
|
48216
48233
|
return recordQuery(selection, alias, apiName, [], input);
|
|
48217
48234
|
}
|
|
48218
48235
|
function rootQuery(recordNodes, input) {
|
|
@@ -53109,7 +53126,7 @@ function dataTypeToType(objectInfoDataType, apiName) {
|
|
|
53109
53126
|
case 'Url':
|
|
53110
53127
|
return 'UrlValue';
|
|
53111
53128
|
case 'Picklist':
|
|
53112
|
-
return '
|
|
53129
|
+
return 'PicklistValue';
|
|
53113
53130
|
case 'MultiPicklist':
|
|
53114
53131
|
return 'MultiPicklistValue';
|
|
53115
53132
|
case 'Percent':
|
|
@@ -59293,16 +59310,19 @@ function generateTypedBatches(work, batchSize) {
|
|
|
59293
59310
|
|
|
59294
59311
|
const DEFAULT_BATCH_SIZE = 500;
|
|
59295
59312
|
const DEFAULT_CONCURRENCY = 6;
|
|
59313
|
+
const DEFAULT_GQL_QUERY_BATCH_SIZE = 5;
|
|
59296
59314
|
class PrimingSession extends EventEmitter {
|
|
59297
59315
|
constructor(config) {
|
|
59298
59316
|
var _a, _b;
|
|
59299
59317
|
super();
|
|
59318
|
+
this.useBatchGQL = false;
|
|
59300
59319
|
this.batchSize = (_a = config.batchSize) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_SIZE;
|
|
59301
59320
|
this.concurrency = (_b = config.concurrency) !== null && _b !== void 0 ? _b : DEFAULT_CONCURRENCY;
|
|
59302
59321
|
this.recordLoader = config.recordLoader;
|
|
59303
59322
|
this.recordIngestor = config.recordIngestor;
|
|
59304
59323
|
this.objectInfoLoader = config.objectInfoLoader;
|
|
59305
59324
|
this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
|
|
59325
|
+
this.useBatchGQL = ldsPrimingGraphqlBatch.isOpen({ fallback: false });
|
|
59306
59326
|
}
|
|
59307
59327
|
// function that enqueues priming work
|
|
59308
59328
|
async enqueue(work) {
|
|
@@ -59337,91 +59357,129 @@ class PrimingSession extends EventEmitter {
|
|
|
59337
59357
|
}
|
|
59338
59358
|
// parallelizes batches of priming work
|
|
59339
59359
|
enqueueBatches(batches) {
|
|
59340
|
-
|
|
59341
|
-
const
|
|
59342
|
-
|
|
59343
|
-
|
|
59344
|
-
|
|
59345
|
-
|
|
59346
|
-
|
|
59347
|
-
.
|
|
59348
|
-
|
|
59349
|
-
|
|
59350
|
-
|
|
59351
|
-
|
|
59352
|
-
|
|
59360
|
+
if (this.useBatchGQL === false) {
|
|
59361
|
+
for (const batch of batches) {
|
|
59362
|
+
const queuedTime = Date.now();
|
|
59363
|
+
this.networkWorkerPool.push({
|
|
59364
|
+
workFn: (abortController) => {
|
|
59365
|
+
const workTime = Date.now();
|
|
59366
|
+
this.emit('batch-starting', { queuedTime: workTime - queuedTime });
|
|
59367
|
+
return this.recordLoader
|
|
59368
|
+
.fetchRecordData(batch, abortController)
|
|
59369
|
+
.then(async (result) => {
|
|
59370
|
+
this.emit('batch-fetched', {
|
|
59371
|
+
ids: batch.ids,
|
|
59372
|
+
duration: Date.now() - workTime,
|
|
59373
|
+
});
|
|
59374
|
+
this.processFetchedRecords(result, abortController);
|
|
59375
|
+
});
|
|
59376
|
+
},
|
|
59377
|
+
cancelFn: () => {
|
|
59378
|
+
this.emit('error', {
|
|
59353
59379
|
ids: batch.ids,
|
|
59354
|
-
|
|
59380
|
+
code: 'canceled',
|
|
59381
|
+
message: `batch canceled`,
|
|
59355
59382
|
});
|
|
59356
|
-
|
|
59357
|
-
|
|
59358
|
-
|
|
59359
|
-
|
|
59360
|
-
|
|
59361
|
-
|
|
59362
|
-
|
|
59363
|
-
|
|
59364
|
-
|
|
59365
|
-
|
|
59366
|
-
const
|
|
59367
|
-
|
|
59368
|
-
|
|
59369
|
-
|
|
59370
|
-
|
|
59371
|
-
message: `could not find records: ${missingIds.join(', ')}`,
|
|
59372
|
-
});
|
|
59373
|
-
}
|
|
59374
|
-
const { records } = result;
|
|
59375
|
-
const beforeWrite = Date.now();
|
|
59376
|
-
// dispatch the write but DO NOT wait on it to unblock the network pool
|
|
59377
|
-
this.recordIngestor
|
|
59378
|
-
.insertRecords(records)
|
|
59379
|
-
.then(({ written, conflicted, errors }) => {
|
|
59380
|
-
this.emit('batch-written', {
|
|
59381
|
-
written,
|
|
59382
|
-
conflicted,
|
|
59383
|
-
errors: errors
|
|
59384
|
-
.map((e) => e.ids)
|
|
59385
|
-
.reduce((a, b) => a.concat(b), []),
|
|
59386
|
-
duration: Date.now() - beforeWrite,
|
|
59387
|
-
});
|
|
59383
|
+
},
|
|
59384
|
+
});
|
|
59385
|
+
}
|
|
59386
|
+
}
|
|
59387
|
+
else {
|
|
59388
|
+
const chucks = chunk(batches, DEFAULT_GQL_QUERY_BATCH_SIZE);
|
|
59389
|
+
for (const batchChuck of chucks) {
|
|
59390
|
+
const queuedTime = Date.now();
|
|
59391
|
+
this.networkWorkerPool.push({
|
|
59392
|
+
workFn: (abortController) => {
|
|
59393
|
+
const workTime = Date.now();
|
|
59394
|
+
this.emit('batch-starting', { queuedTime: workTime - queuedTime });
|
|
59395
|
+
return this.recordLoader
|
|
59396
|
+
.batchFetchRecordData(batchChuck, abortController)
|
|
59397
|
+
.then(async (results) => {
|
|
59388
59398
|
if (abortController.aborted) {
|
|
59389
59399
|
return;
|
|
59390
59400
|
}
|
|
59391
|
-
|
|
59392
|
-
|
|
59393
|
-
|
|
59394
|
-
|
|
59395
|
-
|
|
59396
|
-
|
|
59397
|
-
});
|
|
59401
|
+
const duration = Date.now() - workTime;
|
|
59402
|
+
// For each query within the Batch gql query, result returns at the same time
|
|
59403
|
+
for (let i = 0; i < results.length; i++) {
|
|
59404
|
+
this.emit('batch-fetched', {
|
|
59405
|
+
ids: batchChuck[i].ids,
|
|
59406
|
+
duration,
|
|
59398
59407
|
});
|
|
59399
59408
|
}
|
|
59400
|
-
|
|
59401
|
-
|
|
59402
|
-
this.emit('primed', Array.from(written));
|
|
59403
|
-
}
|
|
59404
|
-
// TODO [W-12436213]: implement conflict resolution
|
|
59405
|
-
if (conflicted.length > 0) {
|
|
59406
|
-
// for now emit conlicts as errors
|
|
59407
|
-
this.emit('error', {
|
|
59408
|
-
ids: Array.from(conflicted),
|
|
59409
|
-
code: 'unknown',
|
|
59410
|
-
message: 'conflict when persisting record',
|
|
59411
|
-
});
|
|
59409
|
+
for (let i = 0; i < results.length; i++) {
|
|
59410
|
+
this.processFetchedRecords(results[i], abortController);
|
|
59412
59411
|
}
|
|
59413
59412
|
});
|
|
59414
|
-
}
|
|
59415
|
-
|
|
59416
|
-
|
|
59417
|
-
|
|
59418
|
-
|
|
59419
|
-
|
|
59420
|
-
|
|
59421
|
-
|
|
59422
|
-
|
|
59413
|
+
},
|
|
59414
|
+
cancelFn: () => {
|
|
59415
|
+
const chuckIds = batchChuck
|
|
59416
|
+
.map((batch) => batch.ids)
|
|
59417
|
+
.reduce((prev, curr) => prev.concat(curr), []);
|
|
59418
|
+
this.emit('error', {
|
|
59419
|
+
ids: chuckIds,
|
|
59420
|
+
code: 'canceled',
|
|
59421
|
+
message: `batch canceled`,
|
|
59422
|
+
});
|
|
59423
|
+
},
|
|
59424
|
+
});
|
|
59425
|
+
}
|
|
59426
|
+
}
|
|
59427
|
+
}
|
|
59428
|
+
processFetchedRecords(result, abortController) {
|
|
59429
|
+
if (result.ok === false) {
|
|
59430
|
+
const { error } = result;
|
|
59431
|
+
const primingError = error === 'network-error' ? 'service-unavailable' : 'unknown';
|
|
59432
|
+
this.emit('error', {
|
|
59433
|
+
ids: result.missingIds,
|
|
59434
|
+
code: primingError,
|
|
59435
|
+
message: `${result.messages.join(',')}`,
|
|
59436
|
+
});
|
|
59437
|
+
return;
|
|
59438
|
+
}
|
|
59439
|
+
const { missingIds } = result;
|
|
59440
|
+
if (missingIds.length > 0) {
|
|
59441
|
+
this.emit('error', {
|
|
59442
|
+
ids: missingIds,
|
|
59443
|
+
code: 'not-found',
|
|
59444
|
+
message: `could not find records: ${missingIds.join(', ')}`,
|
|
59423
59445
|
});
|
|
59424
59446
|
}
|
|
59447
|
+
const { records } = result;
|
|
59448
|
+
const beforeWrite = Date.now();
|
|
59449
|
+
// dispatch the write but DO NOT wait on it to unblock the network pool
|
|
59450
|
+
this.recordIngestor.insertRecords(records).then(({ written, conflicted, errors }) => {
|
|
59451
|
+
this.emit('batch-written', {
|
|
59452
|
+
written,
|
|
59453
|
+
conflicted,
|
|
59454
|
+
errors: errors.map((e) => e.ids).reduce((a, b) => a.concat(b), []),
|
|
59455
|
+
duration: Date.now() - beforeWrite,
|
|
59456
|
+
});
|
|
59457
|
+
if (abortController.aborted) {
|
|
59458
|
+
return;
|
|
59459
|
+
}
|
|
59460
|
+
if (errors.length > 0) {
|
|
59461
|
+
errors.forEach(({ ids, message }) => {
|
|
59462
|
+
this.emit('error', {
|
|
59463
|
+
ids,
|
|
59464
|
+
code: 'unknown',
|
|
59465
|
+
message: message,
|
|
59466
|
+
});
|
|
59467
|
+
});
|
|
59468
|
+
}
|
|
59469
|
+
// now that the records are persisted, emit the primed event
|
|
59470
|
+
if (written.length > 0) {
|
|
59471
|
+
this.emit('primed', Array.from(written));
|
|
59472
|
+
}
|
|
59473
|
+
// TODO [W-12436213]: implement conflict resolution
|
|
59474
|
+
if (conflicted.length > 0) {
|
|
59475
|
+
// for now emit conlicts as errors
|
|
59476
|
+
this.emit('error', {
|
|
59477
|
+
ids: Array.from(conflicted),
|
|
59478
|
+
code: 'unknown',
|
|
59479
|
+
message: 'conflict when persisting record',
|
|
59480
|
+
});
|
|
59481
|
+
}
|
|
59482
|
+
});
|
|
59425
59483
|
}
|
|
59426
59484
|
async fetchMetadata(batches) {
|
|
59427
59485
|
const apiNames = Array.from(batches.reduce((acc, x) => {
|
|
@@ -59474,12 +59532,39 @@ class RecordLoaderGraphQL {
|
|
|
59474
59532
|
missingIds: batch.ids,
|
|
59475
59533
|
};
|
|
59476
59534
|
}
|
|
59477
|
-
|
|
59535
|
+
return this.generateFetchResult(rep, batch);
|
|
59536
|
+
}
|
|
59537
|
+
async batchFetchRecordData(batchs, abortController) {
|
|
59538
|
+
let reps;
|
|
59539
|
+
try {
|
|
59540
|
+
reps = await this.callBatchGraphQL(batchs, abortController);
|
|
59541
|
+
}
|
|
59542
|
+
catch (e) {
|
|
59543
|
+
const missingIds = batchs
|
|
59544
|
+
.map((batch) => batch.ids)
|
|
59545
|
+
.reduce((prev, curr) => prev.concat(curr), []);
|
|
59546
|
+
return [
|
|
59547
|
+
{
|
|
59548
|
+
ok: false,
|
|
59549
|
+
error: 'network-error',
|
|
59550
|
+
messages: ['Network Error'],
|
|
59551
|
+
missingIds,
|
|
59552
|
+
},
|
|
59553
|
+
];
|
|
59554
|
+
}
|
|
59555
|
+
const recordFetchResults = [];
|
|
59556
|
+
for (let i = 0; i < reps.length; i++) {
|
|
59557
|
+
recordFetchResults.push(this.generateFetchResult(reps[i], batchs[i]));
|
|
59558
|
+
}
|
|
59559
|
+
return recordFetchResults;
|
|
59560
|
+
}
|
|
59561
|
+
generateFetchResult(repResult, batchInput) {
|
|
59562
|
+
const { data, errors } = repResult;
|
|
59478
59563
|
if (errors !== undefined && errors.length > 0) {
|
|
59479
59564
|
// right now if there are any errors in the batch we throw out the entire batch
|
|
59480
59565
|
// for now this is ok all errors will originate on the same node so there shouldn't be a mix of errors and data
|
|
59481
59566
|
return {
|
|
59482
|
-
missingIds:
|
|
59567
|
+
missingIds: batchInput.ids,
|
|
59483
59568
|
ok: false,
|
|
59484
59569
|
error: 'request-error',
|
|
59485
59570
|
messages: errors.map((x) => x.message),
|
|
@@ -59491,11 +59576,11 @@ class RecordLoaderGraphQL {
|
|
|
59491
59576
|
ok: false,
|
|
59492
59577
|
error: 'unknown',
|
|
59493
59578
|
messages: ['unexpected response retrieved from graphql endpoint'],
|
|
59494
|
-
missingIds:
|
|
59579
|
+
missingIds: batchInput.ids,
|
|
59495
59580
|
};
|
|
59496
59581
|
}
|
|
59497
|
-
const seenRecords = new Set(
|
|
59498
|
-
const records = data.uiapi.query[
|
|
59582
|
+
const seenRecords = new Set(batchInput.ids);
|
|
59583
|
+
const records = data.uiapi.query[batchInput.type].edges.map((edge) => {
|
|
59499
59584
|
const record = this.generateDurableRecordRepresentation(edge.node);
|
|
59500
59585
|
seenRecords.delete(record.id);
|
|
59501
59586
|
return record;
|
|
@@ -59510,6 +59595,15 @@ class RecordLoaderGraphQL {
|
|
|
59510
59595
|
const query = this.generateGraphQLQuery(batch.type, batch.fields);
|
|
59511
59596
|
return this.networkAdapter.postGraphQL(query, { ids: batch.ids, first: batch.ids.length }, abortController);
|
|
59512
59597
|
}
|
|
59598
|
+
callBatchGraphQL(batches, abortController) {
|
|
59599
|
+
const gqlInput = batches.map((batch) => {
|
|
59600
|
+
return {
|
|
59601
|
+
query: this.generateGraphQLQuery(batch.type, batch.fields),
|
|
59602
|
+
variables: { ids: batch.ids, first: batch.ids.length },
|
|
59603
|
+
};
|
|
59604
|
+
});
|
|
59605
|
+
return this.networkAdapter.postBatchGraphQL(gqlInput, abortController);
|
|
59606
|
+
}
|
|
59513
59607
|
generateGraphQLQuery(type, fields) {
|
|
59514
59608
|
const fieldList = Object.keys(requiredFieldMap)
|
|
59515
59609
|
.map((field) => {
|
|
@@ -59631,7 +59725,56 @@ function instrumentPrimingSession(session) {
|
|
|
59631
59725
|
/* global __nimbus */
|
|
59632
59726
|
// note this is automatically incremented by scripts/release/bump-api-version.js at each release
|
|
59633
59727
|
const apiVersion = `v59.0`;
|
|
59728
|
+
const batchEndPointPath = `/services/data/${apiVersion}/graphql/batch`;
|
|
59729
|
+
const endPointPath = `/services/data/${apiVersion}/graphql`;
|
|
59634
59730
|
class NimbusPrimingNetworkAdapter {
|
|
59731
|
+
postBatchGraphQL(configs, abortController) {
|
|
59732
|
+
return new Promise((resolve, reject) => {
|
|
59733
|
+
let listener;
|
|
59734
|
+
const unregisterListener = () => {
|
|
59735
|
+
if (listener) {
|
|
59736
|
+
abortController.removeEventListener(listener);
|
|
59737
|
+
}
|
|
59738
|
+
};
|
|
59739
|
+
__nimbus.plugins.LdsNetworkAdapter
|
|
59740
|
+
.sendRequest({
|
|
59741
|
+
method: 'POST',
|
|
59742
|
+
path: batchEndPointPath,
|
|
59743
|
+
body: JSON.stringify({
|
|
59744
|
+
batchQuery: configs,
|
|
59745
|
+
}),
|
|
59746
|
+
headers: {},
|
|
59747
|
+
queryParams: {},
|
|
59748
|
+
priority: 'background',
|
|
59749
|
+
observabilityContext: {},
|
|
59750
|
+
}, (response) => {
|
|
59751
|
+
unregisterListener();
|
|
59752
|
+
const { body } = response;
|
|
59753
|
+
if (body) {
|
|
59754
|
+
const { results } = JSON.parse(body);
|
|
59755
|
+
if (results) {
|
|
59756
|
+
const gqlResults = results.map((compositeGqlResult) => compositeGqlResult.result);
|
|
59757
|
+
resolve(gqlResults);
|
|
59758
|
+
}
|
|
59759
|
+
else {
|
|
59760
|
+
reject(new Error(`No body returned from ${batchEndPointPath} endpoint`));
|
|
59761
|
+
}
|
|
59762
|
+
}
|
|
59763
|
+
else {
|
|
59764
|
+
reject(new Error(`No body returned from ${batchEndPointPath} endpoint`));
|
|
59765
|
+
}
|
|
59766
|
+
}, (error) => {
|
|
59767
|
+
unregisterListener();
|
|
59768
|
+
reject(error);
|
|
59769
|
+
})
|
|
59770
|
+
.then((cancellationToken) => {
|
|
59771
|
+
listener = () => {
|
|
59772
|
+
__nimbus.plugins.LdsNetworkAdapter.cancelRequest(cancellationToken);
|
|
59773
|
+
};
|
|
59774
|
+
abortController.addEventListener(listener);
|
|
59775
|
+
});
|
|
59776
|
+
});
|
|
59777
|
+
}
|
|
59635
59778
|
postGraphQL(query, variables, abortController) {
|
|
59636
59779
|
return new Promise((resolve, reject) => {
|
|
59637
59780
|
let listener;
|
|
@@ -59643,7 +59786,7 @@ class NimbusPrimingNetworkAdapter {
|
|
|
59643
59786
|
__nimbus.plugins.LdsNetworkAdapter
|
|
59644
59787
|
.sendRequest({
|
|
59645
59788
|
method: 'POST',
|
|
59646
|
-
path:
|
|
59789
|
+
path: endPointPath,
|
|
59647
59790
|
body: JSON.stringify({
|
|
59648
59791
|
query,
|
|
59649
59792
|
variables,
|
|
@@ -59659,7 +59802,7 @@ class NimbusPrimingNetworkAdapter {
|
|
|
59659
59802
|
resolve(JSON.parse(body));
|
|
59660
59803
|
}
|
|
59661
59804
|
else {
|
|
59662
|
-
reject(new Error(
|
|
59805
|
+
reject(new Error(`No body returned from ${endPointPath} endpoint`));
|
|
59663
59806
|
}
|
|
59664
59807
|
}, (error) => {
|
|
59665
59808
|
unregisterListener();
|
|
@@ -59907,7 +60050,7 @@ register({
|
|
|
59907
60050
|
id: '@salesforce/lds-network-adapter',
|
|
59908
60051
|
instrument: instrument$1,
|
|
59909
60052
|
});
|
|
59910
|
-
// version: 1.
|
|
60053
|
+
// version: 1.157.0-4246d2656
|
|
59911
60054
|
|
|
59912
60055
|
const { create: create$2, keys: keys$2 } = Object;
|
|
59913
60056
|
const { stringify: stringify$1, parse: parse$1 } = JSON;
|
|
@@ -80752,7 +80895,7 @@ register({
|
|
|
80752
80895
|
configuration: { ...configurationForGraphQLAdapters },
|
|
80753
80896
|
instrument,
|
|
80754
80897
|
});
|
|
80755
|
-
// version: 1.
|
|
80898
|
+
// version: 1.157.0-612ff940a
|
|
80756
80899
|
|
|
80757
80900
|
// On core the unstable adapters are re-exported with different names,
|
|
80758
80901
|
|
|
@@ -82999,7 +83142,7 @@ withDefaultLuvio((luvio) => {
|
|
|
82999
83142
|
unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
|
|
83000
83143
|
graphQLImperative = ldsAdapter;
|
|
83001
83144
|
});
|
|
83002
|
-
// version: 1.
|
|
83145
|
+
// version: 1.157.0-612ff940a
|
|
83003
83146
|
|
|
83004
83147
|
var gqlApi = /*#__PURE__*/Object.freeze({
|
|
83005
83148
|
__proto__: null,
|
|
@@ -83688,4 +83831,4 @@ const { luvio } = getRuntime();
|
|
|
83688
83831
|
setDefaultLuvio({ luvio });
|
|
83689
83832
|
|
|
83690
83833
|
export { createPrimingSession, draftManager, draftQueue, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, invokeAdapter, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, registerReportObserver, setMetadataTTL, setUiApiRecordTTL, subscribeToAdapter };
|
|
83691
|
-
// version: 1.
|
|
83834
|
+
// version: 1.157.0-4246d2656
|
|
@@ -3805,7 +3805,7 @@
|
|
|
3805
3805
|
}
|
|
3806
3806
|
callbacks.push(callback);
|
|
3807
3807
|
}
|
|
3808
|
-
// version: 1.
|
|
3808
|
+
// version: 1.157.0-4246d2656
|
|
3809
3809
|
|
|
3810
3810
|
// TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
|
|
3811
3811
|
function instrumentAdapter$1(createFunction, _metadata) {
|
|
@@ -15238,7 +15238,7 @@
|
|
|
15238
15238
|
updateReferenceMapWithKnownKey(ast, luvioDocumentNode);
|
|
15239
15239
|
return luvioDocumentNode;
|
|
15240
15240
|
}
|
|
15241
|
-
// version: 1.
|
|
15241
|
+
// version: 1.157.0-4246d2656
|
|
15242
15242
|
|
|
15243
15243
|
function unwrap(data) {
|
|
15244
15244
|
// The lwc-luvio bindings import a function from lwc called "unwrap".
|
|
@@ -16151,7 +16151,7 @@
|
|
|
16151
16151
|
const { apiFamily, name } = metadata;
|
|
16152
16152
|
return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
|
|
16153
16153
|
}
|
|
16154
|
-
// version: 1.
|
|
16154
|
+
// version: 1.157.0-4246d2656
|
|
16155
16155
|
|
|
16156
16156
|
/**
|
|
16157
16157
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -44022,7 +44022,7 @@
|
|
|
44022
44022
|
dropFunction: instrumentation$2.notifyRecordUpdateAvailableDropped,
|
|
44023
44023
|
});
|
|
44024
44024
|
});
|
|
44025
|
-
// version: 1.
|
|
44025
|
+
// version: 1.157.0-612ff940a
|
|
44026
44026
|
|
|
44027
44027
|
var caseSensitiveUserId = '005B0000000GR4OIAW';
|
|
44028
44028
|
|
|
@@ -44124,6 +44124,15 @@
|
|
|
44124
44124
|
},
|
|
44125
44125
|
};
|
|
44126
44126
|
|
|
44127
|
+
var ldsPrimingGraphqlBatch = {
|
|
44128
|
+
isOpen: function (e) {
|
|
44129
|
+
return e.fallback;
|
|
44130
|
+
},
|
|
44131
|
+
hasError: function () {
|
|
44132
|
+
return !0;
|
|
44133
|
+
},
|
|
44134
|
+
};
|
|
44135
|
+
|
|
44127
44136
|
/**
|
|
44128
44137
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
44129
44138
|
* All rights reserved.
|
|
@@ -48138,38 +48147,32 @@
|
|
|
48138
48147
|
const draftsField = { type: FieldType.Scalar, extract, path: 'node._drafts' };
|
|
48139
48148
|
const idExtract = { type: ValueType.Extract, jsonAlias: alias, field: 'Id' };
|
|
48140
48149
|
const idField = { type: FieldType.Scalar, extract: idExtract, path: 'node.Id' };
|
|
48141
|
-
// When the exclude stale records gate is open
|
|
48142
|
-
//
|
|
48143
|
-
//
|
|
48144
|
-
|
|
48145
|
-
|
|
48146
|
-
const
|
|
48147
|
-
|
|
48148
|
-
|
|
48149
|
-
|
|
48150
|
-
|
|
48151
|
-
|
|
48152
|
-
|
|
48153
|
-
|
|
48154
|
-
|
|
48155
|
-
|
|
48156
|
-
|
|
48157
|
-
|
|
48158
|
-
|
|
48159
|
-
|
|
48160
|
-
|
|
48161
|
-
|
|
48162
|
-
|
|
48163
|
-
|
|
48164
|
-
|
|
48165
|
-
|
|
48166
|
-
|
|
48167
|
-
predicates.push({
|
|
48168
|
-
type: PredicateType$1.compound,
|
|
48169
|
-
operator: CompoundOperator.or,
|
|
48170
|
-
children: [timestampCheck, isDraft],
|
|
48171
|
-
});
|
|
48172
|
-
}
|
|
48150
|
+
// When the exclude stale records gate is open and there is a root timestamp
|
|
48151
|
+
// in the parser input, inject an additional predicate to limit the search
|
|
48152
|
+
// to records that either have drafts associated to them or were ingested at
|
|
48153
|
+
// least as recently as the query.
|
|
48154
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false }) && input.rootTimestamp !== undefined) {
|
|
48155
|
+
const timestampCheck = {
|
|
48156
|
+
type: PredicateType$1.comparison,
|
|
48157
|
+
left: {
|
|
48158
|
+
type: ValueType.Extract,
|
|
48159
|
+
jsonAlias: alias,
|
|
48160
|
+
field: 'ingestionTimestamp',
|
|
48161
|
+
metadata: true,
|
|
48162
|
+
},
|
|
48163
|
+
operator: ComparisonOperator.gte,
|
|
48164
|
+
right: { type: ValueType.IntLiteral, value: input.rootTimestamp },
|
|
48165
|
+
};
|
|
48166
|
+
const isDraft = {
|
|
48167
|
+
type: PredicateType$1.nullComparison,
|
|
48168
|
+
left: { type: ValueType.Extract, jsonAlias: alias, field: 'drafts' },
|
|
48169
|
+
operator: NullComparisonOperator.isNot,
|
|
48170
|
+
};
|
|
48171
|
+
predicates.push({
|
|
48172
|
+
type: PredicateType$1.compound,
|
|
48173
|
+
operator: CompoundOperator.or,
|
|
48174
|
+
children: [timestampCheck, isDraft],
|
|
48175
|
+
});
|
|
48173
48176
|
}
|
|
48174
48177
|
return queryContainer(internalFields, alias, apiName, predicates).map((result) => {
|
|
48175
48178
|
const { fields, predicates } = result;
|
|
@@ -48219,6 +48222,20 @@
|
|
|
48219
48222
|
if (input.objectInfoMap[alias] === undefined) {
|
|
48220
48223
|
return failure([missingObjectInfo(apiName)]);
|
|
48221
48224
|
}
|
|
48225
|
+
// When the exclude stale records gate is open and the query has an
|
|
48226
|
+
// ingestion timestamp in its cache metadata, associate that with the input
|
|
48227
|
+
// so it can later be used to limit the search to records were ingested at
|
|
48228
|
+
// least as recently as the query.
|
|
48229
|
+
if (excludeStaleRecordsGate.isOpen({ fallback: false })) {
|
|
48230
|
+
const key = input.connectionKeyBuilder(selection, input.config.variables);
|
|
48231
|
+
const queryMetadata = input.metadata[key];
|
|
48232
|
+
// If there is no metadata for this query or it somehow lacks a timestamp
|
|
48233
|
+
// skip setting the root timestamp
|
|
48234
|
+
if (queryMetadata !== undefined && queryMetadata.ingestionTimestamp !== undefined) {
|
|
48235
|
+
// subtract 10ms from timestamp to account for ingestion processing time
|
|
48236
|
+
input.rootTimestamp = queryMetadata.ingestionTimestamp - 10;
|
|
48237
|
+
}
|
|
48238
|
+
}
|
|
48222
48239
|
return recordQuery(selection, alias, apiName, [], input);
|
|
48223
48240
|
}
|
|
48224
48241
|
function rootQuery(recordNodes, input) {
|
|
@@ -53115,7 +53132,7 @@
|
|
|
53115
53132
|
case 'Url':
|
|
53116
53133
|
return 'UrlValue';
|
|
53117
53134
|
case 'Picklist':
|
|
53118
|
-
return '
|
|
53135
|
+
return 'PicklistValue';
|
|
53119
53136
|
case 'MultiPicklist':
|
|
53120
53137
|
return 'MultiPicklistValue';
|
|
53121
53138
|
case 'Percent':
|
|
@@ -59299,16 +59316,19 @@
|
|
|
59299
59316
|
|
|
59300
59317
|
const DEFAULT_BATCH_SIZE = 500;
|
|
59301
59318
|
const DEFAULT_CONCURRENCY = 6;
|
|
59319
|
+
const DEFAULT_GQL_QUERY_BATCH_SIZE = 5;
|
|
59302
59320
|
class PrimingSession extends EventEmitter {
|
|
59303
59321
|
constructor(config) {
|
|
59304
59322
|
var _a, _b;
|
|
59305
59323
|
super();
|
|
59324
|
+
this.useBatchGQL = false;
|
|
59306
59325
|
this.batchSize = (_a = config.batchSize) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_SIZE;
|
|
59307
59326
|
this.concurrency = (_b = config.concurrency) !== null && _b !== void 0 ? _b : DEFAULT_CONCURRENCY;
|
|
59308
59327
|
this.recordLoader = config.recordLoader;
|
|
59309
59328
|
this.recordIngestor = config.recordIngestor;
|
|
59310
59329
|
this.objectInfoLoader = config.objectInfoLoader;
|
|
59311
59330
|
this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
|
|
59331
|
+
this.useBatchGQL = ldsPrimingGraphqlBatch.isOpen({ fallback: false });
|
|
59312
59332
|
}
|
|
59313
59333
|
// function that enqueues priming work
|
|
59314
59334
|
async enqueue(work) {
|
|
@@ -59343,91 +59363,129 @@
|
|
|
59343
59363
|
}
|
|
59344
59364
|
// parallelizes batches of priming work
|
|
59345
59365
|
enqueueBatches(batches) {
|
|
59346
|
-
|
|
59347
|
-
const
|
|
59348
|
-
|
|
59349
|
-
|
|
59350
|
-
|
|
59351
|
-
|
|
59352
|
-
|
|
59353
|
-
.
|
|
59354
|
-
|
|
59355
|
-
|
|
59356
|
-
|
|
59357
|
-
|
|
59358
|
-
|
|
59366
|
+
if (this.useBatchGQL === false) {
|
|
59367
|
+
for (const batch of batches) {
|
|
59368
|
+
const queuedTime = Date.now();
|
|
59369
|
+
this.networkWorkerPool.push({
|
|
59370
|
+
workFn: (abortController) => {
|
|
59371
|
+
const workTime = Date.now();
|
|
59372
|
+
this.emit('batch-starting', { queuedTime: workTime - queuedTime });
|
|
59373
|
+
return this.recordLoader
|
|
59374
|
+
.fetchRecordData(batch, abortController)
|
|
59375
|
+
.then(async (result) => {
|
|
59376
|
+
this.emit('batch-fetched', {
|
|
59377
|
+
ids: batch.ids,
|
|
59378
|
+
duration: Date.now() - workTime,
|
|
59379
|
+
});
|
|
59380
|
+
this.processFetchedRecords(result, abortController);
|
|
59381
|
+
});
|
|
59382
|
+
},
|
|
59383
|
+
cancelFn: () => {
|
|
59384
|
+
this.emit('error', {
|
|
59359
59385
|
ids: batch.ids,
|
|
59360
|
-
|
|
59386
|
+
code: 'canceled',
|
|
59387
|
+
message: `batch canceled`,
|
|
59361
59388
|
});
|
|
59362
|
-
|
|
59363
|
-
|
|
59364
|
-
|
|
59365
|
-
|
|
59366
|
-
|
|
59367
|
-
|
|
59368
|
-
|
|
59369
|
-
|
|
59370
|
-
|
|
59371
|
-
|
|
59372
|
-
const
|
|
59373
|
-
|
|
59374
|
-
|
|
59375
|
-
|
|
59376
|
-
|
|
59377
|
-
message: `could not find records: ${missingIds.join(', ')}`,
|
|
59378
|
-
});
|
|
59379
|
-
}
|
|
59380
|
-
const { records } = result;
|
|
59381
|
-
const beforeWrite = Date.now();
|
|
59382
|
-
// dispatch the write but DO NOT wait on it to unblock the network pool
|
|
59383
|
-
this.recordIngestor
|
|
59384
|
-
.insertRecords(records)
|
|
59385
|
-
.then(({ written, conflicted, errors }) => {
|
|
59386
|
-
this.emit('batch-written', {
|
|
59387
|
-
written,
|
|
59388
|
-
conflicted,
|
|
59389
|
-
errors: errors
|
|
59390
|
-
.map((e) => e.ids)
|
|
59391
|
-
.reduce((a, b) => a.concat(b), []),
|
|
59392
|
-
duration: Date.now() - beforeWrite,
|
|
59393
|
-
});
|
|
59389
|
+
},
|
|
59390
|
+
});
|
|
59391
|
+
}
|
|
59392
|
+
}
|
|
59393
|
+
else {
|
|
59394
|
+
const chucks = chunk(batches, DEFAULT_GQL_QUERY_BATCH_SIZE);
|
|
59395
|
+
for (const batchChuck of chucks) {
|
|
59396
|
+
const queuedTime = Date.now();
|
|
59397
|
+
this.networkWorkerPool.push({
|
|
59398
|
+
workFn: (abortController) => {
|
|
59399
|
+
const workTime = Date.now();
|
|
59400
|
+
this.emit('batch-starting', { queuedTime: workTime - queuedTime });
|
|
59401
|
+
return this.recordLoader
|
|
59402
|
+
.batchFetchRecordData(batchChuck, abortController)
|
|
59403
|
+
.then(async (results) => {
|
|
59394
59404
|
if (abortController.aborted) {
|
|
59395
59405
|
return;
|
|
59396
59406
|
}
|
|
59397
|
-
|
|
59398
|
-
|
|
59399
|
-
|
|
59400
|
-
|
|
59401
|
-
|
|
59402
|
-
|
|
59403
|
-
});
|
|
59407
|
+
const duration = Date.now() - workTime;
|
|
59408
|
+
// For each query within the Batch gql query, result returns at the same time
|
|
59409
|
+
for (let i = 0; i < results.length; i++) {
|
|
59410
|
+
this.emit('batch-fetched', {
|
|
59411
|
+
ids: batchChuck[i].ids,
|
|
59412
|
+
duration,
|
|
59404
59413
|
});
|
|
59405
59414
|
}
|
|
59406
|
-
|
|
59407
|
-
|
|
59408
|
-
this.emit('primed', Array.from(written));
|
|
59409
|
-
}
|
|
59410
|
-
// TODO [W-12436213]: implement conflict resolution
|
|
59411
|
-
if (conflicted.length > 0) {
|
|
59412
|
-
// for now emit conlicts as errors
|
|
59413
|
-
this.emit('error', {
|
|
59414
|
-
ids: Array.from(conflicted),
|
|
59415
|
-
code: 'unknown',
|
|
59416
|
-
message: 'conflict when persisting record',
|
|
59417
|
-
});
|
|
59415
|
+
for (let i = 0; i < results.length; i++) {
|
|
59416
|
+
this.processFetchedRecords(results[i], abortController);
|
|
59418
59417
|
}
|
|
59419
59418
|
});
|
|
59420
|
-
}
|
|
59421
|
-
|
|
59422
|
-
|
|
59423
|
-
|
|
59424
|
-
|
|
59425
|
-
|
|
59426
|
-
|
|
59427
|
-
|
|
59428
|
-
|
|
59419
|
+
},
|
|
59420
|
+
cancelFn: () => {
|
|
59421
|
+
const chuckIds = batchChuck
|
|
59422
|
+
.map((batch) => batch.ids)
|
|
59423
|
+
.reduce((prev, curr) => prev.concat(curr), []);
|
|
59424
|
+
this.emit('error', {
|
|
59425
|
+
ids: chuckIds,
|
|
59426
|
+
code: 'canceled',
|
|
59427
|
+
message: `batch canceled`,
|
|
59428
|
+
});
|
|
59429
|
+
},
|
|
59430
|
+
});
|
|
59431
|
+
}
|
|
59432
|
+
}
|
|
59433
|
+
}
|
|
59434
|
+
processFetchedRecords(result, abortController) {
|
|
59435
|
+
if (result.ok === false) {
|
|
59436
|
+
const { error } = result;
|
|
59437
|
+
const primingError = error === 'network-error' ? 'service-unavailable' : 'unknown';
|
|
59438
|
+
this.emit('error', {
|
|
59439
|
+
ids: result.missingIds,
|
|
59440
|
+
code: primingError,
|
|
59441
|
+
message: `${result.messages.join(',')}`,
|
|
59442
|
+
});
|
|
59443
|
+
return;
|
|
59444
|
+
}
|
|
59445
|
+
const { missingIds } = result;
|
|
59446
|
+
if (missingIds.length > 0) {
|
|
59447
|
+
this.emit('error', {
|
|
59448
|
+
ids: missingIds,
|
|
59449
|
+
code: 'not-found',
|
|
59450
|
+
message: `could not find records: ${missingIds.join(', ')}`,
|
|
59429
59451
|
});
|
|
59430
59452
|
}
|
|
59453
|
+
const { records } = result;
|
|
59454
|
+
const beforeWrite = Date.now();
|
|
59455
|
+
// dispatch the write but DO NOT wait on it to unblock the network pool
|
|
59456
|
+
this.recordIngestor.insertRecords(records).then(({ written, conflicted, errors }) => {
|
|
59457
|
+
this.emit('batch-written', {
|
|
59458
|
+
written,
|
|
59459
|
+
conflicted,
|
|
59460
|
+
errors: errors.map((e) => e.ids).reduce((a, b) => a.concat(b), []),
|
|
59461
|
+
duration: Date.now() - beforeWrite,
|
|
59462
|
+
});
|
|
59463
|
+
if (abortController.aborted) {
|
|
59464
|
+
return;
|
|
59465
|
+
}
|
|
59466
|
+
if (errors.length > 0) {
|
|
59467
|
+
errors.forEach(({ ids, message }) => {
|
|
59468
|
+
this.emit('error', {
|
|
59469
|
+
ids,
|
|
59470
|
+
code: 'unknown',
|
|
59471
|
+
message: message,
|
|
59472
|
+
});
|
|
59473
|
+
});
|
|
59474
|
+
}
|
|
59475
|
+
// now that the records are persisted, emit the primed event
|
|
59476
|
+
if (written.length > 0) {
|
|
59477
|
+
this.emit('primed', Array.from(written));
|
|
59478
|
+
}
|
|
59479
|
+
// TODO [W-12436213]: implement conflict resolution
|
|
59480
|
+
if (conflicted.length > 0) {
|
|
59481
|
+
// for now emit conlicts as errors
|
|
59482
|
+
this.emit('error', {
|
|
59483
|
+
ids: Array.from(conflicted),
|
|
59484
|
+
code: 'unknown',
|
|
59485
|
+
message: 'conflict when persisting record',
|
|
59486
|
+
});
|
|
59487
|
+
}
|
|
59488
|
+
});
|
|
59431
59489
|
}
|
|
59432
59490
|
async fetchMetadata(batches) {
|
|
59433
59491
|
const apiNames = Array.from(batches.reduce((acc, x) => {
|
|
@@ -59480,12 +59538,39 @@
|
|
|
59480
59538
|
missingIds: batch.ids,
|
|
59481
59539
|
};
|
|
59482
59540
|
}
|
|
59483
|
-
|
|
59541
|
+
return this.generateFetchResult(rep, batch);
|
|
59542
|
+
}
|
|
59543
|
+
async batchFetchRecordData(batchs, abortController) {
|
|
59544
|
+
let reps;
|
|
59545
|
+
try {
|
|
59546
|
+
reps = await this.callBatchGraphQL(batchs, abortController);
|
|
59547
|
+
}
|
|
59548
|
+
catch (e) {
|
|
59549
|
+
const missingIds = batchs
|
|
59550
|
+
.map((batch) => batch.ids)
|
|
59551
|
+
.reduce((prev, curr) => prev.concat(curr), []);
|
|
59552
|
+
return [
|
|
59553
|
+
{
|
|
59554
|
+
ok: false,
|
|
59555
|
+
error: 'network-error',
|
|
59556
|
+
messages: ['Network Error'],
|
|
59557
|
+
missingIds,
|
|
59558
|
+
},
|
|
59559
|
+
];
|
|
59560
|
+
}
|
|
59561
|
+
const recordFetchResults = [];
|
|
59562
|
+
for (let i = 0; i < reps.length; i++) {
|
|
59563
|
+
recordFetchResults.push(this.generateFetchResult(reps[i], batchs[i]));
|
|
59564
|
+
}
|
|
59565
|
+
return recordFetchResults;
|
|
59566
|
+
}
|
|
59567
|
+
generateFetchResult(repResult, batchInput) {
|
|
59568
|
+
const { data, errors } = repResult;
|
|
59484
59569
|
if (errors !== undefined && errors.length > 0) {
|
|
59485
59570
|
// right now if there are any errors in the batch we throw out the entire batch
|
|
59486
59571
|
// for now this is ok all errors will originate on the same node so there shouldn't be a mix of errors and data
|
|
59487
59572
|
return {
|
|
59488
|
-
missingIds:
|
|
59573
|
+
missingIds: batchInput.ids,
|
|
59489
59574
|
ok: false,
|
|
59490
59575
|
error: 'request-error',
|
|
59491
59576
|
messages: errors.map((x) => x.message),
|
|
@@ -59497,11 +59582,11 @@
|
|
|
59497
59582
|
ok: false,
|
|
59498
59583
|
error: 'unknown',
|
|
59499
59584
|
messages: ['unexpected response retrieved from graphql endpoint'],
|
|
59500
|
-
missingIds:
|
|
59585
|
+
missingIds: batchInput.ids,
|
|
59501
59586
|
};
|
|
59502
59587
|
}
|
|
59503
|
-
const seenRecords = new Set(
|
|
59504
|
-
const records = data.uiapi.query[
|
|
59588
|
+
const seenRecords = new Set(batchInput.ids);
|
|
59589
|
+
const records = data.uiapi.query[batchInput.type].edges.map((edge) => {
|
|
59505
59590
|
const record = this.generateDurableRecordRepresentation(edge.node);
|
|
59506
59591
|
seenRecords.delete(record.id);
|
|
59507
59592
|
return record;
|
|
@@ -59516,6 +59601,15 @@
|
|
|
59516
59601
|
const query = this.generateGraphQLQuery(batch.type, batch.fields);
|
|
59517
59602
|
return this.networkAdapter.postGraphQL(query, { ids: batch.ids, first: batch.ids.length }, abortController);
|
|
59518
59603
|
}
|
|
59604
|
+
callBatchGraphQL(batches, abortController) {
|
|
59605
|
+
const gqlInput = batches.map((batch) => {
|
|
59606
|
+
return {
|
|
59607
|
+
query: this.generateGraphQLQuery(batch.type, batch.fields),
|
|
59608
|
+
variables: { ids: batch.ids, first: batch.ids.length },
|
|
59609
|
+
};
|
|
59610
|
+
});
|
|
59611
|
+
return this.networkAdapter.postBatchGraphQL(gqlInput, abortController);
|
|
59612
|
+
}
|
|
59519
59613
|
generateGraphQLQuery(type, fields) {
|
|
59520
59614
|
const fieldList = Object.keys(requiredFieldMap)
|
|
59521
59615
|
.map((field) => {
|
|
@@ -59637,7 +59731,56 @@
|
|
|
59637
59731
|
/* global __nimbus */
|
|
59638
59732
|
// note this is automatically incremented by scripts/release/bump-api-version.js at each release
|
|
59639
59733
|
const apiVersion = `v59.0`;
|
|
59734
|
+
const batchEndPointPath = `/services/data/${apiVersion}/graphql/batch`;
|
|
59735
|
+
const endPointPath = `/services/data/${apiVersion}/graphql`;
|
|
59640
59736
|
class NimbusPrimingNetworkAdapter {
|
|
59737
|
+
postBatchGraphQL(configs, abortController) {
|
|
59738
|
+
return new Promise((resolve, reject) => {
|
|
59739
|
+
let listener;
|
|
59740
|
+
const unregisterListener = () => {
|
|
59741
|
+
if (listener) {
|
|
59742
|
+
abortController.removeEventListener(listener);
|
|
59743
|
+
}
|
|
59744
|
+
};
|
|
59745
|
+
__nimbus.plugins.LdsNetworkAdapter
|
|
59746
|
+
.sendRequest({
|
|
59747
|
+
method: 'POST',
|
|
59748
|
+
path: batchEndPointPath,
|
|
59749
|
+
body: JSON.stringify({
|
|
59750
|
+
batchQuery: configs,
|
|
59751
|
+
}),
|
|
59752
|
+
headers: {},
|
|
59753
|
+
queryParams: {},
|
|
59754
|
+
priority: 'background',
|
|
59755
|
+
observabilityContext: {},
|
|
59756
|
+
}, (response) => {
|
|
59757
|
+
unregisterListener();
|
|
59758
|
+
const { body } = response;
|
|
59759
|
+
if (body) {
|
|
59760
|
+
const { results } = JSON.parse(body);
|
|
59761
|
+
if (results) {
|
|
59762
|
+
const gqlResults = results.map((compositeGqlResult) => compositeGqlResult.result);
|
|
59763
|
+
resolve(gqlResults);
|
|
59764
|
+
}
|
|
59765
|
+
else {
|
|
59766
|
+
reject(new Error(`No body returned from ${batchEndPointPath} endpoint`));
|
|
59767
|
+
}
|
|
59768
|
+
}
|
|
59769
|
+
else {
|
|
59770
|
+
reject(new Error(`No body returned from ${batchEndPointPath} endpoint`));
|
|
59771
|
+
}
|
|
59772
|
+
}, (error) => {
|
|
59773
|
+
unregisterListener();
|
|
59774
|
+
reject(error);
|
|
59775
|
+
})
|
|
59776
|
+
.then((cancellationToken) => {
|
|
59777
|
+
listener = () => {
|
|
59778
|
+
__nimbus.plugins.LdsNetworkAdapter.cancelRequest(cancellationToken);
|
|
59779
|
+
};
|
|
59780
|
+
abortController.addEventListener(listener);
|
|
59781
|
+
});
|
|
59782
|
+
});
|
|
59783
|
+
}
|
|
59641
59784
|
postGraphQL(query, variables, abortController) {
|
|
59642
59785
|
return new Promise((resolve, reject) => {
|
|
59643
59786
|
let listener;
|
|
@@ -59649,7 +59792,7 @@
|
|
|
59649
59792
|
__nimbus.plugins.LdsNetworkAdapter
|
|
59650
59793
|
.sendRequest({
|
|
59651
59794
|
method: 'POST',
|
|
59652
|
-
path:
|
|
59795
|
+
path: endPointPath,
|
|
59653
59796
|
body: JSON.stringify({
|
|
59654
59797
|
query,
|
|
59655
59798
|
variables,
|
|
@@ -59665,7 +59808,7 @@
|
|
|
59665
59808
|
resolve(JSON.parse(body));
|
|
59666
59809
|
}
|
|
59667
59810
|
else {
|
|
59668
|
-
reject(new Error(
|
|
59811
|
+
reject(new Error(`No body returned from ${endPointPath} endpoint`));
|
|
59669
59812
|
}
|
|
59670
59813
|
}, (error) => {
|
|
59671
59814
|
unregisterListener();
|
|
@@ -59913,7 +60056,7 @@
|
|
|
59913
60056
|
id: '@salesforce/lds-network-adapter',
|
|
59914
60057
|
instrument: instrument$1,
|
|
59915
60058
|
});
|
|
59916
|
-
// version: 1.
|
|
60059
|
+
// version: 1.157.0-4246d2656
|
|
59917
60060
|
|
|
59918
60061
|
const { create: create$2, keys: keys$2 } = Object;
|
|
59919
60062
|
const { stringify: stringify$1, parse: parse$1 } = JSON;
|
|
@@ -80758,7 +80901,7 @@
|
|
|
80758
80901
|
configuration: { ...configurationForGraphQLAdapters },
|
|
80759
80902
|
instrument,
|
|
80760
80903
|
});
|
|
80761
|
-
// version: 1.
|
|
80904
|
+
// version: 1.157.0-612ff940a
|
|
80762
80905
|
|
|
80763
80906
|
// On core the unstable adapters are re-exported with different names,
|
|
80764
80907
|
|
|
@@ -83005,7 +83148,7 @@
|
|
|
83005
83148
|
unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
|
|
83006
83149
|
graphQLImperative = ldsAdapter;
|
|
83007
83150
|
});
|
|
83008
|
-
// version: 1.
|
|
83151
|
+
// version: 1.157.0-612ff940a
|
|
83009
83152
|
|
|
83010
83153
|
var gqlApi = /*#__PURE__*/Object.freeze({
|
|
83011
83154
|
__proto__: null,
|
|
@@ -83711,4 +83854,4 @@
|
|
|
83711
83854
|
Object.defineProperty(exports, '__esModule', { value: true });
|
|
83712
83855
|
|
|
83713
83856
|
}));
|
|
83714
|
-
// version: 1.
|
|
83857
|
+
// version: 1.157.0-4246d2656
|