@salesforce/lds-worker-api 1.112.1 → 1.113.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.
@@ -731,6 +731,9 @@ function createPrimingSession(config) {
731
731
  return {
732
732
  enqueue: session.enqueue.bind(session),
733
733
  cancel: session.cancel.bind(session),
734
+ on: session.on.bind(session),
735
+ once: session.once.bind(session),
736
+ off: session.off.bind(session),
734
737
  };
735
738
  }
736
739
 
@@ -744,4 +747,4 @@ if (process.env.NODE_ENV !== 'production') {
744
747
  }
745
748
 
746
749
  export { createPrimingSession, draftManager, draftQueue, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, invokeAdapter, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, setMetadataTTL, setUiApiRecordTTL, subscribeToAdapter };
747
- // version: 1.112.1-1a0875b1d
750
+ // version: 1.113.0-a8af103c9
@@ -16,5 +16,8 @@ export interface PrimingSessionConfig {
16
16
  export declare function createPrimingSession(config: PrimingSessionConfig): {
17
17
  enqueue: (work: PrimingWork) => Promise<void>;
18
18
  cancel: () => void;
19
+ on: <K extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K]) => void) => import("@salesforce/lds-priming").PrimingSession;
20
+ once: <K_1 extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K_1, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K_1]) => void) => import("@salesforce/lds-priming").PrimingSession;
21
+ off: <K_2 extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K_2, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K_2]) => void) => import("@salesforce/lds-priming").PrimingSession;
19
22
  };
20
23
  export {};
@@ -3776,7 +3776,7 @@ function withDefaultLuvio(callback) {
3776
3776
  }
3777
3777
  callbacks.push(callback);
3778
3778
  }
3779
- // version: 1.112.1-1a0875b1d
3779
+ // version: 1.113.0-a8af103c9
3780
3780
 
3781
3781
  // TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
