UNPKG

@antischematic/angular-state-library

Version:
1,158 lines (1,140 loc) 42.2 kB
import * as i0 from '@angular/core'; import { ChangeDetectorRef, InjectionToken, inject, INJECTOR, Injectable, ErrorHandler, createEnvironmentInjector, EnvironmentInjector, ElementRef, Directive, Input, EventEmitter } from '@angular/core'; import { defer, filter, Observable, map, Subject, Subscription, switchAll, pipe, mergeAll, concatAll, exhaustAll, startWith, distinctUntilChanged, BehaviorSubject, NEVER, isObservable, ReplaySubject, observable, tap, catchError, EMPTY, takeWhile, merge, fromEvent, of, debounce, interval, switchMap, takeUntil, throttle, timer, retry, share, finalize } from 'rxjs'; import { DOCUMENT } from '@angular/common'; var EventType; (function (EventType) { EventType["Dispatch"] = "dispatch"; EventType["Next"] = "next"; EventType["Error"] = "error"; EventType["Complete"] = "complete"; })(EventType || (EventType = {})); const meta = new WeakMap(); const action$1 = Symbol("action"); const selector = Symbol("selector"); const tracked = Symbol("track"); const injector = Symbol("injector"); const caught = Symbol("caught"); const attach = Symbol("attach"); function ensureKey(target, key) { return target.has(key) ? target.get(key) : target.set(key, new Map()).get(key); } function getMetaKeys(metaKey, target) { return ensureKey(ensureKey(meta, target), metaKey); } function getMeta(metaKey, target, key) { return getMetaKeys(metaKey, target).get(key); } function setMeta(metaKey, value, target, key) { return ensureKey(ensureKey(meta, target), metaKey).set(key, value); } function getMetaValues(metaKey, target) { return Array.from(getMetaKeys(metaKey, target).values()); } function getActions(target, phase) { return getMetaValues(action$1, target).filter(meta => phase ? meta.phase === phase : true); } function getSelectors(target, withDescriptor) { return getMetaValues(selector, target).filter(selector => !!selector.descriptor === withDescriptor); } function getErrorHandlers(target) { return getMetaValues(caught, target); } function getDeps(target, key) { return getMeta(tracked, target, key); } function getToken(token, context, key) { var _a; return (_a = getMeta(injector, context, key)) === null || _a === void 0 ? void 0 : _a.get(token); } function markDirty(context) { getToken(ChangeDetectorRef, context).markForCheck(); } function getAttachments(target) { return getMetaValues(attach, target); } const cache = new WeakMap(); const proxies = new WeakMap(); let deps = []; function pushStack(value) { deps.unshift(value); } function popStack() { deps.shift(); } function isTracking() { return deps.length > 0; } const changesMap = new WeakMap(); function getChanges(deps) { var _a; const changes = (_a = changesMap.get(deps)) !== null && _a !== void 0 ? _a : new Map(); changesMap.set(deps, changes); return changes; } function addDep(object, key, value, previous = value, update = false) { var _a, _b; if (isTracking()) { let seen = false; for (const dep of deps) { const keyValues = (_a = dep.get(object)) !== null && _a !== void 0 ? _a : new Map; dep.set(object, keyValues); if (!seen && update && !Object.is(value, previous)) { seen = true; const changes = getChanges(dep); const change = (_b = changes.get(object)) !== null && _b !== void 0 ? _b : new Map(); changes.set(object, change); if (!change.has(key)) { change.set(key, untrack(previous)); } } if (update && keyValues.has(key) || !update) { keyValues.set(key, value); } } } } function createObjectProxy(object) { return new Proxy(object, { get(target, p) { const value = Reflect.get(target, p); addDep(target, p, value); return value; }, set(target, p, value, receiver) { const previous = Reflect.get(target, p); const result = Reflect.set(target, p, value, receiver); addDep(target, p, value, previous, true); return result; }, deleteProperty(target, p) { const previous = Reflect.get(target, p); const result = Reflect.deleteProperty(target, p); addDep(target, p, void 0, previous, true); return result; } }); } function createProxy(object) { if (!isObject(object)) return object; if (cache.has(object)) { return cache.get(object); } const proxy = createObjectProxy(object); cache.set(object, proxy); proxies.set(proxy, object); return proxy; } function isTracked(object) { return proxies.has(object); } function isObject(value) { return typeof value === "object" && value !== null; } function track(object) { return isObject(object) && !isTracked(object) ? createProxy(object) : object; } function untrack(object) { var _a; return (_a = proxies.get(object)) !== null && _a !== void 0 ? _a : object; } function isPlainObject(obj) { const proto = Object.getPrototypeOf(obj); return proto === null || proto === Object.prototype; } function call(target, key, ...args) { return target[key].apply(target, args); } function wrap(target, property, fn) { var _a; const descriptor = Object.getOwnPropertyDescriptor(target, property); const object = descriptor ? descriptor : target; const getOrValue = (descriptor === null || descriptor === void 0 ? void 0 : descriptor.get) ? "get" : "value"; const originalFunction = (_a = (descriptor ? descriptor[getOrValue] : object[property])) !== null && _a !== void 0 ? _a : noop; Object.defineProperty(target, property, { configurable: true, [getOrValue]: function (...args) { return fn.call(untrack(this), originalFunction, ...args); } }); return originalFunction === noop; } function noop() { } const UID = new InjectionToken("UID", { factory() { let id = 0; return function getId() { return id++; }; } }); function events(token, injector = inject(INJECTOR)) { return defer(() => { const context = typeof token === "function" ? injector.get(token) : token; return injector.get(EVENTS).pipe(filter(event => event.context === context)); }); } function configureStore(config) { return { provide: config.root ? ROOT_CONFIG : STORE_CONFIG, useValue: config }; } function observeInZone(source, zone) { return new Observable(subscriber => { return zone.run(() => { return source.subscribe(subscriber); }); }); } function get(token) { return track(inject(token).value); } function set(token, value) { inject(token).next(value); } function filterByNameType(name, type) { return filter((event) => event.name === name && event.type === type); } function actionEvent(token, name, injector) { return events(token, injector).pipe(filterByNameType(name, EventType.Dispatch)); } function action(token, name, injector) { return actionEvent(token, name, injector).pipe(map((event) => event.value)); } function nextEvent(token, name, injector) { return events(token, injector).pipe(filterByNameType(name, EventType.Next)); } function next(token, name, injector) { return nextEvent(token, name, injector).pipe(map((event) => event.value)); } function errorEvent(token, name, injector) { return events(token, injector).pipe(filterByNameType(name, EventType.Error)); } function error(token, name, injector) { return errorEvent(token, name, injector).pipe(map((event) => event.value)); } function completeEvent(token, name, injector) { return events(token, injector).pipe(filterByNameType(name, EventType.Complete)); } function complete(token, name, injector) { return completeEvent(token, name, injector).pipe(filterByNameType(name, EventType.Complete), map(() => undefined)); } const ACTION = new InjectionToken("ACTION"); const CONTEXT = new InjectionToken("CONTEXT"); const STORE_CONFIG = new InjectionToken("STORE_CONFIG"); const ROOT_CONFIG = new InjectionToken("ROOT_CONFIG", { factory() { return {}; } }); const EVENTS = new InjectionToken("EVENTS", { factory() { return new Subject(); } }); class EventScheduler { constructor(context) { this.context = context; this.events = []; this.dispatcher = inject(EVENTS); this.getId = inject(UID); } schedule(type, name, value, changes) { this.events.push({ id: this.getId(), timestamp: Date.now(), type, context: this.context, name, value, changes }); } flush() { const events = this.events; if (events.length) { let event; this.events = []; while (event = events.shift()) { this.dispatcher.next(event); } } return this.events.length > 0; } } class EffectScheduler { constructor() { this.source = new Subject(); this.queue = []; this.connected = false; this.subscription = Subscription.EMPTY; this.pending = new Set; this.closed = false; } next(source) { this.connect(); this.source.next(source); } enqueue(source) { this.queue.push(source); } dequeue() { let effect; if (this.pending.size === 0) { while (effect = this.queue.shift()) { this.next(effect); } } } connect() { var _a; if (!this.connected && !this.closed) { this.connected = true; this.subscription = this.source.pipe((_a = this.operator) !== null && _a !== void 0 ? _a : switchAll()).subscribe(); this.subscription.add(() => this.connected = false); } } addPending(promise) { this.pending.add(promise); promise.finally(() => { this.pending.delete(promise); this.dequeue(); }); } ngOnDestroy() { this.closed = true; this.source.complete(); this.subscription.unsubscribe(); } } EffectScheduler.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EffectScheduler, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); EffectScheduler.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EffectScheduler }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: EffectScheduler, decorators: [{ type: Injectable }] }); class Teardown { constructor() { this.subscriptions = []; } unsubscribe() { let subscription; while (subscription = this.subscriptions.shift()) { subscription.unsubscribe(); } } ngOnDestroy() { this.unsubscribe(); } } Teardown.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Teardown, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); Teardown.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Teardown }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Teardown, decorators: [{ type: Injectable }] }); class Changes { constructor(target) { this.target = target; } get value() { var _a, _b; return (_b = track((_a = this.target.__ngSimpleChanges__) === null || _a === void 0 ? void 0 : _a.previous)) !== null && _b !== void 0 ? _b : {}; } } class StoreErrorHandler { constructor(prototype, instance) { this.prototype = prototype; this.instance = instance; } handleError(error) { const errorHandlers = getErrorHandlers(this.prototype); for (const handler of errorHandlers) { try { this.instance[handler.key].call(this.instance, error); break; } catch (e) { error = e; } } throw error; } } function useOperator(operator) { const effect = inject(EffectScheduler); if (!effect.operator) { effect.operator = operator; } } function useSwitch(operator) { useOperator(operator ? pipe(operator, switchAll()) : switchAll()); } function useMerge(operator, concurrent = operator) { useOperator(typeof operator === "function" ? pipe(operator, mergeAll(concurrent)) : mergeAll(concurrent)); } function useConcat(operator) { useOperator(operator ? pipe(operator, concatAll()) : concatAll()); } function useExhaust(operator) { useOperator(operator ? pipe(operator, exhaustAll()) : exhaustAll()); } function addTeardown(teardown) { const subscription = new Subscription(); subscription.add(teardown); inject(Teardown).subscriptions.push(subscription); } function useInputs() { return inject(Changes).value; } function pick(object, keys) { if (Array.isArray(keys)) { return keys.reduce((acc, key) => { acc[key] = object[key]; return acc; }, {}); } return object[keys]; } function slice(token, keys, injector = inject(INJECTOR)) { return defer(() => { const context = injector.get(token); return store(token, injector).pipe(map((context) => pick(context, keys)), startWith(pick(context, keys)), distinctUntilChanged((a, b) => !Array.isArray(keys) ? Object.is(a, b) : keys.every(key => Object.is(a[key], b[key])))); }); } function store(token, injector = inject(INJECTOR)) { return defer(() => { const context = injector.get(token); return injector.get(EVENTS).pipe(filter(event => event.changes.has(context)), map(() => context)); }); } function inputs(token, injector = inject(INJECTOR)) { return defer(() => { return events(token, injector).pipe(filter((event) => event.name === "ngOnChanges"), map(event => event.value)); }); } function withState(initial, options = {}) { var _a; const destination = new BehaviorSubject(initial); const source = (_a = options.from) !== null && _a !== void 0 ? _a : NEVER; return { destination, source, }; } const Selector = function Selector(name, select) { class Selector { constructor() { this.connected = false; this.subscription = new Subscription(); const subject = new Subject(); const selection = select(subject); if (isObservable(selection)) { this.source = selection; this.destination = new ReplaySubject(1); } else { this.source = selection.source; this.destination = selection.destination; } this.target = select.length > 0 ? subject : this.destination; this.subscription.add(this.destination.subscribe((value) => { this.value = value; })); } [observable]() { return this; } connect() { if (!this.connected) { this.connected = true; this.subscription.add(this.source.subscribe(this.destination)); } } next(value) { this.target.next(value); } pipe(...operators) { return new Observable(subscriber => { return this.subscribe(subscriber); }).pipe(...operators); } subscribe(observer) { try { return this.destination.subscribe(observer); } finally { this.connect(); } } ngOnDestroy() { this.subscription.unsubscribe(); } } Selector.overriddenName = name; Selector.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Selector, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); Selector.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Selector }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: Selector, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); return Selector; }; class SelectObserver { constructor(target, key, event, cdr, errorHandler) { this.target = target; this.key = key; this.event = event; this.cdr = cdr; this.errorHandler = errorHandler; } next(value) { const previous = this.target[this.key]; this.target[this.key] = track(value); const changes = new Map([[this.target, new Map([[this.key, previous]])]]); this.event.schedule(EventType.Dispatch, this.key, value, changes); this.cdr.markForCheck(); } error(error) { console.error("Error thrown in Select"); console.error("Directive:", this.target); console.error("Key:", this.key); this.errorHandler.handleError(error); } complete() { } } function subscribe(token, directive, key) { var _a, _b, _c; const instance = token ? inject(token) : directive[key]; const observer = new SelectObserver(directive, key, inject(EventScheduler), inject(ChangeDetectorRef), inject(ErrorHandler)); const subscription = (_b = (_a = instance.ngOnSelect) === null || _a === void 0 ? void 0 : _a.call(instance, observer)) !== null && _b !== void 0 ? _b : (_c = instance.subscribe) === null || _c === void 0 ? void 0 : _c.call(instance, observer); if (!subscription) { console.error('Directive:', directive); console.error('Key:', key); console.error('Object:', instance); throw new Error(`Object does not implement OnSelect or Subscribable interfaces`); } directive[key] = track(directive[key]); addTeardown(subscription); } function checkDeps(deps) { let dirty = false; for (const [object, keyValues] of deps) { for (const [key, previous] of keyValues) { const current = object[key]; if (!Object.is(current, previous)) { keyValues.set(key, current); dirty = true; } } } return dirty; } function decorateCheck(target, name) { const actions = getActions(target, name); wrap(target, name, function check(fn) { var _b; const events = getToken(EventScheduler, this); for (const action of actions) { const deps = getDeps(this, action.key); const dirty = action.track && deps && checkDeps(deps); if (((_b = action.descriptor) === null || _b === void 0 ? void 0 : _b.value.length) === 0 && (!deps && action.immediate && action.phase === name || dirty)) { markDirty(this); call(this, action.key); } } for (const action of actions) { const effect = getToken(EffectScheduler, this, action.key); effect.dequeue(); } if (events.flush()) { check.call(this, fn); } else { fn.apply(this); } }); } function getConfig() { var _b; return (_b = inject(STORE_CONFIG, { self: true, optional: true })) !== null && _b !== void 0 ? _b : inject(ROOT_CONFIG); } function provideValue(provide, useValue) { return { provide, useValue }; } function setup(target, factory, ...args) { var _b; const instance = factory(...args); const prototype = target.prototype; const parent = inject(INJECTOR); const storeInjector = createEnvironmentInjector([ provideValue(Changes, new Changes(instance)), provideValue(ErrorHandler, new StoreErrorHandler(prototype, instance)), provideValue(EventScheduler, new EventScheduler(instance)), Teardown ], parent); let storeConfig = getConfig(); setMeta(injector, storeInjector, instance); for (const action of getActions(prototype)) { const actionInjector = createEnvironmentInjector([ provideValue(ACTION, action), provideValue(CONTEXT, { instance }), EffectScheduler, Teardown, (_b = storeConfig === null || storeConfig === void 0 ? void 0 : storeConfig.actionProviders) !== null && _b !== void 0 ? _b : [] ], storeInjector); setMeta(injector, actionInjector, instance, action.key); } return instance; } const stores = new Set(); const decorated = new WeakSet(); function decorateFactory(target, fn, ...additionalArgs) { const factory = target["ɵfac"]; if (factory) { Object.defineProperty(target, "ɵfac", { configurable: true, value: function (...args) { return fn(target, factory, ...additionalArgs, ...args); } }); } } function runInContext(deps, fn, context = {}, catchError = true, key, ...args) { const injector = getToken(EnvironmentInjector, untrack(context), key); const errorHandler = injector.get(ErrorHandler); pushStack(deps); try { return injector.runInContext(() => fn.apply(context, args)); } catch (e) { if (catchError) { errorHandler.handleError(e); } else { throw e; } } finally { popStack(); } } function runAction(fn, key, deps, args) { const event = inject(EventScheduler); event.schedule(EventType.Dispatch, key, args.length === 1 ? args[0] : args, getChanges(deps)); return fn.apply(this, args); } function decorateActions(target) { for (const { key, catchError } of getActions(target)) { wrap(target, key, function (fn, ...args) { const proxy = createProxy(this); const deps = new Map(); setMeta(tracked, deps, this, key); teardown(this, key); return runInContext(deps, runAction, proxy, catchError, key, fn, key, deps, args); }); } } function decorateSelect(target) { var _b; var _a; (_b = (_a = target.prototype).ngOnSelect) !== null && _b !== void 0 ? _b : (_a.ngOnSelect = function (observer) { return store(target).subscribe(observer); }); } function decorateSelectors(target) { for (const { key } of getSelectors(target, true)) { wrap(target, key, function (fn, ...args) { const cacheKey = key + JSON.stringify(args); const proxy = createProxy(this); const deps = getDeps(this, cacheKey); const dirty = deps ? checkDeps(deps) : true; let result = getMeta(cacheKey, this, key); if (dirty) { const newDeps = new Map(); result = runInContext(newDeps, fn, proxy, true, void 0, ...args); setMeta(cacheKey, result, this, key); setMeta(tracked, newDeps, this, cacheKey); } return result; }); } } function decorateChanges(target) { wrap(target, "ngOnChanges", function (fn, value) { const events = getToken(EventScheduler, this); const changes = Object.entries(value).map(([key, change]) => [key, change.previousValue]); events.schedule(EventType.Dispatch, "ngOnChanges", Object.assign({}, value), new Map([[this, new Map(changes)]])); fn.call(this, value); }); } function decorateOnInit(target) { wrap(target, "ngOnInit", function (fn) { const injector = getToken(EnvironmentInjector, this); for (const attachment of getSelectors(target, false)) { injector.runInContext(() => { subscribe(attachment.token, this, attachment.key); }); } fn.call(this); }); } function decorateDestroy(target) { wrap(target, "ngOnDestroy", function (fn) { for (const environmentInjector of getMetaValues(injector, this)) { environmentInjector.destroy(); } fn.apply(this); }); } function teardown(context, key) { var _b; (_b = getToken(Teardown, context, key)) === null || _b === void 0 ? void 0 : _b.unsubscribe(); } const observers = [EventType.Next, EventType.Error, EventType.Complete, "finalize"]; function callObserver(fn, applyThis, value) { fn.call(applyThis, value); } function dispatch(source, observerOrOptions = {}, options = observerOrOptions) { var _a; const action = inject(ACTION); const context = inject(CONTEXT).instance; const applyThis = observerOrOptions && !isPlainObject(observerOrOptions) ? observerOrOptions : context; const errorHandler = inject(ErrorHandler); const event = inject(EventScheduler); const effect = inject(EffectScheduler); const changeDetector = inject(ChangeDetectorRef); const signal = new Subject(); const zone = options.zone === "noop" ? Zone.root : (_a = options.zone) !== null && _a !== void 0 ? _a : Zone.current; const observer = typeof observerOrOptions === "function" ? { next: observerOrOptions } : Object.assign({}, observerOrOptions); for (const key of observers) { wrap(observer, key, function (fn, value) { const isAction = key !== "finalize"; try { if (!changeDetector.destroyed) { const deps = new Map(); isAction && event.schedule(key, action.key, value, getChanges(deps)); changeDetector.markForCheck(); runInContext(deps, callObserver, context, false, action.key, fn, applyThis, value); } } finally { if (isAction) { signal[key](value); } else { signal.complete(); } } }); } effect.enqueue(observeInZone(source.pipe(tap(observer), catchError(e => { zone.runGuarded(() => errorHandler.handleError(e)); return EMPTY; })), zone)); return signal; } class TemplateProvider extends ReplaySubject { constructor() { var _a; super(1); this._firstValue = false; const style = (_a = inject(ElementRef).nativeElement) === null || _a === void 0 ? void 0 : _a.style; if (style) style.display = "contents"; } set __value(value) { this._firstValue = true; this.next(value); } ngOnInit() { if (!this._firstValue) { this.next(this.value); } } subscribe(observer) { return super.subscribe(observer); } } TemplateProvider.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: TemplateProvider, deps: [], target: i0.ɵɵFactoryTarget.Directive }); TemplateProvider.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "15.0.0", type: TemplateProvider, inputs: { __value: ["value", "__value"] }, usesInheritance: true, ngImport: i0 }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: TemplateProvider, decorators: [{ type: Directive }], ctorParameters: function () { return []; }, propDecorators: { __value: [{ type: Input, args: ["value"] }] } }); function loadEffect(load) { return function (...args) { const injector = inject(EnvironmentInjector); const effect = inject(EffectScheduler); const promise = load().then((mod) => { return injector.runInContext(() => { return mod.default(...args); }); }); effect.addPending(promise); return new Observable(subscriber => { promise .then(source => { subscriber.add(source.subscribe(subscriber)); }) .catch(e => { subscriber.error(e); }); return subscriber; }); }; } /// <reference path="../../../node_modules/zone.js/zone.d.ts" /> function handleError(transition) { if (transition.failed) { transition.onError.next(transition.thrownError); } else if (transition.resetOnSuccess) { transition.retryCount = 0; } } function checkStable({ transition, microtasks, macroTasks, parentZone, timeout }) { const { isUnstable } = transition; const { slowMs, timeoutMs, slow, isSlow } = transition; if (!microtasks && !macroTasks && !transition.stable) { clearTimeout(timeout.timeoutId); clearTimeout(timeout.slowId); parentZone.run(() => { handleError(transition); if (slow) { isSlow.next(false); } isUnstable.next(false); }); } if ((microtasks || macroTasks) && transition.stable) { if (transition.failed) { transition.retryCount++; } transition.failed = false; transition.timeout = false; transition.thrownError = null; parentZone.run(() => { isUnstable.next(true); if (slowMs) { timeout.slowId = setTimeout(() => { transition.isSlow.next(true); }, slowMs); } if (timeoutMs) { timeout.timeoutId = setTimeout(() => { transition.failed = true; transition.timeout = true; transition.thrownError = new Error(`Transition timed out after ${timeoutMs}ms`); transition.cancel(); }, timeoutMs); } }); } } let id = 0; class TransitionSpec { constructor(name, transition) { this.name = name; this.transition = transition; this.microtasks = 0; this.macroTasks = 0; this.parentZone = Zone.current; this.tasks = new Set(); this.timeout = {}; this.properties = { id: id++ }; } onScheduleTask(parentZoneDelegate, currentZone, targetZone, task) { this.tasks.add(task); return parentZoneDelegate.scheduleTask(targetZone, task); } onInvokeTask(parentZoneDelegate, currentZone, targetZone, task, applyThis, applyArgs) { this.tasks.delete(task); return parentZoneDelegate.invokeTask(targetZone, task, applyThis, applyArgs); } onCancelTask(parentZoneDelegate, currentZone, targetZone, task) { this.tasks.delete(task); return parentZoneDelegate.cancelTask(targetZone, task); } onHasTask(parentZoneDelegate, currentZone, targetZone, hasTaskState) { if (currentZone === targetZone) { if (hasTaskState.change === "microTask") { this.microtasks += hasTaskState.microTask ? 1 : -1; checkStable(this); } else if (hasTaskState.change === "macroTask") { this.macroTasks += hasTaskState.macroTask ? 1 : -1; checkStable(this); } } return parentZoneDelegate.hasTask(targetZone, hasTaskState); } onHandleError(parentZoneDelegate, currentZone, targetZone, error) { this.transition.failed = true; this.transition.thrownError = error; return parentZoneDelegate.handleError(targetZone, error); } cancelTasks() { for (const task of this.tasks) { task.zone.cancelTask(task); } } } class Transition { constructor(options = {}) { var _a, _b, _c; this.options = options; this.spec = new TransitionSpec("transition", this); this.isUnstable = new BehaviorSubject(false); this.isSlow = new BehaviorSubject(false); this.onError = new Subject(); this.timeout = false; this.failed = false; this.retryCount = 0; this.thrownError = null; this.emitter = new EventEmitter(options.async); this.slowMs = (_a = options.slowMs) !== null && _a !== void 0 ? _a : 0; this.timeoutMs = (_b = options.timeoutMs) !== null && _b !== void 0 ? _b : 0; this.resetOnSuccess = (_c = options.resetOnSuccess) !== null && _c !== void 0 ? _c : false; } get stable() { return !this.unstable; } get unstable() { return this.isUnstable.value; } get slow() { return this.isSlow.value; } next(value) { this.run(this.emitter.next, this.emitter, value); } error(error) { this.run(this.emitter.error, this.emitter, error); } complete() { this.run(this.emitter.complete, this.emitter); } emit(value) { this.run(this.emitter.emit, this.emitter, value); return this.isUnstable.pipe(takeWhile(Boolean)); } cancel() { this.spec.cancelTasks(); } subscribe(observer) { return this.emitter.subscribe(observer); } run(fn, applyThis, ...applyArgs) { if (Zone.current.get("id") === this.spec.properties.id) { return fn.apply(this, applyArgs); } else { const zone = Zone.current.fork(this.spec); if (this.options.cancelPrevious) { this.cancel(); } return zone.runGuarded(fn, applyThis, applyArgs); } } ngOnSelect(observer) { return merge(this.isUnstable, this.isSlow).pipe(map(() => this)).subscribe(observer); } } function useTransition(transition, options = { emit: false }) { return source => transition ? new Observable(subscriber => { return transition.run(() => { if (options.emit) { subscriber.add(transition.subscribe(subscriber)); } subscriber.add(source.subscribe(subscriber)); return subscriber; }); }) : source; } const TransitionToken = class TransitionToken extends InjectionToken { constructor(name, options) { super(name, { factory() { return new Transition(options); } }); } }; const defaults = { track: true, immediate: true }; function createDecorator(symbol, defaults) { return function decorate(options) { return function (target, key, descriptor) { setMeta(symbol, Object.assign(Object.assign(Object.assign({}, defaults), options), { key, descriptor }), target, key); }; }; } function Store() { return function (target) { const { prototype } = target; decorateFactory(target, setup); decorateChanges(prototype); decorateOnInit(prototype); decorateDestroy(prototype); decorateCheck(prototype, "ngDoCheck" /* Phase.DoCheck */); decorateCheck(prototype, "ngAfterContentChecked" /* Phase.AfterContentChecked */); decorateCheck(prototype, "ngAfterViewChecked" /* Phase.AfterViewChecked */); decorateActions(prototype); decorateSelectors(prototype); decorateSelect(target); }; } const Action = createDecorator(action$1, { phase: "ngDoCheck" /* Phase.DoCheck */ }); const Invoke = createDecorator(action$1, Object.assign(Object.assign({}, defaults), { phase: "ngDoCheck" /* Phase.DoCheck */ })); const Before = createDecorator(action$1, Object.assign(Object.assign({}, defaults), { phase: "ngAfterContentChecked" /* Phase.AfterContentChecked */ })); const Layout = createDecorator(action$1, Object.assign(Object.assign({}, defaults), { phase: "ngAfterViewChecked" /* Phase.AfterViewChecked */ })); function Caught() { return function (target, key, descriptor) { setMeta(action$1, { key, descriptor, phase: "ngDoCheck" /* Phase.DoCheck */, catchError: false }, target, key); setMeta(caught, { key, descriptor }, target, key); }; } function Select(token) { return function (target, key, descriptor) { setMeta(selector, { key, token, descriptor }, target, key); }; } function onVisible(document, refCount) { return toggle(refCount, fromEvent(document, "visibilitychange").pipe(filter(() => document.visibilityState === "visible"))); } function onReconnect(document, refCount) { const window = document.defaultView; if (window) { return toggle(refCount, fromEvent(window, "online")); } else { return EMPTY; } } function toggle(refCount, source) { const delay = refCount.pipe(filter((count) => count > 0)); const resume = of(null); return source.pipe(debounce(() => refCount.value > 0 ? resume : delay)); } class ResourceManager { constructor() { this.cache = new Map(); this.document = inject(DOCUMENT); } query(source, options) { const key = this.keygen(options.key); const { cache, document } = this; if (cache.has(key)) { const { resource, fetch, errors } = cache.get(key); if (options.refreshIfStale !== false) { fetch.next(source); } return merge(resource, errors); } const cancel = new Subject(); const invalidate = new Subject(); const fetch = new BehaviorSubject(source); const refCount = new BehaviorSubject(0); const invalidators = [fetch]; if (options.refreshOnFocus) { invalidators.push(onVisible(document, refCount)); } if (options.refreshOnReconnect) { invalidators.push(onReconnect(document, refCount)); } if (options.refreshInterval) { const nativeInterval = observeInZone(interval(options.refreshInterval), Zone.root); invalidators.push(toggle(refCount, nativeInterval)); } const errors = new Subject(); const reload = merge(...invalidators).pipe(switchMap(() => fetch.pipe(takeUntil(cancel))), takeUntil(cancel), throttle(() => { var _a; return observeInZone(timer((_a = options.staleTime) !== null && _a !== void 0 ? _a : 0), Zone.root); })); const resource = invalidate.pipe(startWith(null), switchMap(() => reload), switchAll(), retry({ resetOnSuccess: true, delay: (error, retryCount) => { fetch.next(void 0); errors.error(new QueryError(error, retryCount)); return resource; } }), share({ connector: () => { var _a; return new ReplaySubject(1, (_a = options.cacheTime) !== null && _a !== void 0 ? _a : Infinity); }, resetOnError: false, resetOnComplete: false, resetOnRefCountZero: false }), tap({ subscribe: () => refCount.next(refCount.value + 1), unsubscribe: () => refCount.next(refCount.value - 1) })); cache.set(key, { resource, errors, fetch, cancel, invalidate, source, options }); return merge(resource, errors); } mutate(source, options) { const keys = options.invalidate ? Array.isArray(options.invalidate[0]) ? options.invalidate.map(this.keygen) : [this.keygen(options.invalidate)] : []; for (const key of keys) { this.invalidate(key, true); } return source.pipe(finalize(() => { for (const key of keys) { this.invalidate(key, false); } })); } revalidate(key) { this.invalidate(this.keygen(key), true); this.invalidate(this.keygen(key), false); } keygen(seed) { return JSON.stringify(seed); } invalidate(key, doCancel) { for (const [matchKey, { invalidate, cancel }] of this.cache) { if (matchKey.startsWith(key.slice(0, key.length - 2))) { if (doCancel) { cancel.next(); } else { invalidate.next(); } } } } } ResourceManager.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResourceManager, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); ResourceManager.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResourceManager, providedIn: "root" }); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.0.0", ngImport: i0, type: ResourceManager, decorators: [{ type: Injectable, args: [{ providedIn: "root" }] }] }); function useQuery(options) { var _a; const resource = (_a = options.resource) !== null && _a !== void 0 ? _a : inject(ResourceManager); return source => resource.query(source, options); } function useMutation(options) { var _a; const resource = (_a = options.resource) !== null && _a !== void 0 ? _a : inject(ResourceManager); return source => resource.mutate(source, options); } class QueryError { constructor(error, retryCount) { this.error = error; this.retryCount = retryCount; } } // noinspection JSUnusedGlobalSymbols /** * Generated bundle index. Do not edit. */ export { track as $, untrack as $$, ACTION, Action, Before, Caught, EVENTS, EventType, Invoke, Layout, QueryError, ResourceManager, Select, Selector, Store, TemplateProvider, Transition, TransitionToken, action, actionEvent, addTeardown, complete, completeEvent, configureStore, dispatch, error, errorEvent, events, get, inputs, isTracked, loadEffect, next, nextEvent, set, slice, store, track, untrack, useConcat, useExhaust, useInputs, useMerge, useMutation, useOperator, useQuery, useSwitch, useTransition, withState, decorateFactory as ɵɵdecorateFactory, stores as ɵɵstores }; //# sourceMappingURL=antischematic-angular-state-library.mjs.map //# sourceMappingURL=antischematic-angular-state-library.mjs.map