@dereekb/rxjs 12.1.4 → 12.1.6

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/index.cjs.js CHANGED
@@ -2483,7 +2483,9 @@ function scanBuildArray(init) {
2483
2483
  }
2484
2484
  }
2485
2485
  return acc;
2486
- }, seed ?? []), distinctUntilArrayLengthChanges(), rxjs.shareReplay(1));
2486
+ }, seed ?? []), distinctUntilArrayLengthChanges(), rxjs.map(x => [...x]),
2487
+ // always create a copy of the accumulated array when emitting
2488
+ rxjs.shareReplay(1));
2487
2489
  });
2488
2490
  }
2489
2491
  // MARK: MapForEach
@@ -4024,16 +4026,19 @@ function itemAccumulator(itemIteration, inputMapItem) {
4024
4026
  const mapItemFunction = inputMapItem ?? (a => a);
4025
4027
  const hasCompletedInitialLoad$ = itemIteration.firstState$.pipe(rxjs.map(() => true), rxjs.startWith(false), rxjs.distinctUntilChanged(), rxjs.shareReplay(1));
4026
4028
  const latestSuccessfulState$ = itemIteration.latestState$.pipe(rxjs.filter(x => !isLoadingStateWithError(x)), rxjs.distinctUntilChanged(), rxjs.shareReplay(1));
4027
- const allSuccessfulStates$ = latestSuccessfulState$.pipe(scanIntoArray({
4029
+ const _allSuccessfulStates$ = latestSuccessfulState$.pipe(scanIntoArray({
4028
4030
  immutable: false
4029
4031
  }),
4030
4032
  /**
4031
4033
  * Don't wait for the first successful state in order to avoid never returning a value on immediate failures.
4032
4034
  */
4033
4035
  rxjs.startWith([]), distinctUntilArrayLengthChanges(), rxjs.shareReplay(1));
4034
- const successfulLoadCount$ = allSuccessfulStates$.pipe(rxjs.map(x => x.length), rxjs.shareReplay(1));
4036
+ const allSuccessfulStates$ = _allSuccessfulStates$.pipe(rxjs.map(x => [...x]),
4037
+ // return a copy of the array, and not the scanIntoArray() result that is mutable
4038
+ rxjs.shareReplay(1));
4039
+ const successfulLoadCount$ = _allSuccessfulStates$.pipe(rxjs.map(x => x.length), rxjs.shareReplay(1));
4035
4040
  // MARK: ItemAccumulator
4036
- const currentAllItemPairs$ = allSuccessfulStates$.pipe(scanBuildArray(allSuccessfulStates => {
4041
+ const currentAllItemPairs$ = _allSuccessfulStates$.pipe(scanBuildArray(allSuccessfulStates => {
4037
4042
  const mapStateToItem = util.mapFunctionOutputPair(mapLoadingStateValueFunction(mapItemFunction));
4038
4043
  /*
4039
4044
  Start with allSuccessfulPageResults$ since it contains all page results since the start of the iterator,
@@ -4054,7 +4059,7 @@ function itemAccumulator(itemIteration, inputMapItem) {
4054
4059
  const currentAllItems$ = currentAllItemPairs$.pipe(rxjs.map(x => x.map(y => y.output)), rxjs.shareReplay(1));
4055
4060
  const allItemPairs$ = hasCompletedInitialLoad$.pipe(switchMapWhileTrue(currentAllItemPairs$), rxjs.shareReplay(1));
4056
4061
  const allItems$ = hasCompletedInitialLoad$.pipe(switchMapWhileTrue(currentAllItems$), rxjs.shareReplay(1));
4057
- const sub = new SubscriptionObject(allSuccessfulStates$.subscribe());
4062
+ const sub = new SubscriptionObject(_allSuccessfulStates$.subscribe());
4058
4063
  const destroy = () => sub.destroy();
4059
4064
  const result = {
4060
4065
  itemIteration,
@@ -4325,10 +4330,21 @@ class ItemPageIterationInstance {
4325
4330
  } else {
4326
4331
  return rxjs.of(prevResult).pipe();
4327
4332
  }
4328
- }), rxjs.map(state => ({
4329
- n: request.n,
4330
- state
4331
- })))), rxjs.scan((acc, x) => {
4333
+ }), rxjs.map(inputState => {
4334
+ let state;
4335
+ if (inputState != null) {
4336
+ const end = inputState.value != null ? isItemPageIteratorResultEndResult(inputState.value) : undefined;
4337
+ state = {
4338
+ ...inputState,
4339
+ hasNextPage: util.invertMaybeBoolean(end)
4340
+ };
4341
+ }
4342
+ const result = {
4343
+ n: request.n,
4344
+ state
4345
+ };
4346
+ return result;
4347
+ }))), rxjs.scan((acc, x) => {
4332
4348
  const {
4333
4349
  n,
4334
4350
  state: curr
@@ -4399,7 +4415,7 @@ class ItemPageIterationInstance {
4399
4415
  *
4400
4416
  * Will emit every time the latest page has finished loading.
4401
4417
  */
4402
- this.hasReachedEndResult$ = this.latestPageResultState$.pipe(rxjs.map(x => isItemPageIteratorResultEndResult(x.value)), rxjs.startWith(false),
4418
+ this.hasReachedEndResult$ = this.latestPageResultState$.pipe(rxjs.map(x => !x.hasNextPage), rxjs.startWith(false),
4403
4419
  // Has not reached the end
4404
4420
  rxjs.shareReplay(1));
4405
4421
  this._currentPageResultState$ = this.currentPageResultState$.pipe(rxjs.startWith(undefined), rxjs.shareReplay(1));
@@ -4524,9 +4540,11 @@ function mapItemPageLoadingStateFromResultPageLoadingState() {
4524
4540
  return rxjs.map(itemPageLoadingStateFromResultPageLoadingState);
4525
4541
  }
4526
4542
  function itemPageLoadingStateFromResultPageLoadingState(input) {
4527
- return mapLoadingStateResults(input, {
4543
+ const result = mapLoadingStateResults(input, {
4528
4544
  mapValue: result => result.value
4529
4545
  });
4546
+ result.hasNextPage = util.invertMaybeBoolean(input.value?.end);
4547
+ return result;
4530
4548
  }
4531
4549
 
4532
4550
  const DEFAULT_LOCK_SET_TIME_LOCK_KEY = 'timelock';
package/index.esm.js CHANGED
@@ -1,5 +1,5 @@
1
1
  import { isObservable, of, switchMap, map as map$1, combineLatest, filter, skipWhile, EMPTY, delay, startWith, distinctUntilChanged, mergeMap, BehaviorSubject, shareReplay, skip, defaultIfEmpty, first, merge, finalize, firstValueFrom, scan, exhaustMap, identity, throttleTime, timeout, tap, throwError, timer, takeWhile, delayWhen, asyncScheduler, from, catchError } from 'rxjs';
2
- import { getValueFromGetter, isMaybeSo, filterMaybeArrayValues, areEqualPOJOValues, convertToArray, asGetter, performTaskLoop, isMaybeNot, pushItemOrArrayItemsIntoArray, pushArrayItemsIntoArray, forEachWithArray, asArray, filterAndMapFunction, objectKeysEqualityComparatorFunction, objectKeyEqualityComparatorFunction, asPromise, randomNumberFactory, mapKeysIntersectionObjectToArray, mapsHaveSameKeys, incrementingNumberFactory, filterUniqueFunction, build, cachedGetter, allKeyValueTuples, keyValueMapFactory, multiKeyValueMapFactory, timePeriodCounter, setContainsAllValues, setContainsAnyValue, setContainsNoneOfValue, hasSameValues, compareEqualityWithValueFromItemsFunction, searchStringFilterFunction, valuesAreBothNullishOrEquivalent, objectHasKey, toReadableError, reduceBooleansWithOr, reduceBooleansWithAnd, mergeObjects, safeCompareEquality, hasNonNullValue, limitArray, mapFunctionOutputPair, lastValue, flattenArray, filteredPage, FIRST_PAGE, hasValueOrNotEmpty, getNextPageNumber, reduceBooleansWithOrFn, MS_IN_SECOND } from '@dereekb/util';
2
+ import { getValueFromGetter, isMaybeSo, filterMaybeArrayValues, areEqualPOJOValues, convertToArray, asGetter, performTaskLoop, isMaybeNot, pushItemOrArrayItemsIntoArray, pushArrayItemsIntoArray, forEachWithArray, asArray, filterAndMapFunction, objectKeysEqualityComparatorFunction, objectKeyEqualityComparatorFunction, asPromise, randomNumberFactory, mapKeysIntersectionObjectToArray, mapsHaveSameKeys, incrementingNumberFactory, filterUniqueFunction, build, cachedGetter, allKeyValueTuples, keyValueMapFactory, multiKeyValueMapFactory, timePeriodCounter, setContainsAllValues, setContainsAnyValue, setContainsNoneOfValue, hasSameValues, compareEqualityWithValueFromItemsFunction, searchStringFilterFunction, valuesAreBothNullishOrEquivalent, objectHasKey, toReadableError, reduceBooleansWithOr, reduceBooleansWithAnd, mergeObjects, safeCompareEquality, hasNonNullValue, limitArray, mapFunctionOutputPair, lastValue, flattenArray, filteredPage, invertMaybeBoolean, FIRST_PAGE, hasValueOrNotEmpty, getNextPageNumber, reduceBooleansWithOrFn, MS_IN_SECOND } from '@dereekb/util';
3
3
 
4
4
  var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
5
5
 
@@ -2481,7 +2481,9 @@ function scanBuildArray(init) {
2481
2481
  }
2482
2482
  }
2483
2483
  return acc;
2484
- }, seed ?? []), distinctUntilArrayLengthChanges(), shareReplay(1));
2484
+ }, seed ?? []), distinctUntilArrayLengthChanges(), map$1(x => [...x]),
2485
+ // always create a copy of the accumulated array when emitting
2486
+ shareReplay(1));
2485
2487
  });
2486
2488
  }
2487
2489
  // MARK: MapForEach
@@ -4022,16 +4024,19 @@ function itemAccumulator(itemIteration, inputMapItem) {
4022
4024
  const mapItemFunction = inputMapItem ?? (a => a);
4023
4025
  const hasCompletedInitialLoad$ = itemIteration.firstState$.pipe(map$1(() => true), startWith(false), distinctUntilChanged(), shareReplay(1));
4024
4026
  const latestSuccessfulState$ = itemIteration.latestState$.pipe(filter(x => !isLoadingStateWithError(x)), distinctUntilChanged(), shareReplay(1));
4025
- const allSuccessfulStates$ = latestSuccessfulState$.pipe(scanIntoArray({
4027
+ const _allSuccessfulStates$ = latestSuccessfulState$.pipe(scanIntoArray({
4026
4028
  immutable: false
4027
4029
  }),
4028
4030
  /**
4029
4031
  * Don't wait for the first successful state in order to avoid never returning a value on immediate failures.
4030
4032
  */
4031
4033
  startWith([]), distinctUntilArrayLengthChanges(), shareReplay(1));
4032
- const successfulLoadCount$ = allSuccessfulStates$.pipe(map$1(x => x.length), shareReplay(1));
4034
+ const allSuccessfulStates$ = _allSuccessfulStates$.pipe(map$1(x => [...x]),
4035
+ // return a copy of the array, and not the scanIntoArray() result that is mutable
4036
+ shareReplay(1));
4037
+ const successfulLoadCount$ = _allSuccessfulStates$.pipe(map$1(x => x.length), shareReplay(1));
4033
4038
  // MARK: ItemAccumulator
4034
- const currentAllItemPairs$ = allSuccessfulStates$.pipe(scanBuildArray(allSuccessfulStates => {
4039
+ const currentAllItemPairs$ = _allSuccessfulStates$.pipe(scanBuildArray(allSuccessfulStates => {
4035
4040
  const mapStateToItem = mapFunctionOutputPair(mapLoadingStateValueFunction(mapItemFunction));
4036
4041
  /*
4037
4042
  Start with allSuccessfulPageResults$ since it contains all page results since the start of the iterator,
@@ -4052,7 +4057,7 @@ function itemAccumulator(itemIteration, inputMapItem) {
4052
4057
  const currentAllItems$ = currentAllItemPairs$.pipe(map$1(x => x.map(y => y.output)), shareReplay(1));
4053
4058
  const allItemPairs$ = hasCompletedInitialLoad$.pipe(switchMapWhileTrue(currentAllItemPairs$), shareReplay(1));
4054
4059
  const allItems$ = hasCompletedInitialLoad$.pipe(switchMapWhileTrue(currentAllItems$), shareReplay(1));
4055
- const sub = new SubscriptionObject(allSuccessfulStates$.subscribe());
4060
+ const sub = new SubscriptionObject(_allSuccessfulStates$.subscribe());
4056
4061
  const destroy = () => sub.destroy();
4057
4062
  const result = {
4058
4063
  itemIteration,
@@ -4323,10 +4328,21 @@ class ItemPageIterationInstance {
4323
4328
  } else {
4324
4329
  return of(prevResult).pipe();
4325
4330
  }
4326
- }), map$1(state => ({
4327
- n: request.n,
4328
- state
4329
- })))), scan((acc, x) => {
4331
+ }), map$1(inputState => {
4332
+ let state;
4333
+ if (inputState != null) {
4334
+ const end = inputState.value != null ? isItemPageIteratorResultEndResult(inputState.value) : undefined;
4335
+ state = {
4336
+ ...inputState,
4337
+ hasNextPage: invertMaybeBoolean(end)
4338
+ };
4339
+ }
4340
+ const result = {
4341
+ n: request.n,
4342
+ state
4343
+ };
4344
+ return result;
4345
+ }))), scan((acc, x) => {
4330
4346
  const {
4331
4347
  n,
4332
4348
  state: curr
@@ -4397,7 +4413,7 @@ class ItemPageIterationInstance {
4397
4413
  *
4398
4414
  * Will emit every time the latest page has finished loading.
4399
4415
  */
4400
- this.hasReachedEndResult$ = this.latestPageResultState$.pipe(map$1(x => isItemPageIteratorResultEndResult(x.value)), startWith(false),
4416
+ this.hasReachedEndResult$ = this.latestPageResultState$.pipe(map$1(x => !x.hasNextPage), startWith(false),
4401
4417
  // Has not reached the end
4402
4418
  shareReplay(1));
4403
4419
  this._currentPageResultState$ = this.currentPageResultState$.pipe(startWith(undefined), shareReplay(1));
@@ -4522,9 +4538,11 @@ function mapItemPageLoadingStateFromResultPageLoadingState() {
4522
4538
  return map$1(itemPageLoadingStateFromResultPageLoadingState);
4523
4539
  }
4524
4540
  function itemPageLoadingStateFromResultPageLoadingState(input) {
4525
- return mapLoadingStateResults(input, {
4541
+ const result = mapLoadingStateResults(input, {
4526
4542
  mapValue: result => result.value
4527
4543
  });
4544
+ result.hasNextPage = invertMaybeBoolean(input.value?.end);
4545
+ return result;
4528
4546
  }
4529
4547
 
4530
4548
  const DEFAULT_LOCK_SET_TIME_LOCK_KEY = 'timelock';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dereekb/rxjs",
3
- "version": "12.1.4",
3
+ "version": "12.1.6",
4
4
  "exports": {
5
5
  ".": {
6
6
  "types": "./src/index.d.ts",
@@ -1,4 +1,4 @@
1
- import { type Observable } from 'rxjs';
1
+ import { Observable } from 'rxjs';
2
2
  import { type MapFunctionOutputPair, type Destroyable, type IndexRef, type GetterOrValue, type MapFunction, type PromiseOrValue, type Page } from '@dereekb/util';
3
3
  import { type ItemIteration, type PageItemIteration } from './iteration';
4
4
  import { type LoadingState, type MapLoadingStateValueMapFunction } from '../loading';
@@ -10,7 +10,7 @@ export interface ItemPageLimit {
10
10
  *
11
11
  * If not defined, the will be no ending iteration.
12
12
  */
13
- maxPageLoadLimit?: Maybe<number>;
13
+ readonly maxPageLoadLimit?: Maybe<number>;
14
14
  }
15
15
  export interface ItemPageIteratorRequest<V, F, C extends ItemPageIterationConfig<F> = ItemPageIterationConfig<F>> extends Page {
16
16
  /**
@@ -42,11 +42,11 @@ export interface ItemPageIteratorResult<V> {
42
42
  /**
43
43
  * Error result.
44
44
  */
45
- error?: Error;
45
+ readonly error?: Error;
46
46
  /**
47
47
  * Returned values.
48
48
  */
49
- value?: V;
49
+ readonly value?: V;
50
50
  /**
51
51
  * True if the end has been reached.
52
52
  *
@@ -54,7 +54,7 @@ export interface ItemPageIteratorResult<V> {
54
54
  *
55
55
  * False can be specified to note that despite having no values passed, the end has not yet been reached.
56
56
  */
57
- end?: boolean;
57
+ readonly end?: boolean;
58
58
  }
59
59
  export interface ItemPageIteratorDelegate<V, F, C extends ItemPageIterationConfig<F> = ItemPageIterationConfig<F>> {
60
60
  /**
@@ -62,6 +62,10 @@ export type ListLoadingState<T = unknown> = LoadingState<T[]>;
62
62
  * LoadingState with a Page.
63
63
  */
64
64
  export interface PageLoadingState<T = unknown> extends LoadingState<T>, Page {
65
+ /**
66
+ * Whether or not there is a next page. Null/undefined if unknown.
67
+ */
68
+ readonly hasNextPage?: Maybe<boolean>;
65
69
  }
66
70
  /**
67
71
  * PageLoadingState with a filter.
@@ -69,7 +73,7 @@ export interface PageLoadingState<T = unknown> extends LoadingState<T>, Page {
69
73
  export interface FilteredPageLoadingState<T, F> extends PageLoadingState<T>, FilteredPage<F> {
70
74
  }
71
75
  /**
72
- * LoadingPageState that has an array of the value
76
+ * LoadingPageState that has an array of the values and
73
77
  */
74
78
  export type PageListLoadingState<T> = PageLoadingState<T[]>;
75
79
  /**
@@ -3,7 +3,7 @@ import { type Maybe, type ArrayOrValue, type MapFunction } from '@dereekb/util';
3
3
  export declare function distinctUntilArrayLengthChanges<A>(getArray: (value: A) => unknown[]): MonoTypeOperatorFunction<A>;
4
4
  export declare function distinctUntilArrayLengthChanges<T>(): MonoTypeOperatorFunction<T[]>;
5
5
  export interface ScanIntoArrayConfig {
6
- immutable?: boolean;
6
+ readonly immutable?: boolean;
7
7
  }
8
8
  /**
9
9
  * Scans values from the observable into an array.
@@ -17,15 +17,15 @@ export interface ScanBuildArrayConfig<T> {
17
17
  /**
18
18
  *
19
19
  */
20
- seed?: Maybe<T[]>;
20
+ readonly seed?: Maybe<T[]>;
21
21
  /**
22
22
  *
23
23
  */
24
- accumulatorObs: Observable<Maybe<ArrayOrValue<T>>>;
24
+ readonly accumulatorObs: Observable<Maybe<ArrayOrValue<T>>>;
25
25
  /**
26
26
  * Whether or not to flatten array values that are input.
27
27
  */
28
- flattenArray?: boolean;
28
+ readonly flattenArray?: boolean;
29
29
  }
30
30
  export type ScanBuildArrayConfigFn<S, T> = (seedState: S) => ScanBuildArrayConfig<T>;
31
31
  /**
@@ -51,7 +51,7 @@ export interface MapEachAsyncConfig {
51
51
  /**
52
52
  * Whether or not to map only the first
53
53
  */
54
- onlyFirst?: boolean;
54
+ readonly onlyFirst?: boolean;
55
55
  }
56
56
  /**
57
57
  * Operator function that maps each value in the array independently using Observables, then combines the all results.