@dereekb/dbx-core 14.17.0 → 14.18.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.
@@ -453,6 +453,31 @@ class DbxActionContextStoreSourceInstance {
453
453
  destroy() {
454
454
  this.lockSet.destroyOnNextUnlock();
455
455
  }
456
+ // MARK: Value Snapshot
457
+ /**
458
+ * Registers the function that returns the value a trigger would ready right now. See {@link ActionContextStore.registerValueSnapshot}.
459
+ *
460
+ * @param valueSnapshotFunction - Function that returns the current value.
461
+ * @returns Removes the registration when called.
462
+ */
463
+ registerValueSnapshot(valueSnapshotFunction) {
464
+ let unregister;
465
+ const sub = this.useStore((x) => (unregister = x.registerValueSnapshot(valueSnapshotFunction)));
466
+ return () => {
467
+ sub.unsubscribe();
468
+ unregister?.();
469
+ };
470
+ }
471
+ /**
472
+ * Returns the value a trigger would ready right now, without triggering the action. See {@link ActionContextStore.valueSnapshot}.
473
+ *
474
+ * @returns The current value, or undefined when it is not available synchronously.
475
+ */
476
+ valueSnapshot() {
477
+ let snapshot;
478
+ this.useStore((x) => (snapshot = x.valueSnapshot())).unsubscribe();
479
+ return snapshot;
480
+ }
456
481
  // MARK: Store
457
482
  get store$() {
458
483
  return this.source.store$;
@@ -1168,6 +1193,7 @@ class ActionContextStore extends ComponentStore {
1168
1193
  delayTime: ACTION_CONTEXT_STORE_LOCKSET_DESTROY_DELAY_TIME
1169
1194
  }
1170
1195
  });
1196
+ _valueSnapshotFunction;
1171
1197
  constructor() {
1172
1198
  super({ ...INITIAL_STATE$3 });
1173
1199
  this.lockSet.addLock('working', this.isWorking$);
@@ -1367,6 +1393,34 @@ class ActionContextStore extends ComponentStore {
1367
1393
  return this.state$.pipe(map((x) => [x, loadingStateTypeForActionContextState(x)]), distinctUntilChanged((a, b) => a?.[1] === b?.[1]), // Filter out when the loading state remains the same.
1368
1394
  map((x) => x[0]), shareReplay(1));
1369
1395
  }
1396
+ // MARK: Value Snapshot
1397
+ /**
1398
+ * Registers the function that returns the value a trigger would ready right now. Registered by the action's value source, such as dbxActionValue or dbxActionForm.
1399
+ *
1400
+ * Only one function is kept, so a later registration replaces an earlier one.
1401
+ *
1402
+ * @param valueSnapshotFunction - Function that returns the current value.
1403
+ * @returns Removes the registration when called, unless it was already replaced.
1404
+ */
1405
+ registerValueSnapshot(valueSnapshotFunction) {
1406
+ this._valueSnapshotFunction = valueSnapshotFunction;
1407
+ return () => {
1408
+ if (this._valueSnapshotFunction === valueSnapshotFunction) {
1409
+ this._valueSnapshotFunction = undefined;
1410
+ }
1411
+ };
1412
+ }
1413
+ /**
1414
+ * Returns the value a trigger would ready right now, without triggering the action.
1415
+ *
1416
+ * Lets a change be applied synchronously when the action's own trigger path and its delays can no longer run, such as right before
1417
+ * the content that holds the action is destroyed.
1418
+ *
1419
+ * @returns The current value, or undefined when no value source registered a snapshot or its value is not available synchronously.
1420
+ */
1421
+ valueSnapshot() {
1422
+ return this._valueSnapshotFunction?.();
1423
+ }
1370
1424
  // MARK: Cleanup
1371
1425
  // eslint-disable-next-line @angular-eslint/no-empty-lifecycle-method
1372
1426
  ngOnDestroy() {
@@ -2666,6 +2720,16 @@ class DbxActionValueDirective {
2666
2720
  this.source.readyValue(value);
2667
2721
  })
2668
2722
  });
2723
+ clean(this.source.registerValueSnapshot(() => this.valueSnapshot()));
2724
+ }
2725
+ /**
2726
+ * Returns the value a trigger would ready right now, without triggering the action.
2727
+ *
2728
+ * @returns The current value, or undefined when no value is set.
2729
+ */
2730
+ valueSnapshot() {
2731
+ const valueOrFunction = this._valueOrFunctionOverride.value ?? this.valueOrFunction();
2732
+ return valueOrFunction == null ? undefined : { value: getValueFromGetter(valueOrFunction) };
2669
2733
  }
2670
2734
  setValueOrFunction(value) {
2671
2735
  this._valueOrFunctionOverride.next(value);
@@ -2835,6 +2899,7 @@ class DbxActionValueGetterInstance {
2835
2899
  }).pipe(shareReplay(1));
2836
2900
  source;
2837
2901
  _triggeredSub = new SubscriptionObject();
2902
+ _unregisterValueSnapshot;
2838
2903
  constructor(config) {
2839
2904
  this.source = config.source;
2840
2905
  this.setValueGetterFunction(config.valueGetter);
@@ -2852,13 +2917,7 @@ class DbxActionValueGetterInstance {
2852
2917
  }
2853
2918
  init() {
2854
2919
  // Ready the value after the source is triggered. Do modified check one last time.
2855
- this._triggeredSub.subscription = this.source.triggered$
2856
- .pipe(switchMap(() => this.valueGetterFunction$.pipe(switchMap((valueGetter) => asObservable(valueGetter())), combineLatestWith(this.isModifiedFunction$),
2857
- // If the value is not null/undefined and is considered modified, then pass the value.
2858
- switchMap(([value, isModifiedFunction]) => returnIfIs(isModifiedFunction, value, false).pipe(map((value) => ({ value })))),
2859
- // Catch unknown errors and pass them to reject.
2860
- catchError((reject) => of({ reject: toReadableError(reject) })))))
2861
- .subscribe((result) => {
2920
+ this._triggeredSub.subscription = this.source.triggered$.pipe(switchMap(() => this._valueResult())).subscribe((result) => {
2862
2921
  if (result.value == null) {
2863
2922
  this.source.reject(result.reject);
2864
2923
  }
@@ -2866,8 +2925,32 @@ class DbxActionValueGetterInstance {
2866
2925
  this.source.readyValue(result.value);
2867
2926
  }
2868
2927
  });
2928
+ this._unregisterValueSnapshot = this.source.registerValueSnapshot(() => this.valueSnapshot());
2929
+ }
2930
+ /**
2931
+ * Returns the value a trigger would ready right now, without triggering the action.
2932
+ *
2933
+ * Runs the same value getter and modified check as a trigger.
2934
+ *
2935
+ * @returns The current result, or undefined when the value getter or the modified check does not resolve synchronously.
2936
+ */
2937
+ valueSnapshot() {
2938
+ let snapshot;
2939
+ this._valueResult()
2940
+ .pipe(first())
2941
+ .subscribe((result) => (snapshot = result))
2942
+ .unsubscribe();
2943
+ return snapshot;
2944
+ }
2945
+ _valueResult() {
2946
+ return this.valueGetterFunction$.pipe(switchMap((valueGetter) => asObservable(valueGetter())), combineLatestWith(this.isModifiedFunction$),
2947
+ // If the value is not null/undefined and is considered modified, then pass the value.
2948
+ switchMap(([value, isModifiedFunction]) => returnIfIs(isModifiedFunction, value, false).pipe(map((value) => ({ value })))),
2949
+ // Catch unknown errors and pass them to reject.
2950
+ catchError((reject) => of({ reject: toReadableError(reject) })));
2869
2951
  }
2870
2952
  destroy() {
2953
+ this._unregisterValueSnapshot?.();
2871
2954
  this.source.lockSet.onNextUnlock(() => {
2872
2955
  this._valueGetterFunction.complete();
2873
2956
  this._isModifiedFunction.complete();