@salesforce/lds-worker-api 1.451.0 → 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;
|
|
@@ -14373,7 +14373,7 @@ function coerceFormFactor$1(form) {
|
|
|
14373
14373
|
return undefined;
|
|
14374
14374
|
}
|
|
14375
14375
|
|
|
14376
|
-
const VERSION$10$2 = "
|
|
14376
|
+
const VERSION$10$2 = "3f49d751896cf66e6e29788d8880e2cc";
|
|
14377
14377
|
const RepresentationType$G = 'PlatformActionRepresentation';
|
|
14378
14378
|
function keyBuilder$1P$1(luvio, config) {
|
|
14379
14379
|
return keyPrefix$3 + '::' + RepresentationType$G + ':' + config.externalId + ':' + (config.relatedSourceObject === null ? '' : config.relatedSourceObject) + ':' + (config.relatedListRecordId === null ? '' : config.relatedListRecordId);
|
|
@@ -14433,10 +14433,6 @@ const select$1G$2 = function PlatformActionRepresentationSelect() {
|
|
|
14433
14433
|
name: 'lwcComponent',
|
|
14434
14434
|
kind: 'Scalar'
|
|
14435
14435
|
},
|
|
14436
|
-
{
|
|
14437
|
-
name: 'pageDeveloperName',
|
|
14438
|
-
kind: 'Scalar'
|
|
14439
|
-
},
|
|
14440
14436
|
{
|
|
14441
14437
|
name: 'primaryColor',
|
|
14442
14438
|
kind: 'Scalar'
|
|
@@ -14465,14 +14461,6 @@ const select$1G$2 = function PlatformActionRepresentationSelect() {
|
|
|
14465
14461
|
name: 'targetObject',
|
|
14466
14462
|
kind: 'Scalar'
|
|
14467
14463
|
},
|
|
14468
|
-
{
|
|
14469
|
-
name: 'targetParentField',
|
|
14470
|
-
kind: 'Scalar'
|
|
14471
|
-
},
|
|
14472
|
-
{
|
|
14473
|
-
name: 'targetRecordTypeId',
|
|
14474
|
-
kind: 'Scalar'
|
|
14475
|
-
},
|
|
14476
14464
|
{
|
|
14477
14465
|
name: 'targetUrl',
|
|
14478
14466
|
kind: 'Scalar'
|
|
@@ -14545,11 +14533,6 @@ function equals$S(existing, incoming) {
|
|
|
14545
14533
|
if (!(existing_lwcComponent === incoming_lwcComponent)) {
|
|
14546
14534
|
return false;
|
|
14547
14535
|
}
|
|
14548
|
-
const existing_pageDeveloperName = existing.pageDeveloperName;
|
|
14549
|
-
const incoming_pageDeveloperName = incoming.pageDeveloperName;
|
|
14550
|
-
if (!(existing_pageDeveloperName === incoming_pageDeveloperName)) {
|
|
14551
|
-
return false;
|
|
14552
|
-
}
|
|
14553
14536
|
const existing_primaryColor = existing.primaryColor;
|
|
14554
14537
|
const incoming_primaryColor = incoming.primaryColor;
|
|
14555
14538
|
if (!(existing_primaryColor === incoming_primaryColor)) {
|
|
@@ -14580,16 +14563,6 @@ function equals$S(existing, incoming) {
|
|
|
14580
14563
|
if (!(existing_targetObject === incoming_targetObject)) {
|
|
14581
14564
|
return false;
|
|
14582
14565
|
}
|
|
14583
|
-
const existing_targetParentField = existing.targetParentField;
|
|
14584
|
-
const incoming_targetParentField = incoming.targetParentField;
|
|
14585
|
-
if (!(existing_targetParentField === incoming_targetParentField)) {
|
|
14586
|
-
return false;
|
|
14587
|
-
}
|
|
14588
|
-
const existing_targetRecordTypeId = existing.targetRecordTypeId;
|
|
14589
|
-
const incoming_targetRecordTypeId = incoming.targetRecordTypeId;
|
|
14590
|
-
if (!(existing_targetRecordTypeId === incoming_targetRecordTypeId)) {
|
|
14591
|
-
return false;
|
|
14592
|
-
}
|
|
14593
14566
|
const existing_targetUrl = existing.targetUrl;
|
|
14594
14567
|
const incoming_targetUrl = incoming.targetUrl;
|
|
14595
14568
|
if (!(existing_targetUrl === incoming_targetUrl)) {
|
|
@@ -32574,7 +32547,7 @@ withDefaultLuvio((luvio) => {
|
|
|
32574
32547
|
throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
|
|
32575
32548
|
throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
|
|
32576
32549
|
});
|
|
32577
|
-
// version: 1.
|
|
32550
|
+
// version: 1.452.0-1ecfe8af95
|
|
32578
32551
|
|
|
32579
32552
|
var draftQueueMaxRetryAttemptsGate = {
|
|
32580
32553
|
isOpen: function (e) {
|
|
@@ -32585,6 +32558,15 @@ var draftQueueMaxRetryAttemptsGate = {
|
|
|
32585
32558
|
},
|
|
32586
32559
|
};
|
|
32587
32560
|
|
|
32561
|
+
var draftQueueRedirectScanGate = {
|
|
32562
|
+
isOpen: function (e) {
|
|
32563
|
+
return e.fallback;
|
|
32564
|
+
},
|
|
32565
|
+
hasError: function () {
|
|
32566
|
+
return !0;
|
|
32567
|
+
},
|
|
32568
|
+
};
|
|
32569
|
+
|
|
32588
32570
|
var rotateIdempotencyKeyOn400Killswitch = {
|
|
32589
32571
|
isOpen: function (e) {
|
|
32590
32572
|
return e.fallback;
|
|
@@ -44130,6 +44112,15 @@ var graphqlPartialEmitParity = {
|
|
|
44130
44112
|
},
|
|
44131
44113
|
};
|
|
44132
44114
|
|
|
44115
|
+
var draftQueueStoreSnapshotGate = {
|
|
44116
|
+
isOpen: function (e) {
|
|
44117
|
+
return e.fallback;
|
|
44118
|
+
},
|
|
44119
|
+
hasError: function () {
|
|
44120
|
+
return !0;
|
|
44121
|
+
},
|
|
44122
|
+
};
|
|
44123
|
+
|
|
44133
44124
|
var ldsAdapterO11yLoggingGate = {
|
|
44134
44125
|
isOpen: function (e) {
|
|
44135
44126
|
return e.fallback;
|
|
@@ -45919,6 +45910,15 @@ function resolveAndValidateGraphQLDocument(query, operationName, options) {
|
|
|
45919
45910
|
return ok$3(document);
|
|
45920
45911
|
}
|
|
45921
45912
|
|
|
45913
|
+
var draftQueueSideEffectMapGate = {
|
|
45914
|
+
isOpen: function (e) {
|
|
45915
|
+
return e.fallback;
|
|
45916
|
+
},
|
|
45917
|
+
hasError: function () {
|
|
45918
|
+
return !0;
|
|
45919
|
+
},
|
|
45920
|
+
};
|
|
45921
|
+
|
|
45922
45922
|
var productConsumedSideEffects = {
|
|
45923
45923
|
isOpen: function (e) {
|
|
45924
45924
|
return e.fallback;
|
|
@@ -48241,7 +48241,7 @@ class DurableDraftQueue {
|
|
|
48241
48241
|
}
|
|
48242
48242
|
return handler;
|
|
48243
48243
|
}
|
|
48244
|
-
constructor(draftStore) {
|
|
48244
|
+
constructor(draftStore, instrumentation) {
|
|
48245
48245
|
this.retryIntervalMilliseconds = 0;
|
|
48246
48246
|
this.minimumRetryInterval = 250;
|
|
48247
48247
|
this.maximumRetryInterval = 32000;
|
|
@@ -48258,6 +48258,7 @@ class DurableDraftQueue {
|
|
|
48258
48258
|
this.handlers = {};
|
|
48259
48259
|
this.draftStore = draftStore;
|
|
48260
48260
|
this.workerPool = new AsyncWorkerPool(1);
|
|
48261
|
+
this.instrumentation = instrumentation;
|
|
48261
48262
|
}
|
|
48262
48263
|
addHandler(handler) {
|
|
48263
48264
|
const id = handler.handlerId;
|
|
@@ -48348,15 +48349,22 @@ class DurableDraftQueue {
|
|
|
48348
48349
|
this.state = DraftQueueState.Stopped;
|
|
48349
48350
|
}
|
|
48350
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;
|
|
48351
48357
|
const drafts = (await this.draftStore.getAllDrafts());
|
|
48352
48358
|
const queue = [];
|
|
48353
48359
|
drafts.forEach((draft) => {
|
|
48354
48360
|
if (draft.id === this.uploadingActionId) {
|
|
48355
|
-
draft
|
|
48361
|
+
queue.push({ ...draft, status: DraftActionStatus.Uploading });
|
|
48362
|
+
}
|
|
48363
|
+
else {
|
|
48364
|
+
queue.push(draft);
|
|
48356
48365
|
}
|
|
48357
|
-
queue.push(draft);
|
|
48358
48366
|
});
|
|
48359
|
-
|
|
48367
|
+
const sorted = queue.sort((a, b) => {
|
|
48360
48368
|
const aTime = parseInt(a.id, 10);
|
|
48361
48369
|
const bTime = parseInt(b.id, 10);
|
|
48362
48370
|
// safety check
|
|
@@ -48368,6 +48376,8 @@ class DurableDraftQueue {
|
|
|
48368
48376
|
}
|
|
48369
48377
|
return aTime - bTime;
|
|
48370
48378
|
});
|
|
48379
|
+
instrumentation?.onGetQueueActions?.(Date.now() - start, sorted.length);
|
|
48380
|
+
return sorted;
|
|
48371
48381
|
}
|
|
48372
48382
|
async enqueue(handlerId, data, observabilityContext) {
|
|
48373
48383
|
return this.workerPool.push({
|
|
@@ -48516,6 +48526,8 @@ class DurableDraftQueue {
|
|
|
48516
48526
|
const listener = draftQueueChangedListeners[i];
|
|
48517
48527
|
results.push(listener(event));
|
|
48518
48528
|
}
|
|
48529
|
+
// W-23515682: listener fan-out per event type. Measure-only.
|
|
48530
|
+
this.instrumentation?.onNotifyChangedListeners?.(event.type, draftQueueLen);
|
|
48519
48531
|
await Promise.all(results);
|
|
48520
48532
|
}
|
|
48521
48533
|
/**
|
|
@@ -48763,36 +48775,66 @@ function buildDraftDurableStoreKey(recordKey, draftActionId) {
|
|
|
48763
48775
|
*
|
|
48764
48776
|
*/
|
|
48765
48777
|
class DurableDraftStore {
|
|
48766
|
-
constructor(durableStore) {
|
|
48778
|
+
constructor(durableStore, instrumentation, useSnapshot = true) {
|
|
48767
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 = {};
|
|
48768
48783
|
// queue of writes that were made during the initial sync
|
|
48769
48784
|
this.writeQueue = [];
|
|
48770
48785
|
this.durableStore = durableStore;
|
|
48786
|
+
this.instrumentation = instrumentation;
|
|
48787
|
+
this.useSnapshot = useSnapshot;
|
|
48771
48788
|
this.resyncDraftStore();
|
|
48772
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
|
+
}
|
|
48773
48801
|
writeAction(action) {
|
|
48774
48802
|
const addAction = () => {
|
|
48775
48803
|
const { id, tag } = action;
|
|
48776
48804
|
this.draftStore[id] = action;
|
|
48805
|
+
this.cleanSnapshot[id] = clone$1(action);
|
|
48777
48806
|
const durableEntryKey = buildDraftDurableStoreKey(tag, id);
|
|
48778
48807
|
const entry = {
|
|
48779
48808
|
data: action,
|
|
48780
48809
|
};
|
|
48781
48810
|
const entries = { [durableEntryKey]: entry };
|
|
48782
|
-
return this.durableStore.setEntries(entries, DRAFT_SEGMENT);
|
|
48811
|
+
return this.timeDurableOp('setEntries', DRAFT_SEGMENT, () => this.durableStore.setEntries(entries, DRAFT_SEGMENT));
|
|
48783
48812
|
};
|
|
48784
48813
|
return this.enqueueAction(addAction);
|
|
48785
48814
|
}
|
|
48786
48815
|
getAllDrafts() {
|
|
48787
48816
|
const waitForOngoingSync = this.syncPromise || Promise.resolve();
|
|
48788
48817
|
return waitForOngoingSync.then(() => {
|
|
48789
|
-
const { draftStore } = this;
|
|
48790
|
-
const keys$1 = keys$4(draftStore);
|
|
48791
48818
|
const actionArray = [];
|
|
48792
|
-
|
|
48793
|
-
const
|
|
48794
|
-
|
|
48795
|
-
|
|
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
|
+
}
|
|
48796
48838
|
}
|
|
48797
48839
|
return actionArray;
|
|
48798
48840
|
});
|
|
@@ -48802,8 +48844,9 @@ class DurableDraftStore {
|
|
|
48802
48844
|
const draft = this.draftStore[id];
|
|
48803
48845
|
if (draft !== undefined) {
|
|
48804
48846
|
delete this.draftStore[id];
|
|
48847
|
+
delete this.cleanSnapshot[id];
|
|
48805
48848
|
const durableKey = buildDraftDurableStoreKey(draft.tag, draft.id);
|
|
48806
|
-
return this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT);
|
|
48849
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT));
|
|
48807
48850
|
}
|
|
48808
48851
|
return Promise.resolve();
|
|
48809
48852
|
};
|
|
@@ -48819,10 +48862,11 @@ class DurableDraftStore {
|
|
|
48819
48862
|
const action = draftStore[key];
|
|
48820
48863
|
if (action.tag === tag) {
|
|
48821
48864
|
delete draftStore[action.id];
|
|
48865
|
+
delete this.cleanSnapshot[action.id];
|
|
48822
48866
|
durableKeys.push(buildDraftDurableStoreKey(action.tag, action.id));
|
|
48823
48867
|
}
|
|
48824
48868
|
}
|
|
48825
|
-
return this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT);
|
|
48869
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT));
|
|
48826
48870
|
};
|
|
48827
48871
|
return this.enqueueAction(deleteAction);
|
|
48828
48872
|
}
|
|
@@ -48836,6 +48880,7 @@ class DurableDraftStore {
|
|
|
48836
48880
|
const action = draftStore[operation.id];
|
|
48837
48881
|
if (action !== undefined) {
|
|
48838
48882
|
delete draftStore[operation.id];
|
|
48883
|
+
delete this.cleanSnapshot[operation.id];
|
|
48839
48884
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48840
48885
|
durableStoreOperations.push({
|
|
48841
48886
|
ids: [key],
|
|
@@ -48848,6 +48893,7 @@ class DurableDraftStore {
|
|
|
48848
48893
|
const { action } = operation;
|
|
48849
48894
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48850
48895
|
draftStore[action.id] = action;
|
|
48896
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48851
48897
|
durableStoreOperations.push({
|
|
48852
48898
|
type: 'setEntries',
|
|
48853
48899
|
segment: DRAFT_SEGMENT,
|
|
@@ -48859,7 +48905,7 @@ class DurableDraftStore {
|
|
|
48859
48905
|
});
|
|
48860
48906
|
}
|
|
48861
48907
|
}
|
|
48862
|
-
return this.durableStore.batchOperations(durableStoreOperations);
|
|
48908
|
+
return this.timeDurableOp('batchOperations', DRAFT_SEGMENT, () => this.durableStore.batchOperations(durableStoreOperations));
|
|
48863
48909
|
};
|
|
48864
48910
|
return this.enqueueAction(action);
|
|
48865
48911
|
}
|
|
@@ -48902,6 +48948,7 @@ class DurableDraftStore {
|
|
|
48902
48948
|
.then((durableEntries) => {
|
|
48903
48949
|
if (durableEntries === undefined) {
|
|
48904
48950
|
this.draftStore = {};
|
|
48951
|
+
this.cleanSnapshot = {};
|
|
48905
48952
|
return this.runQueuedOperations();
|
|
48906
48953
|
}
|
|
48907
48954
|
const { draftStore } = this;
|
|
@@ -48910,6 +48957,7 @@ class DurableDraftStore {
|
|
|
48910
48957
|
const entry = durableEntries[keys$1[i]];
|
|
48911
48958
|
const action = entry.data;
|
|
48912
48959
|
draftStore[action.id] = action;
|
|
48960
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48913
48961
|
}
|
|
48914
48962
|
return this.runQueuedOperations();
|
|
48915
48963
|
})
|
|
@@ -80134,6 +80182,14 @@ const DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS = 'draft-queue-total-mergeActions-ca
|
|
|
80134
80182
|
// Used to triage the WOLI duplicate-record investigation in Splunk — correlate by draftId
|
|
80135
80183
|
// with the other draft-queue events. @W-23428669
|
|
80136
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';
|
|
80137
80193
|
/** Content Document */
|
|
80138
80194
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
|
|
80139
80195
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
|
|
@@ -80226,6 +80282,33 @@ function reportDraftActionEvent(state, draftCount, message) {
|
|
|
80226
80282
|
break;
|
|
80227
80283
|
}
|
|
80228
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
|
+
}
|
|
80229
80312
|
/**
|
|
80230
80313
|
* Reports an exception thrown while uploading a draft action. The thrown error is
|
|
80231
80314
|
* otherwise swallowed by the upload handler's retry path, leaving the failure
|
|
@@ -80709,14 +80792,45 @@ class AbstractResourceRequestActionHandler {
|
|
|
80709
80792
|
let updatedActionTargetId = undefined;
|
|
80710
80793
|
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
80711
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.
|
|
80712
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 });
|
|
80713
80801
|
// for each redirected ID/key we loop over the operation to see if it needs
|
|
80714
80802
|
// to be updated
|
|
80715
80803
|
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
80716
|
-
if (
|
|
80717
|
-
basePath
|
|
80718
|
-
|
|
80719
|
-
|
|
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
|
+
}
|
|
80720
80834
|
}
|
|
80721
80835
|
// if the action is performed on a previous draft id, we need to replace the action
|
|
80722
80836
|
// with a new one at the updated canonical key
|
|
@@ -90289,6 +90403,20 @@ function obtainFailureMessage(error) {
|
|
|
90289
90403
|
}
|
|
90290
90404
|
}
|
|
90291
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
|
+
|
|
90292
90420
|
// so eslint doesn't complain about nimbus
|
|
90293
90421
|
/* global __nimbus */
|
|
90294
90422
|
function buildLdsDraftQueue(durableStore) {
|
|
@@ -90297,7 +90425,8 @@ function buildLdsDraftQueue(durableStore) {
|
|
|
90297
90425
|
__nimbus.plugins.LdsDraftQueue !== undefined) {
|
|
90298
90426
|
return new NimbusDraftQueue();
|
|
90299
90427
|
}
|
|
90300
|
-
const
|
|
90428
|
+
const useSnapshot = draftQueueStoreSnapshotGate.isOpen({ fallback: true });
|
|
90429
|
+
const draftQueue = new DurableDraftQueue(new DurableDraftStore(durableStore, draftQueueInstrumentation, useSnapshot), draftQueueInstrumentation);
|
|
90301
90430
|
return instrumentDraftQueue(draftQueue);
|
|
90302
90431
|
}
|
|
90303
90432
|
|
|
@@ -93628,18 +93757,34 @@ class SideEffectStore {
|
|
|
93628
93757
|
this.initialize();
|
|
93629
93758
|
}
|
|
93630
93759
|
async addEffects(effects) {
|
|
93760
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93631
93761
|
const durableEntries = {};
|
|
93632
93762
|
effects.forEach((effect) => {
|
|
93633
93763
|
durableEntries[effect.uniqueId] = { data: effect };
|
|
93634
93764
|
this.allEffects.set(effect.uniqueId, effect);
|
|
93765
|
+
if (incremental) {
|
|
93766
|
+
this.addEffectToKeyMap(effect);
|
|
93767
|
+
}
|
|
93635
93768
|
});
|
|
93636
|
-
|
|
93769
|
+
// Killswitch (W-23515682): closed → original O(N) full rebuild on every add.
|
|
93770
|
+
if (!incremental) {
|
|
93771
|
+
this.regenerateKeyToEffectMap();
|
|
93772
|
+
}
|
|
93637
93773
|
await this.durableStore.setEntries(durableEntries, SIDE_EFFECT_SEGMENT);
|
|
93638
93774
|
}
|
|
93639
93775
|
async removeEffects(effects) {
|
|
93776
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93640
93777
|
const effectKeys = effects.map((e) => e.uniqueId);
|
|
93641
|
-
effects.forEach((
|
|
93642
|
-
|
|
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
|
+
}
|
|
93643
93788
|
await this.durableStore.evictEntries(effectKeys, SIDE_EFFECT_SEGMENT);
|
|
93644
93789
|
}
|
|
93645
93790
|
getEffects(key) {
|
|
@@ -93674,6 +93819,39 @@ class SideEffectStore {
|
|
|
93674
93819
|
});
|
|
93675
93820
|
this.regenerateKeyToEffectMap();
|
|
93676
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
|
+
}
|
|
93677
93855
|
regenerateKeyToEffectMap() {
|
|
93678
93856
|
this.keyToEffectMap.clear();
|
|
93679
93857
|
this.allEffects.forEach((effect) => {
|
|
@@ -96823,7 +97001,7 @@ function buildServiceDescriptor$b(luvio) {
|
|
|
96823
97001
|
},
|
|
96824
97002
|
};
|
|
96825
97003
|
}
|
|
96826
|
-
// version: 1.
|
|
97004
|
+
// version: 1.452.0-bcd113b7fd
|
|
96827
97005
|
|
|
96828
97006
|
/**
|
|
96829
97007
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -96849,7 +97027,7 @@ function buildServiceDescriptor$a(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
96849
97027
|
},
|
|
96850
97028
|
};
|
|
96851
97029
|
}
|
|
96852
|
-
// version: 1.
|
|
97030
|
+
// version: 1.452.0-bcd113b7fd
|
|
96853
97031
|
|
|
96854
97032
|
function findExecutableOperation$1(input) {
|
|
96855
97033
|
const operations = input.query.definitions.filter(
|
|
@@ -99558,7 +99736,7 @@ register$1({
|
|
|
99558
99736
|
id: '@salesforce/lds-network-adapter',
|
|
99559
99737
|
instrument: instrument$2,
|
|
99560
99738
|
});
|
|
99561
|
-
// version: 1.
|
|
99739
|
+
// version: 1.452.0-bcd113b7fd
|
|
99562
99740
|
|
|
99563
99741
|
const { create: create$2, keys: keys$2 } = Object;
|
|
99564
99742
|
const { stringify, parse } = JSON;
|
|
@@ -107093,7 +107271,7 @@ function registerCallback(cb) {
|
|
|
107093
107271
|
cb(graphql_v1_import, graphql_imperative$1, graphql_imperative_legacy_v1_import, graphql_state_manager, useOneStoreGraphQL);
|
|
107094
107272
|
}
|
|
107095
107273
|
}
|
|
107096
|
-
// version: 1.
|
|
107274
|
+
// version: 1.452.0-1ecfe8af95
|
|
107097
107275
|
|
|
107098
107276
|
function createFragmentMap(documentNode) {
|
|
107099
107277
|
const fragments = {};
|
|
@@ -136336,7 +136514,7 @@ register$1({
|
|
|
136336
136514
|
configuration: { ...configurationForGraphQLAdapters$1 },
|
|
136337
136515
|
instrument: instrument$1,
|
|
136338
136516
|
});
|
|
136339
|
-
// version: 1.
|
|
136517
|
+
// version: 1.452.0-1ecfe8af95
|
|
136340
136518
|
|
|
136341
136519
|
// On core the unstable adapters are re-exported with different names,
|
|
136342
136520
|
// we want to match them here.
|
|
@@ -136488,7 +136666,7 @@ withDefaultLuvio((luvio) => {
|
|
|
136488
136666
|
unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
|
|
136489
136667
|
graphQLImperative = ldsAdapter;
|
|
136490
136668
|
});
|
|
136491
|
-
// version: 1.
|
|
136669
|
+
// version: 1.452.0-1ecfe8af95
|
|
136492
136670
|
|
|
136493
136671
|
var gqlApi = /*#__PURE__*/Object.freeze({
|
|
136494
136672
|
__proto__: null,
|
|
@@ -137287,7 +137465,7 @@ const callbacks$1 = [];
|
|
|
137287
137465
|
function register(r) {
|
|
137288
137466
|
callbacks$1.forEach((callback) => callback(r));
|
|
137289
137467
|
}
|
|
137290
|
-
// version: 1.
|
|
137468
|
+
// version: 1.452.0-bcd113b7fd
|
|
137291
137469
|
|
|
137292
137470
|
/**
|
|
137293
137471
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -138576,4 +138754,4 @@ const { luvio } = getRuntime();
|
|
|
138576
138754
|
setDefaultLuvio({ luvio });
|
|
138577
138755
|
|
|
138578
138756
|
export { createPrimingSession, draftManager, draftQueue, evictCacheRecordsByIds, evictExpiredCacheEntries, executeAdapter, executeMutatingAdapter, getImperativeAdapterNames, importLuvioAdapterModule, importOneStoreAdapterModule, invokeAdapter, invokeAdapterWithDraftToMerge, invokeAdapterWithDraftToReplace, invokeAdapterWithMetadata, nimbusDraftQueue, registerReportObserver, setMetadataTTL, setUiApiRecordTTL, stopEviction, subscribeToAdapter };
|
|
138579
|
-
// 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;
|
|
@@ -14379,7 +14379,7 @@
|
|
|
14379
14379
|
return undefined;
|
|
14380
14380
|
}
|
|
14381
14381
|
|
|
14382
|
-
const VERSION$10$2 = "
|
|
14382
|
+
const VERSION$10$2 = "3f49d751896cf66e6e29788d8880e2cc";
|
|
14383
14383
|
const RepresentationType$G = 'PlatformActionRepresentation';
|
|
14384
14384
|
function keyBuilder$1P$1(luvio, config) {
|
|
14385
14385
|
return keyPrefix$3 + '::' + RepresentationType$G + ':' + config.externalId + ':' + (config.relatedSourceObject === null ? '' : config.relatedSourceObject) + ':' + (config.relatedListRecordId === null ? '' : config.relatedListRecordId);
|
|
@@ -14439,10 +14439,6 @@
|
|
|
14439
14439
|
name: 'lwcComponent',
|
|
14440
14440
|
kind: 'Scalar'
|
|
14441
14441
|
},
|
|
14442
|
-
{
|
|
14443
|
-
name: 'pageDeveloperName',
|
|
14444
|
-
kind: 'Scalar'
|
|
14445
|
-
},
|
|
14446
14442
|
{
|
|
14447
14443
|
name: 'primaryColor',
|
|
14448
14444
|
kind: 'Scalar'
|
|
@@ -14471,14 +14467,6 @@
|
|
|
14471
14467
|
name: 'targetObject',
|
|
14472
14468
|
kind: 'Scalar'
|
|
14473
14469
|
},
|
|
14474
|
-
{
|
|
14475
|
-
name: 'targetParentField',
|
|
14476
|
-
kind: 'Scalar'
|
|
14477
|
-
},
|
|
14478
|
-
{
|
|
14479
|
-
name: 'targetRecordTypeId',
|
|
14480
|
-
kind: 'Scalar'
|
|
14481
|
-
},
|
|
14482
14470
|
{
|
|
14483
14471
|
name: 'targetUrl',
|
|
14484
14472
|
kind: 'Scalar'
|
|
@@ -14551,11 +14539,6 @@
|
|
|
14551
14539
|
if (!(existing_lwcComponent === incoming_lwcComponent)) {
|
|
14552
14540
|
return false;
|
|
14553
14541
|
}
|
|
14554
|
-
const existing_pageDeveloperName = existing.pageDeveloperName;
|
|
14555
|
-
const incoming_pageDeveloperName = incoming.pageDeveloperName;
|
|
14556
|
-
if (!(existing_pageDeveloperName === incoming_pageDeveloperName)) {
|
|
14557
|
-
return false;
|
|
14558
|
-
}
|
|
14559
14542
|
const existing_primaryColor = existing.primaryColor;
|
|
14560
14543
|
const incoming_primaryColor = incoming.primaryColor;
|
|
14561
14544
|
if (!(existing_primaryColor === incoming_primaryColor)) {
|
|
@@ -14586,16 +14569,6 @@
|
|
|
14586
14569
|
if (!(existing_targetObject === incoming_targetObject)) {
|
|
14587
14570
|
return false;
|
|
14588
14571
|
}
|
|
14589
|
-
const existing_targetParentField = existing.targetParentField;
|
|
14590
|
-
const incoming_targetParentField = incoming.targetParentField;
|
|
14591
|
-
if (!(existing_targetParentField === incoming_targetParentField)) {
|
|
14592
|
-
return false;
|
|
14593
|
-
}
|
|
14594
|
-
const existing_targetRecordTypeId = existing.targetRecordTypeId;
|
|
14595
|
-
const incoming_targetRecordTypeId = incoming.targetRecordTypeId;
|
|
14596
|
-
if (!(existing_targetRecordTypeId === incoming_targetRecordTypeId)) {
|
|
14597
|
-
return false;
|
|
14598
|
-
}
|
|
14599
14572
|
const existing_targetUrl = existing.targetUrl;
|
|
14600
14573
|
const incoming_targetUrl = incoming.targetUrl;
|
|
14601
14574
|
if (!(existing_targetUrl === incoming_targetUrl)) {
|
|
@@ -32580,7 +32553,7 @@
|
|
|
32580
32553
|
throttle(60, 60000, setupNotifyAllListRecordUpdateAvailable(luvio));
|
|
32581
32554
|
throttle(60, 60000, setupNotifyAllListInfoSummaryUpdateAvailable(luvio));
|
|
32582
32555
|
});
|
|
32583
|
-
// version: 1.
|
|
32556
|
+
// version: 1.452.0-1ecfe8af95
|
|
32584
32557
|
|
|
32585
32558
|
var draftQueueMaxRetryAttemptsGate = {
|
|
32586
32559
|
isOpen: function (e) {
|
|
@@ -32591,6 +32564,15 @@
|
|
|
32591
32564
|
},
|
|
32592
32565
|
};
|
|
32593
32566
|
|
|
32567
|
+
var draftQueueRedirectScanGate = {
|
|
32568
|
+
isOpen: function (e) {
|
|
32569
|
+
return e.fallback;
|
|
32570
|
+
},
|
|
32571
|
+
hasError: function () {
|
|
32572
|
+
return !0;
|
|
32573
|
+
},
|
|
32574
|
+
};
|
|
32575
|
+
|
|
32594
32576
|
var rotateIdempotencyKeyOn400Killswitch = {
|
|
32595
32577
|
isOpen: function (e) {
|
|
32596
32578
|
return e.fallback;
|
|
@@ -44136,6 +44118,15 @@
|
|
|
44136
44118
|
},
|
|
44137
44119
|
};
|
|
44138
44120
|
|
|
44121
|
+
var draftQueueStoreSnapshotGate = {
|
|
44122
|
+
isOpen: function (e) {
|
|
44123
|
+
return e.fallback;
|
|
44124
|
+
},
|
|
44125
|
+
hasError: function () {
|
|
44126
|
+
return !0;
|
|
44127
|
+
},
|
|
44128
|
+
};
|
|
44129
|
+
|
|
44139
44130
|
var ldsAdapterO11yLoggingGate = {
|
|
44140
44131
|
isOpen: function (e) {
|
|
44141
44132
|
return e.fallback;
|
|
@@ -45925,6 +45916,15 @@
|
|
|
45925
45916
|
return ok$3(document);
|
|
45926
45917
|
}
|
|
45927
45918
|
|
|
45919
|
+
var draftQueueSideEffectMapGate = {
|
|
45920
|
+
isOpen: function (e) {
|
|
45921
|
+
return e.fallback;
|
|
45922
|
+
},
|
|
45923
|
+
hasError: function () {
|
|
45924
|
+
return !0;
|
|
45925
|
+
},
|
|
45926
|
+
};
|
|
45927
|
+
|
|
45928
45928
|
var productConsumedSideEffects = {
|
|
45929
45929
|
isOpen: function (e) {
|
|
45930
45930
|
return e.fallback;
|
|
@@ -48247,7 +48247,7 @@
|
|
|
48247
48247
|
}
|
|
48248
48248
|
return handler;
|
|
48249
48249
|
}
|
|
48250
|
-
constructor(draftStore) {
|
|
48250
|
+
constructor(draftStore, instrumentation) {
|
|
48251
48251
|
this.retryIntervalMilliseconds = 0;
|
|
48252
48252
|
this.minimumRetryInterval = 250;
|
|
48253
48253
|
this.maximumRetryInterval = 32000;
|
|
@@ -48264,6 +48264,7 @@
|
|
|
48264
48264
|
this.handlers = {};
|
|
48265
48265
|
this.draftStore = draftStore;
|
|
48266
48266
|
this.workerPool = new AsyncWorkerPool(1);
|
|
48267
|
+
this.instrumentation = instrumentation;
|
|
48267
48268
|
}
|
|
48268
48269
|
addHandler(handler) {
|
|
48269
48270
|
const id = handler.handlerId;
|
|
@@ -48354,15 +48355,22 @@
|
|
|
48354
48355
|
this.state = DraftQueueState.Stopped;
|
|
48355
48356
|
}
|
|
48356
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;
|
|
48357
48363
|
const drafts = (await this.draftStore.getAllDrafts());
|
|
48358
48364
|
const queue = [];
|
|
48359
48365
|
drafts.forEach((draft) => {
|
|
48360
48366
|
if (draft.id === this.uploadingActionId) {
|
|
48361
|
-
draft
|
|
48367
|
+
queue.push({ ...draft, status: DraftActionStatus.Uploading });
|
|
48368
|
+
}
|
|
48369
|
+
else {
|
|
48370
|
+
queue.push(draft);
|
|
48362
48371
|
}
|
|
48363
|
-
queue.push(draft);
|
|
48364
48372
|
});
|
|
48365
|
-
|
|
48373
|
+
const sorted = queue.sort((a, b) => {
|
|
48366
48374
|
const aTime = parseInt(a.id, 10);
|
|
48367
48375
|
const bTime = parseInt(b.id, 10);
|
|
48368
48376
|
// safety check
|
|
@@ -48374,6 +48382,8 @@
|
|
|
48374
48382
|
}
|
|
48375
48383
|
return aTime - bTime;
|
|
48376
48384
|
});
|
|
48385
|
+
instrumentation?.onGetQueueActions?.(Date.now() - start, sorted.length);
|
|
48386
|
+
return sorted;
|
|
48377
48387
|
}
|
|
48378
48388
|
async enqueue(handlerId, data, observabilityContext) {
|
|
48379
48389
|
return this.workerPool.push({
|
|
@@ -48522,6 +48532,8 @@
|
|
|
48522
48532
|
const listener = draftQueueChangedListeners[i];
|
|
48523
48533
|
results.push(listener(event));
|
|
48524
48534
|
}
|
|
48535
|
+
// W-23515682: listener fan-out per event type. Measure-only.
|
|
48536
|
+
this.instrumentation?.onNotifyChangedListeners?.(event.type, draftQueueLen);
|
|
48525
48537
|
await Promise.all(results);
|
|
48526
48538
|
}
|
|
48527
48539
|
/**
|
|
@@ -48769,36 +48781,66 @@
|
|
|
48769
48781
|
*
|
|
48770
48782
|
*/
|
|
48771
48783
|
class DurableDraftStore {
|
|
48772
|
-
constructor(durableStore) {
|
|
48784
|
+
constructor(durableStore, instrumentation, useSnapshot = true) {
|
|
48773
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 = {};
|
|
48774
48789
|
// queue of writes that were made during the initial sync
|
|
48775
48790
|
this.writeQueue = [];
|
|
48776
48791
|
this.durableStore = durableStore;
|
|
48792
|
+
this.instrumentation = instrumentation;
|
|
48793
|
+
this.useSnapshot = useSnapshot;
|
|
48777
48794
|
this.resyncDraftStore();
|
|
48778
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
|
+
}
|
|
48779
48807
|
writeAction(action) {
|
|
48780
48808
|
const addAction = () => {
|
|
48781
48809
|
const { id, tag } = action;
|
|
48782
48810
|
this.draftStore[id] = action;
|
|
48811
|
+
this.cleanSnapshot[id] = clone$1(action);
|
|
48783
48812
|
const durableEntryKey = buildDraftDurableStoreKey(tag, id);
|
|
48784
48813
|
const entry = {
|
|
48785
48814
|
data: action,
|
|
48786
48815
|
};
|
|
48787
48816
|
const entries = { [durableEntryKey]: entry };
|
|
48788
|
-
return this.durableStore.setEntries(entries, DRAFT_SEGMENT);
|
|
48817
|
+
return this.timeDurableOp('setEntries', DRAFT_SEGMENT, () => this.durableStore.setEntries(entries, DRAFT_SEGMENT));
|
|
48789
48818
|
};
|
|
48790
48819
|
return this.enqueueAction(addAction);
|
|
48791
48820
|
}
|
|
48792
48821
|
getAllDrafts() {
|
|
48793
48822
|
const waitForOngoingSync = this.syncPromise || Promise.resolve();
|
|
48794
48823
|
return waitForOngoingSync.then(() => {
|
|
48795
|
-
const { draftStore } = this;
|
|
48796
|
-
const keys$1 = keys$4(draftStore);
|
|
48797
48824
|
const actionArray = [];
|
|
48798
|
-
|
|
48799
|
-
const
|
|
48800
|
-
|
|
48801
|
-
|
|
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
|
+
}
|
|
48802
48844
|
}
|
|
48803
48845
|
return actionArray;
|
|
48804
48846
|
});
|
|
@@ -48808,8 +48850,9 @@
|
|
|
48808
48850
|
const draft = this.draftStore[id];
|
|
48809
48851
|
if (draft !== undefined) {
|
|
48810
48852
|
delete this.draftStore[id];
|
|
48853
|
+
delete this.cleanSnapshot[id];
|
|
48811
48854
|
const durableKey = buildDraftDurableStoreKey(draft.tag, draft.id);
|
|
48812
|
-
return this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT);
|
|
48855
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries([durableKey], DRAFT_SEGMENT));
|
|
48813
48856
|
}
|
|
48814
48857
|
return Promise.resolve();
|
|
48815
48858
|
};
|
|
@@ -48825,10 +48868,11 @@
|
|
|
48825
48868
|
const action = draftStore[key];
|
|
48826
48869
|
if (action.tag === tag) {
|
|
48827
48870
|
delete draftStore[action.id];
|
|
48871
|
+
delete this.cleanSnapshot[action.id];
|
|
48828
48872
|
durableKeys.push(buildDraftDurableStoreKey(action.tag, action.id));
|
|
48829
48873
|
}
|
|
48830
48874
|
}
|
|
48831
|
-
return this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT);
|
|
48875
|
+
return this.timeDurableOp('evictEntries', DRAFT_SEGMENT, () => this.durableStore.evictEntries(durableKeys, DRAFT_SEGMENT));
|
|
48832
48876
|
};
|
|
48833
48877
|
return this.enqueueAction(deleteAction);
|
|
48834
48878
|
}
|
|
@@ -48842,6 +48886,7 @@
|
|
|
48842
48886
|
const action = draftStore[operation.id];
|
|
48843
48887
|
if (action !== undefined) {
|
|
48844
48888
|
delete draftStore[operation.id];
|
|
48889
|
+
delete this.cleanSnapshot[operation.id];
|
|
48845
48890
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48846
48891
|
durableStoreOperations.push({
|
|
48847
48892
|
ids: [key],
|
|
@@ -48854,6 +48899,7 @@
|
|
|
48854
48899
|
const { action } = operation;
|
|
48855
48900
|
const key = buildDraftDurableStoreKey(action.tag, action.id);
|
|
48856
48901
|
draftStore[action.id] = action;
|
|
48902
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48857
48903
|
durableStoreOperations.push({
|
|
48858
48904
|
type: 'setEntries',
|
|
48859
48905
|
segment: DRAFT_SEGMENT,
|
|
@@ -48865,7 +48911,7 @@
|
|
|
48865
48911
|
});
|
|
48866
48912
|
}
|
|
48867
48913
|
}
|
|
48868
|
-
return this.durableStore.batchOperations(durableStoreOperations);
|
|
48914
|
+
return this.timeDurableOp('batchOperations', DRAFT_SEGMENT, () => this.durableStore.batchOperations(durableStoreOperations));
|
|
48869
48915
|
};
|
|
48870
48916
|
return this.enqueueAction(action);
|
|
48871
48917
|
}
|
|
@@ -48908,6 +48954,7 @@
|
|
|
48908
48954
|
.then((durableEntries) => {
|
|
48909
48955
|
if (durableEntries === undefined) {
|
|
48910
48956
|
this.draftStore = {};
|
|
48957
|
+
this.cleanSnapshot = {};
|
|
48911
48958
|
return this.runQueuedOperations();
|
|
48912
48959
|
}
|
|
48913
48960
|
const { draftStore } = this;
|
|
@@ -48916,6 +48963,7 @@
|
|
|
48916
48963
|
const entry = durableEntries[keys$1[i]];
|
|
48917
48964
|
const action = entry.data;
|
|
48918
48965
|
draftStore[action.id] = action;
|
|
48966
|
+
this.cleanSnapshot[action.id] = clone$1(action);
|
|
48919
48967
|
}
|
|
48920
48968
|
return this.runQueuedOperations();
|
|
48921
48969
|
})
|
|
@@ -80140,6 +80188,14 @@
|
|
|
80140
80188
|
// Used to triage the WOLI duplicate-record investigation in Splunk — correlate by draftId
|
|
80141
80189
|
// with the other draft-queue events. @W-23428669
|
|
80142
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';
|
|
80143
80199
|
/** Content Document */
|
|
80144
80200
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
|
|
80145
80201
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
|
|
@@ -80232,6 +80288,33 @@
|
|
|
80232
80288
|
break;
|
|
80233
80289
|
}
|
|
80234
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
|
+
}
|
|
80235
80318
|
/**
|
|
80236
80319
|
* Reports an exception thrown while uploading a draft action. The thrown error is
|
|
80237
80320
|
* otherwise swallowed by the upload handler's retry path, leaving the failure
|
|
@@ -80715,14 +80798,45 @@
|
|
|
80715
80798
|
let updatedActionTargetId = undefined;
|
|
80716
80799
|
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
80717
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.
|
|
80718
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 });
|
|
80719
80807
|
// for each redirected ID/key we loop over the operation to see if it needs
|
|
80720
80808
|
// to be updated
|
|
80721
80809
|
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
80722
|
-
if (
|
|
80723
|
-
basePath
|
|
80724
|
-
|
|
80725
|
-
|
|
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
|
+
}
|
|
80726
80840
|
}
|
|
80727
80841
|
// if the action is performed on a previous draft id, we need to replace the action
|
|
80728
80842
|
// with a new one at the updated canonical key
|
|
@@ -90295,6 +90409,20 @@
|
|
|
90295
90409
|
}
|
|
90296
90410
|
}
|
|
90297
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
|
+
|
|
90298
90426
|
// so eslint doesn't complain about nimbus
|
|
90299
90427
|
/* global __nimbus */
|
|
90300
90428
|
function buildLdsDraftQueue(durableStore) {
|
|
@@ -90303,7 +90431,8 @@
|
|
|
90303
90431
|
__nimbus.plugins.LdsDraftQueue !== undefined) {
|
|
90304
90432
|
return new NimbusDraftQueue();
|
|
90305
90433
|
}
|
|
90306
|
-
const
|
|
90434
|
+
const useSnapshot = draftQueueStoreSnapshotGate.isOpen({ fallback: true });
|
|
90435
|
+
const draftQueue = new DurableDraftQueue(new DurableDraftStore(durableStore, draftQueueInstrumentation, useSnapshot), draftQueueInstrumentation);
|
|
90307
90436
|
return instrumentDraftQueue(draftQueue);
|
|
90308
90437
|
}
|
|
90309
90438
|
|
|
@@ -93634,18 +93763,34 @@
|
|
|
93634
93763
|
this.initialize();
|
|
93635
93764
|
}
|
|
93636
93765
|
async addEffects(effects) {
|
|
93766
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93637
93767
|
const durableEntries = {};
|
|
93638
93768
|
effects.forEach((effect) => {
|
|
93639
93769
|
durableEntries[effect.uniqueId] = { data: effect };
|
|
93640
93770
|
this.allEffects.set(effect.uniqueId, effect);
|
|
93771
|
+
if (incremental) {
|
|
93772
|
+
this.addEffectToKeyMap(effect);
|
|
93773
|
+
}
|
|
93641
93774
|
});
|
|
93642
|
-
|
|
93775
|
+
// Killswitch (W-23515682): closed → original O(N) full rebuild on every add.
|
|
93776
|
+
if (!incremental) {
|
|
93777
|
+
this.regenerateKeyToEffectMap();
|
|
93778
|
+
}
|
|
93643
93779
|
await this.durableStore.setEntries(durableEntries, SIDE_EFFECT_SEGMENT);
|
|
93644
93780
|
}
|
|
93645
93781
|
async removeEffects(effects) {
|
|
93782
|
+
const incremental = draftQueueSideEffectMapGate.isOpen({ fallback: true });
|
|
93646
93783
|
const effectKeys = effects.map((e) => e.uniqueId);
|
|
93647
|
-
effects.forEach((
|
|
93648
|
-
|
|
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
|
+
}
|
|
93649
93794
|
await this.durableStore.evictEntries(effectKeys, SIDE_EFFECT_SEGMENT);
|
|
93650
93795
|
}
|
|
93651
93796
|
getEffects(key) {
|
|
@@ -93680,6 +93825,39 @@
|
|
|
93680
93825
|
});
|
|
93681
93826
|
this.regenerateKeyToEffectMap();
|
|
93682
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
|
+
}
|
|
93683
93861
|
regenerateKeyToEffectMap() {
|
|
93684
93862
|
this.keyToEffectMap.clear();
|
|
93685
93863
|
this.allEffects.forEach((effect) => {
|
|
@@ -96829,7 +97007,7 @@
|
|
|
96829
97007
|
},
|
|
96830
97008
|
};
|
|
96831
97009
|
}
|
|
96832
|
-
// version: 1.
|
|
97010
|
+
// version: 1.452.0-bcd113b7fd
|
|
96833
97011
|
|
|
96834
97012
|
/**
|
|
96835
97013
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -96855,7 +97033,7 @@
|
|
|
96855
97033
|
},
|
|
96856
97034
|
};
|
|
96857
97035
|
}
|
|
96858
|
-
// version: 1.
|
|
97036
|
+
// version: 1.452.0-bcd113b7fd
|
|
96859
97037
|
|
|
96860
97038
|
function findExecutableOperation$1(input) {
|
|
96861
97039
|
const operations = input.query.definitions.filter(
|
|
@@ -99564,7 +99742,7 @@
|
|
|
99564
99742
|
id: '@salesforce/lds-network-adapter',
|
|
99565
99743
|
instrument: instrument$2,
|
|
99566
99744
|
});
|
|
99567
|
-
// version: 1.
|
|
99745
|
+
// version: 1.452.0-bcd113b7fd
|
|
99568
99746
|
|
|
99569
99747
|
const { create: create$2, keys: keys$2 } = Object;
|
|
99570
99748
|
const { stringify, parse } = JSON;
|
|
@@ -107099,7 +107277,7 @@
|
|
|
107099
107277
|
cb(graphql_v1_import, graphql_imperative$1, graphql_imperative_legacy_v1_import, graphql_state_manager, useOneStoreGraphQL);
|
|
107100
107278
|
}
|
|
107101
107279
|
}
|
|
107102
|
-
// version: 1.
|
|
107280
|
+
// version: 1.452.0-1ecfe8af95
|
|
107103
107281
|
|
|
107104
107282
|
function createFragmentMap(documentNode) {
|
|
107105
107283
|
const fragments = {};
|
|
@@ -136342,7 +136520,7 @@
|
|
|
136342
136520
|
configuration: { ...configurationForGraphQLAdapters$1 },
|
|
136343
136521
|
instrument: instrument$1,
|
|
136344
136522
|
});
|
|
136345
|
-
// version: 1.
|
|
136523
|
+
// version: 1.452.0-1ecfe8af95
|
|
136346
136524
|
|
|
136347
136525
|
// On core the unstable adapters are re-exported with different names,
|
|
136348
136526
|
// we want to match them here.
|
|
@@ -136494,7 +136672,7 @@
|
|
|
136494
136672
|
unstable_graphQL_imperative = createImperativeAdapter(luvio, createInstrumentedAdapter(ldsAdapter, adapterMetadata), adapterMetadata);
|
|
136495
136673
|
graphQLImperative = ldsAdapter;
|
|
136496
136674
|
});
|
|
136497
|
-
// version: 1.
|
|
136675
|
+
// version: 1.452.0-1ecfe8af95
|
|
136498
136676
|
|
|
136499
136677
|
var gqlApi = /*#__PURE__*/Object.freeze({
|
|
136500
136678
|
__proto__: null,
|
|
@@ -137293,7 +137471,7 @@
|
|
|
137293
137471
|
function register(r) {
|
|
137294
137472
|
callbacks$1.forEach((callback) => callback(r));
|
|
137295
137473
|
}
|
|
137296
|
-
// version: 1.
|
|
137474
|
+
// version: 1.452.0-bcd113b7fd
|
|
137297
137475
|
|
|
137298
137476
|
/**
|
|
137299
137477
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -138603,4 +138781,4 @@
|
|
|
138603
138781
|
exports.subscribeToAdapter = subscribeToAdapter;
|
|
138604
138782
|
|
|
138605
138783
|
}));
|
|
138606
|
-
// 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",
|