@salesforce/lds-runtime-mobile 1.144.0 → 1.146.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.
- package/dist/main.js +85 -58
- package/package.json +1 -1
- package/sfdc/main.js +85 -58
package/dist/main.js
CHANGED
|
@@ -518,6 +518,7 @@ function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
|
518
518
|
return false;
|
|
519
519
|
}
|
|
520
520
|
const DefaultDurableSegment = 'DEFAULT';
|
|
521
|
+
const RedirectDurableSegment = 'REDIRECT_KEYS';
|
|
521
522
|
|
|
522
523
|
const { keys: keys$6, create: create$5, assign: assign$4, freeze: freeze$1 } = Object;
|
|
523
524
|
|
|
@@ -761,7 +762,7 @@ class DurableTTLStore {
|
|
|
761
762
|
}
|
|
762
763
|
}
|
|
763
764
|
|
|
764
|
-
function flushInMemoryStoreValuesToDurableStore(store, durableStore, durableStoreErrorHandler, additionalDurableStoreOperations = []) {
|
|
765
|
+
function flushInMemoryStoreValuesToDurableStore(store, durableStore, durableStoreErrorHandler, redirects, additionalDurableStoreOperations = []) {
|
|
765
766
|
const durableRecords = create$5(null);
|
|
766
767
|
const evictedRecords = create$5(null);
|
|
767
768
|
const { records, metadata: storeMetadata, visitedIds, refreshedIds, } = store.fallbackStringKeyInMemoryStore;
|
|
@@ -798,6 +799,18 @@ function flushInMemoryStoreValuesToDurableStore(store, durableStore, durableStor
|
|
|
798
799
|
segment: DefaultDurableSegment,
|
|
799
800
|
});
|
|
800
801
|
}
|
|
802
|
+
// redirects
|
|
803
|
+
redirects.forEach((value, key) => {
|
|
804
|
+
durableStoreOperations.push({
|
|
805
|
+
type: 'setEntries',
|
|
806
|
+
entries: {
|
|
807
|
+
[key]: {
|
|
808
|
+
data: { key, redirect: value },
|
|
809
|
+
},
|
|
810
|
+
},
|
|
811
|
+
segment: RedirectDurableSegment,
|
|
812
|
+
});
|
|
813
|
+
});
|
|
801
814
|
// evicts
|
|
802
815
|
const evictedKeys = keys$6(evictedRecords);
|
|
803
816
|
if (evictedKeys.length > 0) {
|
|
@@ -843,6 +856,19 @@ function buildIngestStagingStore(environment) {
|
|
|
843
856
|
return environment.storeBuildIngestionStagingStore();
|
|
844
857
|
}
|
|
845
858
|
|
|
859
|
+
async function reviveRedirects(durableStore, env) {
|
|
860
|
+
const entries = await durableStore.getAllEntries(RedirectDurableSegment);
|
|
861
|
+
if (entries) {
|
|
862
|
+
for (const durableEntry of Object.keys(entries)) {
|
|
863
|
+
const entry = entries[durableEntry];
|
|
864
|
+
const { data: { key, redirect }, } = entry;
|
|
865
|
+
if (entry) {
|
|
866
|
+
env.storeRedirect(key, redirect);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
846
872
|
const AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
847
873
|
const ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
848
874
|
async function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, contextStores, pendingContextStoreKeys, onContextLoaded) {
|
|
@@ -906,13 +932,18 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
906
932
|
// event. If this instance of makeDurable caused that L2 write we can ignore that
|
|
907
933
|
// on change event. This Set helps us do that.
|
|
908
934
|
const pendingContextStoreKeys = new Set();
|
|
935
|
+
// redirects that need to be flushed to the durable store
|
|
936
|
+
const pendingStoreRedirects = new Map();
|
|
909
937
|
const contextStores = create$5(null);
|
|
910
938
|
let initializationPromise = new Promise((resolve) => {
|
|
911
939
|
const finish = () => {
|
|
912
940
|
resolve();
|
|
913
941
|
initializationPromise = undefined;
|
|
914
942
|
};
|
|
915
|
-
|
|
943
|
+
Promise.all([
|
|
944
|
+
reviveTTLOverrides(durableTTLStore, environment),
|
|
945
|
+
reviveRedirects(durableStore, environment),
|
|
946
|
+
]).then(finish);
|
|
916
947
|
});
|
|
917
948
|
//instrumentation for durable store errors
|
|
918
949
|
const durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
|
|
@@ -925,6 +956,8 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
925
956
|
const unsubscribe = durableStore.registerOnChangedListener(async (changes) => {
|
|
926
957
|
const defaultSegmentKeys = [];
|
|
927
958
|
const adapterContextSegmentKeys = [];
|
|
959
|
+
const redirectSegmentKeys = [];
|
|
960
|
+
let shouldBroadcast = false;
|
|
928
961
|
for (let i = 0, len = changes.length; i < len; i++) {
|
|
929
962
|
const change = changes[i];
|
|
930
963
|
// we only care about changes to the data which is stored in the default
|
|
@@ -935,6 +968,20 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
935
968
|
else if (change.segment === AdapterContextSegment) {
|
|
936
969
|
adapterContextSegmentKeys.push(...change.ids);
|
|
937
970
|
}
|
|
971
|
+
else if (change.segment === RedirectDurableSegment) {
|
|
972
|
+
redirectSegmentKeys.push(...change.ids);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
if (redirectSegmentKeys.length > 0) {
|
|
976
|
+
const redirectEntries = await durableStore.getEntries(redirectSegmentKeys, RedirectDurableSegment);
|
|
977
|
+
if (redirectEntries !== undefined) {
|
|
978
|
+
const redirectKeys = Object.keys(redirectEntries);
|
|
979
|
+
for (const key of redirectKeys) {
|
|
980
|
+
const redirectData = redirectEntries[key];
|
|
981
|
+
environment.storeRedirect(redirectData.data.key, redirectData.data.redirect);
|
|
982
|
+
shouldBroadcast = true;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
938
985
|
}
|
|
939
986
|
// process adapter context changes
|
|
940
987
|
const adapterContextKeysFromDifferentInstance = [];
|
|
@@ -971,10 +1018,6 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
971
1018
|
if (defaultSegmentKeysLength > 0) {
|
|
972
1019
|
for (let i = 0; i < defaultSegmentKeysLength; i++) {
|
|
973
1020
|
const key = defaultSegmentKeys[i];
|
|
974
|
-
const canonical = environment.storeGetCanonicalKey(key);
|
|
975
|
-
if (canonical !== key) {
|
|
976
|
-
continue;
|
|
977
|
-
}
|
|
978
1021
|
// TODO: W-8909393 If expiration is the only thing that changed we should not evict the data... so
|
|
979
1022
|
// if we stored expiration and data at different keys (or same keys in different segments)
|
|
980
1023
|
// then we could know if only the expiration has changed and we wouldn't need to evict
|
|
@@ -982,6 +1025,9 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
982
1025
|
// call base environment storeEvict so this evict is not tracked for durable deletion
|
|
983
1026
|
environment.storeEvict(key);
|
|
984
1027
|
}
|
|
1028
|
+
shouldBroadcast = true;
|
|
1029
|
+
}
|
|
1030
|
+
if (shouldBroadcast) {
|
|
985
1031
|
await environment.storeBroadcast(rebuildSnapshot, environment.snapshotAvailable);
|
|
986
1032
|
}
|
|
987
1033
|
});
|
|
@@ -1037,7 +1083,8 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
1037
1083
|
if (ingestStagingStore === null) {
|
|
1038
1084
|
return Promise.resolve();
|
|
1039
1085
|
}
|
|
1040
|
-
const promise = flushInMemoryStoreValuesToDurableStore(ingestStagingStore, durableStore, durableStoreErrorHandler, additionalDurableStoreOperations);
|
|
1086
|
+
const promise = flushInMemoryStoreValuesToDurableStore(ingestStagingStore, durableStore, durableStoreErrorHandler, new Map(pendingStoreRedirects), additionalDurableStoreOperations);
|
|
1087
|
+
pendingStoreRedirects.clear();
|
|
1041
1088
|
ingestStagingStore = null;
|
|
1042
1089
|
return promise;
|
|
1043
1090
|
};
|
|
@@ -1119,6 +1166,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
1119
1166
|
};
|
|
1120
1167
|
const storeRedirect = function (existingKey, canonicalKey) {
|
|
1121
1168
|
validateNotDisposed();
|
|
1169
|
+
pendingStoreRedirects.set(existingKey, canonicalKey);
|
|
1122
1170
|
// call redirect on staging store so "old" keys are removed from L2 on
|
|
1123
1171
|
// the next publishChangesToDurableStore. NOTE: we don't need to call
|
|
1124
1172
|
// redirect on the base environment store because staging store and base
|
|
@@ -4830,7 +4878,6 @@ function buildLuvioOverrideForDraftAdapters(luvio, handler, extractTargetIdFromC
|
|
|
4830
4878
|
}
|
|
4831
4879
|
|
|
4832
4880
|
const DraftIdMappingKeyPrefix240 = 'DraftIdMapping::';
|
|
4833
|
-
const DraftKeyMappingKeyPrefix = 'DraftKeyMapping::V2::';
|
|
4834
4881
|
const DRAFT_ID_MAPPINGS_SEGMENT = 'DRAFT_ID_MAPPINGS';
|
|
4835
4882
|
function isLegacyDraftIdMapping(key, data) {
|
|
4836
4883
|
return key.startsWith(DraftIdMappingKeyPrefix240);
|
|
@@ -4840,9 +4887,6 @@ function isLegacyDraftIdMapping(key, data) {
|
|
|
4840
4887
|
function getRecordKeyForId$1(id) {
|
|
4841
4888
|
return `UiApi::RecordRepresentation:${id}`;
|
|
4842
4889
|
}
|
|
4843
|
-
function generateDraftIdMappingKey(draftIdMapping) {
|
|
4844
|
-
return `${DraftKeyMappingKeyPrefix}${draftIdMapping.draftKey}::${draftIdMapping.canonicalKey}`;
|
|
4845
|
-
}
|
|
4846
4890
|
/**
|
|
4847
4891
|
*
|
|
4848
4892
|
* @param mappingIds (optional) requested mapping ids, if undefined all will be retrieved
|
|
@@ -4876,6 +4920,15 @@ async function getDraftIdMappings(durableStore, mappingIds) {
|
|
|
4876
4920
|
}
|
|
4877
4921
|
return mappings;
|
|
4878
4922
|
}
|
|
4923
|
+
async function clearDraftIdSegment(durableStore) {
|
|
4924
|
+
const entries = await durableStore.getAllEntries(DRAFT_ID_MAPPINGS_SEGMENT);
|
|
4925
|
+
if (entries) {
|
|
4926
|
+
const keys$1 = keys$4(entries);
|
|
4927
|
+
if (keys$1.length > 0) {
|
|
4928
|
+
await durableStore.evictEntries(keys$1, DRAFT_ID_MAPPINGS_SEGMENT);
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
}
|
|
4879
4932
|
|
|
4880
4933
|
/**
|
|
4881
4934
|
* Generates a time-ordered, unique id to associate with a DraftAction. Ensures
|
|
@@ -4966,9 +5019,6 @@ function customActionHandler(executor, id, draftQueue) {
|
|
|
4966
5019
|
});
|
|
4967
5020
|
return queueOperations;
|
|
4968
5021
|
};
|
|
4969
|
-
const getRedirectMappings = (_action) => {
|
|
4970
|
-
return undefined;
|
|
4971
|
-
};
|
|
4972
5022
|
return {
|
|
4973
5023
|
handlerId: id,
|
|
4974
5024
|
enqueue: (data) => {
|
|
@@ -4980,7 +5030,6 @@ function customActionHandler(executor, id, draftQueue) {
|
|
|
4980
5030
|
handleReplaceAction: () => {
|
|
4981
5031
|
throw Error('replaceAction not supported for custom actions');
|
|
4982
5032
|
},
|
|
4983
|
-
getRedirectMappings,
|
|
4984
5033
|
handleActionRemoved: () => Promise.resolve(),
|
|
4985
5034
|
handleActionCompleted: () => Promise.resolve(),
|
|
4986
5035
|
handleActionEnqueued: () => Promise.resolve(),
|
|
@@ -5155,17 +5204,11 @@ class DurableDraftQueue {
|
|
|
5155
5204
|
const handler = this.getHandler(action.handler);
|
|
5156
5205
|
let queue = await this.getQueueActions();
|
|
5157
5206
|
const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
: idAndKeyMappings.map((m) => {
|
|
5162
|
-
return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
|
|
5163
|
-
});
|
|
5164
|
-
await this.draftStore.completeAction(queueOperations, keyMappings);
|
|
5165
|
-
queue = await this.getQueueActions();
|
|
5207
|
+
// write the queue operations to the store prior to ingesting the result
|
|
5208
|
+
await this.draftStore.completeAction(queueOperations);
|
|
5209
|
+
await handler.handleActionCompleted(action, queueOperations, values$1(this.handlers));
|
|
5166
5210
|
this.retryIntervalMilliseconds = 0;
|
|
5167
5211
|
this.uploadingActionId = undefined;
|
|
5168
|
-
await handler.handleActionCompleted(action, queueOperations, queue, values$1(this.handlers));
|
|
5169
5212
|
await this.notifyChangedListeners({
|
|
5170
5213
|
type: DraftQueueEventType.ActionCompleted,
|
|
5171
5214
|
action,
|
|
@@ -5488,7 +5531,7 @@ class DurableDraftStore {
|
|
|
5488
5531
|
};
|
|
5489
5532
|
return this.enqueueAction(deleteAction);
|
|
5490
5533
|
}
|
|
5491
|
-
completeAction(queueOperations
|
|
5534
|
+
completeAction(queueOperations) {
|
|
5492
5535
|
const action = () => {
|
|
5493
5536
|
const durableStoreOperations = [];
|
|
5494
5537
|
const { draftStore } = this;
|
|
@@ -5521,18 +5564,6 @@ class DurableDraftStore {
|
|
|
5521
5564
|
});
|
|
5522
5565
|
}
|
|
5523
5566
|
}
|
|
5524
|
-
if (mappings !== undefined) {
|
|
5525
|
-
const entries = {};
|
|
5526
|
-
for (const mapping of mappings) {
|
|
5527
|
-
const mappingKey = generateDraftIdMappingKey(mapping);
|
|
5528
|
-
entries[mappingKey] = { data: mapping };
|
|
5529
|
-
}
|
|
5530
|
-
durableStoreOperations.push({
|
|
5531
|
-
entries,
|
|
5532
|
-
type: 'setEntries',
|
|
5533
|
-
segment: DRAFT_ID_MAPPINGS_SEGMENT,
|
|
5534
|
-
});
|
|
5535
|
-
}
|
|
5536
5567
|
return this.durableStore.batchOperations(durableStoreOperations);
|
|
5537
5568
|
};
|
|
5538
5569
|
return this.enqueueAction(action);
|
|
@@ -5811,7 +5842,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
5811
5842
|
},
|
|
5812
5843
|
];
|
|
5813
5844
|
}
|
|
5814
|
-
async handleActionCompleted(action, queueOperations,
|
|
5845
|
+
async handleActionCompleted(action, queueOperations, allHandlers) {
|
|
5815
5846
|
const { data: request, tag } = action;
|
|
5816
5847
|
const { method } = request;
|
|
5817
5848
|
if (method === 'delete') {
|
|
@@ -5925,11 +5956,18 @@ class AbstractResourceRequestActionHandler {
|
|
|
5925
5956
|
async ingestResponses(responses, action) {
|
|
5926
5957
|
const luvio = this.getLuvio();
|
|
5927
5958
|
await luvio.handleSuccessResponse(() => {
|
|
5959
|
+
if (action.status === DraftActionStatus.Completed) {
|
|
5960
|
+
const mappings = this.getRedirectMappings(action);
|
|
5961
|
+
if (mappings) {
|
|
5962
|
+
mappings.forEach((mapping) => {
|
|
5963
|
+
luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
|
|
5964
|
+
});
|
|
5965
|
+
}
|
|
5966
|
+
}
|
|
5928
5967
|
for (const entry of responses) {
|
|
5929
5968
|
const { response, synchronousIngest } = entry;
|
|
5930
5969
|
synchronousIngest(response, action);
|
|
5931
5970
|
}
|
|
5932
|
-
// must call base broadcast
|
|
5933
5971
|
return luvio.storeBroadcast();
|
|
5934
5972
|
},
|
|
5935
5973
|
// getTypeCacheKeysRecord uses the response, not the full path factory
|
|
@@ -6258,6 +6296,8 @@ class DraftManager {
|
|
|
6258
6296
|
|
|
6259
6297
|
function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
|
|
6260
6298
|
const draftMetadata = {};
|
|
6299
|
+
// in 246 luvio took charge of persisting redirect mappings, this needs to stick around
|
|
6300
|
+
// for a couple of releases to support older environments
|
|
6261
6301
|
// setup existing store redirects when bootstrapping the environment
|
|
6262
6302
|
(async () => {
|
|
6263
6303
|
const mappings = await getDraftIdMappings(durableStore);
|
|
@@ -6265,23 +6305,9 @@ function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueu
|
|
|
6265
6305
|
const { draftKey, canonicalKey } = mapping;
|
|
6266
6306
|
env.storeRedirect(draftKey, canonicalKey);
|
|
6267
6307
|
});
|
|
6308
|
+
await env.storeBroadcast(env.rebuildSnapshot, env.snapshotAvailable);
|
|
6309
|
+
await clearDraftIdSegment(durableStore);
|
|
6268
6310
|
})();
|
|
6269
|
-
durableStore.registerOnChangedListener(async (changes) => {
|
|
6270
|
-
const draftIdMappingsIds = [];
|
|
6271
|
-
for (let i = 0, len = changes.length; i < len; i++) {
|
|
6272
|
-
const change = changes[i];
|
|
6273
|
-
if (change.segment === DRAFT_ID_MAPPINGS_SEGMENT) {
|
|
6274
|
-
draftIdMappingsIds.push(...change.ids);
|
|
6275
|
-
}
|
|
6276
|
-
}
|
|
6277
|
-
if (draftIdMappingsIds.length > 0) {
|
|
6278
|
-
const mappings = await getDraftIdMappings(durableStore, draftIdMappingsIds);
|
|
6279
|
-
mappings.forEach((mapping) => {
|
|
6280
|
-
const { draftKey, canonicalKey } = mapping;
|
|
6281
|
-
env.storeRedirect(draftKey, canonicalKey);
|
|
6282
|
-
});
|
|
6283
|
-
}
|
|
6284
|
-
});
|
|
6285
6311
|
const handleSuccessResponse = async function (ingestAndBroadcastFunc, getResponseCacheKeysFunc) {
|
|
6286
6312
|
const queue = await draftQueue.getQueueActions();
|
|
6287
6313
|
if (queue.length === 0) {
|
|
@@ -14717,6 +14743,7 @@ function instrumentAdapter(adapter, metadata) {
|
|
|
14717
14743
|
return instrumentAdapter$1(instrumentedMobileAdapter, metadata, {
|
|
14718
14744
|
trackL1Hits: true,
|
|
14719
14745
|
trackL2Hits: true,
|
|
14746
|
+
trackCacheMisses: true,
|
|
14720
14747
|
reportObserver: (report) => {
|
|
14721
14748
|
for (const observer of reportObservers) {
|
|
14722
14749
|
observer(report);
|
|
@@ -15019,7 +15046,7 @@ class NimbusSqliteStore {
|
|
|
15019
15046
|
registerOnChangedListener(listener) {
|
|
15020
15047
|
let unsubscribeId = undefined;
|
|
15021
15048
|
this.plugin
|
|
15022
|
-
.registerOnChangedListener((changes) => {
|
|
15049
|
+
.registerOnChangedListener(async (changes) => {
|
|
15023
15050
|
const durableChanges = changes.map((c) => {
|
|
15024
15051
|
return {
|
|
15025
15052
|
type: c.type === 'upsert' ? 'setEntries' : 'evictEntries',
|
|
@@ -15028,7 +15055,7 @@ class NimbusSqliteStore {
|
|
|
15028
15055
|
segment: c.context.segment,
|
|
15029
15056
|
};
|
|
15030
15057
|
});
|
|
15031
|
-
listener(durableChanges);
|
|
15058
|
+
await listener(durableChanges);
|
|
15032
15059
|
})
|
|
15033
15060
|
.then((unsub) => {
|
|
15034
15061
|
unsubscribeId = unsub;
|
|
@@ -15970,4 +15997,4 @@ register({
|
|
|
15970
15997
|
});
|
|
15971
15998
|
|
|
15972
15999
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
15973
|
-
// version: 1.
|
|
16000
|
+
// version: 1.146.0-6ca270a7a
|
package/package.json
CHANGED
package/sfdc/main.js
CHANGED
|
@@ -518,6 +518,7 @@ function isDeprecatedDurableStoreEntry(durableRecord) {
|
|
|
518
518
|
return false;
|
|
519
519
|
}
|
|
520
520
|
const DefaultDurableSegment = 'DEFAULT';
|
|
521
|
+
const RedirectDurableSegment = 'REDIRECT_KEYS';
|
|
521
522
|
|
|
522
523
|
const { keys: keys$6, create: create$5, assign: assign$4, freeze: freeze$1 } = Object;
|
|
523
524
|
|
|
@@ -761,7 +762,7 @@ class DurableTTLStore {
|
|
|
761
762
|
}
|
|
762
763
|
}
|
|
763
764
|
|
|
764
|
-
function flushInMemoryStoreValuesToDurableStore(store, durableStore, durableStoreErrorHandler, additionalDurableStoreOperations = []) {
|
|
765
|
+
function flushInMemoryStoreValuesToDurableStore(store, durableStore, durableStoreErrorHandler, redirects, additionalDurableStoreOperations = []) {
|
|
765
766
|
const durableRecords = create$5(null);
|
|
766
767
|
const evictedRecords = create$5(null);
|
|
767
768
|
const { records, metadata: storeMetadata, visitedIds, refreshedIds, } = store.fallbackStringKeyInMemoryStore;
|
|
@@ -798,6 +799,18 @@ function flushInMemoryStoreValuesToDurableStore(store, durableStore, durableStor
|
|
|
798
799
|
segment: DefaultDurableSegment,
|
|
799
800
|
});
|
|
800
801
|
}
|
|
802
|
+
// redirects
|
|
803
|
+
redirects.forEach((value, key) => {
|
|
804
|
+
durableStoreOperations.push({
|
|
805
|
+
type: 'setEntries',
|
|
806
|
+
entries: {
|
|
807
|
+
[key]: {
|
|
808
|
+
data: { key, redirect: value },
|
|
809
|
+
},
|
|
810
|
+
},
|
|
811
|
+
segment: RedirectDurableSegment,
|
|
812
|
+
});
|
|
813
|
+
});
|
|
801
814
|
// evicts
|
|
802
815
|
const evictedKeys = keys$6(evictedRecords);
|
|
803
816
|
if (evictedKeys.length > 0) {
|
|
@@ -843,6 +856,19 @@ function buildIngestStagingStore(environment) {
|
|
|
843
856
|
return environment.storeBuildIngestionStagingStore();
|
|
844
857
|
}
|
|
845
858
|
|
|
859
|
+
async function reviveRedirects(durableStore, env) {
|
|
860
|
+
const entries = await durableStore.getAllEntries(RedirectDurableSegment);
|
|
861
|
+
if (entries) {
|
|
862
|
+
for (const durableEntry of Object.keys(entries)) {
|
|
863
|
+
const entry = entries[durableEntry];
|
|
864
|
+
const { data: { key, redirect }, } = entry;
|
|
865
|
+
if (entry) {
|
|
866
|
+
env.storeRedirect(key, redirect);
|
|
867
|
+
}
|
|
868
|
+
}
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
846
872
|
const AdapterContextSegment = 'ADAPTER-CONTEXT';
|
|
847
873
|
const ADAPTER_CONTEXT_ID_SUFFIX = '__NAMED_CONTEXT';
|
|
848
874
|
async function reviveOrCreateContext(adapterId, durableStore, durableStoreErrorHandler, contextStores, pendingContextStoreKeys, onContextLoaded) {
|
|
@@ -906,13 +932,18 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
906
932
|
// event. If this instance of makeDurable caused that L2 write we can ignore that
|
|
907
933
|
// on change event. This Set helps us do that.
|
|
908
934
|
const pendingContextStoreKeys = new Set();
|
|
935
|
+
// redirects that need to be flushed to the durable store
|
|
936
|
+
const pendingStoreRedirects = new Map();
|
|
909
937
|
const contextStores = create$5(null);
|
|
910
938
|
let initializationPromise = new Promise((resolve) => {
|
|
911
939
|
const finish = () => {
|
|
912
940
|
resolve();
|
|
913
941
|
initializationPromise = undefined;
|
|
914
942
|
};
|
|
915
|
-
|
|
943
|
+
Promise.all([
|
|
944
|
+
reviveTTLOverrides(durableTTLStore, environment),
|
|
945
|
+
reviveRedirects(durableStore, environment),
|
|
946
|
+
]).then(finish);
|
|
916
947
|
});
|
|
917
948
|
//instrumentation for durable store errors
|
|
918
949
|
const durableStoreErrorHandler = handleDurableStoreRejection(instrumentation);
|
|
@@ -925,6 +956,8 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
925
956
|
const unsubscribe = durableStore.registerOnChangedListener(async (changes) => {
|
|
926
957
|
const defaultSegmentKeys = [];
|
|
927
958
|
const adapterContextSegmentKeys = [];
|
|
959
|
+
const redirectSegmentKeys = [];
|
|
960
|
+
let shouldBroadcast = false;
|
|
928
961
|
for (let i = 0, len = changes.length; i < len; i++) {
|
|
929
962
|
const change = changes[i];
|
|
930
963
|
// we only care about changes to the data which is stored in the default
|
|
@@ -935,6 +968,20 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
935
968
|
else if (change.segment === AdapterContextSegment) {
|
|
936
969
|
adapterContextSegmentKeys.push(...change.ids);
|
|
937
970
|
}
|
|
971
|
+
else if (change.segment === RedirectDurableSegment) {
|
|
972
|
+
redirectSegmentKeys.push(...change.ids);
|
|
973
|
+
}
|
|
974
|
+
}
|
|
975
|
+
if (redirectSegmentKeys.length > 0) {
|
|
976
|
+
const redirectEntries = await durableStore.getEntries(redirectSegmentKeys, RedirectDurableSegment);
|
|
977
|
+
if (redirectEntries !== undefined) {
|
|
978
|
+
const redirectKeys = Object.keys(redirectEntries);
|
|
979
|
+
for (const key of redirectKeys) {
|
|
980
|
+
const redirectData = redirectEntries[key];
|
|
981
|
+
environment.storeRedirect(redirectData.data.key, redirectData.data.redirect);
|
|
982
|
+
shouldBroadcast = true;
|
|
983
|
+
}
|
|
984
|
+
}
|
|
938
985
|
}
|
|
939
986
|
// process adapter context changes
|
|
940
987
|
const adapterContextKeysFromDifferentInstance = [];
|
|
@@ -971,10 +1018,6 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
971
1018
|
if (defaultSegmentKeysLength > 0) {
|
|
972
1019
|
for (let i = 0; i < defaultSegmentKeysLength; i++) {
|
|
973
1020
|
const key = defaultSegmentKeys[i];
|
|
974
|
-
const canonical = environment.storeGetCanonicalKey(key);
|
|
975
|
-
if (canonical !== key) {
|
|
976
|
-
continue;
|
|
977
|
-
}
|
|
978
1021
|
// TODO: W-8909393 If expiration is the only thing that changed we should not evict the data... so
|
|
979
1022
|
// if we stored expiration and data at different keys (or same keys in different segments)
|
|
980
1023
|
// then we could know if only the expiration has changed and we wouldn't need to evict
|
|
@@ -982,6 +1025,9 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
982
1025
|
// call base environment storeEvict so this evict is not tracked for durable deletion
|
|
983
1026
|
environment.storeEvict(key);
|
|
984
1027
|
}
|
|
1028
|
+
shouldBroadcast = true;
|
|
1029
|
+
}
|
|
1030
|
+
if (shouldBroadcast) {
|
|
985
1031
|
await environment.storeBroadcast(rebuildSnapshot, environment.snapshotAvailable);
|
|
986
1032
|
}
|
|
987
1033
|
});
|
|
@@ -1037,7 +1083,8 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
1037
1083
|
if (ingestStagingStore === null) {
|
|
1038
1084
|
return Promise.resolve();
|
|
1039
1085
|
}
|
|
1040
|
-
const promise = flushInMemoryStoreValuesToDurableStore(ingestStagingStore, durableStore, durableStoreErrorHandler, additionalDurableStoreOperations);
|
|
1086
|
+
const promise = flushInMemoryStoreValuesToDurableStore(ingestStagingStore, durableStore, durableStoreErrorHandler, new Map(pendingStoreRedirects), additionalDurableStoreOperations);
|
|
1087
|
+
pendingStoreRedirects.clear();
|
|
1041
1088
|
ingestStagingStore = null;
|
|
1042
1089
|
return promise;
|
|
1043
1090
|
};
|
|
@@ -1119,6 +1166,7 @@ function makeDurable(environment, { durableStore, instrumentation }) {
|
|
|
1119
1166
|
};
|
|
1120
1167
|
const storeRedirect = function (existingKey, canonicalKey) {
|
|
1121
1168
|
validateNotDisposed();
|
|
1169
|
+
pendingStoreRedirects.set(existingKey, canonicalKey);
|
|
1122
1170
|
// call redirect on staging store so "old" keys are removed from L2 on
|
|
1123
1171
|
// the next publishChangesToDurableStore. NOTE: we don't need to call
|
|
1124
1172
|
// redirect on the base environment store because staging store and base
|
|
@@ -4830,7 +4878,6 @@ function buildLuvioOverrideForDraftAdapters(luvio, handler, extractTargetIdFromC
|
|
|
4830
4878
|
}
|
|
4831
4879
|
|
|
4832
4880
|
const DraftIdMappingKeyPrefix240 = 'DraftIdMapping::';
|
|
4833
|
-
const DraftKeyMappingKeyPrefix = 'DraftKeyMapping::V2::';
|
|
4834
4881
|
const DRAFT_ID_MAPPINGS_SEGMENT = 'DRAFT_ID_MAPPINGS';
|
|
4835
4882
|
function isLegacyDraftIdMapping(key, data) {
|
|
4836
4883
|
return key.startsWith(DraftIdMappingKeyPrefix240);
|
|
@@ -4840,9 +4887,6 @@ function isLegacyDraftIdMapping(key, data) {
|
|
|
4840
4887
|
function getRecordKeyForId$1(id) {
|
|
4841
4888
|
return `UiApi::RecordRepresentation:${id}`;
|
|
4842
4889
|
}
|
|
4843
|
-
function generateDraftIdMappingKey(draftIdMapping) {
|
|
4844
|
-
return `${DraftKeyMappingKeyPrefix}${draftIdMapping.draftKey}::${draftIdMapping.canonicalKey}`;
|
|
4845
|
-
}
|
|
4846
4890
|
/**
|
|
4847
4891
|
*
|
|
4848
4892
|
* @param mappingIds (optional) requested mapping ids, if undefined all will be retrieved
|
|
@@ -4876,6 +4920,15 @@ async function getDraftIdMappings(durableStore, mappingIds) {
|
|
|
4876
4920
|
}
|
|
4877
4921
|
return mappings;
|
|
4878
4922
|
}
|
|
4923
|
+
async function clearDraftIdSegment(durableStore) {
|
|
4924
|
+
const entries = await durableStore.getAllEntries(DRAFT_ID_MAPPINGS_SEGMENT);
|
|
4925
|
+
if (entries) {
|
|
4926
|
+
const keys$1 = keys$4(entries);
|
|
4927
|
+
if (keys$1.length > 0) {
|
|
4928
|
+
await durableStore.evictEntries(keys$1, DRAFT_ID_MAPPINGS_SEGMENT);
|
|
4929
|
+
}
|
|
4930
|
+
}
|
|
4931
|
+
}
|
|
4879
4932
|
|
|
4880
4933
|
/**
|
|
4881
4934
|
* Generates a time-ordered, unique id to associate with a DraftAction. Ensures
|
|
@@ -4966,9 +5019,6 @@ function customActionHandler(executor, id, draftQueue) {
|
|
|
4966
5019
|
});
|
|
4967
5020
|
return queueOperations;
|
|
4968
5021
|
};
|
|
4969
|
-
const getRedirectMappings = (_action) => {
|
|
4970
|
-
return undefined;
|
|
4971
|
-
};
|
|
4972
5022
|
return {
|
|
4973
5023
|
handlerId: id,
|
|
4974
5024
|
enqueue: (data) => {
|
|
@@ -4980,7 +5030,6 @@ function customActionHandler(executor, id, draftQueue) {
|
|
|
4980
5030
|
handleReplaceAction: () => {
|
|
4981
5031
|
throw Error('replaceAction not supported for custom actions');
|
|
4982
5032
|
},
|
|
4983
|
-
getRedirectMappings,
|
|
4984
5033
|
handleActionRemoved: () => Promise.resolve(),
|
|
4985
5034
|
handleActionCompleted: () => Promise.resolve(),
|
|
4986
5035
|
handleActionEnqueued: () => Promise.resolve(),
|
|
@@ -5155,17 +5204,11 @@ class DurableDraftQueue {
|
|
|
5155
5204
|
const handler = this.getHandler(action.handler);
|
|
5156
5205
|
let queue = await this.getQueueActions();
|
|
5157
5206
|
const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
|
|
5158
|
-
|
|
5159
|
-
|
|
5160
|
-
|
|
5161
|
-
: idAndKeyMappings.map((m) => {
|
|
5162
|
-
return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
|
|
5163
|
-
});
|
|
5164
|
-
await this.draftStore.completeAction(queueOperations, keyMappings);
|
|
5165
|
-
queue = await this.getQueueActions();
|
|
5207
|
+
// write the queue operations to the store prior to ingesting the result
|
|
5208
|
+
await this.draftStore.completeAction(queueOperations);
|
|
5209
|
+
await handler.handleActionCompleted(action, queueOperations, values$1(this.handlers));
|
|
5166
5210
|
this.retryIntervalMilliseconds = 0;
|
|
5167
5211
|
this.uploadingActionId = undefined;
|
|
5168
|
-
await handler.handleActionCompleted(action, queueOperations, queue, values$1(this.handlers));
|
|
5169
5212
|
await this.notifyChangedListeners({
|
|
5170
5213
|
type: DraftQueueEventType.ActionCompleted,
|
|
5171
5214
|
action,
|
|
@@ -5488,7 +5531,7 @@ class DurableDraftStore {
|
|
|
5488
5531
|
};
|
|
5489
5532
|
return this.enqueueAction(deleteAction);
|
|
5490
5533
|
}
|
|
5491
|
-
completeAction(queueOperations
|
|
5534
|
+
completeAction(queueOperations) {
|
|
5492
5535
|
const action = () => {
|
|
5493
5536
|
const durableStoreOperations = [];
|
|
5494
5537
|
const { draftStore } = this;
|
|
@@ -5521,18 +5564,6 @@ class DurableDraftStore {
|
|
|
5521
5564
|
});
|
|
5522
5565
|
}
|
|
5523
5566
|
}
|
|
5524
|
-
if (mappings !== undefined) {
|
|
5525
|
-
const entries = {};
|
|
5526
|
-
for (const mapping of mappings) {
|
|
5527
|
-
const mappingKey = generateDraftIdMappingKey(mapping);
|
|
5528
|
-
entries[mappingKey] = { data: mapping };
|
|
5529
|
-
}
|
|
5530
|
-
durableStoreOperations.push({
|
|
5531
|
-
entries,
|
|
5532
|
-
type: 'setEntries',
|
|
5533
|
-
segment: DRAFT_ID_MAPPINGS_SEGMENT,
|
|
5534
|
-
});
|
|
5535
|
-
}
|
|
5536
5567
|
return this.durableStore.batchOperations(durableStoreOperations);
|
|
5537
5568
|
};
|
|
5538
5569
|
return this.enqueueAction(action);
|
|
@@ -5811,7 +5842,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
5811
5842
|
},
|
|
5812
5843
|
];
|
|
5813
5844
|
}
|
|
5814
|
-
async handleActionCompleted(action, queueOperations,
|
|
5845
|
+
async handleActionCompleted(action, queueOperations, allHandlers) {
|
|
5815
5846
|
const { data: request, tag } = action;
|
|
5816
5847
|
const { method } = request;
|
|
5817
5848
|
if (method === 'delete') {
|
|
@@ -5925,11 +5956,18 @@ class AbstractResourceRequestActionHandler {
|
|
|
5925
5956
|
async ingestResponses(responses, action) {
|
|
5926
5957
|
const luvio = this.getLuvio();
|
|
5927
5958
|
await luvio.handleSuccessResponse(() => {
|
|
5959
|
+
if (action.status === DraftActionStatus.Completed) {
|
|
5960
|
+
const mappings = this.getRedirectMappings(action);
|
|
5961
|
+
if (mappings) {
|
|
5962
|
+
mappings.forEach((mapping) => {
|
|
5963
|
+
luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
|
|
5964
|
+
});
|
|
5965
|
+
}
|
|
5966
|
+
}
|
|
5928
5967
|
for (const entry of responses) {
|
|
5929
5968
|
const { response, synchronousIngest } = entry;
|
|
5930
5969
|
synchronousIngest(response, action);
|
|
5931
5970
|
}
|
|
5932
|
-
// must call base broadcast
|
|
5933
5971
|
return luvio.storeBroadcast();
|
|
5934
5972
|
},
|
|
5935
5973
|
// getTypeCacheKeysRecord uses the response, not the full path factory
|
|
@@ -6258,6 +6296,8 @@ class DraftManager {
|
|
|
6258
6296
|
|
|
6259
6297
|
function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
|
|
6260
6298
|
const draftMetadata = {};
|
|
6299
|
+
// in 246 luvio took charge of persisting redirect mappings, this needs to stick around
|
|
6300
|
+
// for a couple of releases to support older environments
|
|
6261
6301
|
// setup existing store redirects when bootstrapping the environment
|
|
6262
6302
|
(async () => {
|
|
6263
6303
|
const mappings = await getDraftIdMappings(durableStore);
|
|
@@ -6265,23 +6305,9 @@ function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueu
|
|
|
6265
6305
|
const { draftKey, canonicalKey } = mapping;
|
|
6266
6306
|
env.storeRedirect(draftKey, canonicalKey);
|
|
6267
6307
|
});
|
|
6308
|
+
await env.storeBroadcast(env.rebuildSnapshot, env.snapshotAvailable);
|
|
6309
|
+
await clearDraftIdSegment(durableStore);
|
|
6268
6310
|
})();
|
|
6269
|
-
durableStore.registerOnChangedListener(async (changes) => {
|
|
6270
|
-
const draftIdMappingsIds = [];
|
|
6271
|
-
for (let i = 0, len = changes.length; i < len; i++) {
|
|
6272
|
-
const change = changes[i];
|
|
6273
|
-
if (change.segment === DRAFT_ID_MAPPINGS_SEGMENT) {
|
|
6274
|
-
draftIdMappingsIds.push(...change.ids);
|
|
6275
|
-
}
|
|
6276
|
-
}
|
|
6277
|
-
if (draftIdMappingsIds.length > 0) {
|
|
6278
|
-
const mappings = await getDraftIdMappings(durableStore, draftIdMappingsIds);
|
|
6279
|
-
mappings.forEach((mapping) => {
|
|
6280
|
-
const { draftKey, canonicalKey } = mapping;
|
|
6281
|
-
env.storeRedirect(draftKey, canonicalKey);
|
|
6282
|
-
});
|
|
6283
|
-
}
|
|
6284
|
-
});
|
|
6285
6311
|
const handleSuccessResponse = async function (ingestAndBroadcastFunc, getResponseCacheKeysFunc) {
|
|
6286
6312
|
const queue = await draftQueue.getQueueActions();
|
|
6287
6313
|
if (queue.length === 0) {
|
|
@@ -14717,6 +14743,7 @@ function instrumentAdapter(adapter, metadata) {
|
|
|
14717
14743
|
return instrumentAdapter$1(instrumentedMobileAdapter, metadata, {
|
|
14718
14744
|
trackL1Hits: true,
|
|
14719
14745
|
trackL2Hits: true,
|
|
14746
|
+
trackCacheMisses: true,
|
|
14720
14747
|
reportObserver: (report) => {
|
|
14721
14748
|
for (const observer of reportObservers) {
|
|
14722
14749
|
observer(report);
|
|
@@ -15019,7 +15046,7 @@ class NimbusSqliteStore {
|
|
|
15019
15046
|
registerOnChangedListener(listener) {
|
|
15020
15047
|
let unsubscribeId = undefined;
|
|
15021
15048
|
this.plugin
|
|
15022
|
-
.registerOnChangedListener((changes) => {
|
|
15049
|
+
.registerOnChangedListener(async (changes) => {
|
|
15023
15050
|
const durableChanges = changes.map((c) => {
|
|
15024
15051
|
return {
|
|
15025
15052
|
type: c.type === 'upsert' ? 'setEntries' : 'evictEntries',
|
|
@@ -15028,7 +15055,7 @@ class NimbusSqliteStore {
|
|
|
15028
15055
|
segment: c.context.segment,
|
|
15029
15056
|
};
|
|
15030
15057
|
});
|
|
15031
|
-
listener(durableChanges);
|
|
15058
|
+
await listener(durableChanges);
|
|
15032
15059
|
})
|
|
15033
15060
|
.then((unsub) => {
|
|
15034
15061
|
unsubscribeId = unsub;
|
|
@@ -15970,4 +15997,4 @@ register({
|
|
|
15970
15997
|
});
|
|
15971
15998
|
|
|
15972
15999
|
export { getRuntime, registerReportObserver, reportGraphqlQueryParseError };
|
|
15973
|
-
// version: 1.
|
|
16000
|
+
// version: 1.146.0-6ca270a7a
|