3782
3782
  function instrumentAdapter$1(createFunction, _metadata) {
@@ -15200,7 +15200,7 @@ function parseAndVisit(source) {
15200
15200
  updateReferenceMapWithKnownKey(ast, luvioDocumentNode);
15201
15201
  return luvioDocumentNode;
15202
15202
  }
15203
- // version: 1.112.1-1a0875b1d
15203
+ // version: 1.113.0-a8af103c9
15204
15204
 
15205
15205
  function unwrap(data) {
15206
15206
  // The lwc-luvio bindings import a function from lwc called "unwrap".
@@ -16113,7 +16113,7 @@ function createGraphQLWireAdapterConstructor(luvio, adapter, metadata, astResolv
16113
16113
  const { apiFamily, name } = metadata;
16114
16114
  return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
16115
16115
  }
16116
- // version: 1.112.1-1a0875b1d
16116
+ // version: 1.113.0-a8af103c9
16117
16117
 
16118
16118
  /**
16119
16119
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -44301,7 +44301,7 @@ withDefaultLuvio((luvio) => {
44301
44301
  dropFunction: instrumentation$2.notifyRecordUpdateAvailableDropped,
44302
44302
  });
44303
44303
  });
44304
- // version: 1.112.1-1a0875b1d
44304
+ // version: 1.113.0-a8af103c9
44305
44305
 
44306
44306
  var caseSensitiveUserId = '005B0000000GR4OIAW';
44307
44307
 
@@ -58312,8 +58312,6 @@ function reportDraftAwareContentVersionSynthesizeCalls(mimeType) {
58312
58312
  }
58313
58313
  function reportPrimingError(errorType, recordCount) {
58314
58314
  }
58315
- function reportPrimingSuccess(recordCount) {
58316
- }
58317
58315
 
58318
58316
  function instrumentDraftQueue(queue) {
58319
58317
  queue.registerOnChangedListener((draftQueueEvent) => {
@@ -59203,8 +59201,14 @@ class PrimingSession extends EventEmitter {
59203
59201
  }
59204
59202
  // pop any pending work off the queue
59205
59203
  const batches = typedBatches.splice(0, typedBatches.length);
59204
+ const before = Date.now();
59206
59205
  // fetch the metadata for the batches
59207
- const { availableBatches, unavailableTypes, unavailableIds } = await this.fetchMetadata(batches);
59206
+ const { availableBatches, unavailableTypes, unavailableIds, availableTypes } = await this.fetchMetadata(batches);
59207
+ this.emit('metadata-fetched', {
59208
+ duration: Date.now() - before,
59209
+ availableTypes,
59210
+ unavailableTypes,
59211
+ });
59208
59212
  if (unavailableIds.length > 0) {
59209
59213
  this.emit('error', {
59210
59214
  ids: unavailableIds,
@@ -59223,14 +59227,21 @@ class PrimingSession extends EventEmitter {
59223
59227
  // parallelizes batches of priming work
59224
59228
  enqueueBatches(batches) {
59225
59229
  for (const batch of batches) {
59230
+ const queuedTime = Date.now();
59226
59231
  this.networkWorkerPool.push({
59227
59232
  workFn: (abortController) => {
59233
+ const workTime = Date.now();
59234
+ this.emit('batch-starting', { queuedTime: workTime - queuedTime });
59228
59235
  return this.recordLoader
59229
59236
  .fetchRecordData(batch, abortController)
59230
59237
  .then(async (result) => {
59231
59238
  if (abortController.signal.aborted) {
59232
59239
  return;
59233
59240
  }
59241
+ this.emit('batch-fetched', {
59242
+ ids: batch.ids,
59243
+ duration: Date.now() - workTime,
59244
+ });
59234
59245
  if (result.ok === false) {
59235
59246
  const { error } = result;
59236
59247
  const primingError = error === 'network-error' ? 'service-unavailable' : 'unknown';
@@ -59250,13 +59261,31 @@ class PrimingSession extends EventEmitter {
59250
59261
  });
59251
59262
  }
59252
59263
  const { records } = result;
59264
+ const beforeWrite = Date.now();
59253
59265
  // dispatch the write but DO NOT wait on it to unblock the network pool
59254
59266
  this.recordIngestor
59255
59267
  .insertRecords(records)
59256
- .then(({ written, conflicted }) => {
59268
+ .then(({ written, conflicted, errors }) => {
59269
+ this.emit('batch-written', {
59270
+ written,
59271
+ conflicted,
59272
+ errors: errors
59273
+ .map((e) => e.ids)
59274
+ .reduce((a, b) => a.concat(b), []),
59275
+ duration: Date.now() - beforeWrite,
59276
+ });
59257
59277
  if (abortController.signal.aborted) {
59258
59278
  return;
59259
59279
  }
59280
+ if (errors.length > 0) {
59281
+ errors.forEach(({ ids, message }) => {
59282
+ this.emit('error', {
59283
+ ids,
59284
+ code: 'unknown',
59285
+ message: message,
59286
+ });
59287
+ });
59288
+ }
59260
59289
  // now that the records are persisted, emit the primed event
59261
59290
  if (written.length > 0) {
59262
59291
  this.emit('primed', Array.from(written));
@@ -59289,6 +59318,7 @@ class PrimingSession extends EventEmitter {
59289
59318
  }, new Set()));
59290
59319
  const objectInfoMap = await this.objectInfoLoader.getObjectInfos(apiNames);
59291
59320
  const unavailableTypes = apiNames.filter((x) => !objectInfoMap[x]);
59321
+ const availableTypes = apiNames.filter((x) => objectInfoMap[x]);
59292
59322
  const unavilableBatches = batches.filter((x) => unavailableTypes.includes(x.type));
59293
59323
  const availableBatches = batches.filter((x) => !unavailableTypes.includes(x.type));
59294
59324
  const unavailableIds = unavilableBatches.reduce((acc, x) => {
@@ -59296,9 +59326,11 @@ class PrimingSession extends EventEmitter {
59296
59326
  return acc;
59297
59327
  }, []);
59298
59328
  return {
59329
+ apiNames,
59299
59330
  availableBatches,
59300
59331
  unavilableBatches,
59301
59332
  unavailableTypes,
59333
+ availableTypes,
59302
59334
  unavailableIds,
59303
59335
  };
59304
59336
  }
@@ -59458,44 +59490,28 @@ class RecordIngestor {
59458
59490
  */
59459
59491
  async insertRecords(syntheticRecords) {
59460
59492
  if (syntheticRecords.length === 0) {
59461
- return { written: [], conflicted: [] };
59493
+ return { written: [], conflicted: [], errors: [] };
59462
59494
  }
59463
59495
  const luvio = this.getLuvio();
59464
59496
  const ingestionTimestamp = Date.now();
59465
59497
  const ttlOverride = await luvio.storeGetTTLOverride(keyPrefix$1, RepresentationType$N);
59466
- const metadata = JSON.stringify({
59498
+ const metadata = {
59467
59499
  ingestionTimestamp,
59468
59500
  expirationTimestamp: (ttlOverride !== null && ttlOverride !== void 0 ? ttlOverride : TTL$v) + ingestionTimestamp,
59469
59501
  namespace: keyPrefix$1,
59470
59502
  representationName: RepresentationType$N,
59471
59503
  metadataVersion: DURABLE_METADATA_VERSION,
59472
59504
  version: VERSION$14,
59473
- });
59474
- const idsToPrime = new Set();
59475
- const written = [];
59476
- const rows = syntheticRecords.map((record) => {
59477
- idsToPrime.add(record.id);
59478
- return `('${keyBuilder$1Q(luvio, { recordId: record.id })}', '${JSON.stringify(record)}', '${metadata}')`;
59479
- });
59480
- const dml = `INSERT or IGNORE INTO lds_data (key, data, metadata) VALUES ${rows.join(',\n')} returning key;`;
59481
- const result = await this.store.query(dml, []);
59482
- for (const row of result.rows) {
59483
- const id = extractRecordIdFromStoreKey(row[0]);
59484
- if (id) {
59485
- written.push(id);
59486
- idsToPrime.delete(id);
59487
- }
59488
- }
59489
- return { written: Array.from(written), conflicted: Array.from(idsToPrime) };
59505
+ };
59506
+ return this.store.writeRecords(syntheticRecords.map((record) => ({ record, metadata })));
59490
59507
  }
59491
59508
  }
59492
59509
 
59493
59510
  function instrumentPrimingSession(session) {
59494
- session.on('error', (payload) => {
59495
- reportPrimingError(payload.code, payload.ids.length);
59511
+ session.on('error', ({ code, ids }) => {
59512
+ reportPrimingError(code, ids.length);
59496
59513
  });
59497
- session.on('primed', (payload) => {
59498
- reportPrimingSuccess(payload.length);
59514
+ session.on('primed', ({ length }) => {
59499
59515
  });
59500
59516
  return session;
59501
59517
  }
@@ -59548,11 +59564,78 @@ class NimbusPrimingNetworkAdapter {
59548
59564
  }
59549
59565
  }
59550
59566
 
59567
+ // ref: https://gnome.pages.gitlab.gnome.org/tracker/docs/developer/limits.html?gi-language=c
59568
+ const SQLITE_MAX_VARIABLE_NUMBER = 999;
59569
+ const PARAMS_PER_RECORD = 3;
59570
+ // We need to batch the records to avoid hitting the SQLITE_MAX_VARIABLE_NUMBER limit. Each record has 3 parameters
59571
+ const BATCH_SIZE = Math.floor(SQLITE_MAX_VARIABLE_NUMBER / PARAMS_PER_RECORD);
59572
+ class SqlitePrimingStore {
59573
+ constructor(getLuvio, store) {
59574
+ this.getLuvio = getLuvio;
59575
+ this.store = store;
59576
+ }
59577
+ async writeRecords(records) {
59578
+ const batches = batchArray(records);
59579
+ const writeResult = { written: [], conflicted: [], errors: [] };
59580
+ return (await Promise.all(batches.map((batch) => this.writeBatch(batch)))).reduce((acc, curr) => {
59581
+ acc.written.push(...curr.written);
59582
+ acc.conflicted.push(...curr.conflicted);
59583
+ acc.errors.push(...curr.errors);
59584
+ return acc;
59585
+ }, writeResult);
59586
+ }
59587
+ async writeBatch(records) {
59588
+ const idsToPrime = new Set();
59589
+ const written = [];
59590
+ const statement = `INSERT or IGNORE INTO lds_data (key, data, metadata) VALUES ${records
59591
+ .map((_) => `(?,?,?)`)
59592
+ .join(',')} returning key;`;
59593
+ const params = [];
59594
+ records.forEach(({ record, metadata }) => {
59595
+ idsToPrime.add(record.id);
59596
+ const key = keyBuilder$1Q(this.getLuvio(), { recordId: record.id });
59597
+ params.push(key);
59598
+ params.push(JSON.stringify(record));
59599
+ params.push(JSON.stringify(metadata));
59600
+ });
59601
+ try {
59602
+ const result = await this.store.query(statement, params);
59603
+ for (const row of result.rows) {
59604
+ const id = extractRecordIdFromStoreKey(row[0]);
59605
+ if (id) {
59606
+ written.push(id);
59607
+ idsToPrime.delete(id);
59608
+ }
59609
+ }
59610
+ return { written, conflicted: Array.from(idsToPrime), errors: [] };
59611
+ }
59612
+ catch (e) {
59613
+ return {
59614
+ written: [],
59615
+ conflicted: [],
59616
+ errors: [{ ids: Array.from(idsToPrime), message: e }],
59617
+ };
59618
+ }
59619
+ }
59620
+ }
59621
+ function batchArray(arr, batchSize = BATCH_SIZE) {
59622
+ const batches = [];
59623
+ // If the array length is less than or equal to the batch size, return the array as a single batch
59624
+ if (arr.length <= batchSize) {
59625
+ return [arr];
59626
+ }
59627
+ // Split the array into batches of size batchSize
59628
+ for (let i = 0; i < arr.length; i += batchSize) {
59629
+ batches.push(arr.slice(i, i + batchSize));
59630
+ }
59631
+ return batches;
59632
+ }
59633
+
59551
59634
  function primingSessionFactory(config) {
59552
59635
  const { store, objectInfoService, getLuvio } = config;
59553
59636
  const networkAdapter = new NimbusPrimingNetworkAdapter();
59554
59637
  const recordLoader = new RecordLoaderGraphQL(networkAdapter);
59555
- const recordIngestor = new RecordIngestor(store, getLuvio);
59638
+ const recordIngestor = new RecordIngestor(new SqlitePrimingStore(getLuvio, store), getLuvio);
59556
59639
  const session = new PrimingSession({
59557
59640
  recordLoader,
59558
59641
  recordIngestor,
@@ -59695,7 +59778,7 @@ register({
59695
59778
  id: '@salesforce/lds-network-adapter',
59696
59779
  instrument: instrument$1,
59697
59780
  });
59698
- // version: 1.112.1-1a0875b1d
59781
+ // version: 1.113.0-a8af103c9
59699
59782
 
59700
59783
  const { create: create$2, keys: keys$2 } = Object;
59701
59784
  const { stringify: stringify$1, parse: parse$1 } = JSON;
@@ -77421,7 +77504,7 @@ register({
77421
77504
  configuration: { ...configurationForGraphQLAdapters },
77422
77505
  instrument,
77423
77506
  });
77424
- // version: 1.112.1-1a0875b1d
77507
+ // version: 1.113.0-a8af103c9
77425
77508
 
77426
77509
  // On core the unstable adapters are re-exported with different names,
77427
77510
 
@@ -79550,7 +79633,7 @@ withDefaultLuvio((luvio) => {
79550
79633
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
79551
79634
  graphQLImperative = ldsAdapter;
79552
79635
  });
79553
- // version: 1.112.1-1a0875b1d
79636
+ // version: 1.113.0-a8af103c9
79554
79637
 
79555
79638
  var gqlApi = /*#__PURE__*/Object.freeze({
79556
79639
  __proto__: null,
@@ -80217,6 +80300,9 @@ function createPrimingSession(config) {
80217
80300
  return {
80218
80301
  enqueue: session.enqueue.bind(session),
80219
80302
  cancel: session.cancel.bind(session),
80303
+ on: session.on.bind(session),
80304
+ once: session.once.bind(session),
80305
+ off: session.off.bind(session),
80220
80306
  };
80221
80307
  }
80222
80308
 
@@ -80225,4 +80311,4 @@ const { luvio } = getRuntime();
80225
80311
  setDefaultLuvio({ luvio });
80226
80312
 
80227
80313
  export { createPrimingSession, draftManager, draftQueue, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, invokeAdapter, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, registerReportObserver, setMetadataTTL, setUiApiRecordTTL, subscribeToAdapter };
80228
- // version: 1.112.1-1a0875b1d
80314
+ // version: 1.113.0-a8af103c9
@@ -16,5 +16,8 @@ export interface PrimingSessionConfig {
16
16
  export declare function createPrimingSession(config: PrimingSessionConfig): {
17
17
  enqueue: (work: PrimingWork) => Promise<void>;
18
18
  cancel: () => void;
19
+ on: <K extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K]) => void) => import("@salesforce/lds-priming").PrimingSession;
20
+ once: <K_1 extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K_1, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K_1]) => void) => import("@salesforce/lds-priming").PrimingSession;
21
+ off: <K_2 extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K_2, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K_2]) => void) => import("@salesforce/lds-priming").PrimingSession;
19
22
  };
20
23
  export {};
@@ -3782,7 +3782,7 @@
3782
3782
  }
