@salesforce/lds-runtime-mobile 1.287.0-dev14 → 1.287.0-dev16
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.
- package/dist/main.js +93 -38
- package/package.json +16 -16
- package/sfdc/main.js +93 -38
package/dist/main.js
CHANGED
|
@@ -20,7 +20,7 @@ import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrum
|
|
|
20
20
|
import { HttpStatusCode, setBypassDeepFreeze, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from '@luvio/engine';
|
|
21
21
|
import excludeStaleRecordsGate from '@salesforce/gate/lds.graphqlEvalExcludeStaleRecords';
|
|
22
22
|
import { parseAndVisit, Kind, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$7, extendSchema, isScalarType } from '@luvio/graphql-parser';
|
|
23
|
-
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion
|
|
23
|
+
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, getRecordsAdapterFactory, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion } from '@salesforce/lds-adapters-uiapi';
|
|
24
24
|
import ldsIdempotencyWriteDisabled from '@salesforce/gate/lds.idempotencyWriteDisabled';
|
|
25
25
|
import ldsBackdatingEnabled from '@salesforce/gate/lds.backdatingEnabled';
|
|
26
26
|
import FIRST_DAY_OF_WEEK from '@salesforce/i18n/firstDayOfWeek';
|
|
@@ -1566,6 +1566,32 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
1566
1566
|
}, revivingStore).finally(() => {
|
|
1567
1567
|
});
|
|
1568
1568
|
};
|
|
1569
|
+
const expirePossibleStaleRecords = async function (keys$1, config, refresh) {
|
|
1570
|
+
validateNotDisposed();
|
|
1571
|
+
const metadataKeys = keys$1.map(serializeStructuredKey);
|
|
1572
|
+
const now = Date.now();
|
|
1573
|
+
const entries = await durableStore.getMetadata(metadataKeys, DefaultDurableSegment);
|
|
1574
|
+
if (entries === undefined || keys$7(entries).length === 0) {
|
|
1575
|
+
return environment.expirePossibleStaleRecords(keys$1);
|
|
1576
|
+
}
|
|
1577
|
+
let metaDataChanged = false;
|
|
1578
|
+
const metadataEntries = metadataKeys.reduce((accu, key) => {
|
|
1579
|
+
const metadataEntry = entries[key];
|
|
1580
|
+
if (metadataEntry.metadata !== undefined) {
|
|
1581
|
+
const metadata = { ...metadataEntry.metadata, expirationTimestamp: now };
|
|
1582
|
+
accu[key] = { metadata };
|
|
1583
|
+
metaDataChanged = true;
|
|
1584
|
+
}
|
|
1585
|
+
return accu;
|
|
1586
|
+
}, {});
|
|
1587
|
+
if (metaDataChanged) {
|
|
1588
|
+
await durableStore.setMetadata(metadataEntries, DefaultDurableSegment);
|
|
1589
|
+
}
|
|
1590
|
+
if (config !== undefined && refresh !== undefined) {
|
|
1591
|
+
return environment.refreshPossibleStaleRecords(config, refresh);
|
|
1592
|
+
}
|
|
1593
|
+
return Promise.resolve();
|
|
1594
|
+
};
|
|
1569
1595
|
// set the default cache policy of the base environment
|
|
1570
1596
|
environment.setDefaultCachePolicy({
|
|
1571
1597
|
type: 'stale-while-revalidate',
|
|
@@ -1598,6 +1624,7 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
1598
1624
|
handleErrorResponse: { value: handleErrorResponse },
|
|
1599
1625
|
getNotifyChangeStoreEntries: { value: getNotifyChangeStoreEntries },
|
|
1600
1626
|
notifyStoreUpdateAvailable: { value: notifyStoreUpdateAvailable },
|
|
1627
|
+
expirePossibleStaleRecords: { value: expirePossibleStaleRecords },
|
|
1601
1628
|
});
|
|
1602
1629
|
}
|
|
1603
1630
|
|
|
@@ -7230,6 +7257,7 @@ function createContext(store, objectInfos, eventEmitter, settings, snapshot, dra
|
|
|
7230
7257
|
Record,
|
|
7231
7258
|
snapshot,
|
|
7232
7259
|
seenRecordIds: new Set(),
|
|
7260
|
+
possibleStaleRecordMap: new Map(),
|
|
7233
7261
|
draftFunctions,
|
|
7234
7262
|
};
|
|
7235
7263
|
}
|
|
@@ -7841,7 +7869,6 @@ function isTodayStartOfWeek() {
|
|
|
7841
7869
|
|
|
7842
7870
|
const JSON_EXTRACT_PATH_INGESTION_TIMESTAMP = '$.ingestionTimestamp';
|
|
7843
7871
|
const JSON_EXTRACT_PATH_INGESTION_APINAME = '$.apiName';
|
|
7844
|
-
const JSON_EXTRACT_PATH_DRAFTS = '$.drafts';
|
|
7845
7872
|
|
|
7846
7873
|
const MultiPickListValueSeparator = ';';
|
|
7847
7874
|
function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
|
|
@@ -8371,18 +8398,11 @@ function buildQuery(config) {
|
|
|
8371
8398
|
const joins = buildJoins(config);
|
|
8372
8399
|
const predicates = buildPredicates(config);
|
|
8373
8400
|
const orderBy = buildOrderBy(config);
|
|
8374
|
-
const staleRecordsSql = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
8375
|
-
? `AND (
|
|
8376
|
-
json_extract("${config.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ?
|
|
8377
|
-
OR json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL
|
|
8378
|
-
)`
|
|
8379
|
-
: '';
|
|
8380
8401
|
const sql = `
|
|
8381
|
-
SELECT "${config.alias}".data
|
|
8402
|
+
SELECT "${config.alias}".data, "${config.alias}".metadata
|
|
8382
8403
|
FROM lds_data "${config.alias}" ${joins.sql}
|
|
8383
8404
|
WHERE "${config.alias}".key like 'UiApi::RecordRepresentation:%'
|
|
8384
8405
|
AND json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_INGESTION_APINAME}') = '${config.alias}'
|
|
8385
|
-
${staleRecordsSql}
|
|
8386
8406
|
${predicates.sql}
|
|
8387
8407
|
${orderBy.sql}
|
|
8388
8408
|
LIMIT ?
|
|
@@ -8393,7 +8413,6 @@ function buildQuery(config) {
|
|
|
8393
8413
|
const bindings = [
|
|
8394
8414
|
// bindings from predicates on joins
|
|
8395
8415
|
...joins.bindings,
|
|
8396
|
-
...(excludeStaleRecordsGate.isOpen({ fallback: false }) ? [config.ingestionTimestamp] : []),
|
|
8397
8416
|
// where clause and parent scope bindings
|
|
8398
8417
|
...predicates.bindings,
|
|
8399
8418
|
// limit binding
|
|
@@ -8419,33 +8438,19 @@ function buildJoins(config) {
|
|
|
8419
8438
|
if (allJoins.length === 0)
|
|
8420
8439
|
return { sql, bindings };
|
|
8421
8440
|
sql = allJoins.reduce((joinAccumulator, join) => {
|
|
8422
|
-
let timestampAdded = false;
|
|
8423
8441
|
const joinConditions = join.conditions.reduce((conditionAccumulator, condition) => {
|
|
8424
8442
|
let joined_sql;
|
|
8425
|
-
const joinMetadataTimestamp = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
8426
|
-
? ` AND (json_extract("${join.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ? OR json_extract("${join.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL)`
|
|
8427
|
-
: '';
|
|
8428
8443
|
// predicate on a value, use the newly joined table
|
|
8429
8444
|
if ('type' in condition) {
|
|
8430
8445
|
const { sql, binding } = predicateToSQL(condition, join.alias);
|
|
8431
|
-
joined_sql = ` AND ${sql}
|
|
8446
|
+
joined_sql = ` AND ${sql}`;
|
|
8432
8447
|
bindings.push(...binding);
|
|
8433
|
-
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
8434
|
-
timestampAdded === false) {
|
|
8435
|
-
bindings.push(config.ingestionTimestamp);
|
|
8436
|
-
timestampAdded = true;
|
|
8437
|
-
}
|
|
8438
8448
|
}
|
|
8439
8449
|
else {
|
|
8440
8450
|
// predicate on a path
|
|
8441
8451
|
const left = ` AND json_extract("${join.to}".data, '${condition.leftPath}')`;
|
|
8442
8452
|
const right = `json_extract("${join.alias}".data, '${condition.rightPath}')`;
|
|
8443
|
-
joined_sql = `${left} = ${right}
|
|
8444
|
-
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
8445
|
-
timestampAdded === false) {
|
|
8446
|
-
bindings.push(config.ingestionTimestamp);
|
|
8447
|
-
timestampAdded = true;
|
|
8448
|
-
}
|
|
8453
|
+
joined_sql = `${left} = ${right}`;
|
|
8449
8454
|
}
|
|
8450
8455
|
conditionAccumulator += joined_sql;
|
|
8451
8456
|
return conditionAccumulator;
|
|
@@ -9390,8 +9395,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9390
9395
|
for (const field of fields) {
|
|
9391
9396
|
if (field.name === 'node') {
|
|
9392
9397
|
field.resolve = function nodeResolver(obj, _args, { seenRecordIds }) {
|
|
9393
|
-
const {
|
|
9394
|
-
const recordRepresentation = parse$4(record);
|
|
9398
|
+
const { recordRepresentation, ingestionTimestamp } = obj;
|
|
9395
9399
|
seenRecordIds.add(recordRepresentation.id);
|
|
9396
9400
|
return { recordRepresentation, ingestionTimestamp };
|
|
9397
9401
|
};
|
|
@@ -9605,16 +9609,30 @@ async function connectionEdgeResolver(obj, _args, context) {
|
|
|
9605
9609
|
predicates,
|
|
9606
9610
|
orderBy: orderByToPredicate(parentArgs.orderBy, alias, alias, context.objectInfos),
|
|
9607
9611
|
limit: parentArgs.first,
|
|
9608
|
-
ingestionTimestamp,
|
|
9609
9612
|
};
|
|
9610
9613
|
const { sql, bindings } = buildQuery(queryConfig);
|
|
9611
9614
|
const results = await query(sql, bindings);
|
|
9612
9615
|
//map each sql result with the ingestion timestamp to pass it down a level
|
|
9613
|
-
return results.rows
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
+
return results.rows.map((row) => {
|
|
9617
|
+
const recordMetadataResult = {
|
|
9618
|
+
recordRepresentation: parse$4(row[0]),
|
|
9619
|
+
metadata: parse$4(row[1]),
|
|
9620
|
+
};
|
|
9621
|
+
const { recordRepresentation, metadata } = recordMetadataResult;
|
|
9622
|
+
context.seenRecordIds.add(recordRepresentation.id);
|
|
9623
|
+
if (metadata.ingestionTimestamp < ingestionTimestamp &&
|
|
9624
|
+
recordRepresentation.drafts === undefined) {
|
|
9625
|
+
if (context.possibleStaleRecordMap.has(recordRepresentation.apiName) === false) {
|
|
9626
|
+
context.possibleStaleRecordMap.set(recordRepresentation.apiName, []);
|
|
9627
|
+
}
|
|
9628
|
+
const ids = context.possibleStaleRecordMap.get(recordRepresentation.apiName);
|
|
9629
|
+
if (ids !== undefined) {
|
|
9630
|
+
ids.push(recordRepresentation.id);
|
|
9631
|
+
context.possibleStaleRecordMap.set(recordRepresentation.apiName, ids);
|
|
9632
|
+
}
|
|
9633
|
+
}
|
|
9616
9634
|
return {
|
|
9617
|
-
|
|
9635
|
+
recordRepresentation,
|
|
9618
9636
|
ingestionTimestamp,
|
|
9619
9637
|
};
|
|
9620
9638
|
});
|
|
@@ -10179,7 +10197,11 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
|
|
|
10179
10197
|
seenRecordIds.push(queryString);
|
|
10180
10198
|
});
|
|
10181
10199
|
}
|
|
10182
|
-
return {
|
|
10200
|
+
return {
|
|
10201
|
+
result,
|
|
10202
|
+
seenRecordIds,
|
|
10203
|
+
possibleStaleRecordMap: contextValue.possibleStaleRecordMap,
|
|
10204
|
+
};
|
|
10183
10205
|
}
|
|
10184
10206
|
finally {
|
|
10185
10207
|
eventEmitter({ type: 'graphql-eval-end' });
|
|
@@ -13922,8 +13944,13 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13922
13944
|
: [];
|
|
13923
13945
|
let gqlResult;
|
|
13924
13946
|
let seenRecordIds;
|
|
13947
|
+
let possibleStaleRecordMap;
|
|
13925
13948
|
try {
|
|
13926
|
-
({
|
|
13949
|
+
({
|
|
13950
|
+
result: gqlResult,
|
|
13951
|
+
seenRecordIds,
|
|
13952
|
+
possibleStaleRecordMap,
|
|
13953
|
+
} = await evaluate({
|
|
13927
13954
|
...config,
|
|
13928
13955
|
//need to create another copy of the ast for future writes
|
|
13929
13956
|
query: parse$3(stringify$3(injectedAST)),
|
|
@@ -13953,13 +13980,18 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13953
13980
|
const seenRecords = createSeenRecords(seenRecordIds, nonEvaluatedSnapshot);
|
|
13954
13981
|
const recordId = generateUniqueRecordId();
|
|
13955
13982
|
const rebuildWithLocalEval = async (originalSnapshot) => {
|
|
13956
|
-
let { result: rebuildResult, seenRecordIds } = await evaluate({
|
|
13983
|
+
let { result: rebuildResult, seenRecordIds, possibleStaleRecordMap, } = await evaluate({
|
|
13957
13984
|
...config,
|
|
13958
13985
|
query: injectedAST,
|
|
13959
13986
|
}, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions);
|
|
13960
13987
|
if (!rebuildResult.errors) {
|
|
13961
13988
|
rebuildResult = removeSyntheticFields(rebuildResult, config.query);
|
|
13962
13989
|
}
|
|
13990
|
+
let snapshotState = 'Fulfilled';
|
|
13991
|
+
if (possibleStaleRecordMap.size > 0) {
|
|
13992
|
+
initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
|
|
13993
|
+
snapshotState = 'Stale';
|
|
13994
|
+
}
|
|
13963
13995
|
if (objectsDeepEqual(rebuildResult, originalSnapshot.data)) {
|
|
13964
13996
|
return originalSnapshot;
|
|
13965
13997
|
}
|
|
@@ -13968,6 +14000,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13968
14000
|
...originalSnapshot,
|
|
13969
14001
|
data: rebuildResult,
|
|
13970
14002
|
recordId,
|
|
14003
|
+
state: snapshotState,
|
|
13971
14004
|
seenRecords: createSeenRecords(seenRecordIds, nonEvaluatedSnapshot),
|
|
13972
14005
|
rebuildWithLocalEval,
|
|
13973
14006
|
};
|
|
@@ -14005,6 +14038,10 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
14005
14038
|
},
|
|
14006
14039
|
};
|
|
14007
14040
|
}
|
|
14041
|
+
if (possibleStaleRecordMap.size > 0) {
|
|
14042
|
+
initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
|
|
14043
|
+
resultSnapshot.state = 'Stale';
|
|
14044
|
+
}
|
|
14008
14045
|
return resultSnapshot;
|
|
14009
14046
|
};
|
|
14010
14047
|
}
|
|
@@ -14065,6 +14102,24 @@ function environmentAwareGraphQLBatchAdapterFactory(objectInfoService, luvio, is
|
|
|
14065
14102
|
};
|
|
14066
14103
|
};
|
|
14067
14104
|
}
|
|
14105
|
+
function initiateStaleRecordRefresh(luvio, keyMap) {
|
|
14106
|
+
const staleRecordKeys = from$1(keyMap.values())
|
|
14107
|
+
.flat()
|
|
14108
|
+
.map((id) => `UiApi::RecordRepresentation:${id}`);
|
|
14109
|
+
luvio.storeExpirePossibleStaleRecords(staleRecordKeys, makeGetRecordsConfig(keyMap), getRecordsAdapterFactory(luvio));
|
|
14110
|
+
}
|
|
14111
|
+
function makeGetRecordsConfig(keyMap) {
|
|
14112
|
+
const records = [];
|
|
14113
|
+
keyMap.forEach((recordIds, apiName) => {
|
|
14114
|
+
records.push({
|
|
14115
|
+
recordIds,
|
|
14116
|
+
fields: [`${apiName}.Id`],
|
|
14117
|
+
});
|
|
14118
|
+
});
|
|
14119
|
+
return {
|
|
14120
|
+
records,
|
|
14121
|
+
};
|
|
14122
|
+
}
|
|
14068
14123
|
|
|
14069
14124
|
const CONTENT_DOCUMENT_DRAFT_ID_KEY = 'CONTENT_DOCUMENT_DRAFT_ID';
|
|
14070
14125
|
const CONTENT_VERSION_DRAFT_ID_KEY = 'CONTENT_VERSION_DRAFT_ID';
|
|
@@ -18374,4 +18429,4 @@ register({
|
|
|
18374
18429
|
});
|
|
18375
18430
|
|
|
18376
18431
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
18377
|
-
// version: 1.287.0-
|
|
18432
|
+
// version: 1.287.0-dev16-db839640ab
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-mobile",
|
|
3
|
-
"version": "1.287.0-
|
|
3
|
+
"version": "1.287.0-dev16",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for mobile/hybrid environments.",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -32,25 +32,25 @@
|
|
|
32
32
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-mobile"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@salesforce/lds-adapters-uiapi": "^1.287.0-
|
|
36
|
-
"@salesforce/lds-bindings": "^1.287.0-
|
|
37
|
-
"@salesforce/lds-instrumentation": "^1.287.0-
|
|
38
|
-
"@salesforce/lds-priming": "^1.287.0-
|
|
35
|
+
"@salesforce/lds-adapters-uiapi": "^1.287.0-dev16",
|
|
36
|
+
"@salesforce/lds-bindings": "^1.287.0-dev16",
|
|
37
|
+
"@salesforce/lds-instrumentation": "^1.287.0-dev16",
|
|
38
|
+
"@salesforce/lds-priming": "^1.287.0-dev16",
|
|
39
39
|
"@salesforce/user": "0.0.21",
|
|
40
40
|
"o11y": "250.7.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@salesforce/lds-adapters-graphql": "^1.287.0-
|
|
44
|
-
"@salesforce/lds-drafts": "^1.287.0-
|
|
45
|
-
"@salesforce/lds-drafts-adapters-uiapi": "^1.287.0-
|
|
46
|
-
"@salesforce/lds-graphql-eval": "^1.287.0-
|
|
47
|
-
"@salesforce/lds-network-adapter": "^1.287.0-
|
|
48
|
-
"@salesforce/lds-network-nimbus": "^1.287.0-
|
|
49
|
-
"@salesforce/lds-store-binary": "^1.287.0-
|
|
50
|
-
"@salesforce/lds-store-nimbus": "^1.287.0-
|
|
51
|
-
"@salesforce/lds-store-sql": "^1.287.0-
|
|
52
|
-
"@salesforce/lds-utils-adapters": "^1.287.0-
|
|
53
|
-
"@salesforce/nimbus-plugin-lds": "^1.287.0-
|
|
43
|
+
"@salesforce/lds-adapters-graphql": "^1.287.0-dev16",
|
|
44
|
+
"@salesforce/lds-drafts": "^1.287.0-dev16",
|
|
45
|
+
"@salesforce/lds-drafts-adapters-uiapi": "^1.287.0-dev16",
|
|
46
|
+
"@salesforce/lds-graphql-eval": "^1.287.0-dev16",
|
|
47
|
+
"@salesforce/lds-network-adapter": "^1.287.0-dev16",
|
|
48
|
+
"@salesforce/lds-network-nimbus": "^1.287.0-dev16",
|
|
49
|
+
"@salesforce/lds-store-binary": "^1.287.0-dev16",
|
|
50
|
+
"@salesforce/lds-store-nimbus": "^1.287.0-dev16",
|
|
51
|
+
"@salesforce/lds-store-sql": "^1.287.0-dev16",
|
|
52
|
+
"@salesforce/lds-utils-adapters": "^1.287.0-dev16",
|
|
53
|
+
"@salesforce/nimbus-plugin-lds": "^1.287.0-dev16",
|
|
54
54
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
55
55
|
"wait-for-expect": "^3.0.2"
|
|
56
56
|
},
|
package/sfdc/main.js
CHANGED
|
@@ -20,7 +20,7 @@ import { setupInstrumentation, instrumentAdapter as instrumentAdapter$1, instrum
|
|
|
20
20
|
import { HttpStatusCode, setBypassDeepFreeze, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, createCustomAdapterEventEmitter, StoreKeyMap, isFileReference, Environment, Luvio, InMemoryStore } from 'force/luvioEngine';
|
|
21
21
|
import excludeStaleRecordsGate from '@salesforce/gate/lds.graphqlEvalExcludeStaleRecords';
|
|
22
22
|
import { parseAndVisit, Kind, buildSchema, isObjectType, defaultFieldResolver, visit, execute, parse as parse$7, extendSchema, isScalarType } from 'force/ldsGraphqlParser';
|
|
23
|
-
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion
|
|
23
|
+
import { RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, isStoreKeyRecordViewEntity, getRecordId18, RECORD_REPRESENTATION_NAME, extractRecordIdFromStoreKey, keyBuilderQuickActionExecutionRepresentation, ingestQuickActionExecutionRepresentation, keyBuilderContentDocumentCompositeRepresentation, getResponseCacheKeysContentDocumentCompositeRepresentation, keyBuilderFromTypeContentDocumentCompositeRepresentation, ingestContentDocumentCompositeRepresentation, keyBuilderRecord, RECORD_VIEW_ENTITY_ID_PREFIX, getTypeCacheKeysRecord, keyBuilderFromTypeRecordRepresentation, ingestRecord, getRecordsAdapterFactory, RecordRepresentationRepresentationType, ObjectInfoRepresentationType, getRecordAdapterFactory, getObjectInfoAdapterFactory, getObjectInfosAdapterFactory, getObjectInfoDirectoryAdapterFactory, UiApiNamespace, RecordRepresentationType, RecordRepresentationTTL, RecordRepresentationVersion } from 'force/ldsAdaptersUiapi';
|
|
24
24
|
import ldsIdempotencyWriteDisabled from '@salesforce/gate/lds.idempotencyWriteDisabled';
|
|
25
25
|
import ldsBackdatingEnabled from '@salesforce/gate/lds.backdatingEnabled';
|
|
26
26
|
import FIRST_DAY_OF_WEEK from '@salesforce/i18n/firstDayOfWeek';
|
|
@@ -1566,6 +1566,32 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
1566
1566
|
}, revivingStore).finally(() => {
|
|
1567
1567
|
});
|
|
1568
1568
|
};
|
|
1569
|
+
const expirePossibleStaleRecords = async function (keys$1, config, refresh) {
|
|
1570
|
+
validateNotDisposed();
|
|
1571
|
+
const metadataKeys = keys$1.map(serializeStructuredKey);
|
|
1572
|
+
const now = Date.now();
|
|
1573
|
+
const entries = await durableStore.getMetadata(metadataKeys, DefaultDurableSegment);
|
|
1574
|
+
if (entries === undefined || keys$7(entries).length === 0) {
|
|
1575
|
+
return environment.expirePossibleStaleRecords(keys$1);
|
|
1576
|
+
}
|
|
1577
|
+
let metaDataChanged = false;
|
|
1578
|
+
const metadataEntries = metadataKeys.reduce((accu, key) => {
|
|
1579
|
+
const metadataEntry = entries[key];
|
|
1580
|
+
if (metadataEntry.metadata !== undefined) {
|
|
1581
|
+
const metadata = { ...metadataEntry.metadata, expirationTimestamp: now };
|
|
1582
|
+
accu[key] = { metadata };
|
|
1583
|
+
metaDataChanged = true;
|
|
1584
|
+
}
|
|
1585
|
+
return accu;
|
|
1586
|
+
}, {});
|
|
1587
|
+
if (metaDataChanged) {
|
|
1588
|
+
await durableStore.setMetadata(metadataEntries, DefaultDurableSegment);
|
|
1589
|
+
}
|
|
1590
|
+
if (config !== undefined && refresh !== undefined) {
|
|
1591
|
+
return environment.refreshPossibleStaleRecords(config, refresh);
|
|
1592
|
+
}
|
|
1593
|
+
return Promise.resolve();
|
|
1594
|
+
};
|
|
1569
1595
|
// set the default cache policy of the base environment
|
|
1570
1596
|
environment.setDefaultCachePolicy({
|
|
1571
1597
|
type: 'stale-while-revalidate',
|
|
@@ -1598,6 +1624,7 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
1598
1624
|
handleErrorResponse: { value: handleErrorResponse },
|
|
1599
1625
|
getNotifyChangeStoreEntries: { value: getNotifyChangeStoreEntries },
|
|
1600
1626
|
notifyStoreUpdateAvailable: { value: notifyStoreUpdateAvailable },
|
|
1627
|
+
expirePossibleStaleRecords: { value: expirePossibleStaleRecords },
|
|
1601
1628
|
});
|
|
1602
1629
|
}
|
|
1603
1630
|
|
|
@@ -7230,6 +7257,7 @@ function createContext(store, objectInfos, eventEmitter, settings, snapshot, dra
|
|
|
7230
7257
|
Record,
|
|
7231
7258
|
snapshot,
|
|
7232
7259
|
seenRecordIds: new Set(),
|
|
7260
|
+
possibleStaleRecordMap: new Map(),
|
|
7233
7261
|
draftFunctions,
|
|
7234
7262
|
};
|
|
7235
7263
|
}
|
|
@@ -7841,7 +7869,6 @@ function isTodayStartOfWeek() {
|
|
|
7841
7869
|
|
|
7842
7870
|
const JSON_EXTRACT_PATH_INGESTION_TIMESTAMP = '$.ingestionTimestamp';
|
|
7843
7871
|
const JSON_EXTRACT_PATH_INGESTION_APINAME = '$.apiName';
|
|
7844
|
-
const JSON_EXTRACT_PATH_DRAFTS = '$.drafts';
|
|
7845
7872
|
|
|
7846
7873
|
const MultiPickListValueSeparator = ';';
|
|
7847
7874
|
function filterToPredicates(where, recordType, alias, objectInfoMap, joins, draftFunctions) {
|
|
@@ -8371,18 +8398,11 @@ function buildQuery(config) {
|
|
|
8371
8398
|
const joins = buildJoins(config);
|
|
8372
8399
|
const predicates = buildPredicates(config);
|
|
8373
8400
|
const orderBy = buildOrderBy(config);
|
|
8374
|
-
const staleRecordsSql = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
8375
|
-
? `AND (
|
|
8376
|
-
json_extract("${config.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ?
|
|
8377
|
-
OR json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL
|
|
8378
|
-
)`
|
|
8379
|
-
: '';
|
|
8380
8401
|
const sql = `
|
|
8381
|
-
SELECT "${config.alias}".data
|
|
8402
|
+
SELECT "${config.alias}".data, "${config.alias}".metadata
|
|
8382
8403
|
FROM lds_data "${config.alias}" ${joins.sql}
|
|
8383
8404
|
WHERE "${config.alias}".key like 'UiApi::RecordRepresentation:%'
|
|
8384
8405
|
AND json_extract("${config.alias}".data, '${JSON_EXTRACT_PATH_INGESTION_APINAME}') = '${config.alias}'
|
|
8385
|
-
${staleRecordsSql}
|
|
8386
8406
|
${predicates.sql}
|
|
8387
8407
|
${orderBy.sql}
|
|
8388
8408
|
LIMIT ?
|
|
@@ -8393,7 +8413,6 @@ function buildQuery(config) {
|
|
|
8393
8413
|
const bindings = [
|
|
8394
8414
|
// bindings from predicates on joins
|
|
8395
8415
|
...joins.bindings,
|
|
8396
|
-
...(excludeStaleRecordsGate.isOpen({ fallback: false }) ? [config.ingestionTimestamp] : []),
|
|
8397
8416
|
// where clause and parent scope bindings
|
|
8398
8417
|
...predicates.bindings,
|
|
8399
8418
|
// limit binding
|
|
@@ -8419,33 +8438,19 @@ function buildJoins(config) {
|
|
|
8419
8438
|
if (allJoins.length === 0)
|
|
8420
8439
|
return { sql, bindings };
|
|
8421
8440
|
sql = allJoins.reduce((joinAccumulator, join) => {
|
|
8422
|
-
let timestampAdded = false;
|
|
8423
8441
|
const joinConditions = join.conditions.reduce((conditionAccumulator, condition) => {
|
|
8424
8442
|
let joined_sql;
|
|
8425
|
-
const joinMetadataTimestamp = excludeStaleRecordsGate.isOpen({ fallback: false })
|
|
8426
|
-
? ` AND (json_extract("${join.alias}".metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') >= ? OR json_extract("${join.alias}".data, '${JSON_EXTRACT_PATH_DRAFTS}') IS NOT NULL)`
|
|
8427
|
-
: '';
|
|
8428
8443
|
// predicate on a value, use the newly joined table
|
|
8429
8444
|
if ('type' in condition) {
|
|
8430
8445
|
const { sql, binding } = predicateToSQL(condition, join.alias);
|
|
8431
|
-
joined_sql = ` AND ${sql}
|
|
8446
|
+
joined_sql = ` AND ${sql}`;
|
|
8432
8447
|
bindings.push(...binding);
|
|
8433
|
-
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
8434
|
-
timestampAdded === false) {
|
|
8435
|
-
bindings.push(config.ingestionTimestamp);
|
|
8436
|
-
timestampAdded = true;
|
|
8437
|
-
}
|
|
8438
8448
|
}
|
|
8439
8449
|
else {
|
|
8440
8450
|
// predicate on a path
|
|
8441
8451
|
const left = ` AND json_extract("${join.to}".data, '${condition.leftPath}')`;
|
|
8442
8452
|
const right = `json_extract("${join.alias}".data, '${condition.rightPath}')`;
|
|
8443
|
-
joined_sql = `${left} = ${right}
|
|
8444
|
-
if (excludeStaleRecordsGate.isOpen({ fallback: false }) &&
|
|
8445
|
-
timestampAdded === false) {
|
|
8446
|
-
bindings.push(config.ingestionTimestamp);
|
|
8447
|
-
timestampAdded = true;
|
|
8448
|
-
}
|
|
8453
|
+
joined_sql = `${left} = ${right}`;
|
|
8449
8454
|
}
|
|
8450
8455
|
conditionAccumulator += joined_sql;
|
|
8451
8456
|
return conditionAccumulator;
|
|
@@ -9390,8 +9395,7 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
9390
9395
|
for (const field of fields) {
|
|
9391
9396
|
if (field.name === 'node') {
|
|
9392
9397
|
field.resolve = function nodeResolver(obj, _args, { seenRecordIds }) {
|
|
9393
|
-
const {
|
|
9394
|
-
const recordRepresentation = parse$4(record);
|
|
9398
|
+
const { recordRepresentation, ingestionTimestamp } = obj;
|
|
9395
9399
|
seenRecordIds.add(recordRepresentation.id);
|
|
9396
9400
|
return { recordRepresentation, ingestionTimestamp };
|
|
9397
9401
|
};
|
|
@@ -9605,16 +9609,30 @@ async function connectionEdgeResolver(obj, _args, context) {
|
|
|
9605
9609
|
predicates,
|
|
9606
9610
|
orderBy: orderByToPredicate(parentArgs.orderBy, alias, alias, context.objectInfos),
|
|
9607
9611
|
limit: parentArgs.first,
|
|
9608
|
-
ingestionTimestamp,
|
|
9609
9612
|
};
|
|
9610
9613
|
const { sql, bindings } = buildQuery(queryConfig);
|
|
9611
9614
|
const results = await query(sql, bindings);
|
|
9612
9615
|
//map each sql result with the ingestion timestamp to pass it down a level
|
|
9613
|
-
return results.rows
|
|
9614
|
-
|
|
9615
|
-
|
|
9616
|
+
return results.rows.map((row) => {
|
|
9617
|
+
const recordMetadataResult = {
|
|
9618
|
+
recordRepresentation: parse$4(row[0]),
|
|
9619
|
+
metadata: parse$4(row[1]),
|
|
9620
|
+
};
|
|
9621
|
+
const { recordRepresentation, metadata } = recordMetadataResult;
|
|
9622
|
+
context.seenRecordIds.add(recordRepresentation.id);
|
|
9623
|
+
if (metadata.ingestionTimestamp < ingestionTimestamp &&
|
|
9624
|
+
recordRepresentation.drafts === undefined) {
|
|
9625
|
+
if (context.possibleStaleRecordMap.has(recordRepresentation.apiName) === false) {
|
|
9626
|
+
context.possibleStaleRecordMap.set(recordRepresentation.apiName, []);
|
|
9627
|
+
}
|
|
9628
|
+
const ids = context.possibleStaleRecordMap.get(recordRepresentation.apiName);
|
|
9629
|
+
if (ids !== undefined) {
|
|
9630
|
+
ids.push(recordRepresentation.id);
|
|
9631
|
+
context.possibleStaleRecordMap.set(recordRepresentation.apiName, ids);
|
|
9632
|
+
}
|
|
9633
|
+
}
|
|
9616
9634
|
return {
|
|
9617
|
-
|
|
9635
|
+
recordRepresentation,
|
|
9618
9636
|
ingestionTimestamp,
|
|
9619
9637
|
};
|
|
9620
9638
|
});
|
|
@@ -10179,7 +10197,11 @@ async function evaluate(config, observers, settings, objectInfos, store, snapsho
|
|
|
10179
10197
|
seenRecordIds.push(queryString);
|
|
10180
10198
|
});
|
|
10181
10199
|
}
|
|
10182
|
-
return {
|
|
10200
|
+
return {
|
|
10201
|
+
result,
|
|
10202
|
+
seenRecordIds,
|
|
10203
|
+
possibleStaleRecordMap: contextValue.possibleStaleRecordMap,
|
|
10204
|
+
};
|
|
10183
10205
|
}
|
|
10184
10206
|
finally {
|
|
10185
10207
|
eventEmitter({ type: 'graphql-eval-end' });
|
|
@@ -13922,8 +13944,13 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13922
13944
|
: [];
|
|
13923
13945
|
let gqlResult;
|
|
13924
13946
|
let seenRecordIds;
|
|
13947
|
+
let possibleStaleRecordMap;
|
|
13925
13948
|
try {
|
|
13926
|
-
({
|
|
13949
|
+
({
|
|
13950
|
+
result: gqlResult,
|
|
13951
|
+
seenRecordIds,
|
|
13952
|
+
possibleStaleRecordMap,
|
|
13953
|
+
} = await evaluate({
|
|
13927
13954
|
...config,
|
|
13928
13955
|
//need to create another copy of the ast for future writes
|
|
13929
13956
|
query: parse$3(stringify$3(injectedAST)),
|
|
@@ -13953,13 +13980,18 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13953
13980
|
const seenRecords = createSeenRecords(seenRecordIds, nonEvaluatedSnapshot);
|
|
13954
13981
|
const recordId = generateUniqueRecordId();
|
|
13955
13982
|
const rebuildWithLocalEval = async (originalSnapshot) => {
|
|
13956
|
-
let { result: rebuildResult, seenRecordIds } = await evaluate({
|
|
13983
|
+
let { result: rebuildResult, seenRecordIds, possibleStaleRecordMap, } = await evaluate({
|
|
13957
13984
|
...config,
|
|
13958
13985
|
query: injectedAST,
|
|
13959
13986
|
}, observers, { userId }, objectInfoNeeded, store, originalSnapshot, graphqlSchemaCache, draftFunctions);
|
|
13960
13987
|
if (!rebuildResult.errors) {
|
|
13961
13988
|
rebuildResult = removeSyntheticFields(rebuildResult, config.query);
|
|
13962
13989
|
}
|
|
13990
|
+
let snapshotState = 'Fulfilled';
|
|
13991
|
+
if (possibleStaleRecordMap.size > 0) {
|
|
13992
|
+
initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
|
|
13993
|
+
snapshotState = 'Stale';
|
|
13994
|
+
}
|
|
13963
13995
|
if (objectsDeepEqual(rebuildResult, originalSnapshot.data)) {
|
|
13964
13996
|
return originalSnapshot;
|
|
13965
13997
|
}
|
|
@@ -13968,6 +14000,7 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
13968
14000
|
...originalSnapshot,
|
|
13969
14001
|
data: rebuildResult,
|
|
13970
14002
|
recordId,
|
|
14003
|
+
state: snapshotState,
|
|
13971
14004
|
seenRecords: createSeenRecords(seenRecordIds, nonEvaluatedSnapshot),
|
|
13972
14005
|
rebuildWithLocalEval,
|
|
13973
14006
|
};
|
|
@@ -14005,6 +14038,10 @@ function draftAwareGraphQLAdapterFactory(userId, objectInfoService, store, luvio
|
|
|
14005
14038
|
},
|
|
14006
14039
|
};
|
|
14007
14040
|
}
|
|
14041
|
+
if (possibleStaleRecordMap.size > 0) {
|
|
14042
|
+
initiateStaleRecordRefresh(luvio, possibleStaleRecordMap);
|
|
14043
|
+
resultSnapshot.state = 'Stale';
|
|
14044
|
+
}
|
|
14008
14045
|
return resultSnapshot;
|
|
14009
14046
|
};
|
|
14010
14047
|
}
|
|
@@ -14065,6 +14102,24 @@ function environmentAwareGraphQLBatchAdapterFactory(objectInfoService, luvio, is
|
|
|
14065
14102
|
};
|
|
14066
14103
|
};
|
|
14067
14104
|
}
|
|
14105
|
+
function initiateStaleRecordRefresh(luvio, keyMap) {
|
|
14106
|
+
const staleRecordKeys = from$1(keyMap.values())
|
|
14107
|
+
.flat()
|
|
14108
|
+
.map((id) => `UiApi::RecordRepresentation:${id}`);
|
|
14109
|
+
luvio.storeExpirePossibleStaleRecords(staleRecordKeys, makeGetRecordsConfig(keyMap), getRecordsAdapterFactory(luvio));
|
|
14110
|
+
}
|
|
14111
|
+
function makeGetRecordsConfig(keyMap) {
|
|
14112
|
+
const records = [];
|
|
14113
|
+
keyMap.forEach((recordIds, apiName) => {
|
|
14114
|
+
records.push({
|
|
14115
|
+
recordIds,
|
|
14116
|
+
fields: [`${apiName}.Id`],
|
|
14117
|
+
});
|
|
14118
|
+
});
|
|
14119
|
+
return {
|
|
14120
|
+
records,
|
|
14121
|
+
};
|
|
14122
|
+
}
|
|
14068
14123
|
|
|
14069
14124
|
const CONTENT_DOCUMENT_DRAFT_ID_KEY = 'CONTENT_DOCUMENT_DRAFT_ID';
|
|
14070
14125
|
const CONTENT_VERSION_DRAFT_ID_KEY = 'CONTENT_VERSION_DRAFT_ID';
|
|
@@ -18374,4 +18429,4 @@ register({
|
|
|
18374
18429
|
});
|
|
18375
18430
|
|
|
18376
18431
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
18377
|
-
// version: 1.287.0-
|
|
18432
|
+
// version: 1.287.0-dev16-db839640ab
|