@salesforce/lds-drafts 1.145.0 → 1.146.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.
package/dist/ldsDrafts.js CHANGED
@@ -235,7 +235,6 @@ function buildLuvioOverrideForDraftAdapters(luvio, handler, extractTargetIdFromC
235
235
  }
236
236
 
237
237
  const DraftIdMappingKeyPrefix240 = 'DraftIdMapping::';
238
- const DraftKeyMappingKeyPrefix = 'DraftKeyMapping::V2::';
239
238
  const DRAFT_ID_MAPPINGS_SEGMENT = 'DRAFT_ID_MAPPINGS';
240
239
  function isLegacyDraftIdMapping(key, data) {
241
240
  return key.startsWith(DraftIdMappingKeyPrefix240);
@@ -245,9 +244,6 @@ function isLegacyDraftIdMapping(key, data) {
245
244
  function getRecordKeyForId(id) {
246
245
  return `UiApi::RecordRepresentation:${id}`;
247
246
  }
248
- function generateDraftIdMappingKey(draftIdMapping) {
249
- return `${DraftKeyMappingKeyPrefix}${draftIdMapping.draftKey}::${draftIdMapping.canonicalKey}`;
250
- }
251
247
  /**
252
248
  *
253
249
  * @param mappingIds (optional) requested mapping ids, if undefined all will be retrieved
@@ -281,6 +277,15 @@ async function getDraftIdMappings(durableStore, mappingIds) {
281
277
  }
282
278
  return mappings;
283
279
  }
280
+ async function clearDraftIdSegment(durableStore) {
281
+ const entries = await durableStore.getAllEntries(DRAFT_ID_MAPPINGS_SEGMENT);
282
+ if (entries) {
283
+ const keys$1 = keys(entries);
284
+ if (keys$1.length > 0) {
285
+ await durableStore.evictEntries(keys$1, DRAFT_ID_MAPPINGS_SEGMENT);
286
+ }
287
+ }
288
+ }
284
289
 
285
290
  /**
286
291
  * Generates a time-ordered, unique id to associate with a DraftAction. Ensures
@@ -371,9 +376,6 @@ function customActionHandler(executor, id, draftQueue) {
371
376
  });
372
377
  return queueOperations;
373
378
  };
374
- const getRedirectMappings = (_action) => {
375
- return undefined;
376
- };
377
379
  return {
378
380
  handlerId: id,
379
381
  enqueue: (data) => {
@@ -385,7 +387,6 @@ function customActionHandler(executor, id, draftQueue) {
385
387
  handleReplaceAction: () => {
386
388
  throw Error('replaceAction not supported for custom actions');
387
389
  },
388
- getRedirectMappings,
389
390
  handleActionRemoved: () => Promise.resolve(),
390
391
  handleActionCompleted: () => Promise.resolve(),
391
392
  handleActionEnqueued: () => Promise.resolve(),
@@ -560,17 +561,11 @@ class DurableDraftQueue {
560
561
  const handler = this.getHandler(action.handler);
561
562
  let queue = await this.getQueueActions();
562
563
  const queueOperations = handler.getQueueOperationsForCompletingDrafts(queue, action);
563
- const idAndKeyMappings = handler.getRedirectMappings(action);
564
- const keyMappings = idAndKeyMappings === undefined
565
- ? undefined
566
- : idAndKeyMappings.map((m) => {
567
- return { draftKey: m.draftKey, canonicalKey: m.canonicalKey };
568
- });
569
- await this.draftStore.completeAction(queueOperations, keyMappings);
570
- queue = await this.getQueueActions();
564
+ // write the queue operations to the store prior to ingesting the result
565
+ await this.draftStore.completeAction(queueOperations);
566
+ await handler.handleActionCompleted(action, queueOperations, values(this.handlers));
571
567
  this.retryIntervalMilliseconds = 0;
572
568
  this.uploadingActionId = undefined;
573
- await handler.handleActionCompleted(action, queueOperations, queue, values(this.handlers));
574
569
  await this.notifyChangedListeners({
575
570
  type: DraftQueueEventType.ActionCompleted,
576
571
  action,
@@ -893,7 +888,7 @@ class DurableDraftStore {
893
888
  };
894
889
  return this.enqueueAction(deleteAction);
895
890
  }
896
- completeAction(queueOperations, mappings) {
891
+ completeAction(queueOperations) {
897
892
  const action = () => {
898
893
  const durableStoreOperations = [];
899
894
  const { draftStore } = this;
@@ -926,18 +921,6 @@ class DurableDraftStore {
926
921
  });
927
922
  }
928
923
  }
929
- if (mappings !== undefined) {
930
- const entries = {};
931
- for (const mapping of mappings) {
932
- const mappingKey = generateDraftIdMappingKey(mapping);
933
- entries[mappingKey] = { data: mapping };
934
- }
935
- durableStoreOperations.push({
936
- entries,
937
- type: 'setEntries',
938
- segment: DRAFT_ID_MAPPINGS_SEGMENT,
939
- });
940
- }
941
924
  return this.durableStore.batchOperations(durableStoreOperations);
942
925
  };
943
926
  return this.enqueueAction(action);
@@ -1216,7 +1199,7 @@ class AbstractResourceRequestActionHandler {
1216
1199
  },
1217
1200
  ];
1218
1201
  }
1219
- async handleActionCompleted(action, queueOperations, _queue, allHandlers) {
1202
+ async handleActionCompleted(action, queueOperations, allHandlers) {
1220
1203
  const { data: request, tag } = action;
1221
1204
  const { method } = request;
1222
1205
  if (method === 'delete') {
@@ -1330,11 +1313,18 @@ class AbstractResourceRequestActionHandler {
1330
1313
  async ingestResponses(responses, action) {
1331
1314
  const luvio = this.getLuvio();
1332
1315
  await luvio.handleSuccessResponse(() => {
1316
+ if (action.status === DraftActionStatus.Completed) {
1317
+ const mappings = this.getRedirectMappings(action);
1318
+ if (mappings) {
1319
+ mappings.forEach((mapping) => {
1320
+ luvio.storeRedirect(mapping.draftKey, mapping.canonicalKey);
1321
+ });
1322
+ }
1323
+ }
1333
1324
  for (const entry of responses) {
1334
1325
  const { response, synchronousIngest } = entry;
1335
1326
  synchronousIngest(response, action);
1336
1327
  }
1337
- // must call base broadcast
1338
1328
  return luvio.storeBroadcast();
1339
1329
  },
1340
1330
  // getTypeCacheKeysRecord uses the response, not the full path factory
@@ -1663,6 +1653,8 @@ class DraftManager {
1663
1653
 
1664
1654
  function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
1665
1655
  const draftMetadata = {};
1656
+ // in 246 luvio took charge of persisting redirect mappings, this needs to stick around
1657
+ // for a couple of releases to support older environments
1666
1658
  // setup existing store redirects when bootstrapping the environment
1667
1659
  (async () => {
1668
1660
  const mappings = await getDraftIdMappings(durableStore);
@@ -1670,23 +1662,9 @@ function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueu
1670
1662
  const { draftKey, canonicalKey } = mapping;
1671
1663
  env.storeRedirect(draftKey, canonicalKey);
1672
1664
  });
1665
+ await env.storeBroadcast(env.rebuildSnapshot, env.snapshotAvailable);
1666
+ await clearDraftIdSegment(durableStore);
1673
1667
  })();
1674
- durableStore.registerOnChangedListener(async (changes) => {
1675
- const draftIdMappingsIds = [];
1676
- for (let i = 0, len = changes.length; i < len; i++) {
1677
- const change = changes[i];
1678
- if (change.segment === DRAFT_ID_MAPPINGS_SEGMENT) {
1679
- draftIdMappingsIds.push(...change.ids);
1680
- }
1681
- }
1682
- if (draftIdMappingsIds.length > 0) {
1683
- const mappings = await getDraftIdMappings(durableStore, draftIdMappingsIds);
1684
- mappings.forEach((mapping) => {
1685
- const { draftKey, canonicalKey } = mapping;
1686
- env.storeRedirect(draftKey, canonicalKey);
1687
- });
1688
- }
1689
- });
1690
1668
  const handleSuccessResponse = async function (ingestAndBroadcastFunc, getResponseCacheKeysFunc) {
1691
1669
  const queue = await draftQueue.getQueueActions();
1692
1670
  if (queue.length === 0) {
@@ -4,9 +4,9 @@ export interface DraftKeyMapping {
4
4
  canonicalKey: string;
5
5
  }
6
6
  export declare const DRAFT_ID_MAPPINGS_SEGMENT = "DRAFT_ID_MAPPINGS";
7
- export declare function generateDraftIdMappingKey(draftIdMapping: DraftKeyMapping): string;
8
7
  /**
9
8
  *
10
9
  * @param mappingIds (optional) requested mapping ids, if undefined all will be retrieved
11
10
  */
12
11
  export declare function getDraftIdMappings(durableStore: DurableStore, mappingIds?: string[]): Promise<DraftKeyMapping[]>;
12
+ export declare function clearDraftIdSegment(durableStore: DurableStore): Promise<void>;
@@ -1,5 +1,4 @@
1
1
  import type { DraftAction, QueueOperation } from './DraftQueue';
2
- import type { DraftKeyMapping } from './DraftIdMapping';
3
2
  /**
4
3
  * Defines the store where drafts are persisted
5
4
  */
@@ -8,5 +7,5 @@ export interface DraftStore {
8
7
  getAllDrafts(): Promise<DraftAction<unknown, unknown>[]>;
9
8
  deleteDraft(actionId: string): Promise<void>;
10
9
  deleteByTag(tag: string): Promise<void>;
11
- completeAction(queueOperations: QueueOperation[], mappings: DraftKeyMapping[] | undefined): Promise<void>;
10
+ completeAction(queueOperations: QueueOperation[]): Promise<void>;
12
11
  }
@@ -1,5 +1,4 @@
1
1
  import type { DurableStore } from '@luvio/environments';
2
- import type { DraftKeyMapping } from './DraftIdMapping';
3
2
  import type { DraftAction, QueueOperation } from './DraftQueue';
4
3
  import type { DraftStore } from './DraftStore';
5
4
  /**
@@ -21,7 +20,7 @@ export declare class DurableDraftStore implements DraftStore {
21
20
  getAllDrafts<_R, _D>(): Promise<DraftAction<unknown, unknown>[]>;
22
21
  deleteDraft(id: string): Promise<void>;
23
22
  deleteByTag(tag: string): Promise<void>;
24
- completeAction(queueOperations: QueueOperation[], mappings: DraftKeyMapping[] | undefined): Promise<void>;
23
+ completeAction(queueOperations: QueueOperation[]): Promise<void>;
25
24
  /**
26
25
  * Runs a write operation against the draft store, if the initial
27
26
  * revive is still in progress, the action gets enqueued to run once the
@@ -22,7 +22,7 @@ export declare abstract class AbstractResourceRequestActionHandler<ResponseType,
22
22
  handleActionRemoved(action: DraftAction<ResourceRequest, ResponseType>): Promise<void>;
23
23
  getQueueOperationsForCompletingDrafts(queue: DraftAction<unknown, unknown>[], action: CompletedDraftAction<ResourceRequest, ResponseType>): QueueOperation[];
24
24
  getRedirectMappings(action: CompletedDraftAction<ResourceRequest, ResponseType>): DraftIdAndKeyMapping[] | undefined;
25
- handleActionCompleted(action: CompletedDraftAction<ResourceRequest, ResponseType>, queueOperations: QueueOperation[], _queue: DraftAction<unknown, unknown>[], allHandlers: ActionHandler<unknown, unknown, unknown>[]): Promise<void>;
25
+ handleActionCompleted(action: CompletedDraftAction<ResourceRequest, ResponseType>, queueOperations: QueueOperation[], allHandlers: ActionHandler<unknown, unknown, unknown>[]): Promise<void>;
26
26
  handleReplaceAction(targetAction: DraftAction<ResourceRequest, ResponseType>, sourceAction: DraftAction<ResourceRequest, ResponseType>): DraftAction<ResourceRequest, ResponseType>;
27
27
  mergeActions(targetAction: DraftAction<ResourceRequest, ResponseType>, sourceAction: DraftAction<ResourceRequest, ResponseType>): DraftAction<ResourceRequest, ResponseType>;
28
28
  shouldDeleteActionByTagOnRemoval(action: DraftAction<ResourceRequest, ResponseType>): boolean;
@@ -72,20 +72,12 @@ export interface ActionHandler<Data, DraftMetadata, Type> {
72
72
  * @param action
73
73
  */
74
74
  getQueueOperationsForCompletingDrafts(queue: DraftAction<unknown, unknown>[], action: CompletedDraftAction<Data, Type>): QueueOperation[];
75
- /**
76
- * Invoked by the draft queue when an action is completing. Sometimes after an action completes we
77
- * need to perform a key redirect (i.e. an object that used to have a draft id now has a real id and it needs to redirect the old id)
78
- * This function returns an array of mappings if necessary or undefined if no redirect is necessary as a result of the completed operation
79
- * @param action
80
- */
81
- getRedirectMappings(action: CompletedDraftAction<Data, Type>): DraftIdAndKeyMapping[] | undefined;
82
75
  /**
83
76
  * Invoked by the draft queue after an action completes and is removed from the queue
84
77
  * @param action The completed action
85
78
  * @param queueOperations The queue modification operations that were executes with the completed action
86
- * @param queue The updated queue with the completed action removed
87
79
  */
88
- handleActionCompleted(action: CompletedDraftAction<Data, Type>, queueOperations: QueueOperation[], queue: DraftAction<unknown, unknown>[], allHandlers: ActionHandler<unknown, unknown, unknown>[]): Promise<void>;
80
+ handleActionCompleted(action: CompletedDraftAction<Data, Type>, queueOperations: QueueOperation[], allHandlers: ActionHandler<unknown, unknown, unknown>[]): Promise<void>;
89
81
  /**
90
82
  * Replace the targetAction's data with the sourceAction's data and return
91
83
  * the targetAction. Also sets the targetAction's status to Pending.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-drafts",
3
- "version": "1.145.0",
3
+ "version": "1.146.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS Drafts",
6
6
  "main": "dist/ldsDrafts.js",
@@ -24,8 +24,8 @@
24
24
  "release:corejar": "yarn build && ../core-build/scripts/core.js --adapter=lds-drafts"
25
25
  },
26
26
  "dependencies": {
27
- "@luvio/engine": "0.142.4",
28
- "@luvio/environments": "0.142.4",
27
+ "@luvio/engine": "0.143.0",
28
+ "@luvio/environments": "0.143.0",
29
29
  "@salesforce/lds-utils-adapters": "*"
30
30
  }
31
31
  }