3783
3783
  callbacks.push(callback);
3784
3784
  }
3785
- // version: 1.112.1-1a0875b1d
3785
+ // version: 1.113.0-a8af103c9
3786
3786
 
3787
3787
  // TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
3788
3788
  function instrumentAdapter$1(createFunction, _metadata) {
@@ -15206,7 +15206,7 @@
15206
15206
  updateReferenceMapWithKnownKey(ast, luvioDocumentNode);
15207
15207
  return luvioDocumentNode;
15208
15208
  }
15209
- // version: 1.112.1-1a0875b1d
15209
+ // version: 1.113.0-a8af103c9
15210
15210
 
15211
15211
  function unwrap(data) {
15212
15212
  // The lwc-luvio bindings import a function from lwc called "unwrap".
@@ -16119,7 +16119,7 @@
16119
16119
  const { apiFamily, name } = metadata;
16120
16120
  return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
16121
16121
  }
16122
- // version: 1.112.1-1a0875b1d
16122
+ // version: 1.113.0-a8af103c9
16123
16123
 
16124
16124
  /**
16125
16125
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -44307,7 +44307,7 @@
44307
44307
  dropFunction: instrumentation$2.notifyRecordUpdateAvailableDropped,
44308
44308
  });
44309
44309
  });
44310
- // version: 1.112.1-1a0875b1d
44310
+ // version: 1.113.0-a8af103c9
44311
44311
 
44312
44312
  var caseSensitiveUserId = '005B0000000GR4OIAW';
44313
44313
 
@@ -58318,8 +58318,6 @@
58318
58318
  }
58319
58319
  function reportPrimingError(errorType, recordCount) {
58320
58320
  }
58321
- function reportPrimingSuccess(recordCount) {
58322
- }
58323
58321
 
58324
58322
  function instrumentDraftQueue(queue) {
58325
58323
  queue.registerOnChangedListener((draftQueueEvent) => {
@@ -59209,8 +59207,14 @@
59209
59207
  }
59210
59208
  // pop any pending work off the queue
59211
59209
  const batches = typedBatches.splice(0, typedBatches.length);
59210
+ const before = Date.now();
59212
59211
  // fetch the metadata for the batches
59213
- const { availableBatches, unavailableTypes, unavailableIds } = await this.fetchMetadata(batches);
59212
+ const { availableBatches, unavailableTypes, unavailableIds, availableTypes } = await this.fetchMetadata(batches);
59213
+ this.emit('metadata-fetched', {
59214
+ duration: Date.now() - before,
59215
+ availableTypes,
59216
+ unavailableTypes,
59217
+ });
59214
59218
  if (unavailableIds.length > 0) {
59215
59219
  this.emit('error', {
59216
59220
  ids: unavailableIds,
@@ -59229,14 +59233,21 @@
59229
59233
  // parallelizes batches of priming work
59230
59234
  enqueueBatches(batches) {
59231
59235
  for (const batch of batches) {
59236
+ const queuedTime = Date.now();
59232
59237
  this.networkWorkerPool.push({
59233
59238
  workFn: (abortController) => {
59239
+ const workTime = Date.now();
59240
+ this.emit('batch-starting', { queuedTime: workTime - queuedTime });
59234
59241
  return this.recordLoader
59235
59242
  .fetchRecordData(batch, abortController)
59236
59243
  .then(async (result) => {
59237
59244
  if (abortController.signal.aborted) {
59238
59245
  return;
59239
59246
  }
59247
+ this.emit('batch-fetched', {
59248
+ ids: batch.ids,
59249
+ duration: Date.now() - workTime,
59250
+ });
59240
59251
  if (result.ok === false) {
59241
59252
  const { error } = result;
59242
59253
  const primingError = error === 'network-error' ? 'service-unavailable' : 'unknown';
@@ -59256,13 +59267,31 @@
59256
59267
  });
59257
59268
  }
59258
59269
  const { records } = result;
59270
+ const beforeWrite = Date.now();
59259
59271
  // dispatch the write but DO NOT wait on it to unblock the network pool
59260
59272
  this.recordIngestor
59261
59273
  .insertRecords(records)
59262
- .then(({ written, conflicted }) => {
59274
+ .then(({ written, conflicted, errors }) => {
59275
+ this.emit('batch-written', {
59276
+ written,
59277
+ conflicted,
59278
+ errors: errors
59279
+ .map((e) => e.ids)
59280
+ .reduce((a, b) => a.concat(b), []),
59281
+ duration: Date.now() - beforeWrite,
59282
+ });
59263
59283
  if (abortController.signal.aborted) {
59264
59284
  return;
59265
59285
  }
59286
+ if (errors.length > 0) {
59287
+ errors.forEach(({ ids, message }) => {
59288
+ this.emit('error', {
59289
+ ids,
59290
+ code: 'unknown',
59291
+ message: message,
59292
+ });
59293
+ });
59294
+ }
59266
59295
  // now that the records are persisted, emit the primed event
59267
59296
  if (written.length > 0) {
59268
59297
  this.emit('primed', Array.from(written));
@@ -59295,6 +59324,7 @@
59295
59324
  }, new Set()));
59296
59325
  const objectInfoMap = await this.objectInfoLoader.getObjectInfos(apiNames);
59297
59326
  const unavailableTypes = apiNames.filter((x) => !objectInfoMap[x]);
59327
+ const availableTypes = apiNames.filter((x) => objectInfoMap[x]);
59298
59328
  const unavilableBatches = batches.filter((x) => unavailableTypes.includes(x.type));
59299
59329
  const availableBatches = batches.filter((x) => !unavailableTypes.includes(x.type));
59300
59330
  const unavailableIds = unavilableBatches.reduce((acc, x) => {
@@ -59302,9 +59332,11 @@
59302
59332
  return acc;
59303
59333
  }, []);
59304
59334
  return {
59335
+ apiNames,
59305
59336
  availableBatches,
59306
59337
  unavilableBatches,
59307
59338
  unavailableTypes,
59339
+ availableTypes,
59308
59340
  unavailableIds,
59309
59341
  };
59310
59342
  }
@@ -59464,44 +59496,28 @@
59464
59496
  */
