@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.
|
|
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.
|
|
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.
|
|
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(
|
|
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
|
-
//
|
|
20732
|
-
|
|
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(
|
|
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
|
-
//
|
|
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.
|
|
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
|
|
52061
|
-
|
|
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
|
-
|
|
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}
|
|
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}
|
|
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
|
-
|
|
55833
|
-
const
|
|
55834
|
-
|
|
55835
|
-
|
|
55836
|
-
|
|
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
|
-
|
|
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:
|
|
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(
|
|
56052
|
-
endCursor: encodeV1Cursor(
|
|
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
|
|
56060
|
-
return
|
|
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
|
|
56199
|
+
const CURSOR_PARSE_ERROR = 'Unable to parse cursor';
|
|
56063
56200
|
function decodeV1Cursor(base64cursor) {
|
|
56064
|
-
|
|
56065
|
-
|
|
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(
|
|
56212
|
+
throw new Error(message);
|
|
56068
56213
|
}
|
|
56069
|
-
|
|
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(
|
|
56216
|
+
throw new Error(CURSOR_PARSE_ERROR);
|
|
56073
56217
|
}
|
|
56074
|
-
return
|
|
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 {
|
|
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
|
-
|
|
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
|
|
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 ||
|
|
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
|
-
|
|
56192
|
-
|
|
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 {
|
|
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:
|
|
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
|
-
({
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
91095
|
+
// version: 1.304.0-aa3e5f9550
|