@salesforce/lds-drafts 1.100.2 → 1.100.4
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.
|
@@ -11,6 +11,9 @@ export declare abstract class AbstractResourceRequestActionHandler<ResponseType,
|
|
|
11
11
|
protected readonly draftQueue: DraftQueue;
|
|
12
12
|
protected readonly networkAdapter: NetworkAdapter;
|
|
13
13
|
protected readonly getLuvio: () => Luvio;
|
|
14
|
+
ephemeralRedirects: {
|
|
15
|
+
[key: string]: string;
|
|
16
|
+
};
|
|
14
17
|
constructor(draftQueue: DraftQueue, networkAdapter: NetworkAdapter, getLuvio: () => Luvio);
|
|
15
18
|
enqueue(data: ResourceRequest): Promise<PendingDraftAction<ResourceRequest>>;
|
|
16
19
|
handleAction(action: DraftAction<ResourceRequest, ResponseType>, actionCompleted: (action: CompletedDraftAction<ResourceRequest, ResponseType>) => Promise<void>, actionErrored: (action: DraftAction<ResourceRequest, ResponseType>, retry: boolean) => Promise<void>): Promise<ProcessActionResult>;
|
package/dist/ldsDrafts.js
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
*/
|
|
6
6
|
|
|
7
7
|
import { HttpStatusCode, StoreKeyMap } from '@luvio/engine';
|
|
8
|
+
import { AsyncWorkerPool } from '@salesforce/lds-utils-adapters';
|
|
8
9
|
|
|
9
10
|
var DraftActionStatus;
|
|
10
11
|
(function (DraftActionStatus) {
|
|
@@ -424,6 +425,7 @@ class DurableDraftQueue {
|
|
|
424
425
|
this.timeoutHandler = undefined;
|
|
425
426
|
this.handlers = {};
|
|
426
427
|
this.draftStore = draftStore;
|
|
428
|
+
this.workerPool = new AsyncWorkerPool(1);
|
|
427
429
|
}
|
|
428
430
|
addHandler(handler) {
|
|
429
431
|
const id = handler.handlerId;
|
|
@@ -523,20 +525,22 @@ class DurableDraftQueue {
|
|
|
523
525
|
});
|
|
524
526
|
}
|
|
525
527
|
async enqueue(handlerId, data) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
528
|
+
return this.workerPool.push(async () => {
|
|
529
|
+
let queue = await this.getQueueActions();
|
|
530
|
+
const handler = this.getHandler(handlerId);
|
|
531
|
+
const pendingAction = (await handler.buildPendingAction(data, queue));
|
|
532
|
+
await this.draftStore.writeAction(pendingAction);
|
|
533
|
+
queue = await this.getQueueActions();
|
|
534
|
+
await this.notifyChangedListeners({
|
|
535
|
+
type: DraftQueueEventType.ActionAdded,
|
|
536
|
+
action: pendingAction,
|
|
537
|
+
});
|
|
538
|
+
await handler.handleActionEnqueued(pendingAction, queue);
|
|
539
|
+
if (this.state === DraftQueueState.Started) {
|
|
540
|
+
this.processNextAction();
|
|
541
|
+
}
|
|
542
|
+
return pendingAction;
|
|
534
543
|
});
|
|
535
|
-
await handler.handleActionEnqueued(pendingAction, queue);
|
|
536
|
-
if (this.state === DraftQueueState.Started) {
|
|
537
|
-
this.processNextAction();
|
|
538
|
-
}
|
|
539
|
-
return pendingAction;
|
|
540
544
|
}
|
|
541
545
|
registerOnChangedListener(listener) {
|
|
542
546
|
this.draftQueueChangedListeners.push(listener);
|
|
@@ -548,27 +552,29 @@ class DurableDraftQueue {
|
|
|
548
552
|
};
|
|
549
553
|
}
|
|
550
554
|
async actionCompleted(action) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
555
|
+
return this.workerPool.push(async () => {
|
|
556
|
+
const handler = this.getHandler(action.handler);
|
|
557
|
+
let queue = await this.getQueueActions();
|
|
558
|
+
const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
|
|
559
|
+
const idAndKeyMappings = handler.getRedirectMappings(action);
|
|
560
|
+
const keyMappings = idAndKeyMappings === undefined
|
|
561
|
+
? undefined
|
|
562
|
+
: idAndKeyMappings.map((m) => {
|
|
563
|
+
return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
|
|
564
|
+
});
|
|
565
|
+
await this.draftStore.completeAction(queueOperations, keyMappings);
|
|
566
|
+
queue = await this.getQueueActions();
|
|
567
|
+
this.retryIntervalMilliseconds = 0;
|
|
568
|
+
this.uploadingActionId = undefined;
|
|
569
|
+
await handler.handleActionCompleted(action, queueOperations, queue, values(this.handlers));
|
|
570
|
+
await this.notifyChangedListeners({
|
|
571
|
+
type: DraftQueueEventType.ActionCompleted,
|
|
572
|
+
action,
|
|
559
573
|
});
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
this.uploadingActionId = undefined;
|
|
564
|
-
await handler.handleActionCompleted(action, queueOperations, queue, values(this.handlers));
|
|
565
|
-
await this.notifyChangedListeners({
|
|
566
|
-
type: DraftQueueEventType.ActionCompleted,
|
|
567
|
-
action,
|
|
574
|
+
if (this.state === DraftQueueState.Started) {
|
|
575
|
+
this.processNextAction();
|
|
576
|
+
}
|
|
568
577
|
});
|
|
569
|
-
if (this.state === DraftQueueState.Started) {
|
|
570
|
-
this.processNextAction();
|
|
571
|
-
}
|
|
572
578
|
}
|
|
573
579
|
async actionFailed(action, retry) {
|
|
574
580
|
this.uploadingActionId = undefined;
|
|
@@ -1018,6 +1024,13 @@ class AbstractResourceRequestActionHandler {
|
|
|
1018
1024
|
this.draftQueue = draftQueue;
|
|
1019
1025
|
this.networkAdapter = networkAdapter;
|
|
1020
1026
|
this.getLuvio = getLuvio;
|
|
1027
|
+
// NOTE[W-12567340]: This property stores in-memory mappings between draft
|
|
1028
|
+
// ids and canonical ids for the current session. Having a local copy of
|
|
1029
|
+
// these mappings is necessary to avoid a race condition between publishing
|
|
1030
|
+
// new mappings to the durable store and those mappings being loaded into
|
|
1031
|
+
// the luvio store redirect table, during which a new draft might be enqueued
|
|
1032
|
+
// which would not see a necessary mapping.
|
|
1033
|
+
this.ephemeralRedirects = {};
|
|
1021
1034
|
}
|
|
1022
1035
|
enqueue(data) {
|
|
1023
1036
|
return this.draftQueue.enqueue(this.handlerId, data);
|
|
@@ -1085,7 +1098,8 @@ class AbstractResourceRequestActionHandler {
|
|
|
1085
1098
|
}
|
|
1086
1099
|
getQueueOperationsForCompletingDrafts(queue, action) {
|
|
1087
1100
|
const queueOperations = [];
|
|
1088
|
-
|
|
1101
|
+
const redirects = this.getRedirectMappings(action);
|
|
1102
|
+
if (redirects !== undefined) {
|
|
1089
1103
|
const { length } = queue;
|
|
1090
1104
|
for (let i = 0; i < length; i++) {
|
|
1091
1105
|
const queueAction = queue[i];
|
|
@@ -1095,69 +1109,64 @@ class AbstractResourceRequestActionHandler {
|
|
|
1095
1109
|
continue;
|
|
1096
1110
|
}
|
|
1097
1111
|
if (isResourceRequestAction(queueAction)) {
|
|
1098
|
-
|
|
1099
|
-
|
|
1100
|
-
|
|
1101
|
-
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1110
|
-
|
|
1111
|
-
basePath = basePath.replace(draftId, canonicalId);
|
|
1112
|
-
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
1113
|
-
queueOperationMutated = true;
|
|
1114
|
-
}
|
|
1115
|
-
// if the action is performed on a previous draft id, we need to replace the action
|
|
1116
|
-
// with a new one at the updated canonical key
|
|
1117
|
-
if (queueActionTag === draftKey) {
|
|
1118
|
-
updatedActionTag = canonicalKey;
|
|
1119
|
-
updatedActionTargetId = canonicalId;
|
|
1120
|
-
}
|
|
1112
|
+
let queueOperationMutated = false;
|
|
1113
|
+
let updatedActionTag = undefined;
|
|
1114
|
+
let updatedActionTargetId = undefined;
|
|
1115
|
+
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
1116
|
+
let { basePath, body } = queueActionRequest;
|
|
1117
|
+
let stringifiedBody = stringify(body);
|
|
1118
|
+
// for each redirected ID/key we loop over the operation to see if it needs
|
|
1119
|
+
// to be updated
|
|
1120
|
+
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
1121
|
+
if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
|
|
1122
|
+
basePath = basePath.replace(draftId, canonicalId);
|
|
1123
|
+
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
1124
|
+
queueOperationMutated = true;
|
|
1121
1125
|
}
|
|
1122
|
-
if
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
|
|
1137
|
-
|
|
1138
|
-
|
|
1139
|
-
}
|
|
1140
|
-
|
|
1141
|
-
|
|
1142
|
-
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1126
|
+
// if the action is performed on a previous draft id, we need to replace the action
|
|
1127
|
+
// with a new one at the updated canonical key
|
|
1128
|
+
if (queueActionTag === draftKey) {
|
|
1129
|
+
updatedActionTag = canonicalKey;
|
|
1130
|
+
updatedActionTargetId = canonicalId;
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
if (queueOperationMutated) {
|
|
1134
|
+
if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
|
|
1135
|
+
const updatedAction = {
|
|
1136
|
+
...queueAction,
|
|
1137
|
+
tag: updatedActionTag,
|
|
1138
|
+
targetId: updatedActionTargetId,
|
|
1139
|
+
data: {
|
|
1140
|
+
...queueActionRequest,
|
|
1141
|
+
basePath: basePath,
|
|
1142
|
+
body: parse(stringifiedBody),
|
|
1143
|
+
},
|
|
1144
|
+
};
|
|
1145
|
+
// item needs to be replaced with a new item at the new record key
|
|
1146
|
+
queueOperations.push({
|
|
1147
|
+
type: QueueOperationType.Delete,
|
|
1148
|
+
id: queueActionId,
|
|
1149
|
+
});
|
|
1150
|
+
queueOperations.push({
|
|
1151
|
+
type: QueueOperationType.Add,
|
|
1152
|
+
action: updatedAction,
|
|
1153
|
+
});
|
|
1154
|
+
}
|
|
1155
|
+
else {
|
|
1156
|
+
const updatedAction = {
|
|
1157
|
+
...queueAction,
|
|
1158
|
+
data: {
|
|
1159
|
+
...queueActionRequest,
|
|
1160
|
+
basePath: basePath,
|
|
1161
|
+
body: parse(stringifiedBody),
|
|
1162
|
+
},
|
|
1163
|
+
};
|
|
1164
|
+
// item needs to be updated
|
|
1165
|
+
queueOperations.push({
|
|
1166
|
+
type: QueueOperationType.Update,
|
|
1167
|
+
id: queueActionId,
|
|
1168
|
+
action: updatedAction,
|
|
1169
|
+
});
|
|
1161
1170
|
}
|
|
1162
1171
|
}
|
|
1163
1172
|
}
|
|
@@ -1177,6 +1186,9 @@ class AbstractResourceRequestActionHandler {
|
|
|
1177
1186
|
const body = action.response.body;
|
|
1178
1187
|
const canonicalId = this.getIdFromResponseBody(body);
|
|
1179
1188
|
const draftId = action.targetId;
|
|
1189
|
+
if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
|
|
1190
|
+
this.ephemeralRedirects[draftId] = canonicalId;
|
|
1191
|
+
}
|
|
1180
1192
|
return [
|
|
1181
1193
|
{
|
|
1182
1194
|
draftId,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-drafts",
|
|
3
|
-
"version": "1.100.
|
|
3
|
+
"version": "1.100.4",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.txt",
|
|
5
5
|
"description": "LDS Drafts",
|
|
6
6
|
"main": "dist/ldsDrafts.js",
|
|
@@ -25,6 +25,7 @@
|
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"@luvio/engine": "0.135.4",
|
|
28
|
-
"@luvio/environments": "0.135.4"
|
|
28
|
+
"@luvio/environments": "0.135.4",
|
|
29
|
+
"@salesforce/lds-utils-adapters": "^1.100.4"
|
|
29
30
|
}
|
|
30
31
|
}
|