59465
59497
  async insertRecords(syntheticRecords) {
59466
59498
  if (syntheticRecords.length === 0) {
59467
- return { written: [], conflicted: [] };
59499
+ return { written: [], conflicted: [], errors: [] };
59468
59500
  }
59469
59501
  const luvio = this.getLuvio();
59470
59502
  const ingestionTimestamp = Date.now();
59471
59503
  const ttlOverride = await luvio.storeGetTTLOverride(keyPrefix$1, RepresentationType$N);
59472
- const metadata = JSON.stringify({
59504
+ const metadata = {
59473
59505
  ingestionTimestamp,
59474
59506
  expirationTimestamp: (ttlOverride !== null && ttlOverride !== void 0 ? ttlOverride : TTL$v) + ingestionTimestamp,
59475
59507
  namespace: keyPrefix$1,
59476
59508
  representationName: RepresentationType$N,
59477
59509
  metadataVersion: DURABLE_METADATA_VERSION,
59478
59510
  version: VERSION$14,
59479
- });
59480
- const idsToPrime = new Set();
59481
- const written = [];
59482
- const rows = syntheticRecords.map((record) => {
59483
- idsToPrime.add(record.id);
59484
- return `('${keyBuilder$1Q(luvio, { recordId: record.id })}', '${JSON.stringify(record)}', '${metadata}')`;
59485
- });
59486
- const dml = `INSERT or IGNORE INTO lds_data (key, data, metadata) VALUES ${rows.join(',\n')} returning key;`;
59487
- const result = await this.store.query(dml, []);
59488
- for (const row of result.rows) {
59489
- const id = extractRecordIdFromStoreKey(row[0]);
59490
- if (id) {
59491
- written.push(id);
59492
- idsToPrime.delete(id);
59493
- }
59494
- }
59495
- return { written: Array.from(written), conflicted: Array.from(idsToPrime) };
59511
+ };
59512
+ return this.store.writeRecords(syntheticRecords.map((record) => ({ record, metadata })));
59496
59513
  }
