@salesforce/lds-runtime-mobile 1.449.0 → 1.451.0-dev1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/main.js +68 -10
- package/dist/types/instrumentation/metrics.d.ts +22 -0
- package/package.json +33 -33
- package/sfdc/main.js +68 -10
- package/sfdc/types/instrumentation/metrics.d.ts +22 -0
package/dist/main.js
CHANGED
|
@@ -42273,6 +42273,10 @@ const DRAFT_QUEUE_ACTION_UPDATED = 'draft-queue-action-updated';
|
|
|
42273
42273
|
const DRAFT_QUEUE_ACTION_FAILED = 'draft-queue-action-failed';
|
|
42274
42274
|
const DRAFT_QUEUE_ACTION_UPLOAD_ERROR = 'draft-queue-action-upload-error';
|
|
42275
42275
|
const DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS = 'draft-queue-total-mergeActions-calls';
|
|
42276
|
+
// Emitted every time a draft's Idempotency-Key is rotated (replaced with a fresh uuid).
|
|
42277
|
+
// Used to triage the WOLI duplicate-record investigation in Splunk — correlate by draftId
|
|
42278
|
+
// with the other draft-queue events. @W-23428669
|
|
42279
|
+
const DRAFT_QUEUE_IDEMPOTENCY_KEY_ROTATED = 'draft-queue-idempotency-key-rotated';
|
|
42276
42280
|
/** Content Document */
|
|
42277
42281
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
|
|
42278
42282
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
|
|
@@ -42388,6 +42392,34 @@ function reportDraftActionUploadError(error, handlerId, attempt) {
|
|
|
42388
42392
|
});
|
|
42389
42393
|
ldsMobileInstrumentation.error(normalized, DRAFT_QUEUE_ACTION_UPLOAD_ERROR);
|
|
42390
42394
|
}
|
|
42395
|
+
/**
|
|
42396
|
+
* Emits a single greppable Splunk log line (and an o11y counter) every time a draft's
|
|
42397
|
+
* Idempotency-Key is rotated — i.e. replaced with a fresh uuid rather than reused on
|
|
42398
|
+
* retry. This is the instrumentation for the WOLI duplicate-record investigation
|
|
42399
|
+
* (@W-23428669): a rotation mid-flight is the mechanism by which an already-committed
|
|
42400
|
+
* write can be re-sent under a new key and duplicated on the server, so recording every
|
|
42401
|
+
* rotation lets us reconstruct, on a future reproduction, exactly where and how often a
|
|
42402
|
+
* key changed for a given draft.
|
|
42403
|
+
*
|
|
42404
|
+
* The message is prefixed with a stable literal ("Idempotency key rotated") so it can be
|
|
42405
|
+
* pulled out of Splunk with a substring match, and carries:
|
|
42406
|
+
* - draftId: the local (client-synthesized) draft-action target id, so this event can be
|
|
42407
|
+
* correlated with the other draft-queue events for the same draft. This is NOT a server
|
|
42408
|
+
* record id or any field value — it is the same local id already surfaced by the queue's
|
|
42409
|
+
* other lifecycle logs, so it introduces no new PII.
|
|
42410
|
+
* - reason: which rotation call site fired, to disambiguate the distinct rotation paths.
|
|
42411
|
+
*
|
|
42412
|
+
* @param draftId the local draft-action target id whose key was rotated
|
|
42413
|
+
* @param reason the rotation call site (see IdempotencyKeyRotationReason)
|
|
42414
|
+
*/
|
|
42415
|
+
function reportIdempotencyKeyRotated(draftId, reason) {
|
|
42416
|
+
if (nimbusLogger) {
|
|
42417
|
+
nimbusLogger.logInfo(`Idempotency key rotated: draftId=${draftId}, reason=${reason}`);
|
|
42418
|
+
}
|
|
42419
|
+
ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_IDEMPOTENCY_KEY_ROTATED, 1, undefined, {
|
|
42420
|
+
reason,
|
|
42421
|
+
});
|
|
42422
|
+
}
|
|
42391
42423
|
function reportDraftQueueState(state, draftCount) {
|
|
42392
42424
|
if (nimbusLogger) {
|
|
42393
42425
|
nimbusLogger.logInfo(`Draft state changed: ${state}, depth: ${draftCount}`);
|
|
@@ -42627,6 +42659,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42627
42659
|
// the draft error (shouldRetry stays false). Retained only as an escape
|
|
42628
42660
|
// hatch; this is the path that duplicated already-committed writes.
|
|
42629
42661
|
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
42662
|
+
reportIdempotencyKeyRotated(updatedAction.targetId, 'generic-400-killswitch');
|
|
42630
42663
|
actionDataChanged = true;
|
|
42631
42664
|
}
|
|
42632
42665
|
else if (!this.isServerGeneratedError(response.body)) {
|
|
@@ -42659,6 +42692,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42659
42692
|
if (this.hasIdempotencySupport() &&
|
|
42660
42693
|
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] !== undefined) {
|
|
42661
42694
|
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
42695
|
+
reportIdempotencyKeyRotated(updatedAction.targetId, 'backdating-collision');
|
|
42662
42696
|
}
|
|
42663
42697
|
shouldRetry = true;
|
|
42664
42698
|
actionDataChanged = true;
|
|
@@ -42963,6 +42997,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42963
42997
|
// Updates Idempotency key if target has one
|
|
42964
42998
|
if (targetData.headers && targetData.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
42965
42999
|
merged.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
43000
|
+
reportIdempotencyKeyRotated(merged.targetId, 'merge-actions');
|
|
42966
43001
|
}
|
|
42967
43002
|
// overlay metadata
|
|
42968
43003
|
merged.metadata = { ...targetMetadata, ...sourceMetadata };
|
|
@@ -42992,6 +43027,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42992
43027
|
action.data.headers = action.data.headers || {};
|
|
42993
43028
|
if (updateIdempotencyKey) {
|
|
42994
43029
|
action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
43030
|
+
reportIdempotencyKeyRotated(action.targetId, 'idempotency-error');
|
|
42995
43031
|
}
|
|
42996
43032
|
else {
|
|
42997
43033
|
delete action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY];
|
|
@@ -59101,7 +59137,7 @@ function buildServiceDescriptor$b(luvio) {
|
|
|
59101
59137
|
},
|
|
59102
59138
|
};
|
|
59103
59139
|
}
|
|
59104
|
-
// version: 1.
|
|
59140
|
+
// version: 1.451.0-dev1-a2c5e50338
|
|
59105
59141
|
|
|
59106
59142
|
/**
|
|
59107
59143
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -59127,7 +59163,7 @@ function buildServiceDescriptor$a(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
59127
59163
|
},
|
|
59128
59164
|
};
|
|
59129
59165
|
}
|
|
59130
|
-
// version: 1.
|
|
59166
|
+
// version: 1.451.0-dev1-a2c5e50338
|
|
59131
59167
|
|
|
59132
59168
|
function findExecutableOperation(input) {
|
|
59133
59169
|
const operations = input.query.definitions.filter(
|
|
@@ -59955,6 +59991,15 @@ function buildUserlandError(error) {
|
|
|
59955
59991
|
}
|
|
59956
59992
|
return new Error("Internal error in Lightning Data Service adapter occurred.");
|
|
59957
59993
|
}
|
|
59994
|
+
function unwrapUserlandError(error) {
|
|
59995
|
+
if (isUserVisibleError(error)) {
|
|
59996
|
+
return error.data;
|
|
59997
|
+
}
|
|
59998
|
+
return toError(error);
|
|
59999
|
+
}
|
|
60000
|
+
function throwUnwrappedUserlandError(error) {
|
|
60001
|
+
throw unwrapUserlandError(error);
|
|
60002
|
+
}
|
|
59958
60003
|
function logError(error) {
|
|
59959
60004
|
if (isUserVisibleError(error)) {
|
|
59960
60005
|
return;
|
|
@@ -60018,7 +60063,9 @@ class DefaultImperativeBindingsService {
|
|
|
60018
60063
|
deepFreeze(result.value);
|
|
60019
60064
|
return isSubscribableResult(result) ? result.value.data : result.value;
|
|
60020
60065
|
}
|
|
60021
|
-
|
|
60066
|
+
throwUnwrappedUserlandError(
|
|
60067
|
+
isSubscribableResult(result) ? result.error.failure : result.error
|
|
60068
|
+
);
|
|
60022
60069
|
});
|
|
60023
60070
|
}
|
|
60024
60071
|
}
|
|
@@ -60036,7 +60083,9 @@ class QueryImperativeBindingsService {
|
|
|
60036
60083
|
deepFreeze(result.value);
|
|
60037
60084
|
return isSubscribableResult(result) ? { data: result.value.data } : { data: result.value };
|
|
60038
60085
|
}
|
|
60039
|
-
|
|
60086
|
+
throwUnwrappedUserlandError(
|
|
60087
|
+
isSubscribableResult(result) ? result.error.failure : result.error
|
|
60088
|
+
);
|
|
60040
60089
|
});
|
|
60041
60090
|
}
|
|
60042
60091
|
}
|
|
@@ -60068,7 +60117,10 @@ class SubscribableImperativeBindingsService {
|
|
|
60068
60117
|
subscribe: (cb) => {
|
|
60069
60118
|
return result.value.subscribe((result2) => {
|
|
60070
60119
|
if (result2.isErr()) {
|
|
60071
|
-
return cb({
|
|
60120
|
+
return cb({
|
|
60121
|
+
data: void 0,
|
|
60122
|
+
error: unwrapUserlandError(result2.error)
|
|
60123
|
+
});
|
|
60072
60124
|
}
|
|
60073
60125
|
return cb({ data: result2.value, error: void 0 });
|
|
60074
60126
|
});
|
|
@@ -60090,7 +60142,7 @@ class SubscribableImperativeBindingsService {
|
|
|
60090
60142
|
return api;
|
|
60091
60143
|
}
|
|
60092
60144
|
} else {
|
|
60093
|
-
|
|
60145
|
+
throwUnwrappedUserlandError(result.error.failure);
|
|
60094
60146
|
}
|
|
60095
60147
|
}
|
|
60096
60148
|
}
|
|
@@ -60112,7 +60164,7 @@ class LegacyImperativeBindingsService {
|
|
|
60112
60164
|
deepFreeze(result.value);
|
|
60113
60165
|
callback({ data: result.value.data, error: void 0 });
|
|
60114
60166
|
} else {
|
|
60115
|
-
callback({ data: void 0, error:
|
|
60167
|
+
callback({ data: void 0, error: unwrapUserlandError(result.error.failure) });
|
|
60116
60168
|
}
|
|
60117
60169
|
} catch (error) {
|
|
60118
60170
|
emitError(callback, error);
|
|
@@ -60127,14 +60179,20 @@ class LegacyImperativeBindingsService {
|
|
|
60127
60179
|
command.execute(overrides).then(
|
|
60128
60180
|
(result) => {
|
|
60129
60181
|
if (!result.isOk()) {
|
|
60130
|
-
callback({
|
|
60182
|
+
callback({
|
|
60183
|
+
data: void 0,
|
|
60184
|
+
error: unwrapUserlandError(result.error.failure)
|
|
60185
|
+
});
|
|
60131
60186
|
return;
|
|
60132
60187
|
}
|
|
60133
60188
|
unsubscribe = result.value.subscribe((res) => {
|
|
60134
60189
|
if (res.isOk()) {
|
|
60135
60190
|
callback({ data: res.value, error: void 0 });
|
|
60136
60191
|
} else {
|
|
60137
|
-
callback({
|
|
60192
|
+
callback({
|
|
60193
|
+
data: void 0,
|
|
60194
|
+
error: unwrapUserlandError(res.error)
|
|
60195
|
+
});
|
|
60138
60196
|
}
|
|
60139
60197
|
});
|
|
60140
60198
|
callback({ data: result.value.data, error: void 0 });
|
|
@@ -61817,4 +61875,4 @@ register({
|
|
|
61817
61875
|
});
|
|
61818
61876
|
|
|
61819
61877
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, ingest$1o as ingestDenormalizedRecordRepresentation, initializeOneStore, registerReportObserver, reportGraphqlQueryParseError };
|
|
61820
|
-
// version: 1.
|
|
61878
|
+
// version: 1.451.0-dev1-a2c5e50338
|
|
@@ -24,6 +24,28 @@ export declare function reportDraftActionEvent(state: 'added' | 'uploading' | 'c
|
|
|
24
24
|
* the action's targetId/tag or any request body/field values.
|
|
25
25
|
*/
|
|
26
26
|
export declare function reportDraftActionUploadError(error: unknown, handlerId: string, attempt: number): void;
|
|
27
|
+
export type IdempotencyKeyRotationReason = 'idempotency-error' | 'backdating-collision' | 'merge-actions' | 'generic-400-killswitch';
|
|
28
|
+
/**
|
|
29
|
+
* Emits a single greppable Splunk log line (and an o11y counter) every time a draft's
|
|
30
|
+
* Idempotency-Key is rotated — i.e. replaced with a fresh uuid rather than reused on
|
|
31
|
+
* retry. This is the instrumentation for the WOLI duplicate-record investigation
|
|
32
|
+
* (@W-23428669): a rotation mid-flight is the mechanism by which an already-committed
|
|
33
|
+
* write can be re-sent under a new key and duplicated on the server, so recording every
|
|
34
|
+
* rotation lets us reconstruct, on a future reproduction, exactly where and how often a
|
|
35
|
+
* key changed for a given draft.
|
|
36
|
+
*
|
|
37
|
+
* The message is prefixed with a stable literal ("Idempotency key rotated") so it can be
|
|
38
|
+
* pulled out of Splunk with a substring match, and carries:
|
|
39
|
+
* - draftId: the local (client-synthesized) draft-action target id, so this event can be
|
|
40
|
+
* correlated with the other draft-queue events for the same draft. This is NOT a server
|
|
41
|
+
* record id or any field value — it is the same local id already surfaced by the queue's
|
|
42
|
+
* other lifecycle logs, so it introduces no new PII.
|
|
43
|
+
* - reason: which rotation call site fired, to disambiguate the distinct rotation paths.
|
|
44
|
+
*
|
|
45
|
+
* @param draftId the local draft-action target id whose key was rotated
|
|
46
|
+
* @param reason the rotation call site (see IdempotencyKeyRotationReason)
|
|
47
|
+
*/
|
|
48
|
+
export declare function reportIdempotencyKeyRotated(draftId: string, reason: IdempotencyKeyRotationReason): void;
|
|
27
49
|
export declare function reportDraftQueueState(state: 'started' | 'error' | 'waiting' | 'stopped', draftCount: number): void;
|
|
28
50
|
export declare function reportDraftAwareContentDocumentVersionSynthesizeError(err: unknown): void;
|
|
29
51
|
export declare function reportDraftAwareContentVersionSynthesizeCalls(mimeType: string): void;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-runtime-mobile",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.451.0-dev1",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS runtime for mobile/hybrid environments.",
|
|
6
6
|
"main": "dist/main.js",
|
|
@@ -32,43 +32,43 @@
|
|
|
32
32
|
"release:corejar": "yarn build && ../core-build/scripts/core.js --name=lds-runtime-mobile"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@conduit-client/service-bindings-imperative": "3.
|
|
36
|
-
"@conduit-client/service-bindings-lwc": "3.
|
|
37
|
-
"@conduit-client/service-provisioner": "3.
|
|
38
|
-
"@salesforce/lds-adapters-uiapi": "^1.
|
|
39
|
-
"@salesforce/lds-bindings": "^1.
|
|
40
|
-
"@salesforce/lds-instrumentation": "^1.
|
|
41
|
-
"@salesforce/lds-luvio-service": "^1.
|
|
42
|
-
"@salesforce/lds-luvio-uiapi-records-service": "^1.
|
|
35
|
+
"@conduit-client/service-bindings-imperative": "3.26.0",
|
|
36
|
+
"@conduit-client/service-bindings-lwc": "3.26.0",
|
|
37
|
+
"@conduit-client/service-provisioner": "3.26.0",
|
|
38
|
+
"@salesforce/lds-adapters-uiapi": "^1.451.0-dev1",
|
|
39
|
+
"@salesforce/lds-bindings": "^1.451.0-dev1",
|
|
40
|
+
"@salesforce/lds-instrumentation": "^1.451.0-dev1",
|
|
41
|
+
"@salesforce/lds-luvio-service": "^1.451.0-dev1",
|
|
42
|
+
"@salesforce/lds-luvio-uiapi-records-service": "^1.451.0-dev1",
|
|
43
43
|
"@salesforce/user": "0.0.21",
|
|
44
44
|
"o11y": "250.7.0",
|
|
45
45
|
"o11y_schema": "256.126.0"
|
|
46
46
|
},
|
|
47
47
|
"devDependencies": {
|
|
48
|
-
"@conduit-client/command-aura-network": "3.
|
|
49
|
-
"@conduit-client/command-aura-normalized-cache-control": "3.
|
|
50
|
-
"@conduit-client/command-fetch-network": "3.
|
|
51
|
-
"@conduit-client/command-http-normalized-cache-control": "3.
|
|
52
|
-
"@conduit-client/command-network": "3.
|
|
53
|
-
"@conduit-client/service-cache": "3.
|
|
54
|
-
"@conduit-client/service-cache-control": "3.
|
|
55
|
-
"@conduit-client/service-cache-inclusion-policy": "3.
|
|
56
|
-
"@conduit-client/service-fetch-network": "3.
|
|
57
|
-
"@conduit-client/service-instrument-command": "3.
|
|
58
|
-
"@conduit-client/service-instrumentation": "3.
|
|
59
|
-
"@conduit-client/service-pubsub": "3.
|
|
60
|
-
"@conduit-client/service-store": "3.
|
|
61
|
-
"@conduit-client/utils": "3.
|
|
62
|
-
"@salesforce/lds-adapters-graphql": "^1.
|
|
63
|
-
"@salesforce/lds-drafts": "^1.
|
|
64
|
-
"@salesforce/lds-durable-records": "^1.
|
|
65
|
-
"@salesforce/lds-network-adapter": "^1.
|
|
66
|
-
"@salesforce/lds-network-nimbus": "^1.
|
|
67
|
-
"@salesforce/lds-store-binary": "^1.
|
|
68
|
-
"@salesforce/lds-store-nimbus": "^1.
|
|
69
|
-
"@salesforce/lds-store-sql": "^1.
|
|
70
|
-
"@salesforce/lds-utils-adapters": "^1.
|
|
71
|
-
"@salesforce/nimbus-plugin-lds": "^1.
|
|
48
|
+
"@conduit-client/command-aura-network": "3.26.0",
|
|
49
|
+
"@conduit-client/command-aura-normalized-cache-control": "3.26.0",
|
|
50
|
+
"@conduit-client/command-fetch-network": "3.26.0",
|
|
51
|
+
"@conduit-client/command-http-normalized-cache-control": "3.26.0",
|
|
52
|
+
"@conduit-client/command-network": "3.26.0",
|
|
53
|
+
"@conduit-client/service-cache": "3.26.0",
|
|
54
|
+
"@conduit-client/service-cache-control": "3.26.0",
|
|
55
|
+
"@conduit-client/service-cache-inclusion-policy": "3.26.0",
|
|
56
|
+
"@conduit-client/service-fetch-network": "3.26.0",
|
|
57
|
+
"@conduit-client/service-instrument-command": "3.26.0",
|
|
58
|
+
"@conduit-client/service-instrumentation": "3.26.0",
|
|
59
|
+
"@conduit-client/service-pubsub": "3.26.0",
|
|
60
|
+
"@conduit-client/service-store": "3.26.0",
|
|
61
|
+
"@conduit-client/utils": "3.26.0",
|
|
62
|
+
"@salesforce/lds-adapters-graphql": "^1.451.0-dev1",
|
|
63
|
+
"@salesforce/lds-drafts": "^1.451.0-dev1",
|
|
64
|
+
"@salesforce/lds-durable-records": "^1.451.0-dev1",
|
|
65
|
+
"@salesforce/lds-network-adapter": "^1.451.0-dev1",
|
|
66
|
+
"@salesforce/lds-network-nimbus": "^1.451.0-dev1",
|
|
67
|
+
"@salesforce/lds-store-binary": "^1.451.0-dev1",
|
|
68
|
+
"@salesforce/lds-store-nimbus": "^1.451.0-dev1",
|
|
69
|
+
"@salesforce/lds-store-sql": "^1.451.0-dev1",
|
|
70
|
+
"@salesforce/lds-utils-adapters": "^1.451.0-dev1",
|
|
71
|
+
"@salesforce/nimbus-plugin-lds": "^1.451.0-dev1",
|
|
72
72
|
"babel-plugin-dynamic-import-node": "^2.3.3",
|
|
73
73
|
"wait-for-expect": "^3.0.2"
|
|
74
74
|
},
|
package/sfdc/main.js
CHANGED
|
@@ -42273,6 +42273,10 @@ const DRAFT_QUEUE_ACTION_UPDATED = 'draft-queue-action-updated';
|
|
|
42273
42273
|
const DRAFT_QUEUE_ACTION_FAILED = 'draft-queue-action-failed';
|
|
42274
42274
|
const DRAFT_QUEUE_ACTION_UPLOAD_ERROR = 'draft-queue-action-upload-error';
|
|
42275
42275
|
const DRAFT_QUEUE_TOTAL_MERGE_ACTIONS_CALLS = 'draft-queue-total-mergeActions-calls';
|
|
42276
|
+
// Emitted every time a draft's Idempotency-Key is rotated (replaced with a fresh uuid).
|
|
42277
|
+
// Used to triage the WOLI duplicate-record investigation in Splunk — correlate by draftId
|
|
42278
|
+
// with the other draft-queue events. @W-23428669
|
|
42279
|
+
const DRAFT_QUEUE_IDEMPOTENCY_KEY_ROTATED = 'draft-queue-idempotency-key-rotated';
|
|
42276
42280
|
/** Content Document */
|
|
42277
42281
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_TOTAL_SYNTHESIZE_CALLS = 'content-document-version-total-synthesize-calls';
|
|
42278
42282
|
const CREATE_CONTENT_DOCUMENT_AND_VERSION_DRAFT_SYNTHESIZE_ERROR = 'create-content-document-version-draft-synthesize-error';
|
|
@@ -42388,6 +42392,34 @@ function reportDraftActionUploadError(error, handlerId, attempt) {
|
|
|
42388
42392
|
});
|
|
42389
42393
|
ldsMobileInstrumentation.error(normalized, DRAFT_QUEUE_ACTION_UPLOAD_ERROR);
|
|
42390
42394
|
}
|
|
42395
|
+
/**
|
|
42396
|
+
* Emits a single greppable Splunk log line (and an o11y counter) every time a draft's
|
|
42397
|
+
* Idempotency-Key is rotated — i.e. replaced with a fresh uuid rather than reused on
|
|
42398
|
+
* retry. This is the instrumentation for the WOLI duplicate-record investigation
|
|
42399
|
+
* (@W-23428669): a rotation mid-flight is the mechanism by which an already-committed
|
|
42400
|
+
* write can be re-sent under a new key and duplicated on the server, so recording every
|
|
42401
|
+
* rotation lets us reconstruct, on a future reproduction, exactly where and how often a
|
|
42402
|
+
* key changed for a given draft.
|
|
42403
|
+
*
|
|
42404
|
+
* The message is prefixed with a stable literal ("Idempotency key rotated") so it can be
|
|
42405
|
+
* pulled out of Splunk with a substring match, and carries:
|
|
42406
|
+
* - draftId: the local (client-synthesized) draft-action target id, so this event can be
|
|
42407
|
+
* correlated with the other draft-queue events for the same draft. This is NOT a server
|
|
42408
|
+
* record id or any field value — it is the same local id already surfaced by the queue's
|
|
42409
|
+
* other lifecycle logs, so it introduces no new PII.
|
|
42410
|
+
* - reason: which rotation call site fired, to disambiguate the distinct rotation paths.
|
|
42411
|
+
*
|
|
42412
|
+
* @param draftId the local draft-action target id whose key was rotated
|
|
42413
|
+
* @param reason the rotation call site (see IdempotencyKeyRotationReason)
|
|
42414
|
+
*/
|
|
42415
|
+
function reportIdempotencyKeyRotated(draftId, reason) {
|
|
42416
|
+
if (nimbusLogger) {
|
|
42417
|
+
nimbusLogger.logInfo(`Idempotency key rotated: draftId=${draftId}, reason=${reason}`);
|
|
42418
|
+
}
|
|
42419
|
+
ldsMobileInstrumentation.incrementCounter(DRAFT_QUEUE_IDEMPOTENCY_KEY_ROTATED, 1, undefined, {
|
|
42420
|
+
reason,
|
|
42421
|
+
});
|
|
42422
|
+
}
|
|
42391
42423
|
function reportDraftQueueState(state, draftCount) {
|
|
42392
42424
|
if (nimbusLogger) {
|
|
42393
42425
|
nimbusLogger.logInfo(`Draft state changed: ${state}, depth: ${draftCount}`);
|
|
@@ -42627,6 +42659,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42627
42659
|
// the draft error (shouldRetry stays false). Retained only as an escape
|
|
42628
42660
|
// hatch; this is the path that duplicated already-committed writes.
|
|
42629
42661
|
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
42662
|
+
reportIdempotencyKeyRotated(updatedAction.targetId, 'generic-400-killswitch');
|
|
42630
42663
|
actionDataChanged = true;
|
|
42631
42664
|
}
|
|
42632
42665
|
else if (!this.isServerGeneratedError(response.body)) {
|
|
@@ -42659,6 +42692,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42659
42692
|
if (this.hasIdempotencySupport() &&
|
|
42660
42693
|
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] !== undefined) {
|
|
42661
42694
|
updatedAction.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
42695
|
+
reportIdempotencyKeyRotated(updatedAction.targetId, 'backdating-collision');
|
|
42662
42696
|
}
|
|
42663
42697
|
shouldRetry = true;
|
|
42664
42698
|
actionDataChanged = true;
|
|
@@ -42963,6 +42997,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42963
42997
|
// Updates Idempotency key if target has one
|
|
42964
42998
|
if (targetData.headers && targetData.headers[HTTP_HEADER_IDEMPOTENCY_KEY]) {
|
|
42965
42999
|
merged.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
43000
|
+
reportIdempotencyKeyRotated(merged.targetId, 'merge-actions');
|
|
42966
43001
|
}
|
|
42967
43002
|
// overlay metadata
|
|
42968
43003
|
merged.metadata = { ...targetMetadata, ...sourceMetadata };
|
|
@@ -42992,6 +43027,7 @@ class AbstractResourceRequestActionHandler {
|
|
|
42992
43027
|
action.data.headers = action.data.headers || {};
|
|
42993
43028
|
if (updateIdempotencyKey) {
|
|
42994
43029
|
action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY] = uuidv4();
|
|
43030
|
+
reportIdempotencyKeyRotated(action.targetId, 'idempotency-error');
|
|
42995
43031
|
}
|
|
42996
43032
|
else {
|
|
42997
43033
|
delete action.data.headers[HTTP_HEADER_IDEMPOTENCY_KEY];
|
|
@@ -59101,7 +59137,7 @@ function buildServiceDescriptor$b(luvio) {
|
|
|
59101
59137
|
},
|
|
59102
59138
|
};
|
|
59103
59139
|
}
|
|
59104
|
-
// version: 1.
|
|
59140
|
+
// version: 1.451.0-dev1-a2c5e50338
|
|
59105
59141
|
|
|
59106
59142
|
/**
|
|
59107
59143
|
* Copyright (c) 2022, Salesforce, Inc.,
|
|
@@ -59127,7 +59163,7 @@ function buildServiceDescriptor$a(notifyRecordUpdateAvailable, getNormalizedLuvi
|
|
|
59127
59163
|
},
|
|
59128
59164
|
};
|
|
59129
59165
|
}
|
|
59130
|
-
// version: 1.
|
|
59166
|
+
// version: 1.451.0-dev1-a2c5e50338
|
|
59131
59167
|
|
|
59132
59168
|
function findExecutableOperation(input) {
|
|
59133
59169
|
const operations = input.query.definitions.filter(
|
|
@@ -59955,6 +59991,15 @@ function buildUserlandError(error) {
|
|
|
59955
59991
|
}
|
|
59956
59992
|
return new Error("Internal error in Lightning Data Service adapter occurred.");
|
|
59957
59993
|
}
|
|
59994
|
+
function unwrapUserlandError(error) {
|
|
59995
|
+
if (isUserVisibleError(error)) {
|
|
59996
|
+
return error.data;
|
|
59997
|
+
}
|
|
59998
|
+
return toError(error);
|
|
59999
|
+
}
|
|
60000
|
+
function throwUnwrappedUserlandError(error) {
|
|
60001
|
+
throw unwrapUserlandError(error);
|
|
60002
|
+
}
|
|
59958
60003
|
function logError(error) {
|
|
59959
60004
|
if (isUserVisibleError(error)) {
|
|
59960
60005
|
return;
|
|
@@ -60018,7 +60063,9 @@ class DefaultImperativeBindingsService {
|
|
|
60018
60063
|
deepFreeze(result.value);
|
|
60019
60064
|
return isSubscribableResult(result) ? result.value.data : result.value;
|
|
60020
60065
|
}
|
|
60021
|
-
|
|
60066
|
+
throwUnwrappedUserlandError(
|
|
60067
|
+
isSubscribableResult(result) ? result.error.failure : result.error
|
|
60068
|
+
);
|
|
60022
60069
|
});
|
|
60023
60070
|
}
|
|
60024
60071
|
}
|
|
@@ -60036,7 +60083,9 @@ class QueryImperativeBindingsService {
|
|
|
60036
60083
|
deepFreeze(result.value);
|
|
60037
60084
|
return isSubscribableResult(result) ? { data: result.value.data } : { data: result.value };
|
|
60038
60085
|
}
|
|
60039
|
-
|
|
60086
|
+
throwUnwrappedUserlandError(
|
|
60087
|
+
isSubscribableResult(result) ? result.error.failure : result.error
|
|
60088
|
+
);
|
|
60040
60089
|
});
|
|
60041
60090
|
}
|
|
60042
60091
|
}
|
|
@@ -60068,7 +60117,10 @@ class SubscribableImperativeBindingsService {
|
|
|
60068
60117
|
subscribe: (cb) => {
|
|
60069
60118
|
return result.value.subscribe((result2) => {
|
|
60070
60119
|
if (result2.isErr()) {
|
|
60071
|
-
return cb({
|
|
60120
|
+
return cb({
|
|
60121
|
+
data: void 0,
|
|
60122
|
+
error: unwrapUserlandError(result2.error)
|
|
60123
|
+
});
|
|
60072
60124
|
}
|
|
60073
60125
|
return cb({ data: result2.value, error: void 0 });
|
|
60074
60126
|
});
|
|
@@ -60090,7 +60142,7 @@ class SubscribableImperativeBindingsService {
|
|
|
60090
60142
|
return api;
|
|
60091
60143
|
}
|
|
60092
60144
|
} else {
|
|
60093
|
-
|
|
60145
|
+
throwUnwrappedUserlandError(result.error.failure);
|
|
60094
60146
|
}
|
|
60095
60147
|
}
|
|
60096
60148
|
}
|
|
@@ -60112,7 +60164,7 @@ class LegacyImperativeBindingsService {
|
|
|
60112
60164
|
deepFreeze(result.value);
|
|
60113
60165
|
callback({ data: result.value.data, error: void 0 });
|
|
60114
60166
|
} else {
|
|
60115
|
-
callback({ data: void 0, error:
|
|
60167
|
+
callback({ data: void 0, error: unwrapUserlandError(result.error.failure) });
|
|
60116
60168
|
}
|
|
60117
60169
|
} catch (error) {
|
|
60118
60170
|
emitError(callback, error);
|
|
@@ -60127,14 +60179,20 @@ class LegacyImperativeBindingsService {
|
|
|
60127
60179
|
command.execute(overrides).then(
|
|
60128
60180
|
(result) => {
|
|
60129
60181
|
if (!result.isOk()) {
|
|
60130
|
-
callback({
|
|
60182
|
+
callback({
|
|
60183
|
+
data: void 0,
|
|
60184
|
+
error: unwrapUserlandError(result.error.failure)
|
|
60185
|
+
});
|
|
60131
60186
|
return;
|
|
60132
60187
|
}
|
|
60133
60188
|
unsubscribe = result.value.subscribe((res) => {
|
|
60134
60189
|
if (res.isOk()) {
|
|
60135
60190
|
callback({ data: res.value, error: void 0 });
|
|
60136
60191
|
} else {
|
|
60137
|
-
callback({
|
|
60192
|
+
callback({
|
|
60193
|
+
data: void 0,
|
|
60194
|
+
error: unwrapUserlandError(res.error)
|
|
60195
|
+
});
|
|
60138
60196
|
}
|
|
60139
60197
|
});
|
|
60140
60198
|
callback({ data: result.value.data, error: void 0 });
|
|
@@ -61817,4 +61875,4 @@ register({
|
|
|
61817
61875
|
});
|
|
61818
61876
|
|
|
61819
61877
|
export { O11Y_NAMESPACE_LDS_MOBILE, getRuntime, ingest$1o as ingestDenormalizedRecordRepresentation, initializeOneStore, registerReportObserver, reportGraphqlQueryParseError };
|
|
61820
|
-
// version: 1.
|
|
61878
|
+
// version: 1.451.0-dev1-a2c5e50338
|
|
@@ -24,6 +24,28 @@ export declare function reportDraftActionEvent(state: 'added' | 'uploading' | 'c
|
|
|
24
24
|
* the action's targetId/tag or any request body/field values.
|
|
25
25
|
*/
|
|
26
26
|
export declare function reportDraftActionUploadError(error: unknown, handlerId: string, attempt: number): void;
|
|
27
|
+
export type IdempotencyKeyRotationReason = 'idempotency-error' | 'backdating-collision' | 'merge-actions' | 'generic-400-killswitch';
|
|
28
|
+
/**
|
|
29
|
+
* Emits a single greppable Splunk log line (and an o11y counter) every time a draft's
|
|
30
|
+
* Idempotency-Key is rotated — i.e. replaced with a fresh uuid rather than reused on
|
|
31
|
+
* retry. This is the instrumentation for the WOLI duplicate-record investigation
|
|
32
|
+
* (@W-23428669): a rotation mid-flight is the mechanism by which an already-committed
|
|
33
|
+
* write can be re-sent under a new key and duplicated on the server, so recording every
|
|
34
|
+
* rotation lets us reconstruct, on a future reproduction, exactly where and how often a
|
|
35
|
+
* key changed for a given draft.
|
|
36
|
+
*
|
|
37
|
+
* The message is prefixed with a stable literal ("Idempotency key rotated") so it can be
|
|
38
|
+
* pulled out of Splunk with a substring match, and carries:
|
|
39
|
+
* - draftId: the local (client-synthesized) draft-action target id, so this event can be
|
|
40
|
+
* correlated with the other draft-queue events for the same draft. This is NOT a server
|
|
41
|
+
* record id or any field value — it is the same local id already surfaced by the queue's
|
|
42
|
+
* other lifecycle logs, so it introduces no new PII.
|
|
43
|
+
* - reason: which rotation call site fired, to disambiguate the distinct rotation paths.
|
|
44
|
+
*
|
|
45
|
+
* @param draftId the local draft-action target id whose key was rotated
|
|
46
|
+
* @param reason the rotation call site (see IdempotencyKeyRotationReason)
|
|
47
|
+
*/
|
|
48
|
+
export declare function reportIdempotencyKeyRotated(draftId: string, reason: IdempotencyKeyRotationReason): void;
|
|
27
49
|
export declare function reportDraftQueueState(state: 'started' | 'error' | 'waiting' | 'stopped', draftCount: number): void;
|
|
28
50
|
export declare function reportDraftAwareContentDocumentVersionSynthesizeError(err: unknown): void;
|
|
29
51
|
export declare function reportDraftAwareContentVersionSynthesizeCalls(mimeType: string): void;
|