@juulsgaard/signal-tools 18.0.0 → 18.0.2

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.
Files changed (33) hide show
  1. package/dist/async.mjs +96 -0
  2. package/dist/data-structures/signal-map.mjs +134 -0
  3. package/dist/data-structures/signal-queue.js +115 -0
  4. package/dist/data-structures/signal-queue.mjs +115 -0
  5. package/dist/data-structures/signal-set.mjs +143 -0
  6. package/dist/data-structures/signal-stack.js +90 -0
  7. package/dist/data-structures/signal-stack.mjs +90 -0
  8. package/dist/index.d.ts +564 -62
  9. package/dist/index.js +12 -1
  10. package/dist/index.mjs +16 -0
  11. package/dist/interop.mjs +11 -0
  12. package/dist/loading-signal.mjs +68 -0
  13. package/dist/operators.js +13 -0
  14. package/dist/operators.mjs +13 -0
  15. package/dist/request-state/async-request-state.js +48 -0
  16. package/dist/request-state/async-request-state.mjs +48 -0
  17. package/dist/request-state/constructors.js +25 -0
  18. package/dist/request-state/constructors.mjs +25 -0
  19. package/dist/request-state/empty-request-state.js +20 -0
  20. package/dist/request-state/empty-request-state.mjs +20 -0
  21. package/dist/request-state/error-request-state.js +20 -0
  22. package/dist/request-state/error-request-state.mjs +20 -0
  23. package/dist/request-state/loading-request-state.js +25 -0
  24. package/dist/request-state/loading-request-state.mjs +25 -0
  25. package/dist/request-state/request-state.js +39 -0
  26. package/dist/request-state/request-state.mjs +39 -0
  27. package/dist/request-state/request-tracker.js +64 -0
  28. package/dist/request-state/request-tracker.mjs +64 -0
  29. package/dist/request-state/static-request-state.js +32 -0
  30. package/dist/request-state/static-request-state.mjs +32 -0
  31. package/dist/request-state/writable-request-state.js +75 -0
  32. package/dist/request-state/writable-request-state.mjs +75 -0
  33. package/package.json +12 -11
package/dist/index.js CHANGED
@@ -1,5 +1,16 @@
1
1
  export { debouncedSignal, debouncedThrottledSignal, searchSignal, throttledSignal } from './async.js';
2
2
  export { subjectToSignal } from './interop.js';
3
3
  export { loadingSignal, toLoadingSignal } from './loading-signal.js';
4
- export { SignalSet } from './data-structures/signal-set.js';
5
4
  export { SignalMap } from './data-structures/signal-map.js';
5
+ export { SignalSet } from './data-structures/signal-set.js';
6
+ export { SignalQueue } from './data-structures/signal-queue.js';
7
+ export { SignalStack } from './data-structures/signal-stack.js';
8
+ export { requestState } from './request-state/constructors.js';
9
+ export { IRequestState, IValueRequestState } from './request-state/request-state.js';
10
+ export { AsyncRequestState } from './request-state/async-request-state.js';
11
+ export { EmptyRequestState } from './request-state/empty-request-state.js';
12
+ export { ErrorRequestState } from './request-state/error-request-state.js';
13
+ export { LoadingRequestState } from './request-state/loading-request-state.js';
14
+ export { StaticRequestState } from './request-state/static-request-state.js';
15
+ export { WritableRequestState } from './request-state/writable-request-state.js';
16
+ export { RequestTracker, ValueRequestTracker, requestTracker } from './request-state/request-tracker.js';
package/dist/index.mjs ADDED
@@ -0,0 +1,16 @@
1
+ export { debouncedSignal, debouncedThrottledSignal, searchSignal, throttledSignal } from './async.mjs';
2
+ export { subjectToSignal } from './interop.mjs';
3
+ export { loadingSignal, toLoadingSignal } from './loading-signal.mjs';
4
+ export { SignalMap } from './data-structures/signal-map.mjs';
5
+ export { SignalSet } from './data-structures/signal-set.mjs';
6
+ export { SignalQueue } from './data-structures/signal-queue.mjs';
7
+ export { SignalStack } from './data-structures/signal-stack.mjs';
8
+ export { requestState } from './request-state/constructors.mjs';
9
+ export { IRequestState, IValueRequestState } from './request-state/request-state.mjs';
10
+ export { AsyncRequestState } from './request-state/async-request-state.mjs';
11
+ export { EmptyRequestState } from './request-state/empty-request-state.mjs';
12
+ export { ErrorRequestState } from './request-state/error-request-state.mjs';
13
+ export { LoadingRequestState } from './request-state/loading-request-state.mjs';
14
+ export { StaticRequestState } from './request-state/static-request-state.mjs';
15
+ export { WritableRequestState } from './request-state/writable-request-state.mjs';
16
+ export { RequestTracker, ValueRequestTracker, requestTracker } from './request-state/request-tracker.mjs';
@@ -0,0 +1,11 @@
1
+ import { signal } from '@angular/core';
2
+ import { BehaviorSubject } from 'rxjs';
3
+
4
+ function subjectToSignal(subject, initial) {
5
+ const init = subject instanceof BehaviorSubject ? subject.value : initial;
6
+ const sig = signal(init);
7
+ subject.subscribe((val) => sig.set(val));
8
+ return sig;
9
+ }
10
+
11
+ export { subjectToSignal };
@@ -0,0 +1,68 @@
1
+ import { signal, assertInInjectionContext, DestroyRef, inject } from '@angular/core';
2
+ import { ILoadingState } from '@juulsgaard/rxjs-tools';
3
+ import { toSignal } from '@angular/core/rxjs-interop';
4
+ import { parseError } from '@juulsgaard/ts-tools';
5
+
6
+ function loadingSignal(value, options) {
7
+ const loadingSignal2 = value;
8
+ loadingSignal2.loading = options?.loading ?? signal(false);
9
+ loadingSignal2.error = options?.error ?? signal(void 0);
10
+ loadingSignal2.dispose = options?.dispose ?? (() => void 0);
11
+ return loadingSignal2;
12
+ }
13
+ function toLoadingSignal(loadingState, options) {
14
+ const injector = options?.injector;
15
+ const needsInjector = !!options?.autoDispose;
16
+ if (needsInjector && !injector) assertInInjectionContext(toLoadingSignal);
17
+ let state;
18
+ if (loadingState instanceof ILoadingState) {
19
+ state = fromLoadingState(loadingState);
20
+ } else if (loadingState instanceof Promise) {
21
+ state = fromPromise(loadingState);
22
+ } else {
23
+ state = fromObservable(loadingState);
24
+ }
25
+ if (options?.autoDispose) {
26
+ const destroy = injector?.get(DestroyRef) ?? inject(DestroyRef);
27
+ destroy.onDestroy(() => state.dispose());
28
+ }
29
+ return state;
30
+ }
31
+ function fromObservable(value$) {
32
+ const value = signal(void 0);
33
+ const loading = signal(true);
34
+ const error = signal(void 0);
35
+ const sub = value$.subscribe({
36
+ next: (val) => {
37
+ sub.unsubscribe();
38
+ loading.set(false);
39
+ value.set(val);
40
+ },
41
+ error: (err) => {
42
+ sub.unsubscribe();
43
+ loading.set(false);
44
+ error.set(parseError(err));
45
+ },
46
+ complete: () => {
47
+ sub.unsubscribe();
48
+ loading.set(false);
49
+ }
50
+ });
51
+ return loadingSignal(value, { loading, error, dispose: () => sub.unsubscribe() });
52
+ }
53
+ function fromPromise(promise) {
54
+ const value = signal(void 0);
55
+ const loading = signal(true);
56
+ const error = signal(void 0);
57
+ promise.then((val) => value.set(val), (err) => error.set(parseError(err)));
58
+ promise.finally(() => loading.set(false));
59
+ return loadingSignal(value, { loading, error });
60
+ }
61
+ function fromLoadingState(state) {
62
+ const value = toSignal(state.result$, { manualCleanup: true });
63
+ const loading = toSignal(state.loading$, { manualCleanup: true, initialValue: true });
64
+ const error = toSignal(state.error$, { manualCleanup: true });
65
+ return loadingSignal(value, { loading, error, dispose: () => state.cancel() });
66
+ }
67
+
68
+ export { loadingSignal, toLoadingSignal };
@@ -0,0 +1,13 @@
1
+ import { computed } from '@angular/core';
2
+
3
+ function pairwiseSignal(inputSignal, firstValue) {
4
+ let prevValue = firstValue;
5
+ return computed(() => {
6
+ const nextValue = inputSignal();
7
+ const tuple = [prevValue, nextValue];
8
+ prevValue = nextValue;
9
+ return tuple;
10
+ });
11
+ }
12
+
13
+ export { pairwiseSignal };
@@ -0,0 +1,13 @@
1
+ import { computed } from '@angular/core';
2
+
3
+ function pairwiseSignal(inputSignal, firstValue) {
4
+ let prevValue = firstValue;
5
+ return computed(() => {
6
+ const nextValue = inputSignal();
7
+ const tuple = [prevValue, nextValue];
8
+ prevValue = nextValue;
9
+ return tuple;
10
+ });
11
+ }
12
+
13
+ export { pairwiseSignal };
@@ -0,0 +1,48 @@
1
+ import { ReplaySubject, isObservable, take, from } from 'rxjs';
2
+ import { signal, computed } from '@angular/core';
3
+ import { parseError, isString, isFunction } from '@juulsgaard/ts-tools';
4
+ import { CancelledError } from '@juulsgaard/rxjs-tools';
5
+ import { IValueRequestState } from './request-state.js';
6
+
7
+ class AsyncRequestState extends IValueRequestState {
8
+ constructor(request) {
9
+ super();
10
+ this._request$ = new ReplaySubject();
11
+ this.request$ = this._request$.asObservable();
12
+ this._result$ = new ReplaySubject();
13
+ this.result$ = this._result$.asObservable();
14
+ this._result = signal(void 0);
15
+ this.result = this._result.asReadonly();
16
+ this._loading = signal(true);
17
+ this.loading = this._loading.asReadonly();
18
+ this._error = signal(void 0);
19
+ this.error = this._error.asReadonly();
20
+ this.failed = computed(() => this._error() !== void 0);
21
+ const request$ = isObservable(request) ? request.pipe(take(1)) : from(request);
22
+ this.sub = request$.subscribe(this._request$);
23
+ this.request$.subscribe({
24
+ next: (value) => {
25
+ this._result$.next(value);
26
+ this._result.set(value);
27
+ },
28
+ error: (error) => {
29
+ this._error.set(parseError(error));
30
+ this._result$.complete();
31
+ this._loading.set(false);
32
+ },
33
+ complete: () => {
34
+ this._result$.complete();
35
+ this._loading.set(false);
36
+ }
37
+ });
38
+ }
39
+ cancel(error) {
40
+ if (this.sub.closed) return false;
41
+ this.sub.unsubscribe();
42
+ const fullError = isString(error) ? new CancelledError(error) : isFunction(error) ? error() : error;
43
+ this._request$.error(fullError);
44
+ return true;
45
+ }
46
+ }
47
+
48
+ export { AsyncRequestState };
@@ -0,0 +1,48 @@
1
+ import { ReplaySubject, isObservable, take, from } from 'rxjs';
2
+ import { signal, computed } from '@angular/core';
3
+ import { parseError, isString, isFunction } from '@juulsgaard/ts-tools';
4
+ import { CancelledError } from '@juulsgaard/rxjs-tools';
5
+ import { IValueRequestState } from './request-state.mjs';
6
+
7
+ class AsyncRequestState extends IValueRequestState {
8
+ constructor(request) {
9
+ super();
10
+ this._request$ = new ReplaySubject();
11
+ this.request$ = this._request$.asObservable();
12
+ this._result$ = new ReplaySubject();
13
+ this.result$ = this._result$.asObservable();
14
+ this._result = signal(void 0);
15
+ this.result = this._result.asReadonly();
16
+ this._loading = signal(true);
17
+ this.loading = this._loading.asReadonly();
18
+ this._error = signal(void 0);
19
+ this.error = this._error.asReadonly();
20
+ this.failed = computed(() => this._error() !== void 0);
21
+ const request$ = isObservable(request) ? request.pipe(take(1)) : from(request);
22
+ this.sub = request$.subscribe(this._request$);
23
+ this.request$.subscribe({
24
+ next: (value) => {
25
+ this._result$.next(value);
26
+ this._result.set(value);
27
+ },
28
+ error: (error) => {
29
+ this._error.set(parseError(error));
30
+ this._result$.complete();
31
+ this._loading.set(false);
32
+ },
33
+ complete: () => {
34
+ this._result$.complete();
35
+ this._loading.set(false);
36
+ }
37
+ });
38
+ }
39
+ cancel(error) {
40
+ if (this.sub.closed) return false;
41
+ this.sub.unsubscribe();
42
+ const fullError = isString(error) ? new CancelledError(error) : isFunction(error) ? error() : error;
43
+ this._request$.error(fullError);
44
+ return true;
45
+ }
46
+ }
47
+
48
+ export { AsyncRequestState };
@@ -0,0 +1,25 @@
1
+ import { isObservable } from 'rxjs';
2
+ import { WritableRequestState } from './writable-request-state.js';
3
+ import { AsyncRequestState } from './async-request-state.js';
4
+ import { StaticRequestState } from './static-request-state.js';
5
+ import { ErrorRequestState } from './error-request-state.js';
6
+ import '@angular/core';
7
+ import '@juulsgaard/ts-tools';
8
+
9
+ function valueRequestState(data) {
10
+ if (isObservable(data)) return new AsyncRequestState(data);
11
+ if (data instanceof Promise) return new AsyncRequestState(data);
12
+ return new StaticRequestState(data);
13
+ }
14
+ function errorRequestState(error) {
15
+ return new ErrorRequestState(error instanceof Error ? () => error : error);
16
+ }
17
+ function writableRequestState(onCancel) {
18
+ return new WritableRequestState(onCancel);
19
+ }
20
+ const compiled = valueRequestState;
21
+ compiled.writable = writableRequestState;
22
+ compiled.error = errorRequestState;
23
+ const requestState = compiled;
24
+
25
+ export { requestState };
@@ -0,0 +1,25 @@
1
+ import { isObservable } from 'rxjs';
2
+ import { WritableRequestState } from './writable-request-state.mjs';
3
+ import { AsyncRequestState } from './async-request-state.mjs';
4
+ import { StaticRequestState } from './static-request-state.mjs';
5
+ import { ErrorRequestState } from './error-request-state.mjs';
6
+ import '@angular/core';
7
+ import '@juulsgaard/ts-tools';
8
+
9
+ function valueRequestState(data) {
10
+ if (isObservable(data)) return new AsyncRequestState(data);
11
+ if (data instanceof Promise) return new AsyncRequestState(data);
12
+ return new StaticRequestState(data);
13
+ }
14
+ function errorRequestState(error) {
15
+ return new ErrorRequestState(error instanceof Error ? () => error : error);
16
+ }
17
+ function writableRequestState(onCancel) {
18
+ return new WritableRequestState(onCancel);
19
+ }
20
+ const compiled = valueRequestState;
21
+ compiled.writable = writableRequestState;
22
+ compiled.error = errorRequestState;
23
+ const requestState = compiled;
24
+
25
+ export { requestState };
@@ -0,0 +1,20 @@
1
+ import { EMPTY } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.js';
4
+
5
+ class EmptyRequestState extends IValueRequestState {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.request$ = EMPTY;
9
+ this.result$ = this.request$;
10
+ this.result = signal(void 0).asReadonly();
11
+ this.loading = signal(false);
12
+ this.error = signal(void 0);
13
+ this.failed = signal(false);
14
+ }
15
+ cancel() {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ export { EmptyRequestState };
@@ -0,0 +1,20 @@
1
+ import { EMPTY } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.mjs';
4
+
5
+ class EmptyRequestState extends IValueRequestState {
6
+ constructor() {
7
+ super(...arguments);
8
+ this.request$ = EMPTY;
9
+ this.result$ = this.request$;
10
+ this.result = signal(void 0).asReadonly();
11
+ this.loading = signal(false);
12
+ this.error = signal(void 0);
13
+ this.failed = signal(false);
14
+ }
15
+ cancel() {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ export { EmptyRequestState };
@@ -0,0 +1,20 @@
1
+ import { EMPTY, throwError } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.js';
4
+
5
+ class ErrorRequestState extends IValueRequestState {
6
+ constructor(getError) {
7
+ super();
8
+ this.result$ = EMPTY;
9
+ this.result = signal(void 0).asReadonly();
10
+ this.loading = signal(false);
11
+ this.failed = signal(true);
12
+ this.error = signal(getError());
13
+ this.request$ = throwError(getError);
14
+ }
15
+ cancel() {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ export { ErrorRequestState };
@@ -0,0 +1,20 @@
1
+ import { EMPTY, throwError } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.mjs';
4
+
5
+ class ErrorRequestState extends IValueRequestState {
6
+ constructor(getError) {
7
+ super();
8
+ this.result$ = EMPTY;
9
+ this.result = signal(void 0).asReadonly();
10
+ this.loading = signal(false);
11
+ this.failed = signal(true);
12
+ this.error = signal(getError());
13
+ this.request$ = throwError(getError);
14
+ }
15
+ cancel() {
16
+ return false;
17
+ }
18
+ }
19
+
20
+ export { ErrorRequestState };
@@ -0,0 +1,25 @@
1
+ import { Subject } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.js';
4
+
5
+ class LoadingRequestState extends IValueRequestState {
6
+ constructor() {
7
+ super(...arguments);
8
+ this._request$ = new Subject();
9
+ this.request$ = this._request$.asObservable();
10
+ this.result$ = this.request$;
11
+ this.result = signal(void 0).asReadonly();
12
+ this._loading = signal(true);
13
+ this.loading = this._loading.asReadonly();
14
+ this.error = signal(void 0);
15
+ this.failed = signal(false);
16
+ }
17
+ cancel() {
18
+ if (this._request$.closed) return false;
19
+ this._request$.complete();
20
+ this._loading.set(false);
21
+ return false;
22
+ }
23
+ }
24
+
25
+ export { LoadingRequestState };
@@ -0,0 +1,25 @@
1
+ import { Subject } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.mjs';
4
+
5
+ class LoadingRequestState extends IValueRequestState {
6
+ constructor() {
7
+ super(...arguments);
8
+ this._request$ = new Subject();
9
+ this.request$ = this._request$.asObservable();
10
+ this.result$ = this.request$;
11
+ this.result = signal(void 0).asReadonly();
12
+ this._loading = signal(true);
13
+ this.loading = this._loading.asReadonly();
14
+ this.error = signal(void 0);
15
+ this.failed = signal(false);
16
+ }
17
+ cancel() {
18
+ if (this._request$.closed) return false;
19
+ this._request$.complete();
20
+ this._loading.set(false);
21
+ return false;
22
+ }
23
+ }
24
+
25
+ export { LoadingRequestState };
@@ -0,0 +1,39 @@
1
+ import { first } from 'rxjs';
2
+ import { parseError } from '@juulsgaard/ts-tools';
3
+
4
+ class IRequestState {
5
+ /**
6
+ * Subscribe to the underlying request Observable
7
+ * @param observer
8
+ */
9
+ subscribe(observer) {
10
+ return this.request$.subscribe(observer);
11
+ }
12
+ }
13
+ class IValueRequestState extends IRequestState {
14
+ subscribe(observer) {
15
+ return this.request$.subscribe(observer);
16
+ }
17
+ then(onValue, onError) {
18
+ this.request$.pipe(first()).subscribe({
19
+ next: (v) => onValue(v),
20
+ error: (e) => onError?.(parseError(e))
21
+ });
22
+ return this;
23
+ }
24
+ catch(onError) {
25
+ this.request$.subscribe({
26
+ error: (e) => onError(parseError(e))
27
+ });
28
+ return this;
29
+ }
30
+ finally(onComplete) {
31
+ this.request$.subscribe({
32
+ error: (e) => onComplete(parseError(e)),
33
+ complete: () => onComplete()
34
+ });
35
+ return this;
36
+ }
37
+ }
38
+
39
+ export { IRequestState, IValueRequestState };
@@ -0,0 +1,39 @@
1
+ import { first } from 'rxjs';
2
+ import { parseError } from '@juulsgaard/ts-tools';
3
+
4
+ class IRequestState {
5
+ /**
6
+ * Subscribe to the underlying request Observable
7
+ * @param observer
8
+ */
9
+ subscribe(observer) {
10
+ return this.request$.subscribe(observer);
11
+ }
12
+ }
13
+ class IValueRequestState extends IRequestState {
14
+ subscribe(observer) {
15
+ return this.request$.subscribe(observer);
16
+ }
17
+ then(onValue, onError) {
18
+ this.request$.pipe(first()).subscribe({
19
+ next: (v) => onValue(v),
20
+ error: (e) => onError?.(parseError(e))
21
+ });
22
+ return this;
23
+ }
24
+ catch(onError) {
25
+ this.request$.subscribe({
26
+ error: (e) => onError(parseError(e))
27
+ });
28
+ return this;
29
+ }
30
+ finally(onComplete) {
31
+ this.request$.subscribe({
32
+ error: (e) => onComplete(parseError(e)),
33
+ complete: () => onComplete()
34
+ });
35
+ return this;
36
+ }
37
+ }
38
+
39
+ export { IRequestState, IValueRequestState };
@@ -0,0 +1,64 @@
1
+ import { computed, signal, untracked } from '@angular/core';
2
+ import { IValueRequestState } from './request-state.js';
3
+ import { requestState } from './constructors.js';
4
+
5
+ class RequestTracker {
6
+ constructor(request) {
7
+ /** Emits true if the current RequestState is loading */
8
+ this.loading = computed(() => this._request().loading());
9
+ /** Emits an error if the current RequestState is in an error state */
10
+ this.error = computed(() => this._request().error());
11
+ /** Emits true if the current RequestState has failed */
12
+ this.failed = computed(() => this._request().failed());
13
+ this._request = signal(request ?? requestState.empty());
14
+ this.request = this._request.asReadonly();
15
+ }
16
+ /** The currently active RequestState */
17
+ set current(req) {
18
+ this.set(req);
19
+ }
20
+ get current() {
21
+ return untracked(this.request);
22
+ }
23
+ /**
24
+ * Set a new current RequestState
25
+ * @param state - The new RequestState
26
+ */
27
+ set(state) {
28
+ this._request.set(state);
29
+ }
30
+ /**
31
+ * Resets the Tracker to an Empty state
32
+ */
33
+ reset() {
34
+ this._request.set(requestState.empty());
35
+ }
36
+ }
37
+ class ValueRequestTracker extends RequestTracker {
38
+ set current(req) {
39
+ this.set(req);
40
+ }
41
+ get current() {
42
+ return untracked(this.request);
43
+ }
44
+ constructor(request) {
45
+ super();
46
+ this._valueRequest = signal(request ?? requestState.empty());
47
+ this.request = this._valueRequest.asReadonly();
48
+ }
49
+ set(req) {
50
+ super.set(req);
51
+ this._valueRequest.set(req);
52
+ }
53
+ reset() {
54
+ super.reset();
55
+ this.set(requestState.empty());
56
+ }
57
+ }
58
+ function requestTracker(request) {
59
+ if (!request) return new ValueRequestTracker();
60
+ if (request instanceof IValueRequestState) return new ValueRequestTracker(request);
61
+ return new RequestTracker(request);
62
+ }
63
+
64
+ export { RequestTracker, ValueRequestTracker, requestTracker };
@@ -0,0 +1,64 @@
1
+ import { computed, signal, untracked } from '@angular/core';
2
+ import { IValueRequestState } from './request-state.mjs';
3
+ import { requestState } from './constructors.mjs';
4
+
5
+ class RequestTracker {
6
+ constructor(request) {
7
+ /** Emits true if the current RequestState is loading */
8
+ this.loading = computed(() => this._request().loading());
9
+ /** Emits an error if the current RequestState is in an error state */
10
+ this.error = computed(() => this._request().error());
11
+ /** Emits true if the current RequestState has failed */
12
+ this.failed = computed(() => this._request().failed());
13
+ this._request = signal(request ?? requestState.empty());
14
+ this.request = this._request.asReadonly();
15
+ }
16
+ /** The currently active RequestState */
17
+ set current(req) {
18
+ this.set(req);
19
+ }
20
+ get current() {
21
+ return untracked(this.request);
22
+ }
23
+ /**
24
+ * Set a new current RequestState
25
+ * @param state - The new RequestState
26
+ */
27
+ set(state) {
28
+ this._request.set(state);
29
+ }
30
+ /**
31
+ * Resets the Tracker to an Empty state
32
+ */
33
+ reset() {
34
+ this._request.set(requestState.empty());
35
+ }
36
+ }
37
+ class ValueRequestTracker extends RequestTracker {
38
+ set current(req) {
39
+ this.set(req);
40
+ }
41
+ get current() {
42
+ return untracked(this.request);
43
+ }
44
+ constructor(request) {
45
+ super();
46
+ this._valueRequest = signal(request ?? requestState.empty());
47
+ this.request = this._valueRequest.asReadonly();
48
+ }
49
+ set(req) {
50
+ super.set(req);
51
+ this._valueRequest.set(req);
52
+ }
53
+ reset() {
54
+ super.reset();
55
+ this.set(requestState.empty());
56
+ }
57
+ }
58
+ function requestTracker(request) {
59
+ if (!request) return new ValueRequestTracker();
60
+ if (request instanceof IValueRequestState) return new ValueRequestTracker(request);
61
+ return new RequestTracker(request);
62
+ }
63
+
64
+ export { RequestTracker, ValueRequestTracker, requestTracker };
@@ -0,0 +1,32 @@
1
+ import { of } from 'rxjs';
2
+ import { signal } from '@angular/core';
3
+ import { IValueRequestState } from './request-state.js';
4
+
5
+ class StaticRequestState extends IValueRequestState {
6
+ constructor(value) {
7
+ super();
8
+ this.value = value;
9
+ this.loading = signal(false);
10
+ this.error = signal(void 0);
11
+ this.failed = signal(false);
12
+ this.request$ = of(value);
13
+ this.result$ = this.request$;
14
+ this.result = signal(value);
15
+ }
16
+ cancel() {
17
+ return false;
18
+ }
19
+ then(next, _error) {
20
+ next(this.value);
21
+ return this;
22
+ }
23
+ catch(_onError) {
24
+ return this;
25
+ }
26
+ finally(onComplete) {
27
+ onComplete();
28
+ return this;
29
+ }
30
+ }
31
+
32
+ export { StaticRequestState };