59497
59514
  }
59498
59515
 
59499
59516
  function instrumentPrimingSession(session) {
59500
- session.on('error', (payload) => {
59501
- reportPrimingError(payload.code, payload.ids.length);
59517
+ session.on('error', ({ code, ids }) => {
59518
+ reportPrimingError(code, ids.length);
59502
59519
  });
59503
- session.on('primed', (payload) => {
59504
- reportPrimingSuccess(payload.length);
59520
+ session.on('primed', ({ length }) => {
59505
59521
  });
59506
59522
  return session;
59507
59523
  }
@@ -59554,11 +59570,78 @@
59554
59570
  }
59555
59571
  }
59556
59572
 
59573
+ // ref: https://gnome.pages.gitlab.gnome.org/tracker/docs/developer/limits.html?gi-language=c
59574
+ const SQLITE_MAX_VARIABLE_NUMBER = 999;
59575
+ const PARAMS_PER_RECORD = 3;
59576
+ // We need to batch the records to avoid hitting the SQLITE_MAX_VARIABLE_NUMBER limit. Each record has 3 parameters
59577
+ const BATCH_SIZE = Math.floor(SQLITE_MAX_VARIABLE_NUMBER / PARAMS_PER_RECORD);
59578
+ class SqlitePrimingStore {
59579
+ constructor(getLuvio, store) {
59580
+ this.getLuvio = getLuvio;
59581
+ this.store = store;
59582
+ }
59583
+ async writeRecords(records) {
59584
+ const batches = batchArray(records);
59585
+ const writeResult = { written: [], conflicted: [], errors: [] };
59586
+ return (await Promise.all(batches.map((batch) => this.writeBatch(batch)))).reduce((acc, curr) => {
59587
+ acc.written.push(...curr.written);
59588
+ acc.conflicted.push(...curr.conflicted);
59589
+ acc.errors.push(...curr.errors);
59590
+ return acc;
59591
+ }, writeResult);
59592
+ }
59593
+ async writeBatch(records) {
59594
+ const idsToPrime = new Set();
59595
+ const written = [];
59596
+ const statement = `INSERT or IGNORE INTO lds_data (key, data, metadata) VALUES ${records
59597
+ .map((_) => `(?,?,?)`)
59598
+ .join(',')} returning key;`;
59599
+ const params = [];
59600
+ records.forEach(({ record, metadata }) => {
59601
+ idsToPrime.add(record.id);
59602
+ const key = keyBuilder$1Q(this.getLuvio(), { recordId: record.id });
59603
+ params.push(key);
59604
+ params.push(JSON.stringify(record));
59605
+ params.push(JSON.stringify(metadata));
59606
+ });
59607
+ try {
59608
+ const result = await this.store.query(statement, params);
59609
+ for (const row of result.rows) {
59610
+ const id = extractRecordIdFromStoreKey(row[0]);
59611
+ if (id) {
59612
+ written.push(id);
59613
+ idsToPrime.delete(id);
59614
+ }
59615
+ }
59616
+ return { written, conflicted: Array.from(idsToPrime), errors: [] };
59617
+ }
59618
+ catch (e) {
59619
+ return {
59620
+ written: [],
59621
+ conflicted: [],
59622
+ errors: [{ ids: Array.from(idsToPrime), message: e }],
59623
+ };
59624
+ }
59625
+ }
59626
+ }
59627
+ function batchArray(arr, batchSize = BATCH_SIZE) {
59628
+ const batches = [];
59629
+ // If the array length is less than or equal to the batch size, return the array as a single batch
59630
+ if (arr.length <= batchSize) {
59631
+ return [arr];
59632
+ }
59633
+ // Split the array into batches of size batchSize
59634
+ for (let i = 0; i < arr.length; i += batchSize) {
59635
+ batches.push(arr.slice(i, i + batchSize));
59636
+ }
59637
+ return batches;
59638
+ }
59639
+
59557
59640
  function primingSessionFactory(config) {
59558
59641
  const { store, objectInfoService, getLuvio } = config;
59559
59642
  const networkAdapter = new NimbusPrimingNetworkAdapter();
59560
59643
  const recordLoader = new RecordLoaderGraphQL(networkAdapter);
59561
- const recordIngestor = new RecordIngestor(store, getLuvio);
59644
+ const recordIngestor = new RecordIngestor(new SqlitePrimingStore(getLuvio, store), getLuvio);
59562
59645
  const session = new PrimingSession({
59563
59646
  recordLoader,
59564
59647
  recordIngestor,
@@ -59701,7 +59784,7 @@
59701
59784
  id: '@salesforce/lds-network-adapter',
59702
59785
  instrument: instrument$1,
59703
59786
  });
59704
- // version: 1.112.1-1a0875b1d
59787
+ // version: 1.113.0-a8af103c9
59705
59788
 
59706
59789
  const { create: create$2, keys: keys$2 } = Object;
59707
59790
  const { stringify: stringify$1, parse: parse$1 } = JSON;
@@ -77427,7 +77510,7 @@
77427
77510
  configuration: { ...configurationForGraphQLAdapters },
77428
77511
  instrument,
77429
77512
  });
77430
- // version: 1.112.1-1a0875b1d
77513
+ // version: 1.113.0-a8af103c9
77431
77514
 
77432
77515
  // On core the unstable adapters are re-exported with different names,
77433
77516
 
@@ -79556,7 +79639,7 @@
79556
79639
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
79557
79640
  graphQLImperative = ldsAdapter;
79558
79641
  });
