@dereekb/rxjs 10.1.30 → 11.0.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/index.cjs.js +508 -321
- package/index.esm.js +326 -184
- package/package.json +1 -1
- package/src/lib/iterator/iteration.accumulator.d.ts +2 -14
- package/src/lib/iterator/iteration.mapped.d.ts +1 -1
- package/src/lib/loading/loading.context.simple.d.ts +2 -2
- package/src/lib/loading/loading.context.state.d.ts +2 -1
- package/src/lib/loading/loading.state.d.ts +136 -31
- package/src/lib/loading/loading.state.list.d.ts +15 -2
- package/src/lib/loading/loading.state.rxjs.d.ts +1 -1
- package/src/lib/object.d.ts +5 -1
- package/src/lib/subscription.d.ts +1 -1
package/index.esm.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { isObservable, of, switchMap, map, filter, skipWhile, EMPTY, combineLatest, delay, startWith, distinctUntilChanged, mergeMap, BehaviorSubject, shareReplay, skip, first, merge, finalize, firstValueFrom, scan, exhaustMap, identity, throttleTime, timeout, tap, throwError, timer, takeWhile, delayWhen, asyncScheduler, from, catchError, defaultIfEmpty } from 'rxjs';
|
|
1
|
+
import { isObservable, of, switchMap, map, filter, skipWhile, EMPTY, combineLatest, delay, startWith, distinctUntilChanged, mergeMap, BehaviorSubject, shareReplay, skip, first, merge, finalize, firstValueFrom, scan, exhaustMap, identity, throttleTime, timeout, tap, throwError, timer, takeWhile, delayWhen, asyncScheduler, from, combineLatestWith, catchError, defaultIfEmpty } from 'rxjs';
|
|
2
2
|
import { getValueFromGetter, isMaybeSo, 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, objectHasKey, toReadableError, reduceBooleansWithOr, reduceBooleansWithAnd, valuesAreBothNullishOrEquivalent, filterMaybeValues, mergeObjects, safeCompareEquality, limitArray, hasNonNullValue, mapFunctionOutputPair, lastValue, flattenArray, filteredPage, 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 : {};
|
|
@@ -1803,7 +1803,9 @@ function emitAfterDelay(value, delayTime) {
|
|
|
1803
1803
|
}
|
|
1804
1804
|
|
|
1805
1805
|
/**
|
|
1806
|
-
* Equivalent to distinctUntilChanged() using
|
|
1806
|
+
* Equivalent to distinctUntilChanged() using areEqualPOJOValues().
|
|
1807
|
+
*
|
|
1808
|
+
* The compared objects should only be POJOs or compatable with the areEqualPOJOValues() function.
|
|
1807
1809
|
*/
|
|
1808
1810
|
function distinctUntilObjectValuesChanged() {
|
|
1809
1811
|
return distinctUntilChanged((a, b) => areEqualPOJOValues(a, b));
|
|
@@ -1811,6 +1813,8 @@ function distinctUntilObjectValuesChanged() {
|
|
|
1811
1813
|
|
|
1812
1814
|
/**
|
|
1813
1815
|
* Observable filter that filters the input if the object is unchanged/equal to the input.
|
|
1816
|
+
*
|
|
1817
|
+
* The compared objects should only be POJOs or compatable with the areEqualPOJOValues() function.
|
|
1814
1818
|
*/
|
|
1815
1819
|
|
|
1816
1820
|
function filterIfObjectValuesUnchanged(input) {
|
|
@@ -2008,6 +2012,7 @@ class FilterMapKeyInstance {
|
|
|
2008
2012
|
constructor(dbxFilterMap, key) {
|
|
2009
2013
|
this.dbxFilterMap = dbxFilterMap;
|
|
2010
2014
|
this.key = key;
|
|
2015
|
+
this.filter$ = void 0;
|
|
2011
2016
|
this.filter$ = this.dbxFilterMap.filterForKey(this.key);
|
|
2012
2017
|
}
|
|
2013
2018
|
initWithFilter(filterObs) {
|
|
@@ -4185,7 +4190,7 @@ function useFirst(obs, useFn) {
|
|
|
4185
4190
|
*/
|
|
4186
4191
|
|
|
4187
4192
|
/**
|
|
4188
|
-
* Replaces the value type of the input
|
|
4193
|
+
* Replaces the value type of the input LoadingState.
|
|
4189
4194
|
*/
|
|
4190
4195
|
|
|
4191
4196
|
/**
|
|
@@ -4239,14 +4244,31 @@ let LoadingStateType = /*#__PURE__*/function (LoadingStateType) {
|
|
|
4239
4244
|
* @returns
|
|
4240
4245
|
*/
|
|
4241
4246
|
function loadingStateType(loadingState) {
|
|
4242
|
-
|
|
4243
|
-
|
|
4244
|
-
|
|
4245
|
-
|
|
4246
|
-
} else
|
|
4247
|
-
|
|
4247
|
+
const isLoading = !isLoadingStateFinishedLoading(loadingState);
|
|
4248
|
+
let type;
|
|
4249
|
+
if (isLoading) {
|
|
4250
|
+
type = LoadingStateType.LOADING;
|
|
4251
|
+
} else {
|
|
4252
|
+
if (objectHasKey(loadingState, 'value')) {
|
|
4253
|
+
type = LoadingStateType.SUCCESS;
|
|
4254
|
+
} else if (objectHasKey(loadingState, 'error')) {
|
|
4255
|
+
type = LoadingStateType.ERROR;
|
|
4256
|
+
} else {
|
|
4257
|
+
type = LoadingStateType.IDLE;
|
|
4258
|
+
}
|
|
4259
|
+
}
|
|
4260
|
+
return type;
|
|
4261
|
+
}
|
|
4262
|
+
function isLoadingStateFinishedLoading(state) {
|
|
4263
|
+
if (state) {
|
|
4264
|
+
const loading = state.loading;
|
|
4265
|
+
if (loading === true) {
|
|
4266
|
+
return false;
|
|
4267
|
+
} else {
|
|
4268
|
+
return loading === false || Boolean(state.value || state.error) || state.value === null;
|
|
4269
|
+
}
|
|
4248
4270
|
} else {
|
|
4249
|
-
return
|
|
4271
|
+
return false;
|
|
4250
4272
|
}
|
|
4251
4273
|
}
|
|
4252
4274
|
|
|
@@ -4297,56 +4319,81 @@ function errorPageResult(page, error) {
|
|
|
4297
4319
|
page
|
|
4298
4320
|
});
|
|
4299
4321
|
}
|
|
4300
|
-
|
|
4301
|
-
|
|
4302
|
-
|
|
4303
|
-
|
|
4304
|
-
|
|
4305
|
-
|
|
4306
|
-
|
|
4307
|
-
|
|
4308
|
-
|
|
4309
|
-
} else {
|
|
4310
|
-
return true;
|
|
4311
|
-
}
|
|
4312
|
-
}
|
|
4313
|
-
function loadingStateIsLoading(state) {
|
|
4314
|
-
return !loadingStateHasFinishedLoading(state);
|
|
4315
|
-
}
|
|
4316
|
-
function isSuccessLoadingState(state) {
|
|
4317
|
-
if (state) {
|
|
4318
|
-
return loadingStateType(state) === LoadingStateType.SUCCESS;
|
|
4319
|
-
} else {
|
|
4320
|
-
return false;
|
|
4321
|
-
}
|
|
4322
|
+
|
|
4323
|
+
/**
|
|
4324
|
+
* Returns true if any of the input LoadingStates return true for isLoadingStateLoading().
|
|
4325
|
+
*
|
|
4326
|
+
* @param states
|
|
4327
|
+
* @returns
|
|
4328
|
+
*/
|
|
4329
|
+
function isAnyLoadingStateInLoadingState(states) {
|
|
4330
|
+
return reduceBooleansWithOr(states.map(isLoadingStateLoading), false);
|
|
4322
4331
|
}
|
|
4323
|
-
|
|
4324
|
-
|
|
4325
|
-
|
|
4326
|
-
|
|
4327
|
-
|
|
4328
|
-
|
|
4332
|
+
|
|
4333
|
+
/**
|
|
4334
|
+
* Returns true if all input LoadingStates return true for isLoadingStateLoading().
|
|
4335
|
+
*
|
|
4336
|
+
* @param states
|
|
4337
|
+
* @returns
|
|
4338
|
+
*/
|
|
4339
|
+
function areAllLoadingStatesFinishedLoading(states) {
|
|
4340
|
+
return reduceBooleansWithAnd(states.map(isLoadingStateFinishedLoading), true);
|
|
4329
4341
|
}
|
|
4330
|
-
function
|
|
4331
|
-
|
|
4332
|
-
|
|
4333
|
-
if (
|
|
4334
|
-
return
|
|
4342
|
+
function isLoadingStateWithStateType(type) {
|
|
4343
|
+
const defaultResult = type === LoadingStateType.IDLE ? true : false;
|
|
4344
|
+
return state => {
|
|
4345
|
+
if (state) {
|
|
4346
|
+
return loadingStateType(state) === type;
|
|
4335
4347
|
} else {
|
|
4336
|
-
return
|
|
4348
|
+
return defaultResult;
|
|
4337
4349
|
}
|
|
4338
|
-
}
|
|
4339
|
-
return false;
|
|
4340
|
-
}
|
|
4350
|
+
};
|
|
4341
4351
|
}
|
|
4342
4352
|
|
|
4343
4353
|
/**
|
|
4344
|
-
*
|
|
4354
|
+
* Returns true if the input LoadingState passed to loadingStateType() returns IDLE.
|
|
4355
|
+
*
|
|
4356
|
+
* @param state
|
|
4357
|
+
* @returns
|
|
4358
|
+
*/
|
|
4359
|
+
const isLoadingStateInIdleState = isLoadingStateWithStateType(LoadingStateType.IDLE);
|
|
4360
|
+
|
|
4361
|
+
/**
|
|
4362
|
+
* Returns true if the input LoadingState passed to loadingStateType() returns LOADING.
|
|
4345
4363
|
*
|
|
4346
4364
|
* @param state
|
|
4347
4365
|
* @returns
|
|
4348
4366
|
*/
|
|
4349
|
-
|
|
4367
|
+
const isLoadingStateLoading = isLoadingStateWithStateType(LoadingStateType.LOADING);
|
|
4368
|
+
|
|
4369
|
+
/**
|
|
4370
|
+
* Alias of isLoadingStateLoading.
|
|
4371
|
+
*/
|
|
4372
|
+
const isLoadingStateInLoadingState = isLoadingStateLoading;
|
|
4373
|
+
|
|
4374
|
+
/**
|
|
4375
|
+
* Returns true if the input LoadingState passed to loadingStateType() returns SUCCESS.
|
|
4376
|
+
*
|
|
4377
|
+
* @param state
|
|
4378
|
+
* @returns
|
|
4379
|
+
*/
|
|
4380
|
+
const isLoadingStateInSuccessState = isLoadingStateWithStateType(LoadingStateType.SUCCESS);
|
|
4381
|
+
|
|
4382
|
+
/**
|
|
4383
|
+
* Returns true if the input LoadingState passed to loadingStateType() returns ERROR.
|
|
4384
|
+
*
|
|
4385
|
+
* @param state
|
|
4386
|
+
* @returns
|
|
4387
|
+
*/
|
|
4388
|
+
const isLoadingStateInErrorState = isLoadingStateWithStateType(LoadingStateType.ERROR);
|
|
4389
|
+
|
|
4390
|
+
/**
|
|
4391
|
+
* Whether or not the input LoadingState has a non-undefined value.
|
|
4392
|
+
*
|
|
4393
|
+
* @param state
|
|
4394
|
+
* @returns
|
|
4395
|
+
*/
|
|
4396
|
+
function isLoadingStateWithDefinedValue(state) {
|
|
4350
4397
|
if (state) {
|
|
4351
4398
|
return state.value !== undefined;
|
|
4352
4399
|
} else {
|
|
@@ -4355,12 +4402,12 @@ function loadingStateHasValue(state) {
|
|
|
4355
4402
|
}
|
|
4356
4403
|
|
|
4357
4404
|
/**
|
|
4358
|
-
* Whether or not the input
|
|
4405
|
+
* Whether or not the input LoadingState has a non-null error defined. It may be loading.
|
|
4359
4406
|
*
|
|
4360
4407
|
* @param state
|
|
4361
4408
|
* @returns
|
|
4362
4409
|
*/
|
|
4363
|
-
function
|
|
4410
|
+
function isLoadingStateWithError(state) {
|
|
4364
4411
|
if (state) {
|
|
4365
4412
|
return state.error != null;
|
|
4366
4413
|
} else {
|
|
@@ -4369,28 +4416,28 @@ function loadingStateHasError(state) {
|
|
|
4369
4416
|
}
|
|
4370
4417
|
|
|
4371
4418
|
/**
|
|
4372
|
-
* Whether or not the input
|
|
4419
|
+
* Whether or not the input LoadingState is not loading and has a non-null value.
|
|
4373
4420
|
*
|
|
4374
4421
|
* @param state
|
|
4375
4422
|
* @returns
|
|
4376
4423
|
*/
|
|
4377
|
-
function
|
|
4424
|
+
function isLoadingStateFinishedLoadingWithDefinedValue(state) {
|
|
4378
4425
|
if (state) {
|
|
4379
|
-
return
|
|
4426
|
+
return isLoadingStateFinishedLoading(state) && state.value !== undefined;
|
|
4380
4427
|
} else {
|
|
4381
4428
|
return false;
|
|
4382
4429
|
}
|
|
4383
4430
|
}
|
|
4384
4431
|
|
|
4385
4432
|
/**
|
|
4386
|
-
* Whether or not the input
|
|
4433
|
+
* Whether or not the input LoadingState is not loading and has an error defined.
|
|
4387
4434
|
*
|
|
4388
4435
|
* @param state
|
|
4389
4436
|
* @returns
|
|
4390
4437
|
*/
|
|
4391
|
-
function
|
|
4438
|
+
function isLoadingStateFinishedLoadingWithError(state) {
|
|
4392
4439
|
if (state) {
|
|
4393
|
-
return
|
|
4440
|
+
return isLoadingStateFinishedLoading(state) && state.error != null;
|
|
4394
4441
|
} else {
|
|
4395
4442
|
return false;
|
|
4396
4443
|
}
|
|
@@ -4404,14 +4451,14 @@ function loadingStateHasFinishedLoadingWithError(state) {
|
|
|
4404
4451
|
* @param a
|
|
4405
4452
|
* @param b
|
|
4406
4453
|
*/
|
|
4407
|
-
function
|
|
4454
|
+
function isPageLoadingStateMetadataEqual(a, b) {
|
|
4408
4455
|
return valuesAreBothNullishOrEquivalent(a.page, b.page) && a.loading == b.loading && valuesAreBothNullishOrEquivalent(a.error, b.error);
|
|
4409
4456
|
}
|
|
4410
4457
|
|
|
4411
|
-
// TODO: Fix all LoadingState types to use the LoadingStateValue inference
|
|
4458
|
+
// TODO(BREAKING_CHANGE): Fix all LoadingState types to use the LoadingStateValue inference typings
|
|
4412
4459
|
|
|
4413
4460
|
/**
|
|
4414
|
-
* Merges the input
|
|
4461
|
+
* Merges the input LoadingStates.
|
|
4415
4462
|
*
|
|
4416
4463
|
* If one is unavailable, it is considered loading.
|
|
4417
4464
|
* If one is loading, will return the loading state.
|
|
@@ -4437,7 +4484,7 @@ function mergeLoadingStates(...args) {
|
|
|
4437
4484
|
error
|
|
4438
4485
|
};
|
|
4439
4486
|
} else {
|
|
4440
|
-
const loading = reduceBooleansWithOr(loadingStates.map(
|
|
4487
|
+
const loading = reduceBooleansWithOr(loadingStates.map(isLoadingStateLoading));
|
|
4441
4488
|
if (loading) {
|
|
4442
4489
|
result = {
|
|
4443
4490
|
loading: true
|
|
@@ -4455,9 +4502,9 @@ function mergeLoadingStates(...args) {
|
|
|
4455
4502
|
}
|
|
4456
4503
|
|
|
4457
4504
|
/**
|
|
4458
|
-
*
|
|
4505
|
+
* Returns a new merged state to be loading or idle, and clears the current/error value. It will have a LoadingStateType of LOADING if loading is true.
|
|
4459
4506
|
*/
|
|
4460
|
-
function
|
|
4507
|
+
function mergeLoadingStateWithLoading(state, loading = true) {
|
|
4461
4508
|
return Object.assign({}, state, {
|
|
4462
4509
|
value: undefined,
|
|
4463
4510
|
loading,
|
|
@@ -4466,9 +4513,9 @@ function updatedStateForSetLoading(state, loading = true) {
|
|
|
4466
4513
|
}
|
|
4467
4514
|
|
|
4468
4515
|
/**
|
|
4469
|
-
*
|
|
4516
|
+
* Returns a new merged state with the input value. It will have a LoadingStateType of SUCCESS now.
|
|
4470
4517
|
*/
|
|
4471
|
-
function
|
|
4518
|
+
function mergeLoadingStateWithValue(state, value) {
|
|
4472
4519
|
return Object.assign({}, state, {
|
|
4473
4520
|
value: value != null ? value : undefined,
|
|
4474
4521
|
loading: false,
|
|
@@ -4477,9 +4524,9 @@ function updatedStateForSetValue(state, value) {
|
|
|
4477
4524
|
}
|
|
4478
4525
|
|
|
4479
4526
|
/**
|
|
4480
|
-
*
|
|
4527
|
+
* Returns a new merged state with the input error. It will have a LoadingStateType of ERROR now.
|
|
4481
4528
|
*/
|
|
4482
|
-
function
|
|
4529
|
+
function mergeLoadingStateWithError(state, error) {
|
|
4483
4530
|
return Object.assign({}, state, {
|
|
4484
4531
|
loading: false,
|
|
4485
4532
|
error
|
|
@@ -4490,7 +4537,7 @@ function mapMultipleLoadingStateResults(input, config) {
|
|
|
4490
4537
|
mapValues,
|
|
4491
4538
|
mapState
|
|
4492
4539
|
} = config;
|
|
4493
|
-
const loading =
|
|
4540
|
+
const loading = isAnyLoadingStateInLoadingState(input);
|
|
4494
4541
|
const error = input.map(x => x == null ? void 0 : x.error).filter(x => Boolean(x))[0];
|
|
4495
4542
|
let result;
|
|
4496
4543
|
if (!error && !loading) {
|
|
@@ -4542,21 +4589,102 @@ function mapLoadingStateValueFunction(mapFn) {
|
|
|
4542
4589
|
};
|
|
4543
4590
|
}
|
|
4544
4591
|
|
|
4592
|
+
// MARK: Compat
|
|
4593
|
+
/**
|
|
4594
|
+
* @deprecated use unknownLoadingStatesIsLoading instead.
|
|
4595
|
+
*/
|
|
4596
|
+
const unknownLoadingStatesIsLoading = isAnyLoadingStateInLoadingState;
|
|
4597
|
+
|
|
4598
|
+
/**
|
|
4599
|
+
* @deprecated use areAllLoadingStatesFinishedLoading instead.
|
|
4600
|
+
*/
|
|
4601
|
+
const allLoadingStatesHaveFinishedLoading = areAllLoadingStatesFinishedLoading;
|
|
4602
|
+
|
|
4603
|
+
/**
|
|
4604
|
+
* @deprecated use isLoadingStateInIdleState instead.
|
|
4605
|
+
*/
|
|
4606
|
+
const loadingStateIsIdle = isLoadingStateInIdleState;
|
|
4607
|
+
|
|
4608
|
+
/**
|
|
4609
|
+
* @deprecated use isLoadingStateInSuccessState instead.
|
|
4610
|
+
*/
|
|
4611
|
+
const isSuccessLoadingState = isLoadingStateInSuccessState;
|
|
4612
|
+
|
|
4613
|
+
/**
|
|
4614
|
+
* @deprecated use isLoadingStateInErrorState instead.
|
|
4615
|
+
*/
|
|
4616
|
+
const isErrorLoadingState = isLoadingStateInErrorState;
|
|
4617
|
+
|
|
4618
|
+
/**
|
|
4619
|
+
* @deprecated Use isLoadingStateLoading instead.
|
|
4620
|
+
*/
|
|
4621
|
+
const loadingStateIsLoading = isLoadingStateLoading;
|
|
4622
|
+
|
|
4623
|
+
/**
|
|
4624
|
+
* @deprecated use isLoadingStateFinishedLoading instead.
|
|
4625
|
+
*/
|
|
4626
|
+
const loadingStateHasFinishedLoading = isLoadingStateFinishedLoading;
|
|
4627
|
+
|
|
4628
|
+
/**
|
|
4629
|
+
* @deprecated use isLoadingStateWithError instead.
|
|
4630
|
+
*/
|
|
4631
|
+
const loadingStateHasError = isLoadingStateWithError;
|
|
4632
|
+
|
|
4633
|
+
/**
|
|
4634
|
+
* @deprecated use isLoadingStateWithDefinedValue instead.
|
|
4635
|
+
*/
|
|
4636
|
+
const loadingStateHasValue = isLoadingStateWithDefinedValue;
|
|
4637
|
+
|
|
4638
|
+
/**
|
|
4639
|
+
* @deprecated use isLoadingStateFinishedLoadingWithDefinedValue instead.
|
|
4640
|
+
*/
|
|
4641
|
+
const loadingStateHasFinishedLoadingWithValue = isLoadingStateFinishedLoadingWithDefinedValue;
|
|
4642
|
+
|
|
4643
|
+
/**
|
|
4644
|
+
* @deprecated use isLoadingStateFinishedLoadingWithError instead.
|
|
4645
|
+
*/
|
|
4646
|
+
const loadingStateHasFinishedLoadingWithError = isLoadingStateFinishedLoadingWithError;
|
|
4647
|
+
|
|
4648
|
+
/**
|
|
4649
|
+
* @deprecated use isPageLoadingStateMetadataEqual instead.
|
|
4650
|
+
*/
|
|
4651
|
+
const loadingStatesHaveEquivalentMetadata = isPageLoadingStateMetadataEqual;
|
|
4652
|
+
|
|
4653
|
+
/**
|
|
4654
|
+
* @deprecated use LoadingStateWithDefinedValue instead.
|
|
4655
|
+
*/
|
|
4656
|
+
|
|
4657
|
+
/**
|
|
4658
|
+
* @deprecated use mergeLoadingStateWithLoading instead.
|
|
4659
|
+
*/
|
|
4660
|
+
const updatedStateForSetLoading = mergeLoadingStateWithLoading;
|
|
4661
|
+
|
|
4662
|
+
/**
|
|
4663
|
+
* @deprecated use updatedStateForSetValue instead.
|
|
4664
|
+
*/
|
|
4665
|
+
const updatedStateForSetValue = mergeLoadingStateWithValue;
|
|
4666
|
+
|
|
4667
|
+
/**
|
|
4668
|
+
* @deprecated use mergeLoadingStateWithError instead.
|
|
4669
|
+
*/
|
|
4670
|
+
const updatedStateForSetError = mergeLoadingStateWithError;
|
|
4671
|
+
|
|
4545
4672
|
/**
|
|
4546
4673
|
* Abstract LoadingContext implementation using LoadingState.
|
|
4547
4674
|
*/
|
|
4548
4675
|
class AbstractLoadingStateContextInstance {
|
|
4549
|
-
constructor(
|
|
4550
|
-
this._stateSubject
|
|
4551
|
-
this._config =
|
|
4552
|
-
this.
|
|
4676
|
+
constructor(_config) {
|
|
4677
|
+
this._stateSubject = new BehaviorSubject(undefined);
|
|
4678
|
+
this._config = new BehaviorSubject(undefined);
|
|
4679
|
+
this.config$ = this._config.pipe(filterMaybe(), shareReplay(1));
|
|
4680
|
+
this.stateSubject$ = this._stateSubject.pipe(filterMaybe(), distinctUntilChanged(), shareReplay(1));
|
|
4553
4681
|
this.state$ = this.stateSubject$.pipe(switchMap(x => x), shareReplay(1));
|
|
4554
|
-
this.stateObs$ = this._stateSubject
|
|
4555
|
-
this.stream$ = this.
|
|
4682
|
+
this.stateObs$ = this._stateSubject.asObservable();
|
|
4683
|
+
this.stream$ = this.stateObs$.pipe(mergeMap(obs => {
|
|
4556
4684
|
if (obs) {
|
|
4557
4685
|
return obs.pipe(
|
|
4558
4686
|
// If the observable did not pass a value immediately, we start with the start value.
|
|
4559
|
-
timeoutStartWith(beginLoading()), map(x => this.loadingEventForLoadingPair(x,
|
|
4687
|
+
timeoutStartWith(beginLoading()), combineLatestWith(this.config$), map(([x, config]) => this.loadingEventForLoadingPair(x, config)));
|
|
4560
4688
|
} else {
|
|
4561
4689
|
return of(beginLoading());
|
|
4562
4690
|
}
|
|
@@ -4566,30 +4694,35 @@ class AbstractLoadingStateContextInstance {
|
|
|
4566
4694
|
/**
|
|
4567
4695
|
* Emits when the input state has changed.
|
|
4568
4696
|
*/
|
|
4569
|
-
this.stateChange$ = this._stateSubject
|
|
4697
|
+
this.stateChange$ = this._stateSubject.pipe(map(() => undefined));
|
|
4570
4698
|
this.loading$ = this.stream$.pipe(map(x => x.loading), shareReplay(1));
|
|
4571
|
-
|
|
4572
|
-
|
|
4573
|
-
|
|
4699
|
+
let nextConfig;
|
|
4700
|
+
if (isObservable(_config)) {
|
|
4701
|
+
nextConfig = {
|
|
4702
|
+
obs: _config
|
|
4574
4703
|
};
|
|
4575
4704
|
} else {
|
|
4576
|
-
|
|
4705
|
+
nextConfig = _config != null ? _config : {
|
|
4577
4706
|
showLoadingOnNoValue: false
|
|
4578
4707
|
};
|
|
4579
4708
|
}
|
|
4580
|
-
|
|
4581
|
-
|
|
4709
|
+
this._config.next(nextConfig);
|
|
4710
|
+
|
|
4711
|
+
// Only set once
|
|
4712
|
+
if (nextConfig.obs) {
|
|
4713
|
+
this.setStateObs(nextConfig.obs);
|
|
4582
4714
|
}
|
|
4583
4715
|
}
|
|
4584
4716
|
setStateObs(state) {
|
|
4585
|
-
this._stateSubject
|
|
4717
|
+
this._stateSubject.next(state);
|
|
4586
4718
|
}
|
|
4587
4719
|
destroy() {
|
|
4588
|
-
this._stateSubject
|
|
4720
|
+
this._stateSubject.complete();
|
|
4721
|
+
this._config.complete();
|
|
4589
4722
|
}
|
|
4590
4723
|
}
|
|
4591
4724
|
|
|
4592
|
-
// TODO: Fix all LoadingState types to use the LoadingStateValue inference
|
|
4725
|
+
// TODO(BREAKING_CHANGE): Fix all LoadingState types to use the LoadingStateValue inference typings
|
|
4593
4726
|
|
|
4594
4727
|
/**
|
|
4595
4728
|
* Wraps an observable output and maps the value to a LoadingState.
|
|
@@ -4600,16 +4733,7 @@ function loadingStateFromObs(obs, firstOnly) {
|
|
|
4600
4733
|
if (firstOnly) {
|
|
4601
4734
|
obs = obs.pipe(first());
|
|
4602
4735
|
}
|
|
4603
|
-
return obs.pipe(map(value => (
|
|
4604
|
-
loading: false,
|
|
4605
|
-
value,
|
|
4606
|
-
error: undefined
|
|
4607
|
-
})), catchError(error => of({
|
|
4608
|
-
loading: false,
|
|
4609
|
-
error
|
|
4610
|
-
})), timeoutStartWith({
|
|
4611
|
-
loading: true
|
|
4612
|
-
}, 50), shareReplay(1));
|
|
4736
|
+
return obs.pipe(map(value => successResult(value)), catchError(error => of(errorResult(error))), timeoutStartWith(beginLoading(), 50), shareReplay(1));
|
|
4613
4737
|
}
|
|
4614
4738
|
|
|
4615
4739
|
/**
|
|
@@ -4650,7 +4774,7 @@ function combineLoadingStatesStatus(sources) {
|
|
|
4650
4774
|
if (firstErrorState) {
|
|
4651
4775
|
result = errorResult(firstErrorState.error);
|
|
4652
4776
|
} else {
|
|
4653
|
-
const oneOrMoreStatesAreCurrentlyLoading = allLoadingStates.findIndex(
|
|
4777
|
+
const oneOrMoreStatesAreCurrentlyLoading = allLoadingStates.findIndex(isLoadingStateLoading) !== -1;
|
|
4654
4778
|
if (oneOrMoreStatesAreCurrentlyLoading) {
|
|
4655
4779
|
result = beginLoading(); // still loading
|
|
4656
4780
|
} else {
|
|
@@ -4678,7 +4802,7 @@ function startWithBeginLoading(state) {
|
|
|
4678
4802
|
*/
|
|
4679
4803
|
function valueFromLoadingState() {
|
|
4680
4804
|
return obs => {
|
|
4681
|
-
return obs.pipe(filter(
|
|
4805
|
+
return obs.pipe(filter(isLoadingStateWithDefinedValue), map(x => x.value));
|
|
4682
4806
|
};
|
|
4683
4807
|
}
|
|
4684
4808
|
|
|
@@ -4687,7 +4811,7 @@ function valueFromLoadingState() {
|
|
|
4687
4811
|
*/
|
|
4688
4812
|
function errorFromLoadingState() {
|
|
4689
4813
|
return obs => {
|
|
4690
|
-
return obs.pipe(filter(
|
|
4814
|
+
return obs.pipe(filter(isLoadingStateWithError), map(x => x.error));
|
|
4691
4815
|
};
|
|
4692
4816
|
}
|
|
4693
4817
|
|
|
@@ -4696,7 +4820,7 @@ function errorFromLoadingState() {
|
|
|
4696
4820
|
*/
|
|
4697
4821
|
function valueFromFinishedLoadingState() {
|
|
4698
4822
|
return obs => {
|
|
4699
|
-
return obs.pipe(filter(
|
|
4823
|
+
return obs.pipe(filter(isLoadingStateFinishedLoading), map(x => x.value));
|
|
4700
4824
|
};
|
|
4701
4825
|
}
|
|
4702
4826
|
|
|
@@ -4709,7 +4833,7 @@ function valueFromFinishedLoadingState() {
|
|
|
4709
4833
|
function tapOnLoadingStateType(fn, type) {
|
|
4710
4834
|
let decisionFunction;
|
|
4711
4835
|
if (type === LoadingStateType.LOADING) {
|
|
4712
|
-
decisionFunction =
|
|
4836
|
+
decisionFunction = isLoadingStateLoading;
|
|
4713
4837
|
} else {
|
|
4714
4838
|
decisionFunction = state => loadingStateType(state) === type;
|
|
4715
4839
|
}
|
|
@@ -4746,7 +4870,7 @@ function mapLoadingStateValueWithOperator(operator, mapOnUndefined = false) {
|
|
|
4746
4870
|
return obs => {
|
|
4747
4871
|
return obs.pipe(switchMap(state => {
|
|
4748
4872
|
let mappedObs;
|
|
4749
|
-
if (
|
|
4873
|
+
if (isLoadingStateWithDefinedValue(state) || mapOnUndefined && isLoadingStateFinishedLoading(state) && !isLoadingStateWithError(state)) {
|
|
4750
4874
|
// map the value
|
|
4751
4875
|
mappedObs = of(state.value).pipe(operator, map(value => Object.assign({}, state, {
|
|
4752
4876
|
value
|
|
@@ -4758,7 +4882,7 @@ function mapLoadingStateValueWithOperator(operator, mapOnUndefined = false) {
|
|
|
4758
4882
|
}), 0));
|
|
4759
4883
|
} else {
|
|
4760
4884
|
// only pass through if there is an error, otherwise show loading.
|
|
4761
|
-
if (
|
|
4885
|
+
if (isLoadingStateWithError(state)) {
|
|
4762
4886
|
mappedObs = of(Object.assign({}, state, {
|
|
4763
4887
|
value: undefined
|
|
4764
4888
|
}));
|
|
@@ -4795,14 +4919,14 @@ function distinctLoadingState(inputConfig) {
|
|
|
4795
4919
|
valueComparator: inputConfig
|
|
4796
4920
|
} : inputConfig;
|
|
4797
4921
|
const passRetainedValue = inputPassRetainedValue != null ? inputPassRetainedValue : x => x !== null;
|
|
4798
|
-
const metadataComparator = inputMetadataComparator != null ? inputMetadataComparator :
|
|
4922
|
+
const metadataComparator = inputMetadataComparator != null ? inputMetadataComparator : isPageLoadingStateMetadataEqual;
|
|
4799
4923
|
return obs => {
|
|
4800
4924
|
return obs.pipe(scan((acc, state) => {
|
|
4801
4925
|
const nextValue = state.value;
|
|
4802
4926
|
|
|
4803
4927
|
// determine the value change
|
|
4804
4928
|
let isSameValue = false;
|
|
4805
|
-
if (
|
|
4929
|
+
if (isLoadingStateWithDefinedValue(state) || compareOnUndefinedValue && isLoadingStateFinishedLoading(state) && !isLoadingStateWithError(state)) {
|
|
4806
4930
|
// if the value is the same, then
|
|
4807
4931
|
isSameValue = valueComparator(nextValue, acc.value);
|
|
4808
4932
|
} else if (passRetainedValue(nextValue, acc.value, state, acc.previous)) {
|
|
@@ -4846,7 +4970,7 @@ function distinctLoadingState(inputConfig) {
|
|
|
4846
4970
|
* @returns
|
|
4847
4971
|
*/
|
|
4848
4972
|
function promiseFromLoadingState(obs) {
|
|
4849
|
-
return firstValueFrom(obs.pipe(filter(
|
|
4973
|
+
return firstValueFrom(obs.pipe(filter(isLoadingStateFinishedLoading))).then(x => {
|
|
4850
4974
|
let result;
|
|
4851
4975
|
if (x.error) {
|
|
4852
4976
|
throw x.error;
|
|
@@ -4857,19 +4981,23 @@ function promiseFromLoadingState(obs) {
|
|
|
4857
4981
|
});
|
|
4858
4982
|
}
|
|
4859
4983
|
|
|
4860
|
-
// TODO: breaking change refactor: Switch the names of these functions below, so the isListLoadingStateEmpty is the non-operator function.
|
|
4861
|
-
|
|
4862
4984
|
/**
|
|
4863
4985
|
* Returns true if the loading state is not loading and is empty.
|
|
4864
4986
|
*
|
|
4865
4987
|
* @param listLoadingState
|
|
4866
4988
|
* @returns
|
|
4867
4989
|
*/
|
|
4868
|
-
function
|
|
4990
|
+
function isListLoadingStateWithEmptyValue(listLoadingState) {
|
|
4869
4991
|
return Boolean(!listLoadingState.value || !listLoadingState.value.length);
|
|
4870
4992
|
}
|
|
4871
|
-
|
|
4872
|
-
|
|
4993
|
+
|
|
4994
|
+
/**
|
|
4995
|
+
* Convenience function that merges map() with isListLoadingStateWithEmptyValue()
|
|
4996
|
+
*
|
|
4997
|
+
* @returns
|
|
4998
|
+
*/
|
|
4999
|
+
function mapIsListLoadingStateWithEmptyValue() {
|
|
5000
|
+
return map(isListLoadingStateWithEmptyValue);
|
|
4873
5001
|
}
|
|
4874
5002
|
|
|
4875
5003
|
/**
|
|
@@ -4882,6 +5010,17 @@ function pageLoadingStateFromObs(obs, firstOnly, page = 0) {
|
|
|
4882
5010
|
}));
|
|
4883
5011
|
}
|
|
4884
5012
|
|
|
5013
|
+
// MARK: Compat
|
|
5014
|
+
/**
|
|
5015
|
+
* @deprecated use isListLoadingStateWithEmptyValue instead.
|
|
5016
|
+
*/
|
|
5017
|
+
const listLoadingStateIsEmpty = isListLoadingStateWithEmptyValue;
|
|
5018
|
+
|
|
5019
|
+
/**
|
|
5020
|
+
* @deprecated use mapIsListLoadingStateWithEmptyValue instead.
|
|
5021
|
+
*/
|
|
5022
|
+
const isListLoadingStateEmpty = mapIsListLoadingStateWithEmptyValue;
|
|
5023
|
+
|
|
4885
5024
|
/**
|
|
4886
5025
|
* LoadingContext implementation that uses a ListLoadingState observable.
|
|
4887
5026
|
*/
|
|
@@ -4898,7 +5037,7 @@ class ListLoadingStateContextInstance extends AbstractLoadingStateContextInstanc
|
|
|
4898
5037
|
/**
|
|
4899
5038
|
* Returns true while loading and the current value is considered empty.
|
|
4900
5039
|
*/
|
|
4901
|
-
this.isEmptyLoading$ = this.stream$.pipe(map(x =>
|
|
5040
|
+
this.isEmptyLoading$ = this.stream$.pipe(map(x => isLoadingStateLoading(x) && isListLoadingStateWithEmptyValue(x)), distinctUntilChanged(), shareReplay(1));
|
|
4902
5041
|
/**
|
|
4903
5042
|
* Whether or not the current value is empty.
|
|
4904
5043
|
*
|
|
@@ -4906,9 +5045,9 @@ class ListLoadingStateContextInstance extends AbstractLoadingStateContextInstanc
|
|
|
4906
5045
|
*
|
|
4907
5046
|
* After that, will return true if the value is empty even if loading a new value.
|
|
4908
5047
|
*/
|
|
4909
|
-
this.isEmpty$ = this.stream$.pipe(skipWhile(x =>
|
|
5048
|
+
this.isEmpty$ = this.stream$.pipe(skipWhile(x => isLoadingStateLoading(x)),
|
|
4910
5049
|
// skip until the first non-loading event has occured
|
|
4911
|
-
|
|
5050
|
+
mapIsListLoadingStateWithEmptyValue(), distinctUntilChanged());
|
|
4912
5051
|
/**
|
|
4913
5052
|
* Whether or not the current value is empty and not loading.
|
|
4914
5053
|
*
|
|
@@ -4916,9 +5055,9 @@ class ListLoadingStateContextInstance extends AbstractLoadingStateContextInstanc
|
|
|
4916
5055
|
*
|
|
4917
5056
|
* After that, will return true if the value is empty even if loading a new value.
|
|
4918
5057
|
*/
|
|
4919
|
-
this.isEmptyAndNotLoading$ = this.stream$.pipe(skipWhile(x =>
|
|
5058
|
+
this.isEmptyAndNotLoading$ = this.stream$.pipe(skipWhile(x => isLoadingStateLoading(x)),
|
|
4920
5059
|
// skip until the first non-loading event has occured
|
|
4921
|
-
map(x => !
|
|
5060
|
+
map(x => !isLoadingStateLoading(x) && isListLoadingStateWithEmptyValue(x)), distinctUntilChanged());
|
|
4922
5061
|
}
|
|
4923
5062
|
loadingEventForLoadingPair(state, config = {}) {
|
|
4924
5063
|
const {
|
|
@@ -4937,7 +5076,7 @@ class ListLoadingStateContextInstance extends AbstractLoadingStateContextInstanc
|
|
|
4937
5076
|
if (showLoadingOnNoValue) {
|
|
4938
5077
|
loading = !hasValue;
|
|
4939
5078
|
} else {
|
|
4940
|
-
loading =
|
|
5079
|
+
loading = isLoadingStateLoading(state);
|
|
4941
5080
|
}
|
|
4942
5081
|
}
|
|
4943
5082
|
return {
|
|
@@ -4970,7 +5109,7 @@ class LoadingStateContextInstance extends AbstractLoadingStateContextInstance {
|
|
|
4970
5109
|
if (showLoadingOnNoValue) {
|
|
4971
5110
|
loading = !hasNonNullValue(value);
|
|
4972
5111
|
} else {
|
|
4973
|
-
loading =
|
|
5112
|
+
loading = isLoadingStateLoading(pair);
|
|
4974
5113
|
}
|
|
4975
5114
|
}
|
|
4976
5115
|
return {
|
|
@@ -5079,68 +5218,65 @@ class ValuesLoadingContext extends SimpleLoadingContext {
|
|
|
5079
5218
|
*/
|
|
5080
5219
|
|
|
5081
5220
|
/**
|
|
5082
|
-
*
|
|
5083
|
-
*/
|
|
5084
|
-
class ItemAccumulatorInstance {
|
|
5085
|
-
constructor(itemIteration, mapItemFunction) {
|
|
5086
|
-
this.itemIteration = itemIteration;
|
|
5087
|
-
this.mapItemFunction = mapItemFunction;
|
|
5088
|
-
this.hasCompletedInitialLoad$ = this.itemIteration.firstState$.pipe(map(() => true), startWith(false), distinctUntilChanged(), shareReplay(1));
|
|
5089
|
-
this.latestSuccessfulState$ = this.itemIteration.latestState$.pipe(filter(x => !loadingStateHasError(x)), distinctUntilChanged(), shareReplay(1));
|
|
5090
|
-
/**
|
|
5091
|
-
* All successful page results in a single array.
|
|
5092
|
-
*/
|
|
5093
|
-
this.allSuccessfulStates$ = this.latestSuccessfulState$.pipe(scanIntoArray({
|
|
5094
|
-
immutable: false
|
|
5095
|
-
}),
|
|
5096
|
-
/**
|
|
5097
|
-
* Don't wait for the first successful state in order to avoid never returning a value on immediate failures.
|
|
5098
|
-
*/
|
|
5099
|
-
startWith([]), distinctUntilArrayLengthChanges(), shareReplay(1));
|
|
5100
|
-
this.successfulLoadCount$ = this.allSuccessfulStates$.pipe(map(x => x.length), shareReplay(1));
|
|
5101
|
-
// MARK: ItemAccumulator
|
|
5102
|
-
this.currentAllItemPairs$ = this.allSuccessfulStates$.pipe(scanBuildArray(allSuccessfulStates => {
|
|
5103
|
-
const mapStateToItem = mapFunctionOutputPair(mapLoadingStateValueFunction(this.mapItemFunction));
|
|
5104
|
-
|
|
5105
|
-
/*
|
|
5106
|
-
Start with allSuccessfulPageResults$ since it contains all page results since the start of the iterator,
|
|
5107
|
-
and subscription to allItems may not have started at the same time.
|
|
5108
|
-
We use scan to add in all models coming in afterwards by pushing them into the accumulator.
|
|
5109
|
-
This is to prevent performance issues with very large iteration sets, since we can
|
|
5110
|
-
append onto the array, rather than concat/copy the array each time.
|
|
5111
|
-
*/
|
|
5112
|
-
const allPageResultsUpToFirstSubscription = allSuccessfulStates;
|
|
5113
|
-
const firstLatestState = lastValue(allPageResultsUpToFirstSubscription);
|
|
5114
|
-
const seed = allPageResultsUpToFirstSubscription.map(mapStateToItem).filter(x => isMaybeSo(x.output));
|
|
5115
|
-
const accumulatorObs = this.latestSuccessfulState$.pipe(skipWhile(x => x === firstLatestState), map(mapStateToItem), filter(x => isMaybeSo(x.output)));
|
|
5116
|
-
return {
|
|
5117
|
-
seed,
|
|
5118
|
-
accumulatorObs
|
|
5119
|
-
};
|
|
5120
|
-
}), shareReplay(1));
|
|
5121
|
-
this.currentAllItems$ = this.currentAllItemPairs$.pipe(map(x => x.map(y => y.output)), shareReplay(1));
|
|
5122
|
-
this.allItemPairs$ = this.hasCompletedInitialLoad$.pipe(switchMapWhileTrue(this.currentAllItemPairs$), shareReplay(1));
|
|
5123
|
-
this.allItems$ = this.hasCompletedInitialLoad$.pipe(switchMapWhileTrue(this.currentAllItems$), shareReplay(1));
|
|
5124
|
-
this._sub = new SubscriptionObject(this.allSuccessfulStates$.subscribe());
|
|
5125
|
-
}
|
|
5126
|
-
destroy() {
|
|
5127
|
-
this._sub.destroy();
|
|
5128
|
-
}
|
|
5129
|
-
}
|
|
5130
|
-
|
|
5131
|
-
/**
|
|
5132
|
-
* Creates a new ItemAccumulator instance give the input ItemIteration.
|
|
5221
|
+
* Creates a new ItemAccumulatorInstance give the input ItemIteration and optional map function.
|
|
5133
5222
|
*
|
|
5134
5223
|
* @param itemIteration
|
|
5135
5224
|
* @param mapItem
|
|
5136
5225
|
* @returns
|
|
5137
5226
|
*/
|
|
5138
5227
|
|
|
5139
|
-
function itemAccumulator(itemIteration,
|
|
5140
|
-
|
|
5141
|
-
|
|
5142
|
-
|
|
5143
|
-
|
|
5228
|
+
function itemAccumulator(itemIteration, inputMapItem) {
|
|
5229
|
+
const mapItemFunction = inputMapItem != null ? inputMapItem : a => a;
|
|
5230
|
+
const hasCompletedInitialLoad$ = itemIteration.firstState$.pipe(map(() => true), startWith(false), distinctUntilChanged(), shareReplay(1));
|
|
5231
|
+
const latestSuccessfulState$ = itemIteration.latestState$.pipe(filter(x => !isLoadingStateWithError(x)), distinctUntilChanged(), shareReplay(1));
|
|
5232
|
+
const allSuccessfulStates$ = latestSuccessfulState$.pipe(scanIntoArray({
|
|
5233
|
+
immutable: false
|
|
5234
|
+
}),
|
|
5235
|
+
/**
|
|
5236
|
+
* Don't wait for the first successful state in order to avoid never returning a value on immediate failures.
|
|
5237
|
+
*/
|
|
5238
|
+
startWith([]), distinctUntilArrayLengthChanges(), shareReplay(1));
|
|
5239
|
+
const successfulLoadCount$ = allSuccessfulStates$.pipe(map(x => x.length), shareReplay(1));
|
|
5240
|
+
|
|
5241
|
+
// MARK: ItemAccumulator
|
|
5242
|
+
const currentAllItemPairs$ = allSuccessfulStates$.pipe(scanBuildArray(allSuccessfulStates => {
|
|
5243
|
+
const mapStateToItem = mapFunctionOutputPair(mapLoadingStateValueFunction(mapItemFunction));
|
|
5244
|
+
|
|
5245
|
+
/*
|
|
5246
|
+
Start with allSuccessfulPageResults$ since it contains all page results since the start of the iterator,
|
|
5247
|
+
and subscription to allItems may not have started at the same time.
|
|
5248
|
+
We use scan to add in all models coming in afterwards by pushing them into the accumulator.
|
|
5249
|
+
This is to prevent performance issues with very large iteration sets, since we can
|
|
5250
|
+
append onto the array, rather than concat/copy the array each time.
|
|
5251
|
+
*/
|
|
5252
|
+
const allPageResultsUpToFirstSubscription = allSuccessfulStates;
|
|
5253
|
+
const firstLatestState = lastValue(allPageResultsUpToFirstSubscription);
|
|
5254
|
+
const seed = allPageResultsUpToFirstSubscription.map(mapStateToItem).filter(x => isMaybeSo(x.output));
|
|
5255
|
+
const accumulatorObs = latestSuccessfulState$.pipe(skipWhile(x => x === firstLatestState), map(mapStateToItem), filter(x => isMaybeSo(x.output)));
|
|
5256
|
+
return {
|
|
5257
|
+
seed,
|
|
5258
|
+
accumulatorObs
|
|
5259
|
+
};
|
|
5260
|
+
}), shareReplay(1));
|
|
5261
|
+
const currentAllItems$ = currentAllItemPairs$.pipe(map(x => x.map(y => y.output)), shareReplay(1));
|
|
5262
|
+
const allItemPairs$ = hasCompletedInitialLoad$.pipe(switchMapWhileTrue(currentAllItemPairs$), shareReplay(1));
|
|
5263
|
+
const allItems$ = hasCompletedInitialLoad$.pipe(switchMapWhileTrue(currentAllItems$), shareReplay(1));
|
|
5264
|
+
const sub = new SubscriptionObject(allSuccessfulStates$.subscribe());
|
|
5265
|
+
const destroy = () => sub.destroy();
|
|
5266
|
+
const result = {
|
|
5267
|
+
itemIteration,
|
|
5268
|
+
mapItemFunction,
|
|
5269
|
+
hasCompletedInitialLoad$,
|
|
5270
|
+
latestSuccessfulState$,
|
|
5271
|
+
allSuccessfulStates$,
|
|
5272
|
+
successfulLoadCount$,
|
|
5273
|
+
currentAllItemPairs$,
|
|
5274
|
+
currentAllItems$,
|
|
5275
|
+
allItemPairs$,
|
|
5276
|
+
allItems$,
|
|
5277
|
+
destroy
|
|
5278
|
+
};
|
|
5279
|
+
return result;
|
|
5144
5280
|
}
|
|
5145
5281
|
|
|
5146
5282
|
// MARK: Utility
|
|
@@ -5263,6 +5399,11 @@ class MappedItemIterationInstance {
|
|
|
5263
5399
|
constructor(itemIterator, config) {
|
|
5264
5400
|
this.itemIterator = itemIterator;
|
|
5265
5401
|
this.config = config;
|
|
5402
|
+
this.hasNext$ = void 0;
|
|
5403
|
+
this.canLoadMore$ = void 0;
|
|
5404
|
+
this.firstState$ = void 0;
|
|
5405
|
+
this.latestState$ = void 0;
|
|
5406
|
+
this.currentState$ = void 0;
|
|
5266
5407
|
this.hasNext$ = this.itemIterator.hasNext$;
|
|
5267
5408
|
this.canLoadMore$ = this.itemIterator.canLoadMore$;
|
|
5268
5409
|
this.firstState$ = this.itemIterator.firstState$.pipe(map(state => mapLoadingStateResults(state, this.config)), shareReplay(1));
|
|
@@ -5373,7 +5514,7 @@ class ItemPageIterationInstance {
|
|
|
5373
5514
|
this._next = new BehaviorSubject({
|
|
5374
5515
|
n: 0
|
|
5375
5516
|
});
|
|
5376
|
-
this._maxPageLoadLimit = new BehaviorSubject(
|
|
5517
|
+
this._maxPageLoadLimit = new BehaviorSubject(undefined);
|
|
5377
5518
|
// MARK: State
|
|
5378
5519
|
this.state$ = this._next.pipe(delay(0), exhaustMap(request => combineLatest([this.hasNextAndCanLoadMore$, this._lastFinishedPageResultState$]).pipe(first(), map(([hasNextAndCanLoadMore, prevResult]) => [itemPageIteratorShouldLoadNextPage(request, hasNextAndCanLoadMore, prevResult), prevResult]), mergeMap(([shouldLoadNextPage, prevResult]) => {
|
|
5379
5520
|
if (shouldLoadNextPage) {
|
|
@@ -5423,13 +5564,13 @@ class ItemPageIterationInstance {
|
|
|
5423
5564
|
|
|
5424
5565
|
// If it was a replay of the previous result, change nothing.
|
|
5425
5566
|
if (acc.current !== curr) {
|
|
5426
|
-
if (
|
|
5567
|
+
if (isLoadingStateFinishedLoading(curr)) {
|
|
5427
5568
|
// only set first finished once
|
|
5428
5569
|
if (!next.firstFinished) {
|
|
5429
5570
|
next.firstFinished = curr;
|
|
5430
5571
|
}
|
|
5431
5572
|
next.latestFinished = curr;
|
|
5432
|
-
if (!
|
|
5573
|
+
if (!isLoadingStateWithError(curr)) {
|
|
5433
5574
|
next.lastSuccessful = curr;
|
|
5434
5575
|
if (!next.firstSuccessful) {
|
|
5435
5576
|
next.firstSuccessful = curr;
|
|
@@ -5459,7 +5600,7 @@ class ItemPageIterationInstance {
|
|
|
5459
5600
|
/**
|
|
5460
5601
|
* Same as _nextTrigger$, but catches finished loading events.
|
|
5461
5602
|
*/
|
|
5462
|
-
this._nextFinished$ = this._nextTrigger$.pipe(filter(x =>
|
|
5603
|
+
this._nextFinished$ = this._nextTrigger$.pipe(filter(x => isLoadingStateFinishedLoading(x.current)));
|
|
5463
5604
|
/**
|
|
5464
5605
|
* The first page results that finished loading.
|
|
5465
5606
|
*/
|
|
@@ -5486,7 +5627,7 @@ class ItemPageIterationInstance {
|
|
|
5486
5627
|
/**
|
|
5487
5628
|
* Whether or not items are currently being loaded.
|
|
5488
5629
|
*/
|
|
5489
|
-
this.isLoading$ = this._currentPageResultState$.pipe(map(x =>
|
|
5630
|
+
this.isLoading$ = this._currentPageResultState$.pipe(map(x => isLoadingStateLoading(x)), distinctUntilChanged(), shareReplay(1));
|
|
5490
5631
|
this._lastFinishedPageResultState$ = this.latestPageResultState$.pipe(startWith(undefined), shareReplay(1));
|
|
5491
5632
|
this._lastFinishedPageResult$ = this._lastFinishedPageResultState$.pipe(map(x => x == null ? void 0 : x.value));
|
|
5492
5633
|
this._lastFinishedPageResultItem$ = this._lastFinishedPageResult$.pipe(map(x => x == null ? void 0 : x.value));
|
|
@@ -5517,6 +5658,7 @@ class ItemPageIterationInstance {
|
|
|
5517
5658
|
this.firstState$ = this.firstPageResultState$.pipe(mapItemPageLoadingStateFromResultPageLoadingState(), shareReplay(1));
|
|
5518
5659
|
this.latestState$ = this.latestPageResultState$.pipe(mapItemPageLoadingStateFromResultPageLoadingState(), shareReplay(1));
|
|
5519
5660
|
this.latestItems$ = this.latestState$.pipe(distinctUntilChanged(), map(x => x.value), shareReplay(1));
|
|
5661
|
+
this._maxPageLoadLimit.next((_this$config$maxPageL = this.config.maxPageLoadLimit) != null ? _this$config$maxPageL : this.iterator.maxPageLoadLimit);
|
|
5520
5662
|
}
|
|
5521
5663
|
// MARK: PageItemIteration
|
|
5522
5664
|
get maxPageLoadLimit() {
|
|
@@ -5587,13 +5729,13 @@ function isItemPageIteratorResultEndResult(result) {
|
|
|
5587
5729
|
function itemPageIteratorShouldLoadNextPage(request, hasNextAndCanLoadMore, prevResult) {
|
|
5588
5730
|
return hasNextAndCanLoadMore &&
|
|
5589
5731
|
// Must be able to load more
|
|
5590
|
-
Boolean(!
|
|
5732
|
+
Boolean(!isLoadingStateWithError(prevResult) || request.retry) &&
|
|
5591
5733
|
// Must not have any errors
|
|
5592
5734
|
Boolean(request.page == null || nextIteratorPageNumber(prevResult) === request.page); // Must match the page, if provided
|
|
5593
5735
|
}
|
|
5594
5736
|
|
|
5595
5737
|
function nextIteratorPageNumber(prevResult) {
|
|
5596
|
-
return
|
|
5738
|
+
return isLoadingStateWithError(prevResult) ? prevResult.page : getNextPageNumber(prevResult);
|
|
5597
5739
|
}
|
|
5598
5740
|
function mapItemPageLoadingStateFromResultPageLoadingState() {
|
|
5599
5741
|
return map(itemPageLoadingStateFromResultPageLoadingState);
|
|
@@ -5765,7 +5907,7 @@ class WorkInstance {
|
|
|
5765
5907
|
this._sub = new SubscriptionObject();
|
|
5766
5908
|
this.loadingState$ = this._loadingState.pipe(filterMaybe());
|
|
5767
5909
|
this._hasStarted$ = this._loadingState.pipe(map(x => Boolean(x)), shareReplay(1));
|
|
5768
|
-
this._isComplete$ = this.loadingState$.pipe(map(x =>
|
|
5910
|
+
this._isComplete$ = this.loadingState$.pipe(map(x => isLoadingStateFinishedLoading(x)), shareReplay(1));
|
|
5769
5911
|
// Schedule to cleanup self once isComplete is true.
|
|
5770
5912
|
this.result$.subscribe(loadingState => {
|
|
5771
5913
|
this._result = loadingState;
|
|
@@ -5779,7 +5921,7 @@ class WorkInstance {
|
|
|
5779
5921
|
return this._done ? of(this._doneActionBegan) : this._hasStarted$;
|
|
5780
5922
|
}
|
|
5781
5923
|
get isComplete() {
|
|
5782
|
-
return this._done ||
|
|
5924
|
+
return this._done || isLoadingStateFinishedLoading(this._loadingState.value);
|
|
5783
5925
|
}
|
|
5784
5926
|
get isComplete$() {
|
|
5785
5927
|
return this._done ? of(true) : this._isComplete$;
|
|
@@ -5803,7 +5945,7 @@ class WorkInstance {
|
|
|
5803
5945
|
this._sub.subscription = obs.pipe(delay(0),
|
|
5804
5946
|
// delay to prevent an immediate start working, which can override the _sub.subscription value
|
|
5805
5947
|
first()).subscribe(() => {
|
|
5806
|
-
this.startWorkingWithObservable(obs.pipe(filter(x => x && !
|
|
5948
|
+
this.startWorkingWithObservable(obs.pipe(filter(x => x && !isLoadingStateLoading(x)),
|
|
5807
5949
|
// don't return until it has finished loading.
|
|
5808
5950
|
map(x => {
|
|
5809
5951
|
if (x.error) {
|
|
@@ -5979,4 +6121,4 @@ function workFactoryForConfigFactory(configFactory) {
|
|
|
5979
6121
|
};
|
|
5980
6122
|
}
|
|
5981
6123
|
|
|
5982
|
-
export { AbstractLoadingStateContextInstance, DEFAULT_ASYNC_PUSHER_THROTTLE, DEFAULT_FACTORY_TIMER_INTERVAL, DEFAULT_ITEM_PAGE_ITERATOR_MAX, DEFAULT_LOCK_SET_TIME_LOCK_KEY, FilterMap, FilterMapKeyInstance, FilterSource, FilterSourceConnector, FilterSourceInstance,
|
|
6124
|
+
export { AbstractLoadingStateContextInstance, DEFAULT_ASYNC_PUSHER_THROTTLE, DEFAULT_FACTORY_TIMER_INTERVAL, DEFAULT_ITEM_PAGE_ITERATOR_MAX, DEFAULT_LOCK_SET_TIME_LOCK_KEY, FilterMap, FilterMapKeyInstance, FilterSource, FilterSourceConnector, FilterSourceInstance, ItemPageIterationInstance, ItemPageIterator, ListLoadingStateContextInstance, LoadingStateContextInstance, LoadingStateType, LockSet, MappedItemIterationInstance, MappedPageItemIterationInstance, MultiSubscriptionObject, PresetFilterSource, SimpleLoadingContext, SubscriptionObject, ValuesLoadingContext, WorkInstance, accumulatorCurrentPageListLoadingState, accumulatorFlattenPageListLoadingState, allLoadingStatesHaveFinishedLoading, areAllLoadingStatesFinishedLoading, asObservable, asObservableFromGetter, asyncPusher, asyncPusherCache, beginLoading, beginLoadingPage, checkIs, cleanup, cleanupDestroyable, combineLatestFromArrayObsFn, combineLatestFromMapValuesObsFn, combineLatestFromObject, combineLatestMapFrom, combineLoadingStates, combineLoadingStatesStatus, distinctLoadingState, distinctUntilArrayLengthChanges, distinctUntilHasDifferentValues, distinctUntilItemsHaveDifferentValues, distinctUntilItemsValueChanges, distinctUntilKeysChange, distinctUntilMapHasDifferentKeys, distinctUntilModelIdChange, distinctUntilModelKeyChange, distinctUntilObjectKeyChange, distinctUntilObjectValuesChanged, emitAfterDelay, emitDelayObs, errorFromLoadingState, errorOnEmissionsInPeriod, errorPageResult, errorResult, factoryTimer, filterIfObjectValuesUnchanged, filterItemsWithObservableDecision, filterMaybe, filterUnique, filterWithSearchString, flattenAccumulatorResultItemArray, idleLoadingState, incrementingNumberTimer, initialize, invertObservableDecision, isAnyLoadingStateInLoadingState, isErrorLoadingState, isItemPageIteratorResultEndResult, isListLoadingStateEmpty, isListLoadingStateWithEmptyValue, isLoading, isLoadingStateFinishedLoading, isLoadingStateFinishedLoadingWithDefinedValue, isLoadingStateFinishedLoadingWithError, isLoadingStateInErrorState, isLoadingStateInIdleState, isLoadingStateInLoadingState, isLoadingStateInSuccessState, isLoadingStateLoading, isLoadingStateWithDefinedValue, isLoadingStateWithError, isLoadingStateWithStateType, isNot, isPageLoadingStateMetadataEqual, isSuccessLoadingState, itemAccumulator, itemAccumulatorNextPageUntilResultsCount, iterationHasNextAndCanLoadMore, iteratorNextPageUntilMaxPageLoadLimit, iteratorNextPageUntilPage, keyValueMap, lazyFrom, listLoadingStateContext, listLoadingStateIsEmpty, loadingStateContext, loadingStateFromObs, loadingStateHasError, loadingStateHasFinishedLoading, loadingStateHasFinishedLoadingWithError, loadingStateHasFinishedLoadingWithValue, loadingStateHasValue, loadingStateIsIdle, loadingStateIsLoading, loadingStateType, loadingStatesHaveEquivalentMetadata, makeCheckIsFunction, makeMapFilterWithPresetFn, makeReturnIfIsFunction, mapEachAsync, mapFilterWithPreset, mapForEach, mapIf, mapIsListLoadingStateWithEmptyValue, mapItemIteration, mapKeysIntersectionToArray, mapLoadingState, mapLoadingStateResults, mapLoadingStateValueFunction, mapLoadingStateValueWithOperator, mapMaybe, mapMultipleLoadingStateResults, mapPageItemIteration, maybeValueFromObservableOrValueGetter, mergeLoadingStateWithError, mergeLoadingStateWithLoading, mergeLoadingStateWithValue, mergeLoadingStates, multiKeyValueMap, onFalseToTrue, onLockSetNextUnlock, onMatchDelta, onTrueToFalse, pageItemAccumulatorCurrentPage, pageLoadingStateFromObs, pipeIf, preventComplete, promiseFromLoadingState, randomDelay, randomDelayWithRandomFunction, returnIfIs, scanBuildArray, scanCount, scanIntoArray, setContainsAllValuesFrom, setContainsAnyValueFrom, setContainsNoValueFrom, skipFirstMaybe, startWithBeginLoading, successPageResult, successResult, switchMapMaybeDefault, switchMapMaybeObs, switchMapObject, switchMapOnBoolean, switchMapToDefault, switchMapWhileFalse, switchMapWhileTrue, tapAfterTimeout, tapFirst, tapLog, tapOnLoadingStateSuccess, tapOnLoadingStateType, throwErrorAfterTimeout, timeoutStartWith, unknownLoadingStatesIsLoading, updatedStateForSetError, updatedStateForSetLoading, updatedStateForSetValue, useAsObservable, useFirst, valueFromFinishedLoadingState, valueFromLoadingState, valueFromObservableOrValue, valueFromObservableOrValueGetter, workFactory, workFactoryForConfigFactory };
|