@salesforce/lds-worker-api 1.451.0-dev2 → 1.452.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.
|
@@ -1373,4 +1373,4 @@ if (process.env.NODE_ENV !== 'production') {
|
|
|
1373
1373
|
}
|
|
1374
1374
|
|
|
1375
1375
|
export { createPrimingSession, draftManager, draftQueue, evictCacheRecordsByIds, evictExpiredCacheEntries, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, importLuvioAdapterModule, importOneStoreAdapterModule, invokeAdapter, invokeAdapterWithDraftToMerge, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, setMetadataTTL, setUiApiRecordTTL, stopEviction, subscribeToAdapter };
|
|
1376
|
-
// version: 1.
|
|
1376
|
+
// version: 1.452.0-bcd113b7fd
|
|
@@ -4276,7 +4276,7 @@ function withDefaultLuvio(callback) {
|
|
|
4276
4276
|
}
|
|
4277
4277
|
callbacks.push(callback);
|
|
4278
4278
|
}
|
|
4279
|
-
// version: 1.
|
|
4279
|
+
// version: 1.452.0-bcd113b7fd
|
|
4280
4280
|
|
|
4281
4281
|
// TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
|
|
4282
4282
|
function instrumentAdapter$1(createFunction, _metadata) {
|
|
@@ -5320,7 +5320,7 @@ function createGraphQLWireAdapterConstructor(luvio, adapter, metadata, astResolv
|
|
|
5320
5320
|
const { apiFamily, name } = metadata;
|
|
5321
5321
|
return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
|
|
5322
5322
|
}
|
|
5323
|
-
// version: 1.
|
|
5323
|
+
// version: 1.452.0-bcd113b7fd
|
|
5324
5324
|
|
|
5325
5325
|
function isSupportedEntity(_objectApiName) {
|
|
5326
5326
|
return true;
|
|
@@ -32547,7 +32547,7 @@ withDefaultLuvio((luvio) => {
|
|
|
32547
32547
|
throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
|
|
32548
32548
|
throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
|
|
32549
32549
|
});
|
|
32550
|
-
// version: 1.
|
|
32550
|
+
// version: 1.452.0-1ecfe8af95
|
|
32551
32551
|
|
|
32552
32552
|
var draftQueueMaxRetryAttemptsGate = {
|
|
32553
32553
|
isOpen: function (e) {
|
|
@@ -32558,6 +32558,15 @@ var draftQueueMaxRetryAttemptsGate = {
|
|
|
32558
32558
|
},
|
|
32559
32559
|
};
|
|
32560
32560
|
|
|
32561
|
+
var draftQueueRedirectScanGate = {
|
|
32562
|
+
isOpen: function (e) {
|
|
32563
|
+
return e.fallback;
|
|
32564
|
+
},
|
|
32565
|
+
hasError: function () {
|
|
32566
|
+
return !0;
|
|
32567
|
+
},
|
|
32568
|
+
};
|
|
32569
|
+
|
|
32561
32570
|
var rotateIdempotencyKeyOn400Killswitch = {
|
|
32562
32571
|
isOpen: function (e) {
|
|
32563
32572
|
return e.fallback;
|
|
@@ -44103,6 +44112,15 @@ var graphqlPartialEmitParity = {
|
|
|
44103
44112
|
},
|
|
44104
44113
|
};
|
|
44105
44114
|
|
|
44115
|
+
var draftQueueStoreSnapshotGate = {
|
|
44116
|
+
isOpen: function (e) {
|
|
44117
|
+
return e.fallback;
|
|
44118
|
+
},
|
|
44119
|
+
hasError: function () {
|
|
44120
|
+
return !0;
|
|
44121
|
+
},
|
|
44122
|
+
};
|
|
44123
|
+
|
|
44106
44124
|
var ldsAdapterO11yLoggingGate = {
|
|
44107
44125
|
isOpen: function (e) {
|
|
44108
44126
|
return e.fallback;
|
|
@@ -45892,6 +45910,15 @@ function resolveAndValidateGraphQLDocument(query, operationName, options) {
|
|
|
45892
45910
|
return ok$3(document);
|
|
45893
45911
|
}
|
|
45894
45912
|
|
|
45913
|
+
var draftQueueSideEffectMapGate = {
|
|
45914
|
+
isOpen: function (e) {
|
|
45915
|
+
return e.fallback;
|
|
45916
|
+
},
|
|
45917
|
+
hasError: function () {
|
|
45918
|
+
return !0;
|
|
45919
|
+
},
|
|
45920
|
+
};
|
|
45921
|
+
|
|
45895
45922
|
var productConsumedSideEffects = {
|
|
45896
45923
|
isOpen: function (e) {
|
|
45897
45924
|
return e.fallback;
|
|
@@ -48214,7 +48241,7 @@ class DurableDraftQueue {
|
|
|
48214
48241
|
}
|
|
48215
48242
|
return handler;
|
|
48216
48243
|
}
|
|
48217
|
-
constructor(draftStore) {
|
|
48244
|
+
constructor(draftStore, instrumentation) {
|
|
48218
48245
|
this.retryIntervalMilliseconds = 0;
|
|
48219
48246
|
this.minimumRetryInterval = 250;
|
|
48220
48247
|
this.maximumRetryInterval = 32000;
|
|
@@ -48231,6 +48258,7 @@ class DurableDraftQueue {
|
|
|
48231
48258
|
this.handlers = {};
|
|
48232
48259
|
this.draftStore = draftStore;
|
|
48233
48260
|
this.workerPool = new AsyncWorkerPool(1);
|
|
48261
|
+
this.instrumentation = instrumentation;
|
|
48234
48262
|
}
|
|
48235
48263
|
addHandler(handler) {
|
|
48236
48264
|
const id = handler.handlerId;
|
|
@@ -48321,15 +48349,22 @@ class DurableDraftQueue {
|
|
|
48321
48349
|
this.state = DraftQueueState.Stopped;
|
|
48322
48350
|
}
|
|
48323
48351
|
async getQueueActions() {
|
|
48352
|
+
// W-23515682: time the whole call, including this queue's own internal
|
|
48353
|
+
// this.getQueueActions() during a drain — the amplification signal an external wrapper
|
|
48354
|
+
// cannot see. Measure-only; control flow below is unchanged.
|
|
48355
|
+
const { instrumentation } = this;
|
|
48356
|
+
const start = instrumentation?.onGetQueueActions !== undefined ? Date.now() : 0;
|
|
48324
48357
|
const drafts = (await this.draftStore.getAllDrafts());
|
|
48325
48358
|
const queue = [];
|
|
48326
48359
|
drafts.forEach((draft) => {
|
|
48327
48360
|
if (draft.id === this.uploadingActionId) {
|
|
48328
|
-
draft
|
|
48361
|
+
queue.push({ ...draft, status: DraftActionStatus.Uploading });
|
|
48362
|
+
}
|
|
48363
|
+
else {
|
|
48364
|
+
queue.push(draft);
|
|
48329
48365
|
}
|
|
48330
|
-
queue.push(draft);
|
|
48331
48366
|
});
|
|
48332
|
-
|
|
48367
|
+
const sorted = queue.sort((a, b) => {
|
|
48333
48368
|
const aTime = parseInt(a.id, 10);
|
|
48334
48369
|
const bTime = parseInt(b.id, 10);
|
|
48335
48370
|
// safety check
|
|
@@ -48341,6 +48376,8 @@ class DurableDraftQueue {
|
|
|
48341
48376
|
}
|
|
48342
48377
|
return aTime - bTime;
|
|
48343
48378
|
});
|
|
48379
|
+
instrumentation?.onGetQueueActions?.(Date.now() - start, sorted.length);
|
|
48380
|
+
return sorted;
|
|
48344
48381
|
}
|
|
48345
48382
|
async enqueue(handlerId, data, observabilityContext) {
|
|
48346
48383
|
return this.workerPool.push({
|
|
@@ -48489,6 +48526,8 @@ class DurableDraftQueue {
|
|
|
48489
48526
|
const listener = draftQueueChangedListeners[i];
|
|
48490
48527
|
results.push(listener(event));
|
|
48491
48528
|
}
|
|
48529
|
+
// W-23515682: listener fan-out per event type. Measure-only.
|
|
48530
|
+
this.instrumentation?.onNotifyChangedListeners?.(event.type, draftQueueLen);
|
|
48492
48531
|
await Promise.all(results);
|
|
48493
48532
|
}
|
|
48494
48533
|
/**
|
|
@@ -48736,36 +48775,66 @@ function buildDraftDurableStoreKey(recordKey, draftActionId) {
|
|
|
48736
48775
|
*
|
|
48737
48776
|
*/
|
|
48738
48777
|
class DurableDraftStore {
|
|
48739
|
-
constructor(durableStore) {
|
|
48778
|
+
constructor(durableStore, instrumentation, useSnapshot = true) {
|
|
48740
48779
|
this.draftStore = {};
|
|
48780
|
+
// Snapshot: holds deep clones of each draft, refreshed at write time.
|
|
48781
|
+
// getAllDrafts serves from this snapshot with zero deep clones per read.
|
|
48782
|
+
this.cleanSnapshot = {};
|
|
48741
48783
|
// queue of writes that were made during the initial sync
|
|
48742
48784
|
this.writeQueue = [];
|
|
48743
48785
|
this.durableStore = durableStore;
|
|
48786
|
+
this.instrumentation = instrumentation;
|
|
48787
|
+
this.useSnapshot = useSnapshot;
|
|
48744
48788
|
this.resyncDraftStore();
|
|
48745
48789
|
}
|
|
48790
|
+
// When no instrumentation is injected the promise is returned as-is (zero overhead).
|
|
48791
|
+
timeDurableOp(op, segment, run) {
|
|
48792
|
+
const onDurableOperation = this.instrumentation?.onDurableOperation;
|
|
48793
|
+
if (onDurableOperation === undefined) {
|
|
48794
|
+
return run();
|
|
48795
|
+
}
|
|
48796
|
+
const start = Date.now();
|
|
48797
|
+
return run().finally(() => {
|
|
48798
|
+
onDurableOperation(op, segment, Date.now() - start);
|
|
48799
|
+
});
|
|
48800
|
+
}
|
|
48746
48801
|
writeAction(action) {
|
|
48747
48802
|
const addAction = () => {
|
|
48748
48803
|
const { id, tag } = action;
|
|
48749
48804
|
this.draftStore[id] = action;
|
|
48805
|
+
this.cleanSnapshot[id] = clone$1(action);
|
|
48750
48806
|
const durableEntryKey = buildDraftDurableStoreKey(tag, id);
|
|
48751
48807
|
const entry = {
|
|
48752
48808
|
data: action,
|
|
48753
48809
|
};
|
|
48754
48810
|
const entries = { [durableEntryKey]: entry };
|
|
48755
|
-
return this.durableStore.setEntries(entries, DRAFT_SEGMENT);
|
|
48811
|
+
return this.timeDurableOp('setEntries', DRAFT_SEGMENT, () => this.durableStore.setEntries(entries, DRAFT_SEGMENT));
|
|
48756
48812
|
};
|
|
48757
48813
|
return this.enqueueAction(addAction);
|
|
48758
48814
|
}
|
|
48759
48815
|
getAllDrafts() {
|
|
48760
48816
|
const waitForOngoingSync = this.syncPromise || Promise.resolve();
|
|
48761
48817
|
return waitForOngoingSync.then(() => {
|
|
48762
|
-
const { draftStore } = this;
|
|
48763
|
-
const keys$1 = keys$4(draftStore);
|
|
48764
48818
|
const actionArray = [];
|
|
48765
|
-
|
|
48766
|
-
const
|
|
48767
|
-
|
|
48768
|
-
|
|
48819
|
+
if (this.useSnapshot) {
|
|
48820
|
+
const { cleanSnapshot } = this;
|
|
48821
|
+
const keys$1 = keys$4(cleanSnapshot);
|
|
48822
|
+
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
48823
|
+
const key = keys$1[i];
|
|
48824
|
+
// Return shallow spread of snapshot entries so top-level caller mutations
|
|
48825
|
+
// (e.g., .status =) don't persist into the snapshot. The snapshot itself
|
|
48826
|
+
// is a deep clone of draftStore, so no nested mutation reaches draftStore.
|
|
48827
|
+
actionArray.push({ ...cleanSnapshot[key] });
|
|
48828
|
+
}
|
|
48829
|
+
}
|
|
48830
|
+
else {
|
|
48831
|
+
// Killswitch (W-23515682): original pre-fix behavior — deep-clone every draft on
|
|
48832
|
+
// every read so the internal draft store is never exposed. O(N) clones per read.
|
|
48833
|
+
const { draftStore } = this;
|
|
48834
|
+
const keys$1 = keys$4(draftStore);
|
|
48835
|
+
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
48836
|
+
actionArray.push(clone$1(draftStore[keys$1[i]]));
|
|
48837
|
+
}
|
|
48769
48838
|
}
|
|
48770
48839
|
return actionArray;
|
|
48771
48840
|
});
|
|
@@ -48775,8 +48844,9 @@ class DurableDraftStore {
|
|
|
48775
48844
|
const draft = this.draftStore[id];
|
|
48776
48845
|
if (draft !== undefined) {
|
|
48777
48846
|
delete this.draftStore[id];
|
|
48847
|
+
delete this.cleanSnapshot[id];
|
|
48778
48848
|
const durableKey = buildDraftDurableStoreKey(draft.tag, draft.id);
|
|
48779
|
-
return this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT);
|
|
48849
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT));
|
|
48780
48850
|
}
|
|
48781
48851
|
return Promise.resolve();
|
|
48782
48852
|
};
|
|
@@ -48792,10 +48862,11 @@ class DurableDraftStore {
|
|
|
48792
48862
|
const action = draftStore[key];
|
|
48793
48863
|
if (action.tag === tag) {
|
|
48794
48864
|
delete draftStore[action.id];
|
|
48865
|
+
delete this.cleanSnapshot[action.id];
|
|
48795
48866
|
durableKeys.push(buildDraftDurableStoreKey(action.tag, action.id));
|
|
48796
48867
|
}
|
|
48797
48868
|
}
|
|
48798
|
-
return this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT);
|
|
48869
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT));
|
|
48799
48870
|
};
|
|
48800
48871
|
return this.enqueueAction(deleteAction);
|
|
48801
48872
|
}
|
|
@@ -48809,6 +48880,7 @@ class DurableDraftStore {
|
|
|
48809
48880
|
const action = draftStore[operation.id];
|
|
48810
48881
|
if (action !== undefined) {
|
|
48811
48882
|
delete draftStore[operation.id];
|
|
48883
|
+
delete this.cleanSnapshot[operation.id];
|
|
48812
48884
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48813
48885
|
durableStoreOperations.push({
|
|
48814
48886
|
ids: [key],
|
|
@@ -48821,6 +48893,7 @@ class DurableDraftStore {
|
|
|
48821
48893
|
const { action } = operation;
|
|
48822
48894
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48823
48895
|
draftStore[action.id] = action;
|
|
48896
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48824
48897
|
durableStoreOperations.push({
|
|
48825
48898
|
type: 'setEntries',
|
|
48826
48899
|
segment: DRAFT_SEGMENT,
|
|
@@ -48832,7 +48905,7 @@ class DurableDraftStore {
|
|
|
48832
48905
|
});
|
|
48833
48906
|
}
|
|
48834
48907
|
}
|
|
48835
|
-
return this.durableStore.batchOperations(durableStoreOperations);
|
|
48908
|
+
return this.timeDurableOp('batchOperations', DRAFT_SEGMENT, () => this.durableStore.batchOperations(durableStoreOperations));
|
|
48836
48909
|
};
|
|
48837
48910
|
return this.enqueueAction(action);
|
|
48838
48911
|
}
|
|
@@ -48875,6 +48948,7 @@ class DurableDraftStore {
|
|
|
48875
48948
|
.then((durableEntries) => {
|
|
48876
48949
|
if (durableEntries === undefined) {
|
|
48877
48950
|
this.draftStore = {};
|
|
48951
|
+
this.cleanSnapshot = {};
|
|
48878
48952
|
return this.runQueuedOperations();
|
|
48879
48953
|
}
|
|
48880
48954
|
const { draftStore } = this;
|
|
@@ -48883,6 +48957,7 @@ class DurableDraftStore {
|
|
|
48883
48957
|
const entry = durableEntries[keys$1[i]];
|
|
48884
48958
|
const action = entry.data;
|
|
48885
48959
|
draftStore[action.id] = action;
|
|
48960
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48886
48961
|
}
|
|
48887
48962
|
return this.runQueuedOperations();
|
|
48888
48963
|
})
|
|
@@ -80107,6 +80182,14 @@ const DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS = 'draft-queue-total-mergeActions-ca
|
|
|
80107
80182
|
// Used to triage the WOLI duplicate-record investigation in Splunk — correlate by draftId
|
|
80108
80183
|
// with the other draft-queue events. @W-23428669
|
|
80109
80184
|
const DRAFT_QUEUE_IDEMPOTENCY_KEY_ROTATED = 'draft-queue-idempotency-key-rotated';
|
|
80185
|
+
// Hotspot-attribution telemetry (@W-23515682). Operational counts/durations only — no
|
|
80186
|
+
// draft content, field values, or server record ids. These attribute the offline-drain wall-clock
|
|
80187
|
+
// to the O(N^2) hotspots (getQueueActions amplification, listener fan-out, durable-op latency).
|
|
80188
|
+
const DRAFT_QUEUE_GET_QUEUE_ACTIONS_COUNT = 'draft-queue-get-queue-actions-count';
|
|
80189
|
+
const DRAFT_QUEUE_GET_QUEUE_ACTIONS_DURATION = 'draft-queue-get-queue-actions-duration';
|
|
80190
|
+
const DRAFT_QUEUE_NOTIFY_CHANGED_LISTENERS_COUNT = 'draft-queue-notify-changed-listeners-count';
|
|
80191
|
+
const DRAFT_QUEUE_DURABLE_OP_COUNT = 'draft-queue-durable-op-count';
|
|
80192
|
+
const DRAFT_QUEUE_DURABLE_OP_DURATION = 'draft-queue-durable-op-duration';
|
|
80110
80193
|
/** Content Document */
|
|
80111
80194
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
|
|
80112
80195
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
|
|
@@ -80199,6 +80282,33 @@ function reportDraftActionEvent(state, draftCount, message) {
|
|
|
80199
80282
|
break;
|
|
80200
80283
|
}
|
|
80201
80284
|
}
|
|
80285
|
+
/**
|
|
80286
|
+
* @W-23515682: count (amplification — queue re-reads per drain) + duration histogram (the
|
|
80287
|
+
* pre/post signal for the getAllDrafts clone-on-write fix). actionCount is queue depth, never content.
|
|
80288
|
+
*/
|
|
80289
|
+
function reportDraftQueueGetQueueActions(durationMs, actionCount) {
|
|
80290
|
+
const depthBuckets = [1, 2, 5, 10, 20, 50, 100, 250, 500];
|
|
80291
|
+
ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_GET_QUEUE_ACTIONS_COUNT);
|
|
80292
|
+
ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_GET_QUEUE_ACTIONS_DURATION, durationMs);
|
|
80293
|
+
ldsMobileInstrumentation$2.bucketValue(DRAFT_QUEUE_GET_QUEUE_ACTIONS_COUNT + '-depth', actionCount, depthBuckets);
|
|
80294
|
+
}
|
|
80295
|
+
/**
|
|
80296
|
+
* @W-23515682: count per event type — listener fan-out / amplification per event.
|
|
80297
|
+
*/
|
|
80298
|
+
function reportDraftQueueNotifyChangedListeners(eventType, listenerCount) {
|
|
80299
|
+
ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_NOTIFY_CHANGED_LISTENERS_COUNT, listenerCount, undefined, { eventType });
|
|
80300
|
+
}
|
|
80301
|
+
/**
|
|
80302
|
+
* @W-23515682: count + duration histogram by operation kind + segment — attributes the
|
|
80303
|
+
* client-CPU-vs-durable split of per-action processing time.
|
|
80304
|
+
*/
|
|
80305
|
+
function reportDraftQueueDurableOperation(op, segment, durationMs) {
|
|
80306
|
+
ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_DURABLE_OP_COUNT, 1, undefined, {
|
|
80307
|
+
op,
|
|
80308
|
+
segment,
|
|
80309
|
+
});
|
|
80310
|
+
ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_DURABLE_OP_DURATION, durationMs);
|
|
80311
|
+
}
|
|
80202
80312
|
/**
|
|
80203
80313
|
* Reports an exception thrown while uploading a draft action. The thrown error is
|
|
80204
80314
|
* otherwise swallowed by the upload handler's retry path, leaving the failure
|
|
@@ -80682,14 +80792,45 @@ class AbstractResourceRequestActionHandler {
|
|
|
80682
80792
|
let updatedActionTargetId = undefined;
|
|
80683
80793
|
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
80684
80794
|
let { basePath, body } = queueActionRequest;
|
|
80795
|
+
// Literal indexOf pre-check (no RegExp coercion, unlike the old String.search) +
|
|
80796
|
+
// a replace RegExp built only when a reference is present — the win over the old scan.
|
|
80685
80797
|
let stringifiedBody = stringify$5(body);
|
|
80798
|
+
// Read the killswitch once for the whole scan (W-23515682) — avoids a
|
|
80799
|
+
// per-redirect gate lookup in this hot loop.
|
|
80800
|
+
const useOptimizedScan = draftQueueRedirectScanGate.isOpen({ fallback: true });
|
|
80686
80801
|
// for each redirected ID/key we loop over the operation to see if it needs
|
|
80687
80802
|
// to be updated
|
|
80688
80803
|
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
80689
|
-
if (
|
|
80690
|
-
basePath
|
|
80691
|
-
|
|
80692
|
-
|
|
80804
|
+
if (useOptimizedScan) {
|
|
80805
|
+
// basePath AND body are checked independently: a queued action can carry
|
|
80806
|
+
// the draft id in either or BOTH, and each occurrence must be rewritten.
|
|
80807
|
+
const basePathNeedsUpdate = basePath.indexOf(draftId) >= 0;
|
|
80808
|
+
const bodyNeedsUpdate = stringifiedBody.indexOf(draftId) >= 0;
|
|
80809
|
+
if (basePathNeedsUpdate || bodyNeedsUpdate) {
|
|
80810
|
+
// Escape metacharacters so the draft id matches literally. Salesforce
|
|
80811
|
+
// ids carry no regex metacharacters today, so this is defensive against
|
|
80812
|
+
// a future id-format change silently corrupting unrelated ids. W-23515682.
|
|
80813
|
+
const escapedDraftId = draftId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
80814
|
+
const replaceRegex = new RegExp(escapedDraftId, 'g');
|
|
80815
|
+
if (basePathNeedsUpdate) {
|
|
80816
|
+
basePath = basePath.replace(replaceRegex, canonicalId);
|
|
80817
|
+
}
|
|
80818
|
+
if (bodyNeedsUpdate) {
|
|
80819
|
+
stringifiedBody = stringifiedBody.replace(replaceRegex, canonicalId);
|
|
80820
|
+
}
|
|
80821
|
+
queueOperationMutated = true;
|
|
80822
|
+
}
|
|
80823
|
+
}
|
|
80824
|
+
else {
|
|
80825
|
+
// Killswitch closed (W-23515682): original pre-fix scan — String.search
|
|
80826
|
+
// (coerces draftId to a RegExp) + a raw (unescaped) replace RegExp applied
|
|
80827
|
+
// to basePath and body together.
|
|
80828
|
+
if (basePath.search(draftId) >= 0 ||
|
|
80829
|
+
stringifiedBody.search(draftId) >= 0) {
|
|
80830
|
+
basePath = basePath.replace(new RegExp(draftId, 'g'), canonicalId);
|
|
80831
|
+
stringifiedBody = stringifiedBody.replace(new RegExp(draftId, 'g'), canonicalId);
|
|
80832
|
+
queueOperationMutated = true;
|
|
80833
|
+
}
|
|
80693
80834
|
}
|
|
80694
80835
|
// if the action is performed on a previous draft id, we need to replace the action
|
|
80695
80836
|
// with a new one at the updated canonical key
|
|
@@ -90262,6 +90403,20 @@ function obtainFailureMessage(error) {
|
|
|
90262
90403
|
}
|
|
90263
90404
|
}
|
|
90264
90405
|
|
|
90406
|
+
// Mobile impl of the shared DraftQueueInstrumentation seam (@W-23515682). Forwards to
|
|
90407
|
+
// ldsMobileInstrumentation via metrics.ts; injected at construction (DraftQueueFactory).
|
|
90408
|
+
const draftQueueInstrumentation = {
|
|
90409
|
+
onGetQueueActions(durationMs, actionCount) {
|
|
90410
|
+
reportDraftQueueGetQueueActions(durationMs, actionCount);
|
|
90411
|
+
},
|
|
90412
|
+
onNotifyChangedListeners(eventType, listenerCount) {
|
|
90413
|
+
reportDraftQueueNotifyChangedListeners(eventType, listenerCount);
|
|
90414
|
+
},
|
|
90415
|
+
onDurableOperation(op, segment, durationMs) {
|
|
90416
|
+
reportDraftQueueDurableOperation(op, segment, durationMs);
|
|
90417
|
+
},
|
|
90418
|
+
};
|
|
90419
|
+
|
|
90265
90420
|
// so eslint doesn't complain about nimbus
|
|
90266
90421
|
/* global __nimbus */
|
|
90267
90422
|
function buildLdsDraftQueue(durableStore) {
|
|
@@ -90270,7 +90425,8 @@ function buildLdsDraftQueue(durableStore) {
|
|
|
90270
90425
|
__nimbus.plugins.LdsDraftQueue !== undefined) {
|
|
90271
90426
|
return new NimbusDraftQueue();
|
|
90272
90427
|
}
|
|
90273
|
-
const
|
|
90428
|
+
const useSnapshot = draftQueueStoreSnapshotGate.isOpen({ fallback: true });
|
|
90429
|
+
const draftQueue = new DurableDraftQueue(new DurableDraftStore(durableStore, draftQueueInstrumentation, useSnapshot), draftQueueInstrumentation);
|
|
90274
90430
|
return instrumentDraftQueue(draftQueue);
|
|
90275
90431
|
}
|
|
90276
90432
|
|
|
@@ -93601,18 +93757,34 @@ class SideEffectStore {
|
|
|
93601
93757
|
this.initialize();
|
|
93602
93758
|
}
|
|
93603
93759
|
async addEffects(effects) {
|
|
93760
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93604
93761
|
const durableEntries = {};
|
|
93605
93762
|
effects.forEach((effect) => {
|
|
93606
93763
|
durableEntries[effect.uniqueId] = { data: effect };
|
|
93607
93764
|
this.allEffects.set(effect.uniqueId, effect);
|
|
93765
|
+
if (incremental) {
|
|
93766
|
+
this.addEffectToKeyMap(effect);
|
|
93767
|
+
}
|
|
93608
93768
|
});
|
|
93609
|
-
|
|
93769
|
+
// Killswitch (W-23515682): closed → original O(N) full rebuild on every add.
|
|
93770
|
+
if (!incremental) {
|
|
93771
|
+
this.regenerateKeyToEffectMap();
|
|
93772
|
+
}
|
|
93610
93773
|
await this.durableStore.setEntries(durableEntries, SIDE_EFFECT_SEGMENT);
|
|
93611
93774
|
}
|
|
93612
93775
|
async removeEffects(effects) {
|
|
93776
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93613
93777
|
const effectKeys = effects.map((e) => e.uniqueId);
|
|
93614
|
-
effects.forEach((
|
|
93615
|
-
|
|
93778
|
+
effects.forEach((effect) => {
|
|
93779
|
+
this.allEffects.delete(effect.uniqueId);
|
|
93780
|
+
if (incremental) {
|
|
93781
|
+
this.removeEffectFromKeyMap(effect);
|
|
93782
|
+
}
|
|
93783
|
+
});
|
|
93784
|
+
// Killswitch (W-23515682): closed → original O(N) full rebuild on every remove.
|
|
93785
|
+
if (!incremental) {
|
|
93786
|
+
this.regenerateKeyToEffectMap();
|
|
93787
|
+
}
|
|
93616
93788
|
await this.durableStore.evictEntries(effectKeys, SIDE_EFFECT_SEGMENT);
|
|
93617
93789
|
}
|
|
93618
93790
|
getEffects(key) {
|
|
@@ -93647,6 +93819,39 @@ class SideEffectStore {
|
|
|
93647
93819
|
});
|
|
93648
93820
|
this.regenerateKeyToEffectMap();
|
|
93649
93821
|
}
|
|
93822
|
+
addEffectToKeyMap(effect) {
|
|
93823
|
+
const recordEffects = this.keyToEffectMap.get(effect.key);
|
|
93824
|
+
if (recordEffects) {
|
|
93825
|
+
// Effects are keyed by uniqueId (mirroring allEffects.set / regenerateKeyToEffectMap):
|
|
93826
|
+
// a re-add of the same uniqueId must REPLACE the resident entry in place, not append a
|
|
93827
|
+
// duplicate. The action-completion replay path (setSideEffectsForActions on still-queued
|
|
93828
|
+
// actions) re-adds resident effects with no preceding remove; without this dedup a
|
|
93829
|
+
// record-field-increment would sit in the array twice and be applied twice (e.g. a
|
|
93830
|
+
// ProductConsumed QuantityOnHand -=5 becomes -=10). W-23515682.
|
|
93831
|
+
const index = recordEffects.findIndex((e) => e.uniqueId === effect.uniqueId);
|
|
93832
|
+
if (index !== -1) {
|
|
93833
|
+
recordEffects[index] = effect;
|
|
93834
|
+
}
|
|
93835
|
+
else {
|
|
93836
|
+
recordEffects.push(effect);
|
|
93837
|
+
}
|
|
93838
|
+
}
|
|
93839
|
+
else {
|
|
93840
|
+
this.keyToEffectMap.set(effect.key, [effect]);
|
|
93841
|
+
}
|
|
93842
|
+
}
|
|
93843
|
+
removeEffectFromKeyMap(effect) {
|
|
93844
|
+
const recordEffects = this.keyToEffectMap.get(effect.key);
|
|
93845
|
+
if (recordEffects) {
|
|
93846
|
+
const index = recordEffects.findIndex((e) => e.uniqueId === effect.uniqueId);
|
|
93847
|
+
if (index !== -1) {
|
|
93848
|
+
recordEffects.splice(index, 1);
|
|
93849
|
+
if (recordEffects.length === 0) {
|
|
93850
|
+
this.keyToEffectMap.delete(effect.key);
|
|
93851
|
+
}
|
|
93852
|
+
}
|
|
93853
|
+
}
|
|
93854
|
+
}
|
|
93650
93855
|
regenerateKeyToEffectMap() {
|
|
93651
93856
|
this.keyToEffectMap.clear();
|
|
93652
93857
|
this.allEffects.forEach((effect) => {
|
|
@@ -96796,7 +97001,7 @@ function buildServiceDescriptor$b(luvio) {
|
|
|
96796
97001
|
},
|
|
96797
97002
|
};
|
|
96798
97003
|
}
|
|
96799
|
-
// version: 1.
|
|
97004
|
+
// version: 1.452.0-bcd113b7fd
|
|
96800
97005
|
|
|
96801
97006
|
/**
|
|
96802
97007
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -96822,7 +97027,7 @@ function buildServiceDescriptor$a(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
96822
97027
|
},
|
|
96823
97028
|
};
|
|
96824
97029
|
}
|
|
96825
|
-
// version: 1.
|
|
97030
|
+
// version: 1.452.0-bcd113b7fd
|
|
96826
97031
|
|
|
96827
97032
|
function findExecutableOperation$1(input) {
|
|
96828
97033
|
const operations = input.query.definitions.filter(
|
|
@@ -99531,7 +99736,7 @@ register$1({
|
|
|
99531
99736
|
id: '@salesforce/lds-network-adapter',
|
|
99532
99737
|
instrument: instrument$2,
|
|
99533
99738
|
});
|
|
99534
|
-
// version: 1.
|
|
99739
|
+
// version: 1.452.0-bcd113b7fd
|
|
99535
99740
|
|
|
99536
99741
|
const { create: create$2, keys: keys$2 } = Object;
|
|
99537
99742
|
const { stringify, parse } = JSON;
|
|
@@ -107066,7 +107271,7 @@ function registerCallback(cb) {
|
|
|
107066
107271
|
cb(graphql_v1_import, graphql_imperative$1, graphql_imperative_legacy_v1_import, graphql_state_manager, useOneStoreGraphQL);
|
|
107067
107272
|
}
|
|
107068
107273
|
}
|
|
107069
|
-
// version: 1.
|
|
107274
|
+
// version: 1.452.0-1ecfe8af95
|
|
107070
107275
|
|
|
107071
107276
|
function createFragmentMap(documentNode) {
|
|
107072
107277
|
const fragments = {};
|
|
@@ -136309,7 +136514,7 @@ register$1({
|
|
|
136309
136514
|
configuration: { ...configurationForGraphQLAdapters$1 },
|
|
136310
136515
|
instrument: instrument$1,
|
|
136311
136516
|
});
|
|
136312
|
-
// version: 1.
|
|
136517
|
+
// version: 1.452.0-1ecfe8af95
|
|
136313
136518
|
|
|
136314
136519
|
// On core the unstable adapters are re-exported with different names,
|
|
136315
136520
|
// we want to match them here.
|
|
@@ -136461,7 +136666,7 @@ withDefaultLuvio((luvio) => {
|
|
|
136461
136666
|
unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
|
|
136462
136667
|
graphQLImperative = ldsAdapter;
|
|
136463
136668
|
});
|
|
136464
|
-
// version: 1.
|
|
136669
|
+
// version: 1.452.0-1ecfe8af95
|
|
136465
136670
|
|
|
136466
136671
|
var gqlApi = /*#__PURE__*/Object.freeze({
|
|
136467
136672
|
__proto__: null,
|
|
@@ -137260,7 +137465,7 @@ const callbacks$1 = [];
|
|
|
137260
137465
|
function register(r) {
|
|
137261
137466
|
callbacks$1.forEach((callback) => callback(r));
|
|
137262
137467
|
}
|
|
137263
|
-
// version: 1.
|
|
137468
|
+
// version: 1.452.0-bcd113b7fd
|
|
137264
137469
|
|
|
137265
137470
|
/**
|
|
137266
137471
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -138549,4 +138754,4 @@ const { luvio } = getRuntime();
|
|
|
138549
138754
|
setDefaultLuvio({ luvio });
|
|
138550
138755
|
|
|
138551
138756
|
export { createPrimingSession, draftManager, draftQueue, evictCacheRecordsByIds, evictExpiredCacheEntries, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, importLuvioAdapterModule, importOneStoreAdapterModule, invokeAdapter, invokeAdapterWithDraftToMerge, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, registerReportObserver, setMetadataTTL, setUiApiRecordTTL, stopEviction, subscribeToAdapter };
|
|
138552
|
-
// version: 1.
|
|
138757
|
+
// version: 1.452.0-bcd113b7fd
|
|
@@ -4282,7 +4282,7 @@
|
|
|
4282
4282
|
}
|
|
4283
4283
|
callbacks.push(callback);
|
|
4284
4284
|
}
|
|
4285
|
-
// version: 1.
|
|
4285
|
+
// version: 1.452.0-bcd113b7fd
|
|
4286
4286
|
|
|
4287
4287
|
// TODO [TD-0081508]: once that TD is fulfilled we can probably change this file
|
|
4288
4288
|
function instrumentAdapter$1(createFunction, _metadata) {
|
|
@@ -5326,7 +5326,7 @@
|
|
|
5326
5326
|
const { apiFamily, name } = metadata;
|
|
5327
5327
|
return createGraphQLWireAdapterConstructor$1(adapter, `${apiFamily}.${name}`, luvio, astResolver);
|
|
5328
5328
|
}
|
|
5329
|
-
// version: 1.
|
|
5329
|
+
// version: 1.452.0-bcd113b7fd
|
|
5330
5330
|
|
|
5331
5331
|
function isSupportedEntity(_objectApiName) {
|
|
5332
5332
|
return true;
|
|
@@ -32553,7 +32553,7 @@
|
|
|
32553
32553
|
throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
|
|
32554
32554
|
throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
|
|
32555
32555
|
});
|
|
32556
|
-
// version: 1.
|
|
32556
|
+
// version: 1.452.0-1ecfe8af95
|
|
32557
32557
|
|
|
32558
32558
|
var draftQueueMaxRetryAttemptsGate = {
|
|
32559
32559
|
isOpen: function (e) {
|
|
@@ -32564,6 +32564,15 @@
|
|
|
32564
32564
|
},
|
|
32565
32565
|
};
|
|
32566
32566
|
|
|
32567
|
+
var draftQueueRedirectScanGate = {
|
|
32568
|
+
isOpen: function (e) {
|
|
32569
|
+
return e.fallback;
|
|
32570
|
+
},
|
|
32571
|
+
hasError: function () {
|
|
32572
|
+
return !0;
|
|
32573
|
+
},
|
|
32574
|
+
};
|
|
32575
|
+
|
|
32567
32576
|
var rotateIdempotencyKeyOn400Killswitch = {
|
|
32568
32577
|
isOpen: function (e) {
|
|
32569
32578
|
return e.fallback;
|
|
@@ -44109,6 +44118,15 @@
|
|
|
44109
44118
|
},
|
|
44110
44119
|
};
|
|
44111
44120
|
|
|
44121
|
+
var draftQueueStoreSnapshotGate = {
|
|
44122
|
+
isOpen: function (e) {
|
|
44123
|
+
return e.fallback;
|
|
44124
|
+
},
|
|
44125
|
+
hasError: function () {
|
|
44126
|
+
return !0;
|
|
44127
|
+
},
|
|
44128
|
+
};
|
|
44129
|
+
|
|
44112
44130
|
var ldsAdapterO11yLoggingGate = {
|
|
44113
44131
|
isOpen: function (e) {
|
|
44114
44132
|
return e.fallback;
|
|
@@ -45898,6 +45916,15 @@
|
|
|
45898
45916
|
return ok$3(document);
|
|
45899
45917
|
}
|
|
45900
45918
|
|
|
45919
|
+
var draftQueueSideEffectMapGate = {
|
|
45920
|
+
isOpen: function (e) {
|
|
45921
|
+
return e.fallback;
|
|
45922
|
+
},
|
|
45923
|
+
hasError: function () {
|
|
45924
|
+
return !0;
|
|
45925
|
+
},
|
|
45926
|
+
};
|
|
45927
|
+
|
|
45901
45928
|
var productConsumedSideEffects = {
|
|
45902
45929
|
isOpen: function (e) {
|
|
45903
45930
|
return e.fallback;
|
|
@@ -48220,7 +48247,7 @@
|
|
|
48220
48247
|
}
|
|
48221
48248
|
return handler;
|
|
48222
48249
|
}
|
|
48223
|
-
constructor(draftStore) {
|
|
48250
|
+
constructor(draftStore, instrumentation) {
|
|
48224
48251
|
this.retryIntervalMilliseconds = 0;
|
|
48225
48252
|
this.minimumRetryInterval = 250;
|
|
48226
48253
|
this.maximumRetryInterval = 32000;
|
|
@@ -48237,6 +48264,7 @@
|
|
|
48237
48264
|
this.handlers = {};
|
|
48238
48265
|
this.draftStore = draftStore;
|
|
48239
48266
|
this.workerPool = new AsyncWorkerPool(1);
|
|
48267
|
+
this.instrumentation = instrumentation;
|
|
48240
48268
|
}
|
|
48241
48269
|
addHandler(handler) {
|
|
48242
48270
|
const id = handler.handlerId;
|
|
@@ -48327,15 +48355,22 @@
|
|
|
48327
48355
|
this.state = DraftQueueState.Stopped;
|
|
48328
48356
|
}
|
|
48329
48357
|
async getQueueActions() {
|
|
48358
|
+
// W-23515682: time the whole call, including this queue's own internal
|
|
48359
|
+
// this.getQueueActions() during a drain — the amplification signal an external wrapper
|
|
48360
|
+
// cannot see. Measure-only; control flow below is unchanged.
|
|
48361
|
+
const { instrumentation } = this;
|
|
48362
|
+
const start = instrumentation?.onGetQueueActions !== undefined ? Date.now() : 0;
|
|
48330
48363
|
const drafts = (await this.draftStore.getAllDrafts());
|
|
48331
48364
|
const queue = [];
|
|
48332
48365
|
drafts.forEach((draft) => {
|
|
48333
48366
|
if (draft.id === this.uploadingActionId) {
|
|
48334
|
-
draft
|
|
48367
|
+
queue.push({ ...draft, status: DraftActionStatus.Uploading });
|
|
48368
|
+
}
|
|
48369
|
+
else {
|
|
48370
|
+
queue.push(draft);
|
|
48335
48371
|
}
|
|
48336
|
-
queue.push(draft);
|
|
48337
48372
|
});
|
|
48338
|
-
|
|
48373
|
+
const sorted = queue.sort((a, b) => {
|
|
48339
48374
|
const aTime = parseInt(a.id, 10);
|
|
48340
48375
|
const bTime = parseInt(b.id, 10);
|
|
48341
48376
|
// safety check
|
|
@@ -48347,6 +48382,8 @@
|
|
|
48347
48382
|
}
|
|
48348
48383
|
return aTime - bTime;
|
|
48349
48384
|
});
|
|
48385
|
+
instrumentation?.onGetQueueActions?.(Date.now() - start, sorted.length);
|
|
48386
|
+
return sorted;
|
|
48350
48387
|
}
|
|
48351
48388
|
async enqueue(handlerId, data, observabilityContext) {
|
|
48352
48389
|
return this.workerPool.push({
|
|
@@ -48495,6 +48532,8 @@
|
|
|
48495
48532
|
const listener = draftQueueChangedListeners[i];
|
|
48496
48533
|
results.push(listener(event));
|
|
48497
48534
|
}
|
|
48535
|
+
// W-23515682: listener fan-out per event type. Measure-only.
|
|
48536
|
+
this.instrumentation?.onNotifyChangedListeners?.(event.type, draftQueueLen);
|
|
48498
48537
|
await Promise.all(results);
|
|
48499
48538
|
}
|
|
48500
48539
|
/**
|
|
@@ -48742,36 +48781,66 @@
|
|
|
48742
48781
|
*
|
|
48743
48782
|
*/
|
|
48744
48783
|
class DurableDraftStore {
|
|
48745
|
-
constructor(durableStore) {
|
|
48784
|
+
constructor(durableStore, instrumentation, useSnapshot = true) {
|
|
48746
48785
|
this.draftStore = {};
|
|
48786
|
+
// Snapshot: holds deep clones of each draft, refreshed at write time.
|
|
48787
|
+
// getAllDrafts serves from this snapshot with zero deep clones per read.
|
|
48788
|
+
this.cleanSnapshot = {};
|
|
48747
48789
|
// queue of writes that were made during the initial sync
|
|
48748
48790
|
this.writeQueue = [];
|
|
48749
48791
|
this.durableStore = durableStore;
|
|
48792
|
+
this.instrumentation = instrumentation;
|
|
48793
|
+
this.useSnapshot = useSnapshot;
|
|
48750
48794
|
this.resyncDraftStore();
|
|
48751
48795
|
}
|
|
48796
|
+
// When no instrumentation is injected the promise is returned as-is (zero overhead).
|
|
48797
|
+
timeDurableOp(op, segment, run) {
|
|
48798
|
+
const onDurableOperation = this.instrumentation?.onDurableOperation;
|
|
48799
|
+
if (onDurableOperation === undefined) {
|
|
48800
|
+
return run();
|
|
48801
|
+
}
|
|
48802
|
+
const start = Date.now();
|
|
48803
|
+
return run().finally(() => {
|
|
48804
|
+
onDurableOperation(op, segment, Date.now() - start);
|
|
48805
|
+
});
|
|
48806
|
+
}
|
|
48752
48807
|
writeAction(action) {
|
|
48753
48808
|
const addAction = () => {
|
|
48754
48809
|
const { id, tag } = action;
|
|
48755
48810
|
this.draftStore[id] = action;
|
|
48811
|
+
this.cleanSnapshot[id] = clone$1(action);
|
|
48756
48812
|
const durableEntryKey = buildDraftDurableStoreKey(tag, id);
|
|
48757
48813
|
const entry = {
|
|
48758
48814
|
data: action,
|
|
48759
48815
|
};
|
|
48760
48816
|
const entries = { [durableEntryKey]: entry };
|
|
48761
|
-
return this.durableStore.setEntries(entries, DRAFT_SEGMENT);
|
|
48817
|
+
return this.timeDurableOp('setEntries', DRAFT_SEGMENT, () => this.durableStore.setEntries(entries, DRAFT_SEGMENT));
|
|
48762
48818
|
};
|
|
48763
48819
|
return this.enqueueAction(addAction);
|
|
48764
48820
|
}
|
|
48765
48821
|
getAllDrafts() {
|
|
48766
48822
|
const waitForOngoingSync = this.syncPromise || Promise.resolve();
|
|
48767
48823
|
return waitForOngoingSync.then(() => {
|
|
48768
|
-
const { draftStore } = this;
|
|
48769
|
-
const keys$1 = keys$4(draftStore);
|
|
48770
48824
|
const actionArray = [];
|
|
48771
|
-
|
|
48772
|
-
const
|
|
48773
|
-
|
|
48774
|
-
|
|
48825
|
+
if (this.useSnapshot) {
|
|
48826
|
+
const { cleanSnapshot } = this;
|
|
48827
|
+
const keys$1 = keys$4(cleanSnapshot);
|
|
48828
|
+
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
48829
|
+
const key = keys$1[i];
|
|
48830
|
+
// Return shallow spread of snapshot entries so top-level caller mutations
|
|
48831
|
+
// (e.g., .status =) don't persist into the snapshot. The snapshot itself
|
|
48832
|
+
// is a deep clone of draftStore, so no nested mutation reaches draftStore.
|
|
48833
|
+
actionArray.push({ ...cleanSnapshot[key] });
|
|
48834
|
+
}
|
|
48835
|
+
}
|
|
48836
|
+
else {
|
|
48837
|
+
// Killswitch (W-23515682): original pre-fix behavior — deep-clone every draft on
|
|
48838
|
+
// every read so the internal draft store is never exposed. O(N) clones per read.
|
|
48839
|
+
const { draftStore } = this;
|
|
48840
|
+
const keys$1 = keys$4(draftStore);
|
|
48841
|
+
for (let i = 0, len = keys$1.length; i < len; i++) {
|
|
48842
|
+
actionArray.push(clone$1(draftStore[keys$1[i]]));
|
|
48843
|
+
}
|
|
48775
48844
|
}
|
|
48776
48845
|
return actionArray;
|
|
48777
48846
|
});
|
|
@@ -48781,8 +48850,9 @@
|
|
|
48781
48850
|
const draft = this.draftStore[id];
|
|
48782
48851
|
if (draft !== undefined) {
|
|
48783
48852
|
delete this.draftStore[id];
|
|
48853
|
+
delete this.cleanSnapshot[id];
|
|
48784
48854
|
const durableKey = buildDraftDurableStoreKey(draft.tag, draft.id);
|
|
48785
|
-
return this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT);
|
|
48855
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT));
|
|
48786
48856
|
}
|
|
48787
48857
|
return Promise.resolve();
|
|
48788
48858
|
};
|
|
@@ -48798,10 +48868,11 @@
|
|
|
48798
48868
|
const action = draftStore[key];
|
|
48799
48869
|
if (action.tag === tag) {
|
|
48800
48870
|
delete draftStore[action.id];
|
|
48871
|
+
delete this.cleanSnapshot[action.id];
|
|
48801
48872
|
durableKeys.push(buildDraftDurableStoreKey(action.tag, action.id));
|
|
48802
48873
|
}
|
|
48803
48874
|
}
|
|
48804
|
-
return this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT);
|
|
48875
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT));
|
|
48805
48876
|
};
|
|
48806
48877
|
return this.enqueueAction(deleteAction);
|
|
48807
48878
|
}
|
|
@@ -48815,6 +48886,7 @@
|
|
|
48815
48886
|
const action = draftStore[operation.id];
|
|
48816
48887
|
if (action !== undefined) {
|
|
48817
48888
|
delete draftStore[operation.id];
|
|
48889
|
+
delete this.cleanSnapshot[operation.id];
|
|
48818
48890
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48819
48891
|
durableStoreOperations.push({
|
|
48820
48892
|
ids: [key],
|
|
@@ -48827,6 +48899,7 @@
|
|
|
48827
48899
|
const { action } = operation;
|
|
48828
48900
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48829
48901
|
draftStore[action.id] = action;
|
|
48902
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48830
48903
|
durableStoreOperations.push({
|
|
48831
48904
|
type: 'setEntries',
|
|
48832
48905
|
segment: DRAFT_SEGMENT,
|
|
@@ -48838,7 +48911,7 @@
|
|
|
48838
48911
|
});
|
|
48839
48912
|
}
|
|
48840
48913
|
}
|
|
48841
|
-
return this.durableStore.batchOperations(durableStoreOperations);
|
|
48914
|
+
return this.timeDurableOp('batchOperations', DRAFT_SEGMENT, () => this.durableStore.batchOperations(durableStoreOperations));
|
|
48842
48915
|
};
|
|
48843
48916
|
return this.enqueueAction(action);
|
|
48844
48917
|
}
|
|
@@ -48881,6 +48954,7 @@
|
|
|
48881
48954
|
.then((durableEntries) => {
|
|
48882
48955
|
if (durableEntries === undefined) {
|
|
48883
48956
|
this.draftStore = {};
|
|
48957
|
+
this.cleanSnapshot = {};
|
|
48884
48958
|
return this.runQueuedOperations();
|
|
48885
48959
|
}
|
|
48886
48960
|
const { draftStore } = this;
|
|
@@ -48889,6 +48963,7 @@
|
|
|
48889
48963
|
const entry = durableEntries[keys$1[i]];
|
|
48890
48964
|
const action = entry.data;
|
|
48891
48965
|
draftStore[action.id] = action;
|
|
48966
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48892
48967
|
}
|
|
48893
48968
|
return this.runQueuedOperations();
|
|
48894
48969
|
})
|
|
@@ -80113,6 +80188,14 @@
|
|
|
80113
80188
|
// Used to triage the WOLI duplicate-record investigation in Splunk — correlate by draftId
|
|
80114
80189
|
// with the other draft-queue events. @W-23428669
|
|
80115
80190
|
const DRAFT_QUEUE_IDEMPOTENCY_KEY_ROTATED = 'draft-queue-idempotency-key-rotated';
|
|
80191
|
+
// Hotspot-attribution telemetry (@W-23515682). Operational counts/durations only — no
|
|
80192
|
+
// draft content, field values, or server record ids. These attribute the offline-drain wall-clock
|
|
80193
|
+
// to the O(N^2) hotspots (getQueueActions amplification, listener fan-out, durable-op latency).
|
|
80194
|
+
const DRAFT_QUEUE_GET_QUEUE_ACTIONS_COUNT = 'draft-queue-get-queue-actions-count';
|
|
80195
|
+
const DRAFT_QUEUE_GET_QUEUE_ACTIONS_DURATION = 'draft-queue-get-queue-actions-duration';
|
|
80196
|
+
const DRAFT_QUEUE_NOTIFY_CHANGED_LISTENERS_COUNT = 'draft-queue-notify-changed-listeners-count';
|
|
80197
|
+
const DRAFT_QUEUE_DURABLE_OP_COUNT = 'draft-queue-durable-op-count';
|
|
80198
|
+
const DRAFT_QUEUE_DURABLE_OP_DURATION = 'draft-queue-durable-op-duration';
|
|
80116
80199
|
/** Content Document */
|
|
80117
80200
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
|
|
80118
80201
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
|
|
@@ -80205,6 +80288,33 @@
|
|
|
80205
80288
|
break;
|
|
80206
80289
|
}
|
|
80207
80290
|
}
|
|
80291
|
+
/**
|
|
80292
|
+
* @W-23515682: count (amplification — queue re-reads per drain) + duration histogram (the
|
|
80293
|
+
* pre/post signal for the getAllDrafts clone-on-write fix). actionCount is queue depth, never content.
|
|
80294
|
+
*/
|
|
80295
|
+
function reportDraftQueueGetQueueActions(durationMs, actionCount) {
|
|
80296
|
+
const depthBuckets = [1, 2, 5, 10, 20, 50, 100, 250, 500];
|
|
80297
|
+
ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_GET_QUEUE_ACTIONS_COUNT);
|
|
80298
|
+
ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_GET_QUEUE_ACTIONS_DURATION, durationMs);
|
|
80299
|
+
ldsMobileInstrumentation$2.bucketValue(DRAFT_QUEUE_GET_QUEUE_ACTIONS_COUNT + '-depth', actionCount, depthBuckets);
|
|
80300
|
+
}
|
|
80301
|
+
/**
|
|
80302
|
+
* @W-23515682: count per event type — listener fan-out / amplification per event.
|
|
80303
|
+
*/
|
|
80304
|
+
function reportDraftQueueNotifyChangedListeners(eventType, listenerCount) {
|
|
80305
|
+
ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_NOTIFY_CHANGED_LISTENERS_COUNT, listenerCount, undefined, { eventType });
|
|
80306
|
+
}
|
|
80307
|
+
/**
|
|
80308
|
+
* @W-23515682: count + duration histogram by operation kind + segment — attributes the
|
|
80309
|
+
* client-CPU-vs-durable split of per-action processing time.
|
|
80310
|
+
*/
|
|
80311
|
+
function reportDraftQueueDurableOperation(op, segment, durationMs) {
|
|
80312
|
+
ldsMobileInstrumentation$2.incrementCounter(DRAFT_QUEUE_DURABLE_OP_COUNT, 1, undefined, {
|
|
80313
|
+
op,
|
|
80314
|
+
segment,
|
|
80315
|
+
});
|
|
80316
|
+
ldsMobileInstrumentation$2.trackValue(DRAFT_QUEUE_DURABLE_OP_DURATION, durationMs);
|
|
80317
|
+
}
|
|
80208
80318
|
/**
|
|
80209
80319
|
* Reports an exception thrown while uploading a draft action. The thrown error is
|
|
80210
80320
|
* otherwise swallowed by the upload handler's retry path, leaving the failure
|
|
@@ -80688,14 +80798,45 @@
|
|
|
80688
80798
|
let updatedActionTargetId = undefined;
|
|
80689
80799
|
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
80690
80800
|
let { basePath, body } = queueActionRequest;
|
|
80801
|
+
// Literal indexOf pre-check (no RegExp coercion, unlike the old String.search) +
|
|
80802
|
+
// a replace RegExp built only when a reference is present — the win over the old scan.
|
|
80691
80803
|
let stringifiedBody = stringify$5(body);
|
|
80804
|
+
// Read the killswitch once for the whole scan (W-23515682) — avoids a
|
|
80805
|
+
// per-redirect gate lookup in this hot loop.
|
|
80806
|
+
const useOptimizedScan = draftQueueRedirectScanGate.isOpen({ fallback: true });
|
|
80692
80807
|
// for each redirected ID/key we loop over the operation to see if it needs
|
|
80693
80808
|
// to be updated
|
|
80694
80809
|
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
80695
|
-
if (
|
|
80696
|
-
basePath
|
|
80697
|
-
|
|
80698
|
-
|
|
80810
|
+
if (useOptimizedScan) {
|
|
80811
|
+
// basePath AND body are checked independently: a queued action can carry
|
|
80812
|
+
// the draft id in either or BOTH, and each occurrence must be rewritten.
|
|
80813
|
+
const basePathNeedsUpdate = basePath.indexOf(draftId) >= 0;
|
|
80814
|
+
const bodyNeedsUpdate = stringifiedBody.indexOf(draftId) >= 0;
|
|
80815
|
+
if (basePathNeedsUpdate || bodyNeedsUpdate) {
|
|
80816
|
+
// Escape metacharacters so the draft id matches literally. Salesforce
|
|
80817
|
+
// ids carry no regex metacharacters today, so this is defensive against
|
|
80818
|
+
// a future id-format change silently corrupting unrelated ids. W-23515682.
|
|
80819
|
+
const escapedDraftId = draftId.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
80820
|
+
const replaceRegex = new RegExp(escapedDraftId, 'g');
|
|
80821
|
+
if (basePathNeedsUpdate) {
|
|
80822
|
+
basePath = basePath.replace(replaceRegex, canonicalId);
|
|
80823
|
+
}
|
|
80824
|
+
if (bodyNeedsUpdate) {
|
|
80825
|
+
stringifiedBody = stringifiedBody.replace(replaceRegex, canonicalId);
|
|
80826
|
+
}
|
|
80827
|
+
queueOperationMutated = true;
|
|
80828
|
+
}
|
|
80829
|
+
}
|
|
80830
|
+
else {
|
|
80831
|
+
// Killswitch closed (W-23515682): original pre-fix scan — String.search
|
|
80832
|
+
// (coerces draftId to a RegExp) + a raw (unescaped) replace RegExp applied
|
|
80833
|
+
// to basePath and body together.
|
|
80834
|
+
if (basePath.search(draftId) >= 0 ||
|
|
80835
|
+
stringifiedBody.search(draftId) >= 0) {
|
|
80836
|
+
basePath = basePath.replace(new RegExp(draftId, 'g'), canonicalId);
|
|
80837
|
+
stringifiedBody = stringifiedBody.replace(new RegExp(draftId, 'g'), canonicalId);
|
|
80838
|
+
queueOperationMutated = true;
|
|
80839
|
+
}
|
|
80699
80840
|
}
|
|
80700
80841
|
// if the action is performed on a previous draft id, we need to replace the action
|
|
80701
80842
|
// with a new one at the updated canonical key
|
|
@@ -90268,6 +90409,20 @@
|
|
|
90268
90409
|
}
|
|
90269
90410
|
}
|
|
90270
90411
|
|
|
90412
|
+
// Mobile impl of the shared DraftQueueInstrumentation seam (@W-23515682). Forwards to
|
|
90413
|
+
// ldsMobileInstrumentation via metrics.ts; injected at construction (DraftQueueFactory).
|
|
90414
|
+
const draftQueueInstrumentation = {
|
|
90415
|
+
onGetQueueActions(durationMs, actionCount) {
|
|
90416
|
+
reportDraftQueueGetQueueActions(durationMs, actionCount);
|
|
90417
|
+
},
|
|
90418
|
+
onNotifyChangedListeners(eventType, listenerCount) {
|
|
90419
|
+
reportDraftQueueNotifyChangedListeners(eventType, listenerCount);
|
|
90420
|
+
},
|
|
90421
|
+
onDurableOperation(op, segment, durationMs) {
|
|
90422
|
+
reportDraftQueueDurableOperation(op, segment, durationMs);
|
|
90423
|
+
},
|
|
90424
|
+
};
|
|
90425
|
+
|
|
90271
90426
|
// so eslint doesn't complain about nimbus
|
|
90272
90427
|
/* global __nimbus */
|
|
90273
90428
|
function buildLdsDraftQueue(durableStore) {
|
|
@@ -90276,7 +90431,8 @@
|
|
|
90276
90431
|
__nimbus.plugins.LdsDraftQueue !== undefined) {
|
|
90277
90432
|
return new NimbusDraftQueue();
|
|
90278
90433
|
}
|
|
90279
|
-
const
|
|
90434
|
+
const useSnapshot = draftQueueStoreSnapshotGate.isOpen({ fallback: true });
|
|
90435
|
+
const draftQueue = new DurableDraftQueue(new DurableDraftStore(durableStore, draftQueueInstrumentation, useSnapshot), draftQueueInstrumentation);
|
|
90280
90436
|
return instrumentDraftQueue(draftQueue);
|
|
90281
90437
|
}
|
|
90282
90438
|
|
|
@@ -93607,18 +93763,34 @@
|
|
|
93607
93763
|
this.initialize();
|
|
93608
93764
|
}
|
|
93609
93765
|
async addEffects(effects) {
|
|
93766
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93610
93767
|
const durableEntries = {};
|
|
93611
93768
|
effects.forEach((effect) => {
|
|
93612
93769
|
durableEntries[effect.uniqueId] = { data: effect };
|
|
93613
93770
|
this.allEffects.set(effect.uniqueId, effect);
|
|
93771
|
+
if (incremental) {
|
|
93772
|
+
this.addEffectToKeyMap(effect);
|
|
93773
|
+
}
|
|
93614
93774
|
});
|
|
93615
|
-
|
|
93775
|
+
// Killswitch (W-23515682): closed → original O(N) full rebuild on every add.
|
|
93776
|
+
if (!incremental) {
|
|
93777
|
+
this.regenerateKeyToEffectMap();
|
|
93778
|
+
}
|
|
93616
93779
|
await this.durableStore.setEntries(durableEntries, SIDE_EFFECT_SEGMENT);
|
|
93617
93780
|
}
|
|
93618
93781
|
async removeEffects(effects) {
|
|
93782
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93619
93783
|
const effectKeys = effects.map((e) => e.uniqueId);
|
|
93620
|
-
effects.forEach((
|
|
93621
|
-
|
|
93784
|
+
effects.forEach((effect) => {
|
|
93785
|
+
this.allEffects.delete(effect.uniqueId);
|
|
93786
|
+
if (incremental) {
|
|
93787
|
+
this.removeEffectFromKeyMap(effect);
|
|
93788
|
+
}
|
|
93789
|
+
});
|
|
93790
|
+
// Killswitch (W-23515682): closed → original O(N) full rebuild on every remove.
|
|
93791
|
+
if (!incremental) {
|
|
93792
|
+
this.regenerateKeyToEffectMap();
|
|
93793
|
+
}
|
|
93622
93794
|
await this.durableStore.evictEntries(effectKeys, SIDE_EFFECT_SEGMENT);
|
|
93623
93795
|
}
|
|
93624
93796
|
getEffects(key) {
|
|
@@ -93653,6 +93825,39 @@
|
|
|
93653
93825
|
});
|
|
93654
93826
|
this.regenerateKeyToEffectMap();
|
|
93655
93827
|
}
|
|
93828
|
+
addEffectToKeyMap(effect) {
|
|
93829
|
+
const recordEffects = this.keyToEffectMap.get(effect.key);
|
|
93830
|
+
if (recordEffects) {
|
|
93831
|
+
// Effects are keyed by uniqueId (mirroring allEffects.set / regenerateKeyToEffectMap):
|
|
93832
|
+
// a re-add of the same uniqueId must REPLACE the resident entry in place, not append a
|
|
93833
|
+
// duplicate. The action-completion replay path (setSideEffectsForActions on still-queued
|
|
93834
|
+
// actions) re-adds resident effects with no preceding remove; without this dedup a
|
|
93835
|
+
// record-field-increment would sit in the array twice and be applied twice (e.g. a
|
|
93836
|
+
// ProductConsumed QuantityOnHand -=5 becomes -=10). W-23515682.
|
|
93837
|
+
const index = recordEffects.findIndex((e) => e.uniqueId === effect.uniqueId);
|
|
93838
|
+
if (index !== -1) {
|
|
93839
|
+
recordEffects[index] = effect;
|
|
93840
|
+
}
|
|
93841
|
+
else {
|
|
93842
|
+
recordEffects.push(effect);
|
|
93843
|
+
}
|
|
93844
|
+
}
|
|
93845
|
+
else {
|
|
93846
|
+
this.keyToEffectMap.set(effect.key, [effect]);
|
|
93847
|
+
}
|
|
93848
|
+
}
|
|
93849
|
+
removeEffectFromKeyMap(effect) {
|
|
93850
|
+
const recordEffects = this.keyToEffectMap.get(effect.key);
|
|
93851
|
+
if (recordEffects) {
|
|
93852
|
+
const index = recordEffects.findIndex((e) => e.uniqueId === effect.uniqueId);
|
|
93853
|
+
if (index !== -1) {
|
|
93854
|
+
recordEffects.splice(index, 1);
|
|
93855
|
+
if (recordEffects.length === 0) {
|
|
93856
|
+
this.keyToEffectMap.delete(effect.key);
|
|
93857
|
+
}
|
|
93858
|
+
}
|
|
93859
|
+
}
|
|
93860
|
+
}
|
|
93656
93861
|
regenerateKeyToEffectMap() {
|
|
93657
93862
|
this.keyToEffectMap.clear();
|
|
93658
93863
|
this.allEffects.forEach((effect) => {
|
|
@@ -96802,7 +97007,7 @@
|
|
|
96802
97007
|
},
|
|
96803
97008
|
};
|
|
96804
97009
|
}
|
|
96805
|
-
// version: 1.
|
|
97010
|
+
// version: 1.452.0-bcd113b7fd
|
|
96806
97011
|
|
|
96807
97012
|
/**
|
|
96808
97013
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -96828,7 +97033,7 @@
|
|
|
96828
97033
|
},
|
|
96829
97034
|
};
|
|
96830
97035
|
}
|
|
96831
|
-
// version: 1.
|
|
97036
|
+
// version: 1.452.0-bcd113b7fd
|
|
96832
97037
|
|
|
96833
97038
|
function findExecutableOperation$1(input) {
|
|
96834
97039
|
const operations = input.query.definitions.filter(
|
|
@@ -99537,7 +99742,7 @@
|
|
|
99537
99742
|
id: '@salesforce/lds-network-adapter',
|
|
99538
99743
|
instrument: instrument$2,
|
|
99539
99744
|
});
|
|
99540
|
-
// version: 1.
|
|
99745
|
+
// version: 1.452.0-bcd113b7fd
|
|
99541
99746
|
|
|
99542
99747
|
const { create: create$2, keys: keys$2 } = Object;
|
|
99543
99748
|
const { stringify, parse } = JSON;
|
|
@@ -107072,7 +107277,7 @@
|
|
|
107072
107277
|
cb(graphql_v1_import, graphql_imperative$1, graphql_imperative_legacy_v1_import, graphql_state_manager, useOneStoreGraphQL);
|
|
107073
107278
|
}
|
|
107074
107279
|
}
|
|
107075
|
-
// version: 1.
|
|
107280
|
+
// version: 1.452.0-1ecfe8af95
|
|
107076
107281
|
|
|
107077
107282
|
function createFragmentMap(documentNode) {
|
|
107078
107283
|
const fragments = {};
|
|
@@ -136315,7 +136520,7 @@
|
|
|
136315
136520
|
configuration: { ...configurationForGraphQLAdapters$1 },
|
|
136316
136521
|
instrument: instrument$1,
|
|
136317
136522
|
});
|
|
136318
|
-
// version: 1.
|
|
136523
|
+
// version: 1.452.0-1ecfe8af95
|
|
136319
136524
|
|
|
136320
136525
|
// On core the unstable adapters are re-exported with different names,
|
|
136321
136526
|
// we want to match them here.
|
|
@@ -136467,7 +136672,7 @@
|
|
|
136467
136672
|
unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
|
|
136468
136673
|
graphQLImperative = ldsAdapter;
|
|
136469
136674
|
});
|
|
136470
|
-
// version: 1.
|
|
136675
|
+
// version: 1.452.0-1ecfe8af95
|
|
136471
136676
|
|
|
136472
136677
|
var gqlApi = /*#__PURE__*/Object.freeze({
|
|
136473
136678
|
__proto__: null,
|
|
@@ -137266,7 +137471,7 @@
|
|
|
137266
137471
|
function register(r) {
|
|
137267
137472
|
callbacks$1.forEach((callback) => callback(r));
|
|
137268
137473
|
}
|
|
137269
|
-
// version: 1.
|
|
137474
|
+
// version: 1.452.0-bcd113b7fd
|
|
137270
137475
|
|
|
137271
137476
|
/**
|
|
137272
137477
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -138576,4 +138781,4 @@
|
|
|
138576
138781
|
exports.subscribeToAdapter = subscribeToAdapter;
|
|
138577
138782
|
|
|
138578
138783
|
}));
|
|
138579
|
-
// version: 1.
|
|
138784
|
+
// version: 1.452.0-bcd113b7fd
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-worker-api",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.452.0",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "",
|
|
6
6
|
"main": "dist/standalone/es/lds-worker-api.js",
|
|
@@ -35,14 +35,14 @@
|
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@oat-sa/rollup-plugin-wildcard-external": "^1.0.0",
|
|
38
|
-
"@salesforce/lds-adapters-graphql": "^1.
|
|
39
|
-
"@salesforce/lds-adapters-uiapi": "^1.
|
|
40
|
-
"@salesforce/lds-default-luvio": "^1.
|
|
41
|
-
"@salesforce/lds-drafts": "^1.
|
|
42
|
-
"@salesforce/lds-graphql-parser": "^1.
|
|
43
|
-
"@salesforce/lds-luvio-engine": "^1.
|
|
44
|
-
"@salesforce/lds-runtime-mobile": "^1.
|
|
45
|
-
"@salesforce/nimbus-plugin-lds": "^1.
|
|
38
|
+
"@salesforce/lds-adapters-graphql": "^1.452.0",
|
|
39
|
+
"@salesforce/lds-adapters-uiapi": "^1.452.0",
|
|
40
|
+
"@salesforce/lds-default-luvio": "^1.452.0",
|
|
41
|
+
"@salesforce/lds-drafts": "^1.452.0",
|
|
42
|
+
"@salesforce/lds-graphql-parser": "^1.452.0",
|
|
43
|
+
"@salesforce/lds-luvio-engine": "^1.452.0",
|
|
44
|
+
"@salesforce/lds-runtime-mobile": "^1.452.0",
|
|
45
|
+
"@salesforce/nimbus-plugin-lds": "^1.452.0",
|
|
46
46
|
"ajv": "^8.11.0",
|
|
47
47
|
"glob": "^7.1.5",
|
|
48
48
|
"nimbus-types": "^2.0.0-alpha1",
|