79559
- // version: 1.112.1-1a0875b1d
79642
+ // version: 1.113.0-a8af103c9
79560
79643
 
79561
79644
  var gqlApi = /*#__PURE__*/Object.freeze({
79562
79645
  __proto__: null,
@@ -80223,6 +80306,9 @@
80223
80306
  return {
80224
80307
  enqueue: session.enqueue.bind(session),
80225
80308
  cancel: session.cancel.bind(session),
80309
+ on: session.on.bind(session),
80310
+ once: session.once.bind(session),
80311
+ off: session.off.bind(session),
80226
80312
  };
80227
80313
  }
80228
80314
 
@@ -80248,4 +80334,4 @@
80248
80334
  Object.defineProperty(exports, '__esModule', { value: true });
80249
80335
 
80250
80336
  }));
80251
- // version: 1.112.1-1a0875b1d
80337
+ // version: 1.113.0-a8af103c9
@@ -16,5 +16,8 @@ export interface PrimingSessionConfig {
16
16
  export declare function createPrimingSession(config: PrimingSessionConfig): {
17
17
  enqueue: (work: PrimingWork) => Promise<void>;
18
18
  cancel: () => void;
19
+ on: <K extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K]) => void) => import("@salesforce/lds-priming").PrimingSession;
20
+ once: <K_1 extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K_1, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K_1]) => void) => import("@salesforce/lds-priming").PrimingSession;
21
+ off: <K_2 extends keyof import("@salesforce/lds-priming").PrimingEvents>(eventName: K_2, callback: (payload: import("@salesforce/lds-priming").PrimingEvents[K_2]) => void) => import("@salesforce/lds-priming").PrimingSession;
19
22
  };
20
23
  export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-worker-api",
3
- "version": "1.112.1",
3
+ "version": "1.113.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "",
6
6
  "main": "dist/standalone/umd/lds-worker-api.js",
@@ -37,15 +37,15 @@
37
37
  "@luvio/engine": "0.137.1",
38
38
  "@luvio/environments": "0.137.1",
39
39
  "@oat-sa/rollup-plugin-wildcard-external": "^0.1.0",
40
- "@salesforce/lds-adapters-graphql": "^1.112.1",
41
- "@salesforce/lds-adapters-uiapi": "^1.112.1",
42
- "@salesforce/lds-default-luvio": "^1.112.1",
43
- "@salesforce/lds-drafts": "^1.112.1",
44
- "@salesforce/lds-graphql-parser": "^1.112.1",
45
- "@salesforce/lds-luvio-engine": "^1.112.1",
46
- "@salesforce/lds-priming": "^1.112.1",
47
- "@salesforce/lds-runtime-mobile": "^1.112.1",
48
- "@salesforce/nimbus-plugin-lds": "^1.112.1",
40
+ "@salesforce/lds-adapters-graphql": "^1.113.0",
41
+ "@salesforce/lds-adapters-uiapi": "^1.113.0",
42
+ "@salesforce/lds-default-luvio": "^1.113.0",
43
+ "@salesforce/lds-drafts": "^1.113.0",
44
+ "@salesforce/lds-graphql-parser": "^1.113.0",
45
+ "@salesforce/lds-luvio-engine": "^1.113.0",
46
+ "@salesforce/lds-priming": "^1.113.0",
47
+ "@salesforce/lds-runtime-mobile": "^1.113.0",
48
+ "@salesforce/nimbus-plugin-lds": "^1.113.0",
49
49
  "ajv": "^8.11.0",
50
50
  "glob": "^7.1.5",
51
51
  "nimbus-types": "^2.0.0-alpha1",
@@ -1,3 +1,5 @@
1
+ /*eslint-env es2020 */
2
+
1
3
  let rows = [];
2
4
  let workOrderRecordId;
3
5
  for (let i = 1; i <= 500; i++) {
@@ -234,7 +236,7 @@ for (let i = 1; i <= 500; i++) {
234
236
  ]);
235
237
  }
236
238
 
237
- global.__nimbus.plugins.LdsSqliteStore.batchOperations(
239
+ globalThis.__nimbus.plugins.LdsSqliteStore.batchOperations(
238
240
  [
239
241
  {
240
242
  type: 'upsert',