@salesforce/lds-worker-api 1.303.0 → 1.304.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.
@@ -4265,7 +4265,7 @@ function withDefaultLuvio(callback) {
4265
4265
  }
4266
4266
  callbacks.push(callback);
4267
4267
  }
4268
- // version: 1.303.0-a698c7cc67
4268
+ // version: 1.304.0-aa3e5f9550
4269
4269
 
4270
4270
  // TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
4271
4271
  function instrumentAdapter$1(createFunction, _metadata) {
@@ -15764,7 +15764,7 @@ function gql(literals, ...subs) {
15764
15764
  }
15765
15765
  return superResult;
15766
15766
  }
15767
- // version: 1.303.0-a698c7cc67
15767
+ // version: 1.304.0-aa3e5f9550
15768
15768
 
15769
15769
  function unwrap(data) {
15770
15770
  // The lwc-luvio bindings import a function from lwc called "unwrap".
@@ -16693,7 +16693,7 @@ function createGraphQLWireAdapterConstructor(luvio, adapter, metadata, astResolv
16693
16693
  const { apiFamily, name } = metadata;
16694
16694
  return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
16695
16695
  }
16696
- // version: 1.303.0-a698c7cc67
16696
+ // version: 1.304.0-aa3e5f9550
16697
16697
 
16698
16698
  /**
16699
16699
  * Copyright (c) 2022, Salesforce, Inc.,
@@ -20522,6 +20522,12 @@ function readFieldStateFromValueNode(fieldNode) {
20522
20522
  }
20523
20523
  return fieldNode.__state.fields;
20524
20524
  }
20525
+ function writeFieldStateNodeValue(fieldNode, propertyName, value) {
20526
+ const node = fieldNode;
20527
+ const state = node.__state || {};
20528
+ state[propertyName] = value;
20529
+ node.write('__state', state);
20530
+ }
20525
20531
 
20526
20532
  const CUSTOM_API_NAME_SUFFIX = '__c';
20527
20533
  const DMO_API_NAME_SUFFIX = '__dlm';
@@ -20570,7 +20576,7 @@ function extractTrackedFieldsToTrie(recordId, node, root) {
20570
20576
  name: key,
20571
20577
  children: {},
20572
20578
  };
20573
- if (isMissing(fieldRep)) {
20579
+ if (fields.isMissing(key)) {
20574
20580
  current.children[key] = next;
20575
20581
  continue;
20576
20582
  }
@@ -20629,14 +20635,6 @@ function convertTrieToFieldsRecursively(root) {
20629
20635
  }
20630
20636
  return reduce$2.call(childKeys, (acc, cur) => concat$2.call(acc, convertTrieToFieldsRecursively(root.children[cur]).map((i) => `${root.name}.${i}`)), []);
20631
20637
  }
20632
- function isMissing(node) {
20633
- // TODO [W-15867870]: JHORST add support for isMissing on graphnode object
20634
- return node.data && node.data.__state && node.data.__state.isMissing === true;
20635
- }
20636
- function isPending(node) {
20637
- // TODO [W-15867870]: JHORST add support for pending on graphnode object
20638
- return node.data && node.data.__state && node.data.__state.pending === true;
20639
- }
20640
20638
  const BLANK_RECORD_FIELDS_TRIE = freeze$4({
20641
20639
  name: '',
20642
20640
  children: {},
@@ -20728,8 +20726,9 @@ function markNulledOutPath(record, path) {
20728
20726
  !isFrozen$2(resolved.data)) {
20729
20727
  const stateFields = readFieldStateFromValueNode(resolved.data);
20730
20728
  const fields = stateFields === undefined ? [] : stateFields;
20731
- // TODO [W-15838292]: JHORST add support for node state on graphnode object
20732
- resolved.write('__state', { fields: dedupe$2([...fields, path.join('.')]) });
20729
+ // Note that GraphNodes are frozen when NODE_ENV != production.
20730
+ // Use with care.
20731
+ writeFieldStateNodeValue(resolved, 'fields', dedupe$2([...fields, path.join('.')]));
20733
20732
  }
20734
20733
  }
20735
20734
  function markNulledOutRequiredFields(record, fields) {
@@ -20756,7 +20755,7 @@ function _markMissingPath(record, path) {
20756
20755
  return;
20757
20756
  }
20758
20757
  const fieldValueValue = fieldValueRepresentation.object(fieldName);
20759
- if (isPending(fieldValueValue)) {
20758
+ if (fieldValueRepresentation.isPending(fieldName)) {
20760
20759
  writeMissingFieldToStore(fieldValueRepresentation, fieldName);
20761
20760
  return;
20762
20761
  }
@@ -20786,7 +20785,8 @@ function _markMissingPath(record, path) {
20786
20785
  function writeMissingFieldToStore(field, fieldName) {
20787
20786
  // TODO [W-6900046]: remove cast, make RecordRepresentationNormalized['fields'] accept
20788
20787
  // an undefined/non-present __ref if isMissing is present
20789
- // TODO [W-15867870]: JHORST add support for isMissing on graphnode object
20788
+ // Note that GraphNodes are frozen when NODE_ENV != production.
20789
+ // Use with care.
20790
20790
  field.write(fieldName, {
20791
20791
  __state: {
20792
20792
  isMissing: true,
@@ -44186,7 +44186,7 @@ withDefaultLuvio((luvio) => {
44186
44186
  throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
44187
44187
  throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
44188
44188
  });
44189
- // version: 1.303.0-b6ed223d95
44189
+ // version: 1.304.0-d87b57badb
44190
44190
 
44191
44191
  var ldsIdempotencyWriteDisabled = {
44192
44192
  isOpen: function (e) {
@@ -50068,6 +50068,31 @@ class DurableDraftQueue {
50068
50068
  await this.startQueue();
50069
50069
  }
50070
50070
  }
50071
+ async updateDraftAction(action) {
50072
+ // stop queue manually
50073
+ this.stopQueueManually();
50074
+ const actionStatus = await this.statusOfAction(action.id);
50075
+ if (actionStatus === DraftActionStatus.Uploading) {
50076
+ return Promise.reject('cannot update an uploading action');
50077
+ }
50078
+ // save the action into the draft store
50079
+ await this.draftStore.writeAction(action);
50080
+ // make the handler replay these drafts on the record
50081
+ const handler = this.getHandler(action.handler);
50082
+ const queue = await this.getQueueActions();
50083
+ await handler.handleActionEnqueued(action, queue);
50084
+ // start queue safely
50085
+ return this.startQueueSafe();
50086
+ }
50087
+ async statusOfAction(actionId) {
50088
+ const queue = await this.getQueueActions();
50089
+ const actions = queue.filter((action) => action.id === actionId);
50090
+ if (actions.length === 0) {
50091
+ return Promise.reject('cannot update non-existent action');
50092
+ }
50093
+ const action = actions[0];
50094
+ return action.status;
50095
+ }
50071
50096
  replaceAction(targetActionId, sourceActionId) {
50072
50097
  return this.replaceOrMergeActions(targetActionId, sourceActionId, false);
50073
50098
  }
@@ -51057,6 +51082,60 @@ class DraftManager {
51057
51082
  };
51058
51083
  });
51059
51084
  }
51085
+ async mergePerformQuickAction(actionId, fields) {
51086
+ if (!this.isValidFieldMap(fields)) {
51087
+ return Promise.reject('fields is not valid');
51088
+ }
51089
+ const queue = await this.draftQueue.getQueueActions();
51090
+ const actions = queue.filter((action) => action.id === actionId);
51091
+ if (actions.length === 0) {
51092
+ return Promise.reject('cannot edit non-existent action');
51093
+ }
51094
+ const action = actions[0];
51095
+ if (!this.isPerformQuickActionDraft(action, 'post')) {
51096
+ return Promise.reject('cannot edit incompatible action type or uploading actions');
51097
+ }
51098
+ action.data.body.fields = { ...action.data.body.fields, ...fields };
51099
+ await this.draftQueue.updateDraftAction(action);
51100
+ return this.buildDraftQueueItem(action);
51101
+ }
51102
+ isValidFieldMap(fields) {
51103
+ const keys$1 = keys$6(fields);
51104
+ const validTypes = ['string', 'number', 'null', 'boolean'];
51105
+ for (let i = 0; i < keys$1.length; i++) {
51106
+ const key = keys$1[i];
51107
+ const value = fields[key];
51108
+ if (!validTypes.includes(typeof value)) {
51109
+ return false;
51110
+ }
51111
+ }
51112
+ return true;
51113
+ }
51114
+ isPerformQuickActionDraft(action, method) {
51115
+ const data = action.data;
51116
+ const isPerformQuickAction = data.basePath.startsWith('/ui-api/actions/perform-quick-action/');
51117
+ const methodMatches = data.method === method;
51118
+ const notUploading = action.status !== DraftActionStatus.Uploading;
51119
+ return isPerformQuickAction && methodMatches && notUploading;
51120
+ }
51121
+ async mergePerformUpdateRecordQuickAction(actionId, fields) {
51122
+ if (!this.isValidFieldMap(fields)) {
51123
+ return Promise.reject('fields is not valid');
51124
+ }
51125
+ const queue = await this.draftQueue.getQueueActions();
51126
+ const actions = queue.filter((action) => action.id === actionId);
51127
+ if (actions.length === 0) {
51128
+ return Promise.reject('cannot edit non-existent action');
51129
+ }
51130
+ const action = actions[0];
51131
+ if (!this.isPerformQuickActionDraft(action, 'patch')) {
51132
+ return Promise.reject('cannot edit incompatible action type or uploading actions');
51133
+ }
51134
+ const data = action.data;
51135
+ data.body.fields = { ...data.body.fields, ...fields };
51136
+ await this.draftQueue.updateDraftAction(action);
51137
+ return this.buildDraftQueueItem(action);
51138
+ }
51060
51139
  buildDraftQueueItem(action) {
51061
51140
  const operationType = getOperationTypeFrom(action);
51062
51141
  const { id, status, timestamp, targetId, metadata } = action;
@@ -51364,6 +51443,12 @@ function getDenormalizedRecord(recordKey, durableStore) {
51364
51443
  function isStoreRecordError(storeRecord) {
51365
51444
  return storeRecord.__type === 'error';
51366
51445
  }
51446
+ function isDraftFieldPending(field) {
51447
+ return !!(field.__state && field.__state.pending === true);
51448
+ }
51449
+ function isDraftFieldMissing(field) {
51450
+ return !!(field.__state && field.__state.isMissing === true);
51451
+ }
51367
51452
 
51368
51453
  /**
51369
51454
  * Checks if a resource request is a GET method on the record endpoint
@@ -52055,12 +52140,9 @@ function applyReferenceLinksToDraft(record, draftMetadata) {
52055
52140
  }
52056
52141
  const { dataType, relationshipName, referenceToInfos } = fieldInfo;
52057
52142
  const draftFieldNode = record.fields[draftField];
52058
- // JHORST: revisit this logic
52059
52143
  // do not try to apply drafts on nodes that are pending or missing
52060
- if (draftFieldNode.__state !== undefined) {
52061
- if (draftFieldNode.__state.pending === true ||
52062
- draftFieldNode.__state.isMissing === true)
52063
- continue;
52144
+ if (isDraftFieldPending(draftFieldNode) || isDraftFieldMissing(draftFieldNode)) {
52145
+ continue;
52064
52146
  }
52065
52147
  const draftFieldValue = draftFieldNode.value;
52066
52148
  if (dataType === 'Reference' && relationshipName !== null) {
@@ -53051,7 +53133,29 @@ function isCreateContentDocumentAndVersionDraftAdapterEvent(customEvent) {
53051
53133
  return customEvent.namespace === CONTENT_DOCUMENT_AND_VERSION_NAMESPACE;
53052
53134
  }
53053
53135
 
53136
+ // so eslint doesn't complain about nimbus
53137
+ /* global __nimbus */
53054
53138
  const ContentDocumentCompositeKeyPrefix = 'UiApi::ContentDocumentCompositeRepresentation:';
53139
+ function chunkToBase64(chunk) {
53140
+ let binary = '';
53141
+ const chunkSize = 32 * 1024;
53142
+ for (let i = 0; i < chunk.length; i += chunkSize) {
53143
+ binary += String.fromCharCode.apply(null, chunk.subarray(i, i + chunkSize));
53144
+ }
53145
+ return btoa(binary);
53146
+ }
53147
+ async function streamBufferToBinaryStore(binaryStore, buffer, mimeType) {
53148
+ const uri = await binaryStore.createStream(mimeType);
53149
+ const bufferSize = 64 * 1024; // 64k buffer size
53150
+ const uint8Array = new Uint8Array(buffer);
53151
+ for (let offset = 0; offset < uint8Array.length; offset += bufferSize) {
53152
+ const chunk = uint8Array.subarray(offset, Math.min(offset + bufferSize, uint8Array.length));
53153
+ const base64Chunk = chunkToBase64(chunk);
53154
+ await binaryStore.writeToStream(uri, base64Chunk);
53155
+ }
53156
+ await binaryStore.closeStream(uri);
53157
+ return uri;
53158
+ }
53055
53159
  function createContentDocumentAndVersionDraftAdapterFactory(luvio, binaryStore, actionHandler) {
53056
53160
  const overriddenLuvio = buildLuvioOverrideForDraftAdapters(luvio, actionHandler, (key) => {
53057
53161
  // if the key is for our top-level response shape
@@ -53074,7 +53178,14 @@ function createContentDocumentAndVersionDraftAdapterFactory(luvio, binaryStore,
53074
53178
  const { fileData } = config;
53075
53179
  const { name, size, type } = fileData;
53076
53180
  const buffer = await fileData.arrayBuffer();
53077
- const uri = await binaryStore.store(new Uint8Array(buffer), type, size);
53181
+ var uri;
53182
+ // see if new chunking-api exists, if it doesnt fall back to memory-intensive mobile api
53183
+ if (!__nimbus.plugins.LdsBinaryStorePlugin.createStream) {
53184
+ uri = await binaryStore.store(new Uint8Array(buffer), type, size);
53185
+ }
53186
+ else {
53187
+ uri = await streamBufferToBinaryStore(binaryStore, buffer, type);
53188
+ }
53078
53189
  config.fileData = {
53079
53190
  isFileReference: true,
53080
53191
  handle: uri,
@@ -53913,7 +54024,7 @@ function recordLoaderFactory(query) {
53913
54024
  return new DataLoader(batchRecordQuery);
53914
54025
  }
53915
54026
 
53916
- function createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions) {
54027
+ function createContext(store, objectInfos, eventEmitter, settings, snapshot, mappedCursors = new Map(), draftFunctions) {
53917
54028
  store.query.bind(store);
53918
54029
  const query = (sql, params) => {
53919
54030
  const now = Date.now();
@@ -53940,7 +54051,9 @@ function createContext(store, objectInfos, eventEmitter, settings, snapshot, dra
53940
54051
  Record,
53941
54052
  snapshot,
53942
54053
  seenRecordIds: new Set(),
54054
+ possibleStaleRecordMap: new Map(),
53943
54055
  draftFunctions,
54056
+ mappedCursors,
53944
54057
  };
53945
54058
  }
53946
54059
 
@@ -54551,7 +54664,6 @@ function isTodayStartOfWeek() {
54551
54664
 
54552
54665
  const JSON_EXTRACT_PATH_INGESTION_TIMESTAMP = '$.ingestionTimestamp';
54553
54666
  const JSON_EXTRACT_PATH_INGESTION_APINAME = '$.apiName';
54554
- const JSON_EXTRACT_PATH_DRAFTS = '$.drafts';
54555
54667
 
54556
54668
  const MultiPickListValueSeparator = ';';
54557
54669
  function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
@@ -55092,14 +55204,10 @@ function buildQuery(config) {
55092
55204
  const predicates = buildPredicates(config);
55093
55205
  const orderBy = buildOrderBy(config);
55094
55206
  const sql = `
55095
- SELECT "${config.alias}".data
55207
+ SELECT "${config.alias}".data, "${config.alias}".metadata
55096
55208
  FROM lds_data "${config.alias}" ${joins.sql}
55097
55209
  WHERE "${config.alias}".key like 'UiApi::RecordRepresentation:%'
55098
55210
  AND json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_INGESTION_APINAME}') = '${config.alias}'
55099
- AND (
55100
- json_extract("${config.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ?
55101
- OR json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL
55102
- )
55103
55211
  ${predicates.sql}
55104
55212
  ${orderBy.sql}
55105
55213
  LIMIT ?
@@ -55111,7 +55219,6 @@ function buildQuery(config) {
55111
55219
  const bindings = [
55112
55220
  // bindings from predicates on joins
55113
55221
  ...joins.bindings,
55114
- config.ingestionTimestamp,
55115
55222
  // where clause and parent scope bindings
55116
55223
  ...predicates.bindings,
55117
55224
  // limit binding
@@ -55138,29 +55245,19 @@ function buildJoins(config) {
55138
55245
  if (allJoins.length === 0)
55139
55246
  return { sql, bindings };
55140
55247
  sql = allJoins.reduce((joinAccumulator, join) => {
55141
- let timestampAdded = false;
55142
55248
  const joinConditions = join.conditions.reduce((conditionAccumulator, condition) => {
55143
55249
  let joined_sql;
55144
- const joinMetadataTimestamp = ` AND (json_extract("${join.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ? OR json_extract("${join.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL)`;
55145
55250
  // predicate on a value, use the newly joined table
55146
55251
  if ('type' in condition) {
55147
55252
  const { sql, binding } = predicateToSQL(condition, join.alias);
55148
- joined_sql = ` AND ${sql}${timestampAdded ? '' : joinMetadataTimestamp}`;
55253
+ joined_sql = ` AND ${sql}`;
55149
55254
  bindings.push(...binding);
55150
- if (timestampAdded === false) {
55151
- bindings.push(config.ingestionTimestamp);
55152
- timestampAdded = true;
55153
- }
55154
55255
  }
55155
55256
  else {
55156
55257
  // predicate on a path
55157
55258
  const left = ` AND json_extract("${join.to}".data, '${condition.leftPath}')`;
55158
55259
  const right = `json_extract("${join.alias}".data, '${condition.rightPath}')`;
55159
- joined_sql = `${left} = ${right}${timestampAdded ? '' : joinMetadataTimestamp}`;
55160
- if (timestampAdded === false) {
55161
- bindings.push(config.ingestionTimestamp);
55162
- timestampAdded = true;
55163
- }
55260
+ joined_sql = `${left} = ${right}`;
55164
55261
  }
55165
55262
  conditionAccumulator += joined_sql;
55166
55263
  return conditionAccumulator;
@@ -55829,11 +55926,15 @@ async function readIngestionTimestampForKey(key, query) {
55829
55926
  }
55830
55927
  return ingestionTimestamp;
55831
55928
  }
55832
- async function readPaginationMetadataForKey(key, query) {
55833
- const sql = `SELECT data FROM lds_data WHERE key=?`;
55834
- const results = await query(sql, [key + '__pagination']);
55835
- const [paginationMetadata] = results.rows.map((row) => parse$3(row[0]));
55836
- return paginationMetadata || {};
55929
+ function isObjectDefinitionNode(node) {
55930
+ const { kind } = node;
55931
+ return typeof kind === 'string' && kind === 'OperationDefinition';
55932
+ }
55933
+ function operationNodeAncestor(ancestors) {
55934
+ let operationNode = ancestors.find((a) => {
55935
+ return !(a instanceof Array) && isObjectDefinitionNode(a);
55936
+ });
55937
+ return operationNode;
55837
55938
  }
55838
55939
 
55839
55940
  function findSpanningField(name) {
@@ -56034,44 +56135,87 @@ function atobPolyfill(data) {
56034
56135
  const base64encode = typeof btoa === 'function' ? btoa : btoaPolyfill;
56035
56136
  const base64decode = typeof atob === 'function' ? atob : atobPolyfill;
56036
56137
 
56138
+ // this truthy value is used to indicate a premature end of results
56139
+ const EARLY_END = 1;
56037
56140
  function cursorResolver(source) {
56038
- return encodeV1Cursor(source.index);
56141
+ let cursor = {
56142
+ i: source.index,
56143
+ };
56144
+ if (source.earlyEnd) {
56145
+ cursor.e = EARLY_END;
56146
+ }
56147
+ return encodeV1Cursor(cursor);
56039
56148
  }
56040
56149
  function pageInfoResolver(source) {
56041
56150
  if (source.records.length === 0) {
56151
+ // we may have found no records, but if more exist we need to
56152
+ // return a valid cursor that can be passed as the next `after`
56153
+ if (source.earlyEnd) {
56154
+ return {
56155
+ startCursor: null,
56156
+ endCursor: encodeV1Cursor({
56157
+ i: source.offset,
56158
+ e: EARLY_END,
56159
+ }),
56160
+ hasNextPage: source.hasNextPage,
56161
+ };
56162
+ }
56042
56163
  return {
56043
56164
  startCursor: null,
56044
56165
  endCursor: null,
56045
- hasNextPage: false,
56166
+ hasNextPage: source.hasNextPage,
56046
56167
  };
56047
56168
  }
56048
56169
  let startIndex = source.records[0].index;
56170
+ let startCursor = {
56171
+ i: startIndex,
56172
+ };
56049
56173
  let endIndex = source.records[source.records.length - 1].index;
56174
+ let endCursor = {
56175
+ i: endIndex,
56176
+ };
56177
+ if (source.earlyEnd) {
56178
+ startCursor.e = EARLY_END;
56179
+ endCursor.e = EARLY_END;
56180
+ }
56050
56181
  return {
56051
- startCursor: encodeV1Cursor(startIndex),
56052
- endCursor: encodeV1Cursor(endIndex),
56182
+ startCursor: encodeV1Cursor(startCursor),
56183
+ endCursor: encodeV1Cursor(endCursor),
56053
56184
  hasNextPage: source.hasNextPage,
56054
56185
  };
56055
56186
  }
56056
56187
  function pageResultCountResolver(source) {
56057
56188
  return source.records.length;
56058
56189
  }
56059
- function encodeV1Cursor(index) {
56060
- return base64encode(`v1:${index}`);
56190
+ function isLocalCursor(maybeCursor) {
56191
+ return (!!maybeCursor &&
56192
+ typeof maybeCursor === 'object' &&
56193
+ 'i' in maybeCursor &&
56194
+ typeof maybeCursor.i === 'number');
56195
+ }
56196
+ function encodeV1Cursor(cursor) {
56197
+ return base64encode(stringify$3(cursor));
56061
56198
  }
56062
- const cursorRegex = /^v1:(?<index>\d+)$/;
56199
+ const CURSOR_PARSE_ERROR = 'Unable to parse cursor';
56063
56200
  function decodeV1Cursor(base64cursor) {
56064
- const cursor = base64decode(base64cursor);
56065
- if (!cursor) {
56201
+ let maybeCursor;
56202
+ try {
56203
+ const cursorString = base64decode(base64cursor);
56204
+ maybeCursor = parse$3(cursorString);
56205
+ }
56206
+ catch (error) {
56207
+ let message = CURSOR_PARSE_ERROR;
56208
+ if (error instanceof Error) {
56209
+ message += ': ' + error.message;
56210
+ }
56066
56211
  // eslint-disable-next-line @salesforce/lds/no-error-in-production
56067
- throw new Error('Unable to parse cursor');
56212
+ throw new Error(message);
56068
56213
  }
56069
- const found = cursor.match(cursorRegex);
56070
- if (!found || !found.groups) {
56214
+ if (!isLocalCursor(maybeCursor)) {
56071
56215
  // eslint-disable-next-line @salesforce/lds/no-error-in-production
56072
- throw new Error('Unable to parse cursor');
56216
+ throw new Error(CURSOR_PARSE_ERROR);
56073
56217
  }
56074
- return Number(found.groups.index);
56218
+ return maybeCursor;
56075
56219
  }
56076
56220
  /**
56077
56221
  * Check the selections for any selection matching `pageInfo { hasNextPage }`
@@ -56109,6 +56253,164 @@ function selectionIncludesHasNextPage(selections, fragments) {
56109
56253
  return false;
56110
56254
  }
56111
56255
 
56256
+ const END_CURSOR = '__END__';
56257
+ // find the closest matching cursor in the server pagination metadata
56258
+ function mapCursorValue(originalValue, paginationMetadata) {
56259
+ let mappedValue = null;
56260
+ if (!originalValue) {
56261
+ return mappedValue;
56262
+ }
56263
+ // flip the pagination metadata into an array by index.
56264
+ let cursors = [];
56265
+ for (const [cursor, index] of Object.entries(paginationMetadata)) {
56266
+ if (index === undefined)
56267
+ continue;
56268
+ cursors[index] = cursor;
56269
+ }
56270
+ let cursor = decodeV1Cursor(originalValue);
56271
+ // cursors containe 1-based indexes, adjust back to 0-based
56272
+ let index = cursor.i - 1;
56273
+ if (
56274
+ // cursor.e being truthy means we had premature end of results and
56275
+ // should pin to the last known server cursor
56276
+ !cursor.e &&
56277
+ // check that the index we have is within the bounds of known cursors
56278
+ index >= 0 &&
56279
+ index < cursors.length &&
56280
+ // and make sure the cursor is not the server end marker
56281
+ cursors[index] !== END_CURSOR) {
56282
+ mappedValue = cursors[index];
56283
+ }
56284
+ else {
56285
+ // in this case, either our local cursor is beyond the max server cursor, or
56286
+ // the local cursor precedes the max server cursor and we ran out of locally
56287
+ // cached results. either way, find the last known server cursor and map to that.
56288
+ for (let i = cursors.length; i > 0; --i) {
56289
+ let cursor = cursors[i - 1];
56290
+ if (cursor !== END_CURSOR) {
56291
+ mappedValue = cursor;
56292
+ break;
56293
+ }
56294
+ }
56295
+ }
56296
+ return mappedValue;
56297
+ }
56298
+ // map all pagination cursors in the document
56299
+ async function mapPaginationCursors(originalAST, variables, store) {
56300
+ // first pass, identify record query cache keys for reading pagination metadata
56301
+ let requiredPaginationMetadataKeys = [];
56302
+ visit$1(originalAST, {
56303
+ Field(node, _key, _parent, _path, ancestors) {
56304
+ // is it a record query?
56305
+ if (!isRecordQuery(node)) {
56306
+ return;
56307
+ }
56308
+ // does it have a defined `after` argument?
56309
+ let after = node.arguments &&
56310
+ node.arguments.find((a) => {
56311
+ return a.name.value === 'after';
56312
+ });
56313
+ if (after && (after.value.kind === 'StringValue' || after.value.kind === 'Variable')) {
56314
+ let operationNode = operationNodeAncestor(ancestors);
56315
+ if (!operationNode) {
56316
+ return false;
56317
+ }
56318
+ let key = buildKeyStringForRecordQuery(operationNode, variables, node.arguments || [], node.name.value);
56319
+ requiredPaginationMetadataKeys.push(key);
56320
+ }
56321
+ // don't need to descend into this node
56322
+ return false;
56323
+ },
56324
+ });
56325
+ // read pagination metadata for identified record queries
56326
+ let paginationMetadataMap = await readPaginationMetadataForKeys(requiredPaginationMetadataKeys, store.query.bind(store));
56327
+ // holds the original cursor values that were mapped back to server cursors
56328
+ let mappedCursors = new Map();
56329
+ // rewrite nodes/variables with mapped cursors now that we read the pagination metadata
56330
+ let ast = visit$1(originalAST, {
56331
+ Field(node, _key, _parent, _path, ancestors) {
56332
+ // is it a record query?
56333
+ if (!isRecordQuery(node)) {
56334
+ // not returning false, we might be in the parent of a record query
56335
+ return;
56336
+ }
56337
+ // does it have a defined `after` argument?
56338
+ if (!node.arguments)
56339
+ return false;
56340
+ let after = node.arguments.find((a) => {
56341
+ return a.name.value === 'after';
56342
+ });
56343
+ if (!after)
56344
+ return false;
56345
+ if (after.value.kind === 'StringValue' || after.value.kind === 'Variable') {
56346
+ let operationNode = operationNodeAncestor(ancestors);
56347
+ if (!operationNode) {
56348
+ return false;
56349
+ }
56350
+ let key = buildKeyStringForRecordQuery(operationNode, variables, node.arguments || [], node.name.value);
56351
+ // pagination metadata may be missing, e.g. due to being offline
56352
+ let paginationMetadata = paginationMetadataMap.get(key) || {};
56353
+ if (after.value.kind === 'StringValue') {
56354
+ let originalValue = after.value.value;
56355
+ mappedCursors.set(key, originalValue);
56356
+ let mappedValue = mapCursorValue(originalValue, paginationMetadata);
56357
+ if (!mappedValue) {
56358
+ // there were no results from the server, remove after argument
56359
+ return {
56360
+ ...node,
56361
+ arguments: node.arguments.filter((a) => a !== after),
56362
+ };
56363
+ }
56364
+ // return a new replacement node
56365
+ return {
56366
+ ...node,
56367
+ arguments: node.arguments.map((a) => {
56368
+ if (a !== after)
56369
+ return a;
56370
+ return {
56371
+ ...a,
56372
+ value: {
56373
+ kind: 'StringValue',
56374
+ value: mappedValue,
56375
+ },
56376
+ };
56377
+ }),
56378
+ };
56379
+ }
56380
+ else if (after.value.kind === 'Variable') {
56381
+ // rewrite the variable
56382
+ let variableName = after.value.name.value;
56383
+ let variableValue = variables[variableName];
56384
+ mappedCursors.set(key, variableValue);
56385
+ let mappedValue = mapCursorValue(variableValue, paginationMetadata);
56386
+ variables[variableName] = mappedValue;
56387
+ }
56388
+ // don't need to descend into this node
56389
+ return false;
56390
+ }
56391
+ },
56392
+ });
56393
+ return {
56394
+ ast,
56395
+ mappedCursors,
56396
+ };
56397
+ }
56398
+ async function readPaginationMetadataForKeys(keys, query) {
56399
+ let metadataMap = new Map();
56400
+ if (keys.length === 0)
56401
+ return metadataMap;
56402
+ const sql = `SELECT key, data FROM lds_data WHERE key in (${Array(keys.length)
56403
+ .fill('?')
56404
+ .join(',')})`;
56405
+ const results = await query(sql, keys.map((k) => k + '__pagination'));
56406
+ for (let row of results.rows) {
56407
+ let key = row[0].replace(/__pagination$/, '');
56408
+ let metadata = parse$3(row[1]);
56409
+ metadataMap.set(key, metadata);
56410
+ }
56411
+ return metadataMap;
56412
+ }
56413
+
56112
56414
  /*
56113
56415
  resolves connections...
56114
56416
  */
@@ -56130,8 +56432,14 @@ async function connectionResolver(obj, args, context, info) {
56130
56432
  const childRelationship = parentObjectInfo &&
56131
56433
  parentObjectInfo.childRelationships.find((rel) => rel.relationshipName === info.fieldName);
56132
56434
  // or emit/throw if we want to report it
56133
- if (!childRelationship)
56134
- return { records: [], hasNextPage: false };
56435
+ if (!childRelationship) {
56436
+ return {
56437
+ records: [],
56438
+ hasNextPage: false,
56439
+ earlyEnd: false,
56440
+ offset: 0,
56441
+ };
56442
+ }
56135
56443
  alias = childRelationship.childObjectApiName;
56136
56444
  childRelationshipFieldName = childRelationship.fieldName;
56137
56445
  }
@@ -56150,7 +56458,12 @@ async function connectionResolver(obj, args, context, info) {
56150
56458
  }
56151
56459
  let offset = 0;
56152
56460
  if (args.after) {
56153
- offset = decodeV1Cursor(args.after) + 1;
56461
+ let originalCursor = context.mappedCursors.get(queryCacheKey);
56462
+ if (!originalCursor) {
56463
+ // eslint-disable-next-line @salesforce/lds/no-error-in-production
56464
+ throw new Error('Internal Error: unable to determine `after` cursor value');
56465
+ }
56466
+ offset = decodeV1Cursor(originalCursor).i;
56154
56467
  }
56155
56468
  // if the query wants to know `hasNextPage` then we need to request 1 additional record
56156
56469
  let selections = info.fieldNodes
@@ -56159,7 +56472,7 @@ async function connectionResolver(obj, args, context, info) {
56159
56472
  let wantsHasNextPage = selectionIncludesHasNextPage(selections, info.fragments);
56160
56473
  let paginationMetadata = undefined;
56161
56474
  if (wantsHasNextPage) {
56162
- paginationMetadata = await readPaginationMetadataForKey(queryCacheKey, query);
56475
+ paginationMetadata = await readPaginationMetadataForKeys([queryCacheKey], query);
56163
56476
  }
56164
56477
  let internalLimit = limit + (wantsHasNextPage ? 1 : 0);
56165
56478
  // Alias starts as entity's ApiName
@@ -56170,36 +56483,60 @@ async function connectionResolver(obj, args, context, info) {
56170
56483
  orderBy: orderByToPredicate(args.orderBy, alias, alias, context.objectInfos),
56171
56484
  limit: internalLimit,
56172
56485
  offset,
56173
- ingestionTimestamp,
56174
56486
  };
56175
56487
  const { sql, bindings } = buildQuery(queryConfig);
56176
56488
  const results = await query(sql, bindings);
56177
56489
  let hasNextPage = false;
56490
+ let earlyEnd = false;
56178
56491
  if (wantsHasNextPage) {
56179
56492
  if (results.rows.length > limit) {
56180
56493
  // more records exist in the cache
56181
56494
  hasNextPage = true;
56182
56495
  results.rows.pop();
56183
56496
  }
56184
- else if (!paginationMetadata || paginationMetadata.__END__ === undefined) {
56497
+ else if (!paginationMetadata ||
56498
+ !paginationMetadata.has(queryCacheKey) ||
56499
+ paginationMetadata.get(queryCacheKey).__END__ === undefined) {
56185
56500
  // more records may exist on the server
56186
56501
  hasNextPage = true;
56502
+ // we hit the end of our local records, so we need to know that we
56503
+ // should start at the end of known server cursors
56504
+ if (results.rows.length < limit) {
56505
+ earlyEnd = true;
56506
+ }
56187
56507
  }
56188
56508
  }
56189
56509
  //map each sql result with the ingestion timestamp to pass it down a level
56190
- let records = results.rows
56191
- .map((row) => parse$3(row[0]))
56192
- .map((recordRepresentation, index) => {
56510
+ let records = results.rows.map((row, index) => {
56511
+ const recordMetadataResult = {
56512
+ recordRepresentation: parse$3(row[0]),
56513
+ metadata: parse$3(row[1]),
56514
+ };
56515
+ const { recordRepresentation, metadata } = recordMetadataResult;
56193
56516
  context.seenRecordIds.add(recordRepresentation.id);
56517
+ if (metadata.ingestionTimestamp < ingestionTimestamp &&
56518
+ recordRepresentation.drafts === undefined) {
56519
+ if (context.possibleStaleRecordMap.has(recordRepresentation.apiName) === false) {
56520
+ context.possibleStaleRecordMap.set(recordRepresentation.apiName, []);
56521
+ }
56522
+ const ids = context.possibleStaleRecordMap.get(recordRepresentation.apiName);
56523
+ if (ids !== undefined) {
56524
+ ids.push(recordRepresentation.id);
56525
+ context.possibleStaleRecordMap.set(recordRepresentation.apiName, ids);
56526
+ }
56527
+ }
56194
56528
  return {
56195
56529
  recordRepresentation,
56196
56530
  ingestionTimestamp,
56197
- index: index + offset,
56531
+ index: index + offset + 1,
56532
+ earlyEnd,
56198
56533
  };
56199
56534
  });
56200
56535
  return {
56201
56536
  records,
56202
56537
  hasNextPage,
56538
+ earlyEnd,
56539
+ offset,
56203
56540
  };
56204
56541
  }
56205
56542
  /**
@@ -56997,7 +57334,7 @@ function getTextAreaType(field) {
56997
57334
  return 'TextAreaValue';
56998
57335
  }
56999
57336
 
57000
- async function evaluate(config, observers, settings, objectInfos, store, snapshot, cache, draftFunctions) {
57337
+ async function evaluate(config, observers, settings, objectInfos, store, snapshot, cache, draftFunctions, mappedCursors) {
57001
57338
  const eventEmitter = createCustomAdapterEventEmitter(GRAPHQL_EVAL_NAMESPACE, observers);
57002
57339
  // this is only wrapped in a try to execute the event after the result was returned
57003
57340
  try {
@@ -57056,7 +57393,7 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
57056
57393
  eventEmitter({ type: 'graphql-preconditions-met' });
57057
57394
  // create the resolver request context, runtime values and functions for
57058
57395
  // resolvers to do their job.
57059
- const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, draftFunctions);
57396
+ const contextValue = createContext(store, objectInfos, eventEmitter, settings, snapshot, mappedCursors, draftFunctions);
57060
57397
  // We're building this from scratch from each request. If this becomes a
57061
57398
  // hotspot we can pull it up and memoize it later
57062
57399
  const schema = createSchemaWithCache(objectInfos, cache);
@@ -57081,7 +57418,11 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
57081
57418
  seenRecordIds.push(queryString);
57082
57419
  });
57083
57420
  }
57084
- return { result, seenRecordIds };
57421
+ return {
57422
+ result,
57423
+ seenRecordIds,
57424
+ possibleStaleRecordMap: contextValue.possibleStaleRecordMap,
57425
+ };
57085
57426
  }
57086
57427
  finally {
57087
57428
  eventEmitter({ type: 'graphql-eval-end' });
@@ -58805,7 +59146,11 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58805
59146
  return async function draftAwareGraphQLAdapter(config, buildCachedSnapshotCachePolicy, buildNetworkSnapshotCachePolicy, requestContext = {}) {
58806
59147
  //create a copy to not accidentally modify the AST in the astResolver map of luvio
58807
59148
  const copy = parse$3(stringify$3(config.query));
59149
+ // the injected ast has extra fields needed for eval in it
58808
59150
  let injectedAST;
59151
+ // the cursor mapped ast is passed upstream so it won't reject on our local cursors
59152
+ let cursorMappedAST;
59153
+ let mappedCursors = new Map();
58809
59154
  let objectInfoNeeded = {};
58810
59155
  let unmappedDraftIDs;
58811
59156
  let internalRequestContext = {
@@ -58821,6 +59166,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58821
59166
  objectInfos: objectInfoNeeded,
58822
59167
  unmappedDraftIDs,
58823
59168
  } = await injectSyntheticFields(copy, objectInfoService, draftFunctions, config.variables));
59169
+ ({ ast: cursorMappedAST, mappedCursors } = await mapPaginationCursors(injectedAST, config.variables || {}, store));
58824
59170
  if (config.variables) {
58825
59171
  config.variables = replaceDraftIdsInVariables$1(config.variables, draftFunctions, unmappedDraftIDs);
58826
59172
  }
@@ -58852,7 +59198,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58852
59198
  const nonEvaluatedSnapshot = (await luvio.applyCachePolicy(internalRequestContext, {
58853
59199
  config: {
58854
59200
  ...config,
58855
- query: injectedAST,
59201
+ query: cursorMappedAST,
58856
59202
  },
58857
59203
  luvio,
58858
59204
  gqlEval: true,
@@ -58865,12 +59211,17 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58865
59211
  : [];
58866
59212
  let gqlResult;
58867
59213
  let seenRecordIds;
59214
+ let possibleStaleRecordMap;
58868
59215
  try {
58869
- ({ result: gqlResult, seenRecordIds } = await evaluate({
59216
+ ({
59217
+ result: gqlResult,
59218
+ seenRecordIds,
59219
+ possibleStaleRecordMap,
59220
+ } = await evaluate({
58870
59221
  ...config,
58871
59222
  //need to create another copy of the ast for future writes
58872
59223
  query: parse$3(stringify$3(injectedAST)),
58873
- }, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache));
59224
+ }, observers, { userId }, objectInfoNeeded, store, nonEvaluatedSnapshot, graphqlSchemaCache, draftFunctions, mappedCursors));
58874
59225
  }
58875
59226
  catch (throwable) {
58876
59227
  const error = throwable;
@@ -58896,13 +59247,18 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58896
59247
  const seenRecords = createSeenRecords(seenRecordIds, nonEvaluatedSnapshot);
58897
59248
  const recordId = generateUniqueRecordId();
58898
59249
  const rebuildWithLocalEval = async (originalSnapshot) => {
58899
- let { result: rebuildResult, seenRecordIds } = await evaluate({
59250
+ let { result: rebuildResult, seenRecordIds, possibleStaleRecordMap, } = await evaluate({
58900
59251
  ...config,
58901
59252
  query: injectedAST,
58902
- }, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions);
59253
+ }, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions, mappedCursors);
58903
59254
  if (!rebuildResult.errors) {
58904
59255
  rebuildResult = removeSyntheticFields(rebuildResult, config.query);
58905
59256
  }
59257
+ let snapshotState = 'Fulfilled';
59258
+ if (possibleStaleRecordMap.size > 0) {
59259
+ initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
59260
+ snapshotState = 'Stale';
59261
+ }
58906
59262
  if (objectsDeepEqual(rebuildResult, originalSnapshot.data)) {
58907
59263
  return originalSnapshot;
58908
59264
  }
@@ -58911,6 +59267,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58911
59267
  ...originalSnapshot,
58912
59268
  data: rebuildResult,
58913
59269
  recordId,
59270
+ state: snapshotState,
58914
59271
  seenRecords: createSeenRecords(seenRecordIds, nonEvaluatedSnapshot),
58915
59272
  rebuildWithLocalEval,
58916
59273
  };
@@ -58948,9 +59305,31 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
58948
59305
  },
58949
59306
  };
58950
59307
  }
59308
+ if (possibleStaleRecordMap.size > 0) {
59309
+ initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
59310
+ resultSnapshot.state = 'Stale';
59311
+ }
58951
59312
  return resultSnapshot;
58952
59313
  };
58953
59314
  }
59315
+ function initiateStaleRecordRefresh(luvio, keyMap) {
59316
+ const staleRecordKeys = from$1(keyMap.values())
59317
+ .flat()
59318
+ .map((id) => `UiApi::RecordRepresentation:${id}`);
59319
+ luvio.storeExpirePossibleStaleRecords(staleRecordKeys, makeGetRecordsConfig(keyMap), getRecordsAdapterFactory(luvio));
59320
+ }
59321
+ function makeGetRecordsConfig(keyMap) {
59322
+ const records = [];
59323
+ keyMap.forEach((recordIds, apiName) => {
59324
+ records.push({
59325
+ recordIds,
59326
+ fields: [`${apiName}.Id`],
59327
+ });
59328
+ });
59329
+ return {
59330
+ records,
59331
+ };
59332
+ }
58954
59333
 
58955
59334
  function environmentAwareGraphQLBatchAdapterFactory(objectInfoService, luvio, isDraftId) {
58956
59335
  return async function environmentAwareGraphQLBatchAdapter(config, buildCachedSnapshotCachePolicy, buildNetworkSnapshotCachePolicy, requestContext = {}) {
@@ -60096,6 +60475,9 @@ class NimbusDraftQueue {
60096
60475
  removeHandler(_id) {
60097
60476
  return Promise.reject(new Error('Cannot call setMetadata from the NimbusDraftQueue'));
60098
60477
  }
60478
+ updateDraftAction(_action) {
60479
+ return Promise.reject(new Error('Cannot call updateDraftAction from the NimbusDraftQueue'));
60480
+ }
60099
60481
  }
60100
60482
 
60101
60483
  function attachObserversToAdapterRequestContext(observers, adapterRequestContext) {
@@ -61209,6 +61591,21 @@ const NimbusBinaryStore = {
61209
61591
  __nimbus.plugins.LdsBinaryStorePlugin.setCanonicalUrl(uri, canonicalUrl, ttlSeconds, resolve, (err) => reject(errorMessageToError(err)));
61210
61592
  });
61211
61593
  },
61594
+ createStream: function (type) {
61595
+ return new Promise((resolve, reject) => {
61596
+ __nimbus.plugins.LdsBinaryStorePlugin.createStream(type, resolve, (err) => reject(errorMessageToError(err)));
61597
+ });
61598
+ },
61599
+ writeToStream: function (uri, chunk) {
61600
+ return new Promise((resolve, reject) => {
61601
+ __nimbus.plugins.LdsBinaryStorePlugin.writeToStream(uri, chunk, resolve, (err) => reject(errorMessageToError(err)));
61602
+ });
61603
+ },
61604
+ closeStream: function (uri) {
61605
+ return new Promise((resolve, reject) => {
61606
+ __nimbus.plugins.LdsBinaryStorePlugin.closeStream(uri, resolve, (err) => reject(errorMessageToError(err)));
61607
+ });
61608
+ },
61212
61609
  };
61213
61610
 
61214
61611
  /**
@@ -62536,7 +62933,6 @@ let lazyDurableStore;
62536
62933
  let lazyNetworkAdapter;
62537
62934
  let lazyObjectInfoService;
62538
62935
  let lazyGetRecords;
62539
- // TODO [W-123]: JHORST hoist, optimize and test this function
62540
62936
  const shouldFlush = (key, value) => {
62541
62937
  if (!isStoreKeyRecordId$1(key)) {
62542
62938
  return { flushValue: true };
@@ -62707,7 +63103,7 @@ register$1({
62707
63103
  id: '@salesforce/lds-network-adapter',
62708
63104
  instrument: instrument$2,
62709
63105
  });
62710
- // version: 1.303.0-a698c7cc67
63106
+ // version: 1.304.0-aa3e5f9550
62711
63107
 
62712
63108
  const { create: create$3, keys: keys$3 } = Object;
62713
63109
  const { stringify: stringify$1, parse: parse$1 } = JSON;
@@ -82743,7 +83139,7 @@ register$1({
82743
83139
  configuration: { ...configurationForGraphQLAdapters$1 },
82744
83140
  instrument: instrument$1,
82745
83141
  });
82746
- // version: 1.303.0-b6ed223d95
83142
+ // version: 1.304.0-d87b57badb
82747
83143
 
82748
83144
  // On core the unstable adapters are re-exported with different names,
82749
83145
  // we want to match them here.
@@ -84999,7 +85395,7 @@ withDefaultLuvio((luvio) => {
84999
85395
  unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
85000
85396
  graphQLImperative = ldsAdapter;
85001
85397
  });
85002
- // version: 1.303.0-b6ed223d95
85398
+ // version: 1.304.0-d87b57badb
85003
85399
 
85004
85400
  var gqlApi = /*#__PURE__*/Object.freeze({
85005
85401
  __proto__: null,
@@ -85734,7 +86130,7 @@ const callbacks$1 = [];
85734
86130
  function register(r) {
85735
86131
  callbacks$1.forEach((callback) => callback(r));
85736
86132
  }
85737
- // version: 1.303.0-a698c7cc67
86133
+ // version: 1.304.0-aa3e5f9550
85738
86134
 
85739
86135
  /**
85740
86136
  * Returns true if the value acts like a Promise, i.e. has a "then" function,
@@ -90696,4 +91092,4 @@ const { luvio } = getRuntime();
90696
91092
  setDefaultLuvio({ luvio });
90697
91093
 
90698
91094
  export { createPrimingSession, draftManager, draftQueue, evictCacheRecordsByIds, evictExpiredCacheEntries, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, invokeAdapter, invokeAdapterWithDraftToMerge, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, registerReportObserver, setMetadataTTL, setUiApiRecordTTL, stopEviction, subscribeToAdapter };
90699
- // version: 1.303.0-a698c7cc67
91095
+ // version: 1.304.0-aa3e5f9550