@salesforce/lds-worker-api 1.156.1 → 1.157.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -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.156.1-7842b5df6
773
+ // version: 1.157.1-a0df85006
@@ -3672,7 +3672,7 @@ class Luvio {
3672
3672
  return this.environment.buildStructuredKey(namespace, representationName, idValues);
3673
3673
  }
3674
3674
  }
3675
- // engine version: 0.143.1-f553bab7
3675
+ // engine version: 0.143.2-f0cd3fab
3676
3676
 
3677
3677
  /**
3678
3678
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -3799,7 +3799,7 @@ function withDefaultLuvio(callback) {
3799
3799
  }
3800
3800
  callbacks.push(callback);
3801
3801
  }
3802
- // version: 1.156.1-7842b5df6
3802
+ // version: 1.157.1-a0df85006
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.156.1-7842b5df6
15235
+ // version: 1.157.1-a0df85006
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.156.1-7842b5df6
16148
+ // version: 1.157.1-a0df85006
16149
16149
 
16150
16150
  /**
16151
16151
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -16228,7 +16228,7 @@ var FragmentReadResultState;
16228
16228
  ({
16229
16229
  state: FragmentReadResultState.Missing,
16230
16230
  });
16231
- // engine version: 0.143.1-f553bab7
16231
+ // engine version: 0.143.2-f0cd3fab
16232
16232
 
16233
16233
  const { keys: ObjectKeys$3, create: ObjectCreate$3 } = Object;
16234
16234
 
@@ -44016,7 +44016,7 @@ withDefaultLuvio((luvio) => {
44016
44016
  dropFunction: instrumentation$2.notifyRecordUpdateAvailableDropped,
44017
44017
  });
44018
44018
  });
44019
- // version: 1.156.1-323bf98b0
44019
+ // version: 1.157.1-633c9f497
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.
@@ -53117,7 +53126,7 @@ function dataTypeToType(objectInfoDataType, apiName) {
53117
53126
  case 'Url':
53118
53127
  return 'UrlValue';
53119
53128
  case 'Picklist':
53120
- return 'UrlValue';
53129
+ return 'PicklistValue';
53121
53130
  case 'MultiPicklist':
53122
53131
  return 'MultiPicklistValue';
53123
53132
  case 'Percent':
@@ -59301,16 +59310,19 @@ function generateTypedBatches(work, batchSize) {
59301
59310
 
59302
59311
  const DEFAULT_BATCH_SIZE = 500;
59303
59312
  const DEFAULT_CONCURRENCY = 6;
59313
+ const DEFAULT_GQL_QUERY_BATCH_SIZE = 5;
59304
59314
  class PrimingSession extends EventEmitter {
59305
59315
  constructor(config) {
59306
59316
  var _a, _b;
59307
59317
  super();
59318
+ this.useBatchGQL = false;
59308
59319
  this.batchSize = (_a = config.batchSize) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_SIZE;
59309
59320
  this.concurrency = (_b = config.concurrency) !== null && _b !== void 0 ? _b : DEFAULT_CONCURRENCY;
59310
59321
  this.recordLoader = config.recordLoader;
59311
59322
  this.recordIngestor = config.recordIngestor;
59312
59323
  this.objectInfoLoader = config.objectInfoLoader;
59313
59324
  this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
59325
+ this.useBatchGQL = ldsPrimingGraphqlBatch.isOpen({ fallback: false });
59314
59326
  }
59315
59327
  // function that enqueues priming work
59316
59328
  async enqueue(work) {
@@ -59345,91 +59357,129 @@ class PrimingSession extends EventEmitter {
59345
59357
  }
59346
59358
  // parallelizes batches of priming work
59347
59359
  enqueueBatches(batches) {
59348
- for (const batch of batches) {
59349
- const queuedTime = Date.now();
59350
- this.networkWorkerPool.push({
59351
- workFn: (abortController) => {
59352
- const workTime = Date.now();
59353
- this.emit('batch-starting', { queuedTime: workTime - queuedTime });
59354
- return this.recordLoader
59355
- .fetchRecordData(batch, abortController)
59356
- .then(async (result) => {
59357
- if (abortController.aborted) {
59358
- return;
59359
- }
59360
- this.emit('batch-fetched', {
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', {
59361
59379
  ids: batch.ids,
59362
- duration: Date.now() - workTime,
59380
+ code: 'canceled',
59381
+ message: `batch canceled`,
59363
59382
  });
59364
- if (result.ok === false) {
59365
- const { error } = result;
59366
- const primingError = error === 'network-error' ? 'service-unavailable' : 'unknown';
59367
- this.emit('error', {
59368
- ids: result.missingIds,
59369
- code: primingError,
59370
- message: `${result.messages.join(',')}`,
59371
- });
59372
- return;
59373
- }
59374
- const { missingIds } = result;
59375
- if (missingIds.length > 0) {
59376
- this.emit('error', {
59377
- ids: missingIds,
59378
- code: 'not-found',
59379
- message: `could not find records: ${missingIds.join(', ')}`,
59380
- });
59381
- }
59382
- const { records } = result;
59383
- const beforeWrite = Date.now();
59384
- // dispatch the write but DO NOT wait on it to unblock the network pool
59385
- this.recordIngestor
59386
- .insertRecords(records)
59387
- .then(({ written, conflicted, errors }) => {
59388
- this.emit('batch-written', {
59389
- written,
59390
- conflicted,
59391
- errors: errors
59392
- .map((e) => e.ids)
59393
- .reduce((a, b) => a.concat(b), []),
59394
- duration: Date.now() - beforeWrite,
59395
- });
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) => {
59396
59398
  if (abortController.aborted) {
59397
59399
  return;
59398
59400
  }
59399
- if (errors.length > 0) {
59400
- errors.forEach(({ ids, message }) => {
59401
- this.emit('error', {
59402
- ids,
59403
- code: 'unknown',
59404
- message: message,
59405
- });
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,
59406
59407
  });
59407
59408
  }
59408
- // now that the records are persisted, emit the primed event
59409
- if (written.length > 0) {
59410
- this.emit('primed', Array.from(written));
59411
- }
59412
- // TODO [W-12436213]: implement conflict resolution
59413
- if (conflicted.length > 0) {
59414
- // for now emit conlicts as errors
59415
- this.emit('error', {
59416
- ids: Array.from(conflicted),
59417
- code: 'unknown',
59418
- message: 'conflict when persisting record',
59419
- });
59409
+ for (let i = 0; i < results.length; i++) {
59410
+ this.processFetchedRecords(results[i], abortController);
59420
59411
  }
59421
59412
  });
59422
- });
59423
- },
59424
- cancelFn: () => {
59425
- this.emit('error', {
59426
- ids: batch.ids,
59427
- code: 'canceled',
59428
- message: `batch canceled`,
59429
- });
59430
- },
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(',')}`,
59431
59436
  });
59437
+ return;
59432
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(', ')}`,
59445
+ });
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
+ });
59433
59483
  }
59434
59484
  async fetchMetadata(batches) {
59435
59485
  const apiNames = Array.from(batches.reduce((acc, x) => {
@@ -59482,12 +59532,39 @@ class RecordLoaderGraphQL {
59482
59532
  missingIds: batch.ids,
59483
59533
  };
59484
59534
  }
59485
- const { data, errors } = rep;
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;
59486
59563
  if (errors !== undefined && errors.length > 0) {
59487
59564
  // right now if there are any errors in the batch we throw out the entire batch
59488
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
59489
59566
  return {
59490
- missingIds: batch.ids,
59567
+ missingIds: batchInput.ids,
59491
59568
  ok: false,
59492
59569
  error: 'request-error',
59493
59570
  messages: errors.map((x) => x.message),
@@ -59499,11 +59576,11 @@ class RecordLoaderGraphQL {
59499
59576
  ok: false,
59500
59577
  error: 'unknown',
59501
59578
  messages: ['unexpected response retrieved from graphql endpoint'],
59502
- missingIds: batch.ids,
59579
+ missingIds: batchInput.ids,
59503
59580
  };
59504
59581
  }
59505
- const seenRecords = new Set(batch.ids);
59506
- const records = data.uiapi.query[batch.type].edges.map((edge) => {
59582
+ const seenRecords = new Set(batchInput.ids);
59583
+ const records = data.uiapi.query[batchInput.type].edges.map((edge) => {
59507
59584
  const record = this.generateDurableRecordRepresentation(edge.node);
59508
59585
  seenRecords.delete(record.id);
59509
59586
  return record;
@@ -59518,6 +59595,15 @@ class RecordLoaderGraphQL {
59518
59595
  const query = this.generateGraphQLQuery(batch.type, batch.fields);
59519
59596
  return this.networkAdapter.postGraphQL(query, { ids: batch.ids, first: batch.ids.length }, abortController);
59520
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
+ }
59521
59607
  generateGraphQLQuery(type, fields) {
59522
59608
  const fieldList = Object.keys(requiredFieldMap)
59523
59609
  .map((field) => {
@@ -59639,7 +59725,56 @@ function instrumentPrimingSession(session) {
59639
59725
  /* global __nimbus */
