@salesforce/lds-runtime-bridge 1.266.0-dev2 → 1.266.0-dev20
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/ldsRuntimeBridge.js +85 -33
- package/package.json +8 -8
package/dist/ldsRuntimeBridge.js
CHANGED
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* *******************************************************************************************
|
|
13
13
|
*/
|
|
14
14
|
import { setDefaultLuvio } from 'force/ldsEngine';
|
|
15
|
-
import { StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, InMemoryStore, Environment, Luvio } from 'force/luvioEngine';
|
|
15
|
+
import { setBypassDeepFreeze, StoreKeySet, serializeStructuredKey, StringKeyInMemoryStore, Reader, deepFreeze, emitAdapterEvent, InMemoryStore, Environment, Luvio } from 'force/luvioEngine';
|
|
16
16
|
import { instrumentLuvio } from 'force/ldsInstrumentation';
|
|
17
17
|
import { isStoreKeyRecordViewEntity, RECORD_ID_PREFIX, RECORD_FIELDS_KEY_JUNCTION, getRecordId18, extractRecordIdFromStoreKey, RECORD_VIEW_ENTITY_ID_PREFIX, keyBuilderRecord } from 'force/ldsAdaptersUiapi';
|
|
18
18
|
import '@salesforce/gate/lds.idempotencyWriteDisabled';
|
|
@@ -529,7 +529,9 @@ function isUnfulfilledSnapshot(cachedSnapshotResult) {
|
|
|
529
529
|
* @param durableStore A DurableStore implementation
|
|
530
530
|
* @param instrumentation An instrumentation function implementation
|
|
531
531
|
*/
|
|
532
|
-
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore, enableDurableMetadataRefresh = false, }) {
|
|
532
|
+
function makeDurable(environment, { durableStore, instrumentation, useRevivingStore, enableDurableMetadataRefresh = false, disableDeepFreeze = false, }) {
|
|
533
|
+
// runtimes can choose to disable deepFreeze, e.g. headless mobile runtime
|
|
534
|
+
setBypassDeepFreeze(disableDeepFreeze);
|
|
533
535
|
let stagingStore = null;
|
|
534
536
|
const durableTTLStore = new DurableTTLStore(durableStore);
|
|
535
537
|
const mergeKeysPromiseMap = new Map();
|
|
@@ -900,6 +902,10 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
900
902
|
}
|
|
901
903
|
return {};
|
|
902
904
|
};
|
|
905
|
+
const getIngestStagingStore = function () {
|
|
906
|
+
validateNotDisposed();
|
|
907
|
+
return stagingStore === null || stagingStore === void 0 ? void 0 : stagingStore.fallbackStringKeyInMemoryStore;
|
|
908
|
+
};
|
|
903
909
|
const handleSuccessResponse = async function (ingestAndBroadcastFunc, getResponseCacheKeysFunc) {
|
|
904
910
|
validateNotDisposed();
|
|
905
911
|
const cacheKeyMap = getResponseCacheKeysFunc();
|
|
@@ -1092,6 +1098,7 @@ function makeDurable(environment, { durableStore, instrumentation, useRevivingSt
|
|
|
1092
1098
|
applyCachePolicy: { value: applyCachePolicy },
|
|
1093
1099
|
getIngestStagingStoreRecords: { value: getIngestStagingStoreRecords },
|
|
1094
1100
|
getIngestStagingStoreMetadata: { value: getIngestStagingStoreMetadata },
|
|
1101
|
+
getIngestStagingStore: { value: getIngestStagingStore },
|
|
1095
1102
|
handleSuccessResponse: { value: handleSuccessResponse },
|
|
1096
1103
|
handleErrorResponse: { value: handleErrorResponse },
|
|
1097
1104
|
getNotifyChangeStoreEntries: { value: getNotifyChangeStoreEntries },
|
|
@@ -2531,6 +2538,9 @@ function createSinglePredicate(val, operator, field, alias) {
|
|
|
2531
2538
|
else if (field.apiName === 'weakEtag') {
|
|
2532
2539
|
leftPath = '$.weakEtag';
|
|
2533
2540
|
}
|
|
2541
|
+
else if (field.apiName === 'RecordTypeId') {
|
|
2542
|
+
leftPath = '$.recordTypeId';
|
|
2543
|
+
}
|
|
2534
2544
|
return {
|
|
2535
2545
|
alias,
|
|
2536
2546
|
leftPath,
|
|
@@ -3006,6 +3016,20 @@ function findFieldInfo(objectInfo, fieldName) {
|
|
|
3006
3016
|
return values$1(objectInfo.fields).find((field) => field.apiName === fieldName ||
|
|
3007
3017
|
(field.dataType === 'Reference' && field.relationshipName === fieldName));
|
|
3008
3018
|
}
|
|
3019
|
+
async function readIngestionTimestampForKey(key, query) {
|
|
3020
|
+
let ingestionTimestamp = 0;
|
|
3021
|
+
const sql = `SELECT json_extract(metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}') FROM lds_data WHERE key IS ?`;
|
|
3022
|
+
const results = await query(sql, [key]);
|
|
3023
|
+
const [timestamp] = results.rows.map((row) => row[0]);
|
|
3024
|
+
if (timestamp !== null) {
|
|
3025
|
+
const numericalTimestamp = Number(timestamp);
|
|
3026
|
+
if (isNaN(numericalTimestamp)) {
|
|
3027
|
+
return ingestionTimestamp;
|
|
3028
|
+
}
|
|
3029
|
+
ingestionTimestamp = numericalTimestamp;
|
|
3030
|
+
}
|
|
3031
|
+
return ingestionTimestamp;
|
|
3032
|
+
}
|
|
3009
3033
|
|
|
3010
3034
|
function findSpanningField(name) {
|
|
3011
3035
|
return (field) => {
|
|
@@ -3330,6 +3354,12 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
3330
3354
|
break;
|
|
3331
3355
|
case 'LastModifiedDate':
|
|
3332
3356
|
field.resolve = ({ recordRepresentation: record }) => {
|
|
3357
|
+
// In UIAPI record reps, LastModifiedDate might be present as a field,
|
|
3358
|
+
// which will include both the value and displayValue
|
|
3359
|
+
if (record.fields['LastModifiedDate']) {
|
|
3360
|
+
return record.fields['LastModifiedDate'];
|
|
3361
|
+
}
|
|
3362
|
+
// If the field is not present, just return the value of the root property
|
|
3333
3363
|
return record.lastModifiedDate
|
|
3334
3364
|
? { value: record.lastModifiedDate }
|
|
3335
3365
|
: null;
|
|
@@ -3364,16 +3394,26 @@ function addResolversToSchema(schema, polyFields) {
|
|
|
3364
3394
|
: null;
|
|
3365
3395
|
};
|
|
3366
3396
|
const { recordRepresentation: record, ingestionTimestamp } = obj;
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
if (
|
|
3397
|
+
let id = undefined;
|
|
3398
|
+
if (field.name === 'RecordType') {
|
|
3399
|
+
// RecordTypeId has special handling during ingest and is
|
|
3400
|
+
// not in record.fields, so check for it at the UIAPI root property location
|
|
3401
|
+
id = record.recordTypeId;
|
|
3402
|
+
}
|
|
3403
|
+
else if (field.name.endsWith('__r')) {
|
|
3404
|
+
// Custom relationships end in `__r` and the corresponding ID field should be `__c`
|
|
3405
|
+
let fieldName = field.name.replace('__r', '__c');
|
|
3406
|
+
id = record.fields[fieldName] && record.fields[fieldName].value;
|
|
3407
|
+
}
|
|
3408
|
+
else {
|
|
3409
|
+
// Standard relationships are just FieldNameId
|
|
3410
|
+
let fieldName = field.name + 'Id';
|
|
3411
|
+
id = record.fields[fieldName] && record.fields[fieldName].value;
|
|
3412
|
+
}
|
|
3413
|
+
if (!id || typeof id !== 'string') {
|
|
3414
|
+
// possibly field injection did not inject the necessary Id field
|
|
3415
|
+
// for the relationship, or we found a non-string value.
|
|
3374
3416
|
return null;
|
|
3375
|
-
if (id['__ref'] !== undefined) {
|
|
3376
|
-
return fetchRecordOrNull(record.fields[`${field.name}Id`].value);
|
|
3377
3417
|
}
|
|
3378
3418
|
seenRecordIds.add(id);
|
|
3379
3419
|
return fetchRecordOrNull(id);
|
|
@@ -3525,18 +3565,7 @@ async function fetchIngestionTimeStampFromDatabase(apiName, info, args, query) {
|
|
|
3525
3565
|
const key = buildKeyStringForRecordQuery(operation,
|
|
3526
3566
|
// join varables passed from query to the argument variables given from the AST
|
|
3527
3567
|
{ ...variableValues, ...args }, info.fieldNodes[0].arguments, apiName);
|
|
3528
|
-
|
|
3529
|
-
SELECT json_extract(metadata, '${JSON_EXTRACT_PATH_INGESTION_TIMESTAMP}')
|
|
3530
|
-
FROM lds_data
|
|
3531
|
-
WHERE key IS ?
|
|
3532
|
-
`;
|
|
3533
|
-
const results = await query(sql, [key]);
|
|
3534
|
-
const [timestamp] = results.rows.map((row) => row[0]);
|
|
3535
|
-
if (timestamp !== null && typeof timestamp === 'number') {
|
|
3536
|
-
// adjust the timestamp to account for ingestion processing time
|
|
3537
|
-
// 30s is used because this is the default record TTL
|
|
3538
|
-
ingestionTimestamp = timestamp - 30000;
|
|
3539
|
-
}
|
|
3568
|
+
return readIngestionTimestampForKey(key, query);
|
|
3540
3569
|
}
|
|
3541
3570
|
return ingestionTimestamp;
|
|
3542
3571
|
}
|
|
@@ -3653,10 +3682,13 @@ function normalizeRecordFields(key, entry) {
|
|
|
3653
3682
|
* Transforms a record for storage in the durable store. The transformation involves denormalizing
|
|
3654
3683
|
* scalar fields and persisting link metadata to transform back into a normalized representation
|
|
3655
3684
|
*
|
|
3685
|
+
* If the record contains pending fields this will return undefined as pending records do not get persisted
|
|
3686
|
+
* to the durable store. There should be a refresh operation outbound that will bring in the updated record.
|
|
3687
|
+
*
|
|
3656
3688
|
* @param normalizedRecord Record containing normalized field links
|
|
3657
3689
|
* @param recordStore a store containing referenced record fields
|
|
3658
3690
|
*/
|
|
3659
|
-
function buildDurableRecordRepresentation(normalizedRecord, records, pendingEntries) {
|
|
3691
|
+
function buildDurableRecordRepresentation(normalizedRecord, records, pendingEntries, store) {
|
|
3660
3692
|
const fields = normalizedRecord.fields;
|
|
3661
3693
|
const filteredFields = {};
|
|
3662
3694
|
const links = {};
|
|
@@ -3667,7 +3699,9 @@ function buildDurableRecordRepresentation(normalizedRecord, records, pendingEntr
|
|
|
3667
3699
|
// pending fields get filtered out of the durable store
|
|
3668
3700
|
const { pending } = field;
|
|
3669
3701
|
if (pending === true) {
|
|
3670
|
-
|
|
3702
|
+
// do not write records with pending fields to the durable store
|
|
3703
|
+
// there should be a refresh operation outbound that will bring in the updated record
|
|
3704
|
+
return undefined;
|
|
3671
3705
|
}
|
|
3672
3706
|
const { __ref } = field;
|
|
3673
3707
|
if (__ref !== undefined) {
|
|
@@ -3683,6 +3717,19 @@ function buildDurableRecordRepresentation(normalizedRecord, records, pendingEntr
|
|
|
3683
3717
|
if (ref !== undefined) {
|
|
3684
3718
|
filteredFields[fieldName] = ref;
|
|
3685
3719
|
}
|
|
3720
|
+
else {
|
|
3721
|
+
// if we have a store to read, try to find the field there too
|
|
3722
|
+
// The durable ingest staging store may pass through to L1, and
|
|
3723
|
+
// not all fields are necessarily published every time, so it is
|
|
3724
|
+
// important to check L1 and not just the fields being published,
|
|
3725
|
+
// otherwise we risk truncating the fields on the record.
|
|
3726
|
+
if (store) {
|
|
3727
|
+
ref = store.readEntry(__ref);
|
|
3728
|
+
if (ref !== undefined) {
|
|
3729
|
+
filteredFields[fieldName] = ref;
|
|
3730
|
+
}
|
|
3731
|
+
}
|
|
3732
|
+
}
|
|
3686
3733
|
}
|
|
3687
3734
|
// we want to preserve fields that are missing nodes
|
|
3688
3735
|
if (filteredFields[fieldName] !== undefined || field.isMissing === true) {
|
|
@@ -3704,7 +3751,7 @@ function getDenormalizedKey(originalKey, recordId, luvio) {
|
|
|
3704
3751
|
}
|
|
3705
3752
|
return keyBuilderRecord(luvio, { recordId });
|
|
3706
3753
|
}
|
|
3707
|
-
function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecords, getStoreMetadata) {
|
|
3754
|
+
function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecords, getStoreMetadata, getStore) {
|
|
3708
3755
|
const getEntries = function (entries, segment) {
|
|
3709
3756
|
// this HOF only inspects records in the default segment
|
|
3710
3757
|
if (segment !== DefaultDurableSegment) {
|
|
@@ -3772,6 +3819,7 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
3772
3819
|
const putRecordViews = {};
|
|
3773
3820
|
const storeRecords = getStoreRecords !== undefined ? getStoreRecords() : {};
|
|
3774
3821
|
const storeMetadata = getStoreMetadata !== undefined ? getStoreMetadata() : {};
|
|
3822
|
+
const store = getStore();
|
|
3775
3823
|
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
3776
3824
|
const key = keys$1[i];
|
|
3777
3825
|
let value = entries[key];
|
|
@@ -3818,11 +3866,13 @@ function makeRecordDenormalizingDurableStore(luvio, durableStore, getStoreRecord
|
|
|
3818
3866
|
metadataVersion: DURABLE_METADATA_VERSION,
|
|
3819
3867
|
};
|
|
3820
3868
|
}
|
|
3821
|
-
const denormalizedRecord = buildDurableRecordRepresentation(record, storeRecords, recordEntries);
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3825
|
-
|
|
3869
|
+
const denormalizedRecord = buildDurableRecordRepresentation(record, storeRecords, recordEntries, store);
|
|
3870
|
+
if (denormalizedRecord !== undefined) {
|
|
3871
|
+
putEntries[recordKey] = {
|
|
3872
|
+
data: denormalizedRecord,
|
|
3873
|
+
metadata,
|
|
3874
|
+
};
|
|
3875
|
+
}
|
|
3826
3876
|
}
|
|
3827
3877
|
else {
|
|
3828
3878
|
putEntries[key] = value;
|
|
@@ -3911,6 +3961,7 @@ new CachedGraphQLSchema();
|
|
|
3911
3961
|
let luvio;
|
|
3912
3962
|
let getIngestRecords;
|
|
3913
3963
|
let getIngestMetadata;
|
|
3964
|
+
let getIngestStore;
|
|
3914
3965
|
// LdsSqliteStore plugin helper
|
|
3915
3966
|
function getNimbusDurableStore() {
|
|
3916
3967
|
const resolvedPlugin = __nimbus.plugins.LdsSqliteStore;
|
|
@@ -3922,7 +3973,7 @@ function getNimbusDurableStore() {
|
|
|
3922
3973
|
* See TD-0153300 for moving RecordDenormalizingDurableStore out of lds-drafts
|
|
3923
3974
|
*/
|
|
3924
3975
|
function createRecordDenormingStore(luvio, durableStore) {
|
|
3925
|
-
const recordDenormingStore = makeRecordDenormalizingDurableStore(luvio, durableStore, () => getIngestRecords(), () => getIngestMetadata());
|
|
3976
|
+
const recordDenormingStore = makeRecordDenormalizingDurableStore(luvio, durableStore, () => getIngestRecords(), () => getIngestMetadata(), () => getIngestStore());
|
|
3926
3977
|
return recordDenormingStore;
|
|
3927
3978
|
}
|
|
3928
3979
|
function getRuntime() {
|
|
@@ -3938,6 +3989,7 @@ function getRuntime() {
|
|
|
3938
3989
|
// Set ingest records/metadata properties from durable environment
|
|
3939
3990
|
getIngestRecords = durableEnv.getIngestStagingStoreRecords;
|
|
3940
3991
|
getIngestMetadata = durableEnv.getIngestStagingStoreMetadata;
|
|
3992
|
+
getIngestStore = durableEnv.getIngestStagingStore;
|
|
3941
3993
|
// Return new luvio instance
|
|
3942
3994
|
luvio = new Luvio(durableEnv, {
|
|
3943
3995
|
instrument: instrumentLuvio,
|
|
@@ -3963,4 +4015,4 @@ function ldsRuntimeBridge() {
|
|
|
3963
4015
|
}
|
|
3964
4016
|
|
|
3965
4017
|
export { ldsRuntimeBridge as default };
|
|
3966
|
-
// version: 1.266.0-
|
|
4018
|
+
// version: 1.266.0-dev20-117d849b4
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-bridge",
|
|
3
|
-
"version": "1.266.0-
|
|
3
|
+
"version": "1.266.0-dev20",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for bridge.app.",
|
|
6
6
|
"main": "dist/ldsRuntimeBridge.js",
|
|
@@ -34,17 +34,17 @@
|
|
|
34
34
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-bridge"
|
|
35
35
|
},
|
|
36
36
|
"dependencies": {
|
|
37
|
-
"@salesforce/lds-adapters-uiapi": "^1.266.0-
|
|
38
|
-
"@salesforce/lds-instrumentation": "^1.266.0-
|
|
37
|
+
"@salesforce/lds-adapters-uiapi": "^1.266.0-dev20",
|
|
38
|
+
"@salesforce/lds-instrumentation": "^1.266.0-dev20",
|
|
39
39
|
"@salesforce/user": "0.0.21",
|
|
40
40
|
"o11y": "244.0.0"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@salesforce/lds-drafts-adapters-uiapi": "^1.266.0-
|
|
44
|
-
"@salesforce/lds-network-aura": "^1.266.0-
|
|
45
|
-
"@salesforce/lds-runtime-aura": "^1.266.0-
|
|
46
|
-
"@salesforce/lds-store-nimbus": "^1.266.0-
|
|
47
|
-
"@salesforce/nimbus-plugin-lds": "^1.266.0-
|
|
43
|
+
"@salesforce/lds-drafts-adapters-uiapi": "^1.266.0-dev20",
|
|
44
|
+
"@salesforce/lds-network-aura": "^1.266.0-dev20",
|
|
45
|
+
"@salesforce/lds-runtime-aura": "^1.266.0-dev20",
|
|
46
|
+
"@salesforce/lds-store-nimbus": "^1.266.0-dev20",
|
|
47
|
+
"@salesforce/nimbus-plugin-lds": "^1.266.0-dev20",
|
|
48
48
|
"babel-plugin-dynamic-import-node": "^2.3.3"
|
|
49
49
|
},
|
|
50
50
|
"luvioBundlesize": [
|