@salesforce/lds-drafts 1.100.3 → 1.100.5
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/DraftQueue.d.ts
CHANGED
|
@@ -144,15 +144,19 @@ export interface UpdateQueueOperation {
|
|
|
144
144
|
action: DraftAction<unknown, unknown>;
|
|
145
145
|
}
|
|
146
146
|
export type QueueOperation = UpdateQueueOperation | AddQueueOperation | DeleteQueueOperation;
|
|
147
|
+
export interface EnqueueResult<Data, Response> {
|
|
148
|
+
action: PendingDraftAction<Data>;
|
|
149
|
+
data: Response;
|
|
150
|
+
}
|
|
147
151
|
export interface DraftQueue {
|
|
148
152
|
/**
|
|
149
153
|
* Enqueues a draft action into the DraftQueue
|
|
150
154
|
* @param handlerId the id of the handler associated with the data
|
|
151
155
|
* @param data the data the handler will use to create the draft action with
|
|
152
|
-
* @returns A promise including the pending action created for the request
|
|
156
|
+
* @returns A promise including the pending action created for the request and the data associated with the action
|
|
153
157
|
* @throws {Error} An error when a proper action handler is not found or conditions are not met to enqueue the action
|
|
154
158
|
*/
|
|
155
|
-
enqueue<Response>(handlerId: string, data:
|
|
159
|
+
enqueue<Data, Response>(handlerId: string, data: Data): Promise<EnqueueResult<Data, Response>>;
|
|
156
160
|
/**
|
|
157
161
|
* add a new handler to the draft queue to process the data in the actions
|
|
158
162
|
* @param id identifier to the handler
|
|
@@ -225,11 +229,5 @@ export interface DraftQueue {
|
|
|
225
229
|
* @param metadata The metadata to set on the specified action
|
|
226
230
|
*/
|
|
227
231
|
setMetadata(actionId: string, metadata: DraftActionMetadata): Promise<DraftAction<unknown, unknown>>;
|
|
228
|
-
/**
|
|
229
|
-
* Gets the data associated with the passed in action. This data will have drafts applied to it
|
|
230
|
-
* @param action
|
|
231
|
-
* @returns the data for the given action or undefined if the data no longer exists
|
|
232
|
-
*/
|
|
233
|
-
getDataForAction<T>(action: DraftAction<T, unknown>): Promise<T | undefined>;
|
|
234
232
|
}
|
|
235
233
|
export {};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { DraftQueue, DraftAction, CompletedDraftAction,
|
|
1
|
+
import type { DraftQueue, DraftAction, CompletedDraftAction, DraftQueueChangeListener, DraftActionMetadata, EnqueueResult } from './DraftQueue';
|
|
2
2
|
import { ProcessActionResult, DraftQueueState } from './DraftQueue';
|
|
3
3
|
import type { CustomActionExecutor } from './actionHandlers/CustomActionHandler';
|
|
4
4
|
import type { ActionHandler } from './actionHandlers/ActionHandler';
|
|
@@ -16,13 +16,13 @@ export declare class DurableDraftQueue implements DraftQueue {
|
|
|
16
16
|
private replacingAction?;
|
|
17
17
|
private uploadingActionId?;
|
|
18
18
|
private timeoutHandler;
|
|
19
|
+
private workerPool;
|
|
19
20
|
private handlers;
|
|
20
21
|
private getHandler;
|
|
21
22
|
constructor(draftStore: DraftStore);
|
|
22
23
|
addHandler<Data>(handler: ActionHandler<Data, unknown, unknown>): Promise<void>;
|
|
23
24
|
removeHandler(id: string): Promise<void>;
|
|
24
25
|
addCustomHandler(id: string, executor: CustomActionExecutor): Promise<void>;
|
|
25
|
-
getDataForAction<T>(action: DraftAction<T, unknown>): Promise<T | undefined>;
|
|
26
26
|
getQueueState(): DraftQueueState;
|
|
27
27
|
startQueue(): Promise<void>;
|
|
28
28
|
stopQueue(): Promise<void>;
|
|
@@ -31,7 +31,7 @@ export declare class DurableDraftQueue implements DraftQueue {
|
|
|
31
31
|
*/
|
|
32
32
|
private stopQueueManually;
|
|
33
33
|
getQueueActions<Data = unknown, Response = unknown>(): Promise<DraftAction<Data, Response>[]>;
|
|
34
|
-
enqueue<Data>(handlerId: string, data: unknown): Promise<
|
|
34
|
+
enqueue<Data, Response>(handlerId: string, data: unknown): Promise<EnqueueResult<Data, Response>>;
|
|
35
35
|
registerOnChangedListener(listener: DraftQueueChangeListener): () => Promise<void>;
|
|
36
36
|
actionCompleted(action: CompletedDraftAction<unknown, unknown>): Promise<void>;
|
|
37
37
|
actionFailed(action: DraftAction<unknown, unknown>, retry: boolean): Promise<void>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { NetworkAdapter, ResourceRequest, Luvio, DurableStoreKeyMetadataMap } from '@luvio/engine';
|
|
2
|
-
import type { DraftAction, CompletedDraftAction, QueueOperation, PendingDraftAction, DraftActionMetadata, DraftQueue } from '../DraftQueue';
|
|
2
|
+
import type { DraftAction, CompletedDraftAction, QueueOperation, PendingDraftAction, DraftActionMetadata, DraftQueue, EnqueueResult } from '../DraftQueue';
|
|
3
3
|
import { ProcessActionResult } from '../DraftQueue';
|
|
4
4
|
import type { ActionHandler, DraftIdAndKeyMapping, ReplacingActions } from './ActionHandler';
|
|
5
5
|
export type ResponseIngestionEntry<T = unknown> = {
|
|
@@ -11,8 +11,11 @@ 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
|
-
enqueue(data: ResourceRequest): Promise<
|
|
18
|
+
enqueue(data: ResourceRequest): Promise<EnqueueResult<ResourceRequest, ResponseType>>;
|
|
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>;
|
|
17
20
|
buildPendingAction(request: ResourceRequest, queue: DraftAction<unknown, unknown>[]): Promise<PendingDraftAction<ResourceRequest>>;
|
|
18
21
|
handleActionEnqueued(action: PendingDraftAction<ResourceRequest>): Promise<void>;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { CompletedDraftAction, DraftAction, DraftActionMetadata, PendingDraftAction, ProcessActionResult, QueueOperation } from '../DraftQueue';
|
|
1
|
+
import type { CompletedDraftAction, DraftAction, DraftActionMetadata, EnqueueResult, PendingDraftAction, ProcessActionResult, QueueOperation } from '../DraftQueue';
|
|
2
2
|
import type { DraftKeyMapping } from '../DraftIdMapping';
|
|
3
3
|
export interface ReplacingActions<Response, Data> {
|
|
4
4
|
original: DraftAction<Response, Data>;
|
|
@@ -36,7 +36,7 @@ export interface ActionHandler<Data, DraftMetadata, Type> {
|
|
|
36
36
|
* Enqueues an action to the draft queue
|
|
37
37
|
* @param data the data that will get added to the draft action
|
|
38
38
|
*/
|
|
39
|
-
enqueue(data: Data): Promise<
|
|
39
|
+
enqueue(data: Data): Promise<EnqueueResult<Data, Type>>;
|
|
40
40
|
/**
|
|
41
41
|
* Used to build a PendingDraftAction that is specific to the type of Data and Response.
|
|
42
42
|
* @param data
|
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) {
|
|
@@ -190,14 +191,13 @@ const { isArray } = Array;
|
|
|
190
191
|
function buildLuvioOverrideForDraftAdapters(luvio, handler, extractTargetIdFromCacheKey, options = {}) {
|
|
191
192
|
// override this to create and enqueue a new draft action, and return synthetic response
|
|
192
193
|
const dispatchResourceRequest = async function (resourceRequest, _context) {
|
|
193
|
-
const
|
|
194
|
+
const { data } = await handler.enqueue(resourceRequest).catch((err) => {
|
|
194
195
|
throw transformErrorToDraftSynthesisError(err);
|
|
195
196
|
});
|
|
196
|
-
|
|
197
|
-
if (record === undefined) {
|
|
197
|
+
if (data === undefined) {
|
|
198
198
|
return Promise.reject(createDraftSynthesisErrorResponse());
|
|
199
199
|
}
|
|
200
|
-
return createOkResponse(
|
|
200
|
+
return createOkResponse(data);
|
|
201
201
|
};
|
|
202
202
|
// override this to use an infinitely large ttl so the cache entry never expires
|
|
203
203
|
const publishStoreMetadata = function (key, storeMetadataParams) {
|
|
@@ -424,6 +424,7 @@ class DurableDraftQueue {
|
|
|
424
424
|
this.timeoutHandler = undefined;
|
|
425
425
|
this.handlers = {};
|
|
426
426
|
this.draftStore = draftStore;
|
|
427
|
+
this.workerPool = new AsyncWorkerPool(1);
|
|
427
428
|
}
|
|
428
429
|
addHandler(handler) {
|
|
429
430
|
const id = handler.handlerId;
|
|
@@ -441,10 +442,6 @@ class DurableDraftQueue {
|
|
|
441
442
|
const handler = customActionHandler(executor, id, this);
|
|
442
443
|
return this.addHandler(handler);
|
|
443
444
|
}
|
|
444
|
-
async getDataForAction(action) {
|
|
445
|
-
const handler = this.getHandler(action.handler);
|
|
446
|
-
return handler.getDataForAction(action);
|
|
447
|
-
}
|
|
448
445
|
getQueueState() {
|
|
449
446
|
return this.state;
|
|
450
447
|
}
|
|
@@ -523,20 +520,26 @@ class DurableDraftQueue {
|
|
|
523
520
|
});
|
|
524
521
|
}
|
|
525
522
|
async enqueue(handlerId, data) {
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
523
|
+
return this.workerPool.push(async () => {
|
|
524
|
+
let queue = await this.getQueueActions();
|
|
525
|
+
const handler = this.getHandler(handlerId);
|
|
526
|
+
const pendingAction = (await handler.buildPendingAction(data, queue));
|
|
527
|
+
await this.draftStore.writeAction(pendingAction);
|
|
528
|
+
queue = await this.getQueueActions();
|
|
529
|
+
await this.notifyChangedListeners({
|
|
530
|
+
type: DraftQueueEventType.ActionAdded,
|
|
531
|
+
action: pendingAction,
|
|
532
|
+
});
|
|
533
|
+
await handler.handleActionEnqueued(pendingAction, queue);
|
|
534
|
+
if (this.state === DraftQueueState.Started) {
|
|
535
|
+
this.processNextAction();
|
|
536
|
+
}
|
|
537
|
+
const actionData = (await handler.getDataForAction(pendingAction));
|
|
538
|
+
return {
|
|
539
|
+
action: pendingAction,
|
|
540
|
+
data: actionData,
|
|
541
|
+
};
|
|
534
542
|
});
|
|
535
|
-
await handler.handleActionEnqueued(pendingAction, queue);
|
|
536
|
-
if (this.state === DraftQueueState.Started) {
|
|
537
|
-
this.processNextAction();
|
|
538
|
-
}
|
|
539
|
-
return pendingAction;
|
|
540
543
|
}
|
|
541
544
|
registerOnChangedListener(listener) {
|
|
542
545
|
this.draftQueueChangedListeners.push(listener);
|
|
@@ -548,27 +551,29 @@ class DurableDraftQueue {
|
|
|
548
551
|
};
|
|
549
552
|
}
|
|
550
553
|
async actionCompleted(action) {
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
554
|
+
return this.workerPool.push(async () => {
|
|
555
|
+
const handler = this.getHandler(action.handler);
|
|
556
|
+
let queue = await this.getQueueActions();
|
|
557
|
+
const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
|
|
558
|
+
const idAndKeyMappings = handler.getRedirectMappings(action);
|
|
559
|
+
const keyMappings = idAndKeyMappings === undefined
|
|
560
|
+
? undefined
|
|
561
|
+
: idAndKeyMappings.map((m) => {
|
|
562
|
+
return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
|
|
563
|
+
});
|
|
564
|
+
await this.draftStore.completeAction(queueOperations, keyMappings);
|
|
565
|
+
queue = await this.getQueueActions();
|
|
566
|
+
this.retryIntervalMilliseconds = 0;
|
|
567
|
+
this.uploadingActionId = undefined;
|
|
568
|
+
await handler.handleActionCompleted(action, queueOperations, queue, values(this.handlers));
|
|
569
|
+
await this.notifyChangedListeners({
|
|
570
|
+
type: DraftQueueEventType.ActionCompleted,
|
|
571
|
+
action,
|
|
559
572
|
});
|
|
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,
|
|
573
|
+
if (this.state === DraftQueueState.Started) {
|
|
574
|
+
this.processNextAction();
|
|
575
|
+
}
|
|
568
576
|
});
|
|
569
|
-
if (this.state === DraftQueueState.Started) {
|
|
570
|
-
this.processNextAction();
|
|
571
|
-
}
|
|
572
577
|
}
|
|
573
578
|
async actionFailed(action, retry) {
|
|
574
579
|
this.uploadingActionId = undefined;
|
|
@@ -1018,6 +1023,13 @@ class AbstractResourceRequestActionHandler {
|
|
|
1018
1023
|
this.draftQueue = draftQueue;
|
|
1019
1024
|
this.networkAdapter = networkAdapter;
|
|
1020
1025
|
this.getLuvio = getLuvio;
|
|
1026
|
+
// NOTE[W-12567340]: This property stores in-memory mappings between draft
|
|
1027
|
+
// ids and canonical ids for the current session. Having a local copy of
|
|
1028
|
+
// these mappings is necessary to avoid a race condition between publishing
|
|
1029
|
+
// new mappings to the durable store and those mappings being loaded into
|
|
1030
|
+
// the luvio store redirect table, during which a new draft might be enqueued
|
|
1031
|
+
// which would not see a necessary mapping.
|
|
1032
|
+
this.ephemeralRedirects = {};
|
|
1021
1033
|
}
|
|
1022
1034
|
enqueue(data) {
|
|
1023
1035
|
return this.draftQueue.enqueue(this.handlerId, data);
|
|
@@ -1085,7 +1097,8 @@ class AbstractResourceRequestActionHandler {
|
|
|
1085
1097
|
}
|
|
1086
1098
|
getQueueOperationsForCompletingDrafts(queue, action) {
|
|
1087
1099
|
const queueOperations = [];
|
|
1088
|
-
|
|
1100
|
+
const redirects = this.getRedirectMappings(action);
|
|
1101
|
+
if (redirects !== undefined) {
|
|
1089
1102
|
const { length } = queue;
|
|
1090
1103
|
for (let i = 0; i < length; i++) {
|
|
1091
1104
|
const queueAction = queue[i];
|
|
@@ -1095,69 +1108,64 @@ class AbstractResourceRequestActionHandler {
|
|
|
1095
1108
|
continue;
|
|
1096
1109
|
}
|
|
1097
1110
|
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
|
-
}
|
|
1111
|
+
let queueOperationMutated = false;
|
|
1112
|
+
let updatedActionTag = undefined;
|
|
1113
|
+
let updatedActionTargetId = undefined;
|
|
1114
|
+
const { tag: queueActionTag, data: queueActionRequest, id: queueActionId, } = queueAction;
|
|
1115
|
+
let { basePath, body } = queueActionRequest;
|
|
1116
|
+
let stringifiedBody = stringify(body);
|
|
1117
|
+
// for each redirected ID/key we loop over the operation to see if it needs
|
|
1118
|
+
// to be updated
|
|
1119
|
+
for (const { draftId, draftKey, canonicalId, canonicalKey } of redirects) {
|
|
1120
|
+
if (basePath.search(draftId) >= 0 || stringifiedBody.search(draftId) >= 0) {
|
|
1121
|
+
basePath = basePath.replace(draftId, canonicalId);
|
|
1122
|
+
stringifiedBody = stringifiedBody.replace(draftId, canonicalId);
|
|
1123
|
+
queueOperationMutated = true;
|
|
1121
1124
|
}
|
|
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
|
-
|
|
1125
|
+
// if the action is performed on a previous draft id, we need to replace the action
|
|
1126
|
+
// with a new one at the updated canonical key
|
|
1127
|
+
if (queueActionTag === draftKey) {
|
|
1128
|
+
updatedActionTag = canonicalKey;
|
|
1129
|
+
updatedActionTargetId = canonicalId;
|
|
1130
|
+
}
|
|
1131
|
+
}
|
|
1132
|
+
if (queueOperationMutated) {
|
|
1133
|
+
if (updatedActionTag !== undefined && updatedActionTargetId !== undefined) {
|
|
1134
|
+
const updatedAction = {
|
|
1135
|
+
...queueAction,
|
|
1136
|
+
tag: updatedActionTag,
|
|
1137
|
+
targetId: updatedActionTargetId,
|
|
1138
|
+
data: {
|
|
1139
|
+
...queueActionRequest,
|
|
1140
|
+
basePath: basePath,
|
|
1141
|
+
body: parse(stringifiedBody),
|
|
1142
|
+
},
|
|
1143
|
+
};
|
|
1144
|
+
// item needs to be replaced with a new item at the new record key
|
|
1145
|
+
queueOperations.push({
|
|
1146
|
+
type: QueueOperationType.Delete,
|
|
1147
|
+
id: queueActionId,
|
|
1148
|
+
});
|
|
1149
|
+
queueOperations.push({
|
|
1150
|
+
type: QueueOperationType.Add,
|
|
1151
|
+
action: updatedAction,
|
|
1152
|
+
});
|
|
1153
|
+
}
|
|
1154
|
+
else {
|
|
1155
|
+
const updatedAction = {
|
|
1156
|
+
...queueAction,
|
|
1157
|
+
data: {
|
|
1158
|
+
...queueActionRequest,
|
|
1159
|
+
basePath: basePath,
|
|
1160
|
+
body: parse(stringifiedBody),
|
|
1161
|
+
},
|
|
1162
|
+
};
|
|
1163
|
+
// item needs to be updated
|
|
1164
|
+
queueOperations.push({
|
|
1165
|
+
type: QueueOperationType.Update,
|
|
1166
|
+
id: queueActionId,
|
|
1167
|
+
action: updatedAction,
|
|
1168
|
+
});
|
|
1161
1169
|
}
|
|
1162
1170
|
}
|
|
1163
1171
|
}
|
|
@@ -1177,6 +1185,9 @@ class AbstractResourceRequestActionHandler {
|
|
|
1177
1185
|
const body = action.response.body;
|
|
1178
1186
|
const canonicalId = this.getIdFromResponseBody(body);
|
|
1179
1187
|
const draftId = action.targetId;
|
|
1188
|
+
if (draftId !== undefined && canonicalId !== undefined && draftId !== canonicalId) {
|
|
1189
|
+
this.ephemeralRedirects[draftId] = canonicalId;
|
|
1190
|
+
}
|
|
1180
1191
|
return [
|
|
1181
1192
|
{
|
|
1182
1193
|
draftId,
|
|
@@ -1471,7 +1482,9 @@ class DraftManager {
|
|
|
1471
1482
|
targetId,
|
|
1472
1483
|
tag,
|
|
1473
1484
|
})
|
|
1474
|
-
.then(
|
|
1485
|
+
.then((result) => {
|
|
1486
|
+
return this.buildDraftQueueItem(result.action);
|
|
1487
|
+
});
|
|
1475
1488
|
}
|
|
1476
1489
|
/**
|
|
1477
1490
|
* Get the current state of each of the DraftActions in the DraftQueue
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@salesforce/lds-drafts",
|
|
3
|
-
"version": "1.100.
|
|
3
|
+
"version": "1.100.5",
|
|
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.5"
|
|
29
30
|
}
|
|
30
31
|
}
|