59640
59726
  // note this is automatically incremented by scripts/release/bump-api-version.js at each release
59641
59727
  const apiVersion = `v59.0`;
59728
+ const batchEndPointPath = `/services/data/${apiVersion}/graphql/batch`;
59729
+ const endPointPath = `/services/data/${apiVersion}/graphql`;
59642
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
+ }
59643
59778
  postGraphQL(query, variables, abortController) {
59644
59779
  return new Promise((resolve, reject) => {
59645
59780
  let listener;
@@ -59651,7 +59786,7 @@ class NimbusPrimingNetworkAdapter {
59651
59786
  __nimbus.plugins.LdsNetworkAdapter
59652
59787
  .sendRequest({
59653
59788
  method: 'POST',
59654
- path: `/services/data/${apiVersion}/graphql`,
59789
+ path: endPointPath,
59655
59790
  body: JSON.stringify({
59656
59791
  query,
59657
59792
  variables,
@@ -59667,7 +59802,7 @@ class NimbusPrimingNetworkAdapter {
59667
59802
  resolve(JSON.parse(body));
59668
59803
  }
59669
59804
  else {
59670
- reject(new Error('No body returned from graphql endpoint'));
59805
+ reject(new Error(`No body returned from ${endPointPath} endpoint`));
59671
59806
  }
59672
59807
  }, (error) => {
59673
59808
  unregisterListener();
@@ -59915,7 +60050,7 @@ register({
59915
60050
  id: '@salesforce/lds-network-adapter',
59916
60051
  instrument: instrument$1,
59917
60052
  });
59918
- // version: 1.156.1-7842b5df6
60053
+ // version: 1.157.1-a0df85006
59919
60054
 
59920
60055
  const { create: create$2, keys: keys$2 } = Object;
59921
60056
  const { stringify: stringify$1, parse: parse$1 } = JSON;
@@ -60226,9 +60361,9 @@ function findMaxOffset(metadata) {
60226
60361
  if (endOfList !== undefined) {
60227
60362
  return endOfList > 0 ? endOfList - 1 : 0; // Cursor based pagination in gql is off by one :)
60228
60363
  }
60229
- const { __END__: _, ...cursorMetadata } = metadata;
60230
- const values = Object.values(cursorMetadata).filter((value) => value !== undefined);
60231
- return Math.max(...values);
60364
+ // end is included in the above case.
60365
+ return Object.values(metadata)
60366
+ .reduce((acc, value) => Math.max(value !== null && value !== void 0 ? value : -1, acc), -1);
60232
60367
  }
60233
60368
  function getPageTokenAndOffset(paginationMetadata, token) {
60234
60369
  if (token === undefined) {
@@ -80760,7 +80895,7 @@ register({
80760
80895
  configuration: { ...configurationForGraphQLAdapters },
80761
80896
  instrument,
80762
80897
  });
80763
- // version: 1.156.1-323bf98b0
80898
+ // version: 1.157.1-633c9f497
80764
80899
 
80765
80900
  // On core the unstable adapters are re-exported with different names,
80766
80901
 
@@ -83007,7 +83142,7 @@ withDefaultLuvio((luvio) => {
83007
83142
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
83008
83143
  graphQLImperative = ldsAdapter;
83009
83144
  });
83010
- // version: 1.156.1-323bf98b0
83145
+ // version: 1.157.1-633c9f497
83011
83146
 
83012
83147
  var gqlApi = /*#__PURE__*/Object.freeze({
83013
83148
  __proto__: null,
@@ -83696,4 +83831,4 @@ const { luvio } = getRuntime();
83696
83831
  setDefaultLuvio({ luvio });
83697
83832
 
83698
83833
  export { createPrimingSession, draftManager, draftQueue, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, invokeAdapter, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, registerReportObserver, setMetadataTTL, setUiApiRecordTTL, subscribeToAdapter };
83699
- // version: 1.156.1-7842b5df6
83834
+ // version: 1.157.1-a0df85006
@@ -3678,7 +3678,7 @@
3678
3678
  return this.environment.buildStructuredKey(namespace, representationName, idValues);
3679
3679
  }
3680
3680
  }
3681
- // engine version: 0.143.1-f553bab7
3681
+ // engine version: 0.143.2-f0cd3fab
3682
3682
 
3683
3683
  /**
3684
3684
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -3805,7 +3805,7 @@
3805
3805
  }
3806
3806
  callbacks.push(callback);
3807
3807
  }
3808
- // version: 1.156.1-7842b5df6
3808
+ // version: 1.157.1-a0df85006
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.156.1-7842b5df6
15241
+ // version: 1.157.1-a0df85006
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.156.1-7842b5df6
16154
+ // version: 1.157.1-a0df85006
16155
16155
 
16156
16156
  /**
16157
16157
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -16234,7 +16234,7 @@
16234
16234
  ({
16235
16235
  state: FragmentReadResultState.Missing,
16236
16236
  });
16237
- // engine version: 0.143.1-f553bab7
16237
+ // engine version: 0.143.2-f0cd3fab
16238
16238
 
16239
16239
  const { keys: ObjectKeys$3, create: ObjectCreate$3 } = Object;
16240
16240
 
@@ -44022,7 +44022,7 @@
44022
44022
  dropFunction: instrumentation$2.notifyRecordUpdateAvailableDropped,
44023
44023
  });
44024
44024
  });
44025
- // version: 1.156.1-323bf98b0
44025
+ // version: 1.157.1-633c9f497
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.
@@ -53123,7 +53132,7 @@
53123
53132
  case 'Url':
53124
53133
  return 'UrlValue';
53125
53134
  case 'Picklist':
53126
- return 'UrlValue';
53135
+ return 'PicklistValue';
53127
53136
  case 'MultiPicklist':
53128
53137
  return 'MultiPicklistValue';
53129
53138
  case 'Percent':
@@ -59307,16 +59316,19 @@
59307
59316
 
59308
59317
  const DEFAULT_BATCH_SIZE = 500;
59309
59318
  const DEFAULT_CONCURRENCY = 6;
59319
+ const DEFAULT_GQL_QUERY_BATCH_SIZE = 5;
59310
59320
  class PrimingSession extends EventEmitter {
59311
59321
  constructor(config) {
59312
59322
  var _a, _b;
59313
59323
  super();
59324
+ this.useBatchGQL = false;
59314
59325
  this.batchSize = (_a = config.batchSize) !== null && _a !== void 0 ? _a : DEFAULT_BATCH_SIZE;
59315
59326
  this.concurrency = (_b = config.concurrency) !== null && _b !== void 0 ? _b : DEFAULT_CONCURRENCY;
59316
59327
  this.recordLoader = config.recordLoader;
59317
59328
  this.recordIngestor = config.recordIngestor;
59318
59329
  this.objectInfoLoader = config.objectInfoLoader;
59319
59330
  this.networkWorkerPool = new AsyncWorkerPool(this.concurrency);
59331
+ this.useBatchGQL = ldsPrimingGraphqlBatch.isOpen({ fallback: false });
59320
59332
  }
59321
59333
  // function that enqueues priming work
59322
59334
  async enqueue(work) {
@@ -59351,91 +59363,129 @@
59351
59363
  }
59352
59364
  // parallelizes batches of priming work
59353
59365
  enqueueBatches(batches) {
59354
- for (const batch of batches) {
59355
- const queuedTime = Date.now();
59356
- this.networkWorkerPool.push({
59357
- workFn: (abortController) => {
59358
- const workTime = Date.now();
59359
- this.emit('batch-starting', { queuedTime: workTime - queuedTime });
59360
- return this.recordLoader
59361
- .fetchRecordData(batch, abortController)
59362
- .then(async (result) => {
59363
- if (abortController.aborted) {
59364
- return;
59365
- }
59366
- this.emit('batch-fetched', {
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', {
59367
59385
  ids: batch.ids,
59368
- duration: Date.now() - workTime,
59386
+ code: 'canceled',
59387
+ message: `batch canceled`,
59369
59388
  });
59370
- if (result.ok === false) {
59371
- const { error } = result;
59372
- const primingError = error === 'network-error' ? 'service-unavailable' : 'unknown';
59373
- this.emit('error', {
59374
- ids: result.missingIds,
59375
- code: primingError,
59376
- message: `${result.messages.join(',')}`,
59377
- });
59378
- return;
59379
- }
59380
- const { missingIds } = result;
59381
- if (missingIds.length > 0) {
59382
- this.emit('error', {
59383
- ids: missingIds,
59384
- code: 'not-found',
59385
- message: `could not find records: ${missingIds.join(', ')}`,
59386
- });
59387
- }
59388
- const { records } = result;
59389
- const beforeWrite = Date.now();
59390
- // dispatch the write but DO NOT wait on it to unblock the network pool
59391
- this.recordIngestor
59392
- .insertRecords(records)
59393
- .then(({ written, conflicted, errors }) => {
59394
- this.emit('batch-written', {
59395
- written,
59396
- conflicted,
59397
- errors: errors
59398
- .map((e) => e.ids)
59399
- .reduce((a, b) => a.concat(b), []),
59400
- duration: Date.now() - beforeWrite,
59401
- });
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) => {
59402
59404
  if (abortController.aborted) {
59403
59405
  return;
59404
59406
  }
59405
- if (errors.length > 0) {
59406
- errors.forEach(({ ids, message }) => {
59407
- this.emit('error', {
59408
- ids,
59409
- code: 'unknown',
59410
- message: message,
59411
- });
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,
59412
59413
  });
59413
59414
  }
59414
- // now that the records are persisted, emit the primed event
59415
- if (written.length > 0) {
59416
- this.emit('primed', Array.from(written));
59417
- }
59418
- // TODO [W-12436213]: implement conflict resolution
59419
- if (conflicted.length > 0) {
59420
- // for now emit conlicts as errors
59421
- this.emit('error', {
59422
- ids: Array.from(conflicted),
59423
- code: 'unknown',
59424
- message: 'conflict when persisting record',
59425
- });
59415
+ for (let i = 0; i < results.length; i++) {
59416
+ this.processFetchedRecords(results[i], abortController);
59426
59417
  }
59427
59418
  });
59428
- });
59429
- },
59430
- cancelFn: () => {
59431
- this.emit('error', {
59432
- ids: batch.ids,
59433
- code: 'canceled',
59434
- message: `batch canceled`,
59435
- });
59436
- },
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(',')}`,
59437
59442
  });
59443
+ return;
59438
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(', ')}`,
59451
+ });
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
+ });
59439
59489
  }
59440
59490
  async fetchMetadata(batches) {
59441
59491
  const apiNames = Array.from(batches.reduce((acc, x) => {
@@ -59488,12 +59538,39 @@
59488
59538
  missingIds: batch.ids,
59489
59539
  };
59490
59540
  }
59491
- const { data, errors } = rep;
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;
59492
59569
  if (errors !== undefined && errors.length > 0) {
59493
59570
  // right now if there are any errors in the batch we throw out the entire batch
59494
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
59495
59572
  return {
59496
- missingIds: batch.ids,
59573
+ missingIds: batchInput.ids,
59497
59574
  ok: false,
59498
59575
  error: 'request-error',
59499
59576
  messages: errors.map((x) => x.message),
@@ -59505,11 +59582,11 @@
59505
59582
  ok: false,
59506
59583
  error: 'unknown',
59507
59584
  messages: ['unexpected response retrieved from graphql endpoint'],
59508
- missingIds: batch.ids,
59585
+ missingIds: batchInput.ids,
59509
59586
  };
59510
59587
  }
59511
- const seenRecords = new Set(batch.ids);
59512
- const records = data.uiapi.query[batch.type].edges.map((edge) => {
59588
+ const seenRecords = new Set(batchInput.ids);
59589
+ const records = data.uiapi.query[batchInput.type].edges.map((edge) => {
59513
59590
  const record = this.generateDurableRecordRepresentation(edge.node);
59514
59591
  seenRecords.delete(record.id);
59515
59592
  return record;
@@ -59524,6 +59601,15 @@
59524
59601
  const query = this.generateGraphQLQuery(batch.type, batch.fields);
59525
59602
  return this.networkAdapter.postGraphQL(query, { ids: batch.ids, first: batch.ids.length }, abortController);
59526
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
+ }
59527
59613
  generateGraphQLQuery(type, fields) {
59528
59614
  const fieldList = Object.keys(requiredFieldMap)
59529
59615
  .map((field) => {
@@ -59645,7 +59731,56 @@
59645
59731
  /* global __nimbus */
59646
59732
  // note this is automatically incremented by scripts/release/bump-api-version.js at each release
59647
59733
  const apiVersion = `v59.0`;
59734
+ const batchEndPointPath = `/services/data/${apiVersion}/graphql/batch`;
59735
+ const endPointPath = `/services/data/${apiVersion}/graphql`;
59648
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
+ }
59649
59784
  postGraphQL(query, variables, abortController) {
59650
59785
  return new Promise((resolve, reject) => {
59651
59786
  let listener;
@@ -59657,7 +59792,7 @@
59657
59792
  __nimbus.plugins.LdsNetworkAdapter
59658
59793
  .sendRequest({
59659
59794
  method: 'POST',
59660
- path: `/services/data/${apiVersion}/graphql`,
59795
+ path: endPointPath,
59661
59796
  body: JSON.stringify({
59662
59797
  query,
59663
59798
  variables,
@@ -59673,7 +59808,7 @@
59673
59808
  resolve(JSON.parse(body));
59674
59809
  }
59675
59810
  else {
59676
- reject(new Error('No body returned from graphql endpoint'));
59811
+ reject(new Error(`No body returned from ${endPointPath} endpoint`));
59677
59812
  }
59678
59813
  }, (error) => {
59679
59814
  unregisterListener();
@@ -59921,7 +60056,7 @@
59921
60056
  id: '@salesforce/lds-network-adapter',
59922
60057
  instrument: instrument$1,
59923
60058
  });
59924
- // version: 1.156.1-7842b5df6
60059
+ // version: 1.157.1-a0df85006
59925
60060
 
59926
60061
  const { create: create$2, keys: keys$2 } = Object;
59927
60062
  const { stringify: stringify$1, parse: parse$1 } = JSON;
@@ -60232,9 +60367,9 @@
60232
60367
  if (endOfList !== undefined) {
60233
60368
  return endOfList > 0 ? endOfList - 1 : 0; // Cursor based pagination in gql is off by one :)
60234
60369
  }
60235
- const { __END__: _, ...cursorMetadata } = metadata;
60236
- const values = Object.values(cursorMetadata).filter((value) => value !== undefined);
60237
- return Math.max(...values);
60370
+ // end is included in the above case.
60371
+ return Object.values(metadata)
60372
+ .reduce((acc, value) => Math.max(value !== null && value !== void 0 ? value : -1, acc), -1);
60238
60373
  }
60239
60374
  function getPageTokenAndOffset(paginationMetadata, token) {
60240
60375
  if (token === undefined) {
@@ -80766,7 +80901,7 @@
80766
80901
  configuration: { ...configurationForGraphQLAdapters },
80767
80902
  instrument,
80768
80903
  });
80769
- // version: 1.156.1-323bf98b0
80904
+ // version: 1.157.1-633c9f497
80770
80905
 
80771
80906
  // On core the unstable adapters are re-exported with different names,
80772
80907
 
@@ -83013,7 +83148,7 @@
83013
83148
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
83014
83149
  graphQLImperative = ldsAdapter;
83015
83150
  });
83016
- // version: 1.156.1-323bf98b0
83151
+ // version: 1.157.1-633c9f497
83017
83152
 
83018
83153
  var gqlApi = /*#__PURE__*/Object.freeze({
83019
83154
  __proto__: null,
@@ -83719,4 +83854,4 @@
83719
83854
  Object.defineProperty(exports, '__esModule', { value: true });
83720
83855
 
83721
83856
  }));
83722
- // version: 1.156.1-7842b5df6
83857
+ // version: 1.157.1-a0df85006
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-worker-api",
3
- "version": "1.156.1",
3
+ "version": "1.157.1",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "",
6
6
  "main": "dist/standalone/es/lds-worker-api.js",