@salesforce/lds-drafts 1.303.0 → 1.305.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
@@ -762,12 +762,60 @@ class DurableDraftQueue {
762
762
  await this.startQueue();
763
763
  }
764
764
  }
765
+ async updateDraftAction(action) {
766
+ // stop queue manually
767
+ this.stopQueueManually();
768
+ const actionStatus = await this.statusOfAction(action.id);
769
+ if (actionStatus === DraftActionStatus.Uploading) {
770
+ return Promise.reject('cannot update an uploading action');
771
+ }
772
+ // save the action into the draft store
773
+ await this.draftStore.writeAction(action);
774
+ // make the handler replay these drafts on the record
775
+ const handler = this.getHandler(action.handler);
776
+ const queue = await this.getQueueActions();
777
+ await handler.handleActionEnqueued(action, queue);
778
+ // start queue safely
779
+ return this.startQueueSafe();
780
+ }
781
+ async statusOfAction(actionId) {
782
+ const queue = await this.getQueueActions();
783
+ const actions = queue.filter((action) => action.id === actionId);
784
+ if (actions.length === 0) {
785
+ return Promise.reject('cannot update non-existent action');
786
+ }
787
+ const action = actions[0];
788
+ return action.status;
789
+ }
765
790
  replaceAction(targetActionId, sourceActionId) {
766
791
  return this.replaceOrMergeActions(targetActionId, sourceActionId, false);
767
792
  }
768
793
  mergeActions(targetActionId, sourceActionId) {
769
794
  return this.replaceOrMergeActions(targetActionId, sourceActionId, true);
770
795
  }
796
+ async retryAction(actionId) {
797
+ this.stopQueueManually();
798
+ const actions = await this.getQueueActions();
799
+ const target = actions[0];
800
+ if (!target || target.id !== actionId) {
801
+ throw Error(`Action ${actionId} not found at the head of the draft queue`);
802
+ }
803
+ if (!isDraftError(target)) {
804
+ throw Error(`Action ${actionId} is not in Error state`);
805
+ }
806
+ let pendingAction = {
807
+ ...target,
808
+ status: DraftActionStatus.Pending,
809
+ error: undefined,
810
+ };
811
+ await this.draftStore.writeAction(pendingAction);
812
+ await this.notifyChangedListeners({
813
+ type: DraftQueueEventType.ActionUpdated,
814
+ action: pendingAction,
815
+ });
816
+ await this.startQueueSafe();
817
+ return pendingAction;
818
+ }
771
819
  async setMetadata(actionId, metadata) {
772
820
  const keys$1 = keys(metadata);
773
821
  const compatibleKeys = keys$1.filter((key) => {
@@ -1765,6 +1813,60 @@ class DraftManager {
1765
1813
  };
1766
1814
  });
1767
1815
  }
1816
+ async mergePerformQuickAction(actionId, fields) {
1817
+ if (!this.isValidFieldMap(fields)) {
1818
+ return Promise.reject('fields is not valid');
1819
+ }
1820
+ const queue = await this.draftQueue.getQueueActions();
1821
+ const actions = queue.filter((action) => action.id === actionId);
1822
+ if (actions.length === 0) {
1823
+ return Promise.reject('cannot edit non-existent action');
1824
+ }
1825
+ const action = actions[0];
1826
+ if (!this.isPerformQuickActionDraft(action, 'post')) {
1827
+ return Promise.reject('cannot edit incompatible action type or uploading actions');
1828
+ }
1829
+ action.data.body.fields = { ...action.data.body.fields, ...fields };
1830
+ await this.draftQueue.updateDraftAction(action);
1831
+ return this.buildDraftQueueItem(action);
1832
+ }
1833
+ isValidFieldMap(fields) {
1834
+ const keys$1 = keys(fields);
1835
+ const validTypes = ['string', 'number', 'null', 'boolean'];
1836
+ for (let i = 0; i < keys$1.length; i++) {
1837
+ const key = keys$1[i];
1838
+ const value = fields[key];
1839
+ if (!validTypes.includes(typeof value)) {
1840
+ return false;
1841
+ }
1842
+ }
1843
+ return true;
1844
+ }
1845
+ isPerformQuickActionDraft(action, method) {
1846
+ const data = action.data;
1847
+ const isPerformQuickAction = data.basePath.startsWith('/ui-api/actions/perform-quick-action/');
1848
+ const methodMatches = data.method === method;
1849
+ const notUploading = action.status !== DraftActionStatus.Uploading;
1850
+ return isPerformQuickAction && methodMatches && notUploading;
1851
+ }
1852
+ async mergePerformUpdateRecordQuickAction(actionId, fields) {
1853
+ if (!this.isValidFieldMap(fields)) {
1854
+ return Promise.reject('fields is not valid');
1855
+ }
1856
+ const queue = await this.draftQueue.getQueueActions();
1857
+ const actions = queue.filter((action) => action.id === actionId);
1858
+ if (actions.length === 0) {
1859
+ return Promise.reject('cannot edit non-existent action');
1860
+ }
1861
+ const action = actions[0];
1862
+ if (!this.isPerformQuickActionDraft(action, 'patch')) {
1863
+ return Promise.reject('cannot edit incompatible action type or uploading actions');
1864
+ }
1865
+ const data = action.data;
1866
+ data.body.fields = { ...data.body.fields, ...fields };
1867
+ await this.draftQueue.updateDraftAction(action);
1868
+ return this.buildDraftQueueItem(action);
1869
+ }
1768
1870
  buildDraftQueueItem(action) {
1769
1871
  const operationType = getOperationTypeFrom(action);
1770
1872
  const { id, status, timestamp, targetId, metadata } = action;
@@ -1860,6 +1962,18 @@ class DraftManager {
1860
1962
  return this.buildDraftQueueItem(updatedAction);
1861
1963
  });
1862
1964
  }
1965
+ /**
1966
+ * Retries a draft action that is in error state without any modification.
1967
+ *
1968
+ * @param actionId The id of the draft action that should be retried
1969
+ * @throws If the draft action is not at the front of the draft queue or is not
1970
+ * in error state.
1971
+ */
1972
+ async retryAction(actionId) {
1973
+ return this.draftQueue.retryAction(actionId).then((updatedAction) => {
1974
+ return this.buildDraftQueueItem(updatedAction);
1975
+ });
1976
+ }
1863
1977
  }
1864
1978
 
1865
1979
  function makeEnvironmentDraftAware(luvio, env, durableStore, handlers, draftQueue) {
@@ -1,6 +1,8 @@
1
1
  import type { CustomActionResult } from './actionHandlers/CustomActionHandler';
2
- import type { DraftActionStatus, DraftQueue, DraftActionMetadata } from './DraftQueue';
2
+ import type { DraftQueue, DraftAction, DraftActionMetadata, PendingDraftAction } from './DraftQueue';
3
+ import { DraftActionStatus } from './DraftQueue';
3
4
  import { DraftQueueState } from './DraftQueue';
5
+ import type { ResourceRequest } from '@luvio/engine';
4
6
  /**
5
7
  * Representation of the current state of the draft queue.
6
8
  * Includes the overall state as well as a list of draft
@@ -14,6 +16,9 @@ export type DraftQueueItemMetadata = {
14
16
  [key: string]: string;
15
17
  };
16
18
  export type DraftManagerCustomActionExecutor = (item: DraftQueueItem, completed: (result: CustomActionResult) => void) => void;
19
+ export type FieldMap = {
20
+ [key: string]: string | number | null | boolean;
21
+ };
17
22
  /**
18
23
  * An item in the draft queue that loosely maps to
19
24
  * a DraftAction
@@ -124,6 +129,10 @@ export declare class DraftManager {
124
129
  * @returns
125
130
  */
126
131
  setCustomActionExecutor(handlerId: string, executor: DraftManagerCustomActionExecutor): Promise<() => Promise<void>>;
132
+ mergePerformQuickAction(actionId: string, fields: FieldMap): Promise<DraftQueueItem>;
133
+ private isValidFieldMap;
134
+ isPerformQuickActionDraft(action: DraftAction<unknown, unknown>, method: string): action is PendingDraftAction<ResourceRequest>;
135
+ mergePerformUpdateRecordQuickAction(actionId: string, fields: FieldMap): Promise<DraftQueueItem>;
127
136
  private buildDraftQueueItem;
128
137
  private callListeners;
129
138
  /**
@@ -162,4 +171,12 @@ export declare class DraftManager {
162
171
  * @param metadata The metadata to set on the specified action
163
172
  */
164
173
  setMetadata(actionId: string, metadata: DraftQueueItemMetadata): Promise<DraftQueueItem>;
174
+ /**
175
+ * Retries a draft action that is in error state without any modification.
176
+ *
177
+ * @param actionId The id of the draft action that should be retried
178
+ * @throws If the draft action is not at the front of the draft queue or is not
179
+ * in error state.
180
+ */
181
+ retryAction(actionId: string): Promise<DraftQueueItem>;
165
182
  }
@@ -204,6 +204,13 @@ export interface DraftQueue {
204
204
  * @param actionId The action identifier
205
205
  */
206
206
  removeDraftAction(actionId: string): Promise<void>;
207
+ /**
208
+ * Saves the specified action into the queue, overwriting previous values
209
+ * of the action with the new ones
210
+ *
211
+ * @param action The action to update with the passed in values
212
+ */
213
+ updateDraftAction<Data, Response>(action: DraftAction<Data, Response>): Promise<void>;
207
214
  /**
208
215
  * Replaces the resource request of `withActionId` for the resource request
209
216
  * of `actionId`. Action ids cannot be equal. Both actions must be acting
@@ -228,6 +235,14 @@ export interface DraftQueue {
228
235
  * action will be removed after the merge.
229
236
  */
230
237
  mergeActions<Data, Response>(targetActionId: string, sourceActionId: string): Promise<DraftAction<Data, Response>>;
238
+ /**
239
+ * Retries a draft action that is in error state without any modification.
240
+ *
241
+ * @param actionId The id of the draft action that should be retried
242
+ * @throws If the draft action is not at the front of the draft queue or is not
243
+ * in error state.
244
+ */
245
+ retryAction<Data, Response>(actionId: string): Promise<DraftAction<Data, Response>>;
231
246
  /** Set the draft queue state to Started and process the next item */
232
247
  startQueue(): Promise<void>;
233
248
  /** Set the draft queue state to Stopped and don't let another item begin */
@@ -1,4 +1,4 @@
1
- import type { DraftQueue, DraftAction, CompletedDraftAction, DraftQueueChangeListener, DraftActionMetadata, EnqueueResult } from './DraftQueue';
1
+ import type { DraftQueue, DraftAction, CompletedDraftAction, PendingDraftAction, 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';
@@ -45,8 +45,11 @@ export declare class DurableDraftQueue implements DraftQueue {
45
45
  */
46
46
  private startQueueSafe;
47
47
  removeDraftAction(actionId: string): Promise<void>;
48
+ updateDraftAction<Data>(action: PendingDraftAction<Data>): Promise<void>;
49
+ private statusOfAction;
48
50
  replaceAction<Data, Response>(targetActionId: string, sourceActionId: string): Promise<DraftAction<Data, Response>>;
49
51
  mergeActions<Data, Response>(targetActionId: string, sourceActionId: string): Promise<DraftAction<Data, Response>>;
52
+ retryAction<Data, Response>(actionId: string): Promise<DraftAction<Data, Response>>;
50
53
  setMetadata(actionId: string, metadata: DraftActionMetadata): Promise<DraftAction<unknown, unknown>>;
51
54
  private scheduleRetryWithSpecifiedDelay;
52
55
  private scheduleRetry;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@salesforce/lds-drafts",
3
- "version": "1.303.0",
3
+ "version": "1.305.0",
4
4
  "license": "SEE LICENSE IN LICENSE.txt",
5
5
  "description": "LDS Drafts",
6
6
  "main": "dist/ldsDrafts.js",
@@ -26,6 +26,9 @@
26
26
  "dependencies": {
27
27
  "@luvio/engine": "0.156.3",
28
28
  "@luvio/environments": "0.156.3",
29
- "@salesforce/lds-utils-adapters": "^1.303.0"
29
+ "@salesforce/lds-utils-adapters": "^1.305.0"
30
+ },
31
+ "volta": {
32
+ "extends": "../../package.json"
30
33
  }
31
34
  }