mirror of https://github.com/ghostfolio/ghostfolio
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
260 lines
7.8 KiB
260 lines
7.8 KiB
/**
|
|
* @license Angular v21.1.1
|
|
* (c) 2010-2026 Google LLC. https://angular.dev/
|
|
* License: MIT
|
|
*/
|
|
|
|
import { Observable, ReplaySubject } from 'rxjs';
|
|
import { takeUntil } from 'rxjs/operators';
|
|
import { assertInInjectionContext, inject, DestroyRef, RuntimeError, Injector, effect, untracked, assertNotInReactiveContext, signal, PendingTasks } from './_untracked-chunk.mjs';
|
|
import { getOutputDestroyRef, computed, resource, encapsulateResourceError } from './_resource-chunk.mjs';
|
|
import './_effect-chunk.mjs';
|
|
import './_not_found-chunk.mjs';
|
|
import '@angular/core/primitives/signals';
|
|
import '@angular/core/primitives/di';
|
|
import './_linked_signal-chunk.mjs';
|
|
|
|
function takeUntilDestroyed(destroyRef) {
|
|
if (!destroyRef) {
|
|
ngDevMode && assertInInjectionContext(takeUntilDestroyed);
|
|
destroyRef = inject(DestroyRef);
|
|
}
|
|
const destroyed$ = new Observable(subscriber => {
|
|
if (destroyRef.destroyed) {
|
|
subscriber.next();
|
|
return;
|
|
}
|
|
const unregisterFn = destroyRef.onDestroy(subscriber.next.bind(subscriber));
|
|
return unregisterFn;
|
|
});
|
|
return source => {
|
|
return source.pipe(takeUntil(destroyed$));
|
|
};
|
|
}
|
|
|
|
class OutputFromObservableRef {
|
|
source;
|
|
destroyed = false;
|
|
destroyRef = inject(DestroyRef);
|
|
constructor(source) {
|
|
this.source = source;
|
|
this.destroyRef.onDestroy(() => {
|
|
this.destroyed = true;
|
|
});
|
|
}
|
|
subscribe(callbackFn) {
|
|
if (this.destroyed) {
|
|
throw new RuntimeError(953, ngDevMode && 'Unexpected subscription to destroyed `OutputRef`. ' + 'The owning directive/component is destroyed.');
|
|
}
|
|
const subscription = this.source.pipe(takeUntilDestroyed(this.destroyRef)).subscribe({
|
|
next: value => callbackFn(value)
|
|
});
|
|
return {
|
|
unsubscribe: () => subscription.unsubscribe()
|
|
};
|
|
}
|
|
}
|
|
function outputFromObservable(observable, opts) {
|
|
ngDevMode && assertInInjectionContext(outputFromObservable);
|
|
return new OutputFromObservableRef(observable);
|
|
}
|
|
|
|
function outputToObservable(ref) {
|
|
const destroyRef = getOutputDestroyRef(ref);
|
|
return new Observable(observer => {
|
|
const unregisterOnDestroy = destroyRef?.onDestroy(() => observer.complete());
|
|
const subscription = ref.subscribe(v => observer.next(v));
|
|
return () => {
|
|
subscription.unsubscribe();
|
|
unregisterOnDestroy?.();
|
|
};
|
|
});
|
|
}
|
|
|
|
function toObservable(source, options) {
|
|
if (ngDevMode && !options?.injector) {
|
|
assertInInjectionContext(toObservable);
|
|
}
|
|
const injector = options?.injector ?? inject(Injector);
|
|
const subject = new ReplaySubject(1);
|
|
const watcher = effect(() => {
|
|
let value;
|
|
try {
|
|
value = source();
|
|
} catch (err) {
|
|
untracked(() => subject.error(err));
|
|
return;
|
|
}
|
|
untracked(() => subject.next(value));
|
|
}, {
|
|
injector,
|
|
manualCleanup: true
|
|
});
|
|
injector.get(DestroyRef).onDestroy(() => {
|
|
watcher.destroy();
|
|
subject.complete();
|
|
});
|
|
return subject.asObservable();
|
|
}
|
|
|
|
function toSignal(source, options) {
|
|
typeof ngDevMode !== 'undefined' && ngDevMode && assertNotInReactiveContext(toSignal, 'Invoking `toSignal` causes new subscriptions every time. ' + 'Consider moving `toSignal` outside of the reactive context and read the signal value where needed.');
|
|
const requiresCleanup = !options?.manualCleanup;
|
|
if (ngDevMode && requiresCleanup && !options?.injector) {
|
|
assertInInjectionContext(toSignal);
|
|
}
|
|
const cleanupRef = requiresCleanup ? options?.injector?.get(DestroyRef) ?? inject(DestroyRef) : null;
|
|
const equal = makeToSignalEqual(options?.equal);
|
|
let state;
|
|
if (options?.requireSync) {
|
|
state = signal({
|
|
kind: 0
|
|
}, {
|
|
equal,
|
|
...(ngDevMode ? createDebugNameObject(options?.debugName, 'state') : undefined)
|
|
});
|
|
} else {
|
|
state = signal({
|
|
kind: 1,
|
|
value: options?.initialValue
|
|
}, {
|
|
equal,
|
|
...(ngDevMode ? createDebugNameObject(options?.debugName, 'state') : undefined)
|
|
});
|
|
}
|
|
let destroyUnregisterFn;
|
|
const sub = source.subscribe({
|
|
next: value => state.set({
|
|
kind: 1,
|
|
value
|
|
}),
|
|
error: error => {
|
|
state.set({
|
|
kind: 2,
|
|
error
|
|
});
|
|
destroyUnregisterFn?.();
|
|
},
|
|
complete: () => {
|
|
destroyUnregisterFn?.();
|
|
}
|
|
});
|
|
if (options?.requireSync && state().kind === 0) {
|
|
throw new RuntimeError(601, (typeof ngDevMode === 'undefined' || ngDevMode) && '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');
|
|
}
|
|
destroyUnregisterFn = cleanupRef?.onDestroy(sub.unsubscribe.bind(sub));
|
|
return computed(() => {
|
|
const current = state();
|
|
switch (current.kind) {
|
|
case 1:
|
|
return current.value;
|
|
case 2:
|
|
throw current.error;
|
|
case 0:
|
|
throw new RuntimeError(601, (typeof ngDevMode === 'undefined' || ngDevMode) && '`toSignal()` called with `requireSync` but `Observable` did not emit synchronously.');
|
|
}
|
|
}, {
|
|
equal: options?.equal,
|
|
...(ngDevMode ? createDebugNameObject(options?.debugName, 'source') : undefined)
|
|
});
|
|
}
|
|
function makeToSignalEqual(userEquality = Object.is) {
|
|
return (a, b) => a.kind === 1 && b.kind === 1 && userEquality(a.value, b.value);
|
|
}
|
|
function createDebugNameObject(toSignalDebugName, internalSignalDebugName) {
|
|
return {
|
|
debugName: `toSignal${toSignalDebugName ? '#' + toSignalDebugName : ''}.${internalSignalDebugName}`
|
|
};
|
|
}
|
|
|
|
function pendingUntilEvent(injector) {
|
|
if (injector === undefined) {
|
|
ngDevMode && assertInInjectionContext(pendingUntilEvent);
|
|
injector = inject(Injector);
|
|
}
|
|
const taskService = injector.get(PendingTasks);
|
|
return sourceObservable => {
|
|
return new Observable(originalSubscriber => {
|
|
const removeTask = taskService.add();
|
|
let cleanedUp = false;
|
|
function cleanupTask() {
|
|
if (cleanedUp) {
|
|
return;
|
|
}
|
|
removeTask();
|
|
cleanedUp = true;
|
|
}
|
|
const innerSubscription = sourceObservable.subscribe({
|
|
next: v => {
|
|
originalSubscriber.next(v);
|
|
cleanupTask();
|
|
},
|
|
complete: () => {
|
|
originalSubscriber.complete();
|
|
cleanupTask();
|
|
},
|
|
error: e => {
|
|
originalSubscriber.error(e);
|
|
cleanupTask();
|
|
}
|
|
});
|
|
innerSubscription.add(() => {
|
|
originalSubscriber.unsubscribe();
|
|
cleanupTask();
|
|
});
|
|
return innerSubscription;
|
|
});
|
|
};
|
|
}
|
|
|
|
function rxResource(opts) {
|
|
if (ngDevMode && !opts?.injector) {
|
|
assertInInjectionContext(rxResource);
|
|
}
|
|
return resource({
|
|
...opts,
|
|
loader: undefined,
|
|
stream: params => {
|
|
let sub;
|
|
const onAbort = () => sub?.unsubscribe();
|
|
params.abortSignal.addEventListener('abort', onAbort);
|
|
const stream = signal({
|
|
value: undefined
|
|
});
|
|
let resolve;
|
|
const promise = new Promise(r => resolve = r);
|
|
function send(value) {
|
|
stream.set(value);
|
|
resolve?.(stream);
|
|
resolve = undefined;
|
|
}
|
|
const streamFn = opts.stream ?? opts.loader;
|
|
if (streamFn === undefined) {
|
|
throw new RuntimeError(990, ngDevMode && `Must provide \`stream\` option.`);
|
|
}
|
|
sub = streamFn(params).subscribe({
|
|
next: value => send({
|
|
value
|
|
}),
|
|
error: error => {
|
|
send({
|
|
error: encapsulateResourceError(error)
|
|
});
|
|
params.abortSignal.removeEventListener('abort', onAbort);
|
|
},
|
|
complete: () => {
|
|
if (resolve) {
|
|
send({
|
|
error: new RuntimeError(991, ngDevMode && 'Resource completed before producing a value')
|
|
});
|
|
}
|
|
params.abortSignal.removeEventListener('abort', onAbort);
|
|
}
|
|
});
|
|
return promise;
|
|
}
|
|
});
|
|
}
|
|
|
|
export { outputFromObservable, outputToObservable, pendingUntilEvent, rxResource, takeUntilDestroyed, toObservable, toSignal };
|
|
//# sourceMappingURL=rxjs-interop.mjs.map
|
|
|