@antischematic/angular-state-library
Version:
Reactive state without boilerplate
145 lines • 14.6 kB
JavaScript
import { inject, Injectable, InjectionToken } from "@angular/core";
import { Subject, Subscription, switchAll } from "rxjs";
import { getErrorHandlers } from "./metadata";
import { track } from "./proxy";
import { UID } from "./utils";
import * as i0 from "@angular/core";
export const ACTION = new InjectionToken("ACTION");
export const CONTEXT = new InjectionToken("CONTEXT");
export const STORE_CONFIG = new InjectionToken("STORE_CONFIG");
export const ROOT_CONFIG = new InjectionToken("ROOT_CONFIG", {
factory() {
return {};
}
});
export const EVENTS = new InjectionToken("EVENTS", {
factory() {
return new Subject();
}
});
export 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;
}
}
export 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() {
if (!this.connected && !this.closed) {
this.connected = true;
this.subscription = this.source.pipe(this.operator ?? 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
}] });
export 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
}] });
export class Changes {
constructor(target) {
this.target = target;
}
get value() {
return track(this.target.__ngSimpleChanges__?.previous) ?? {};
}
}
export 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;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXJzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vcHJvamVjdHMvY29yZS9zcmMvcHJvdmlkZXJzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBZSxNQUFNLEVBQUUsVUFBVSxFQUFFLGNBQWMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUMvRSxPQUFPLEVBQStCLE9BQU8sRUFBRSxZQUFZLEVBQUUsU0FBUyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRXBGLE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFNLFlBQVksQ0FBQztBQUM1QyxPQUFPLEVBQUMsS0FBSyxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBQzlCLE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBTSxTQUFTLENBQUM7O0FBRTVCLE1BQU0sQ0FBQyxNQUFNLE1BQU0sR0FBRyxJQUFJLGNBQWMsQ0FBaUIsUUFBUSxDQUFDLENBQUE7QUFDbEUsTUFBTSxDQUFDLE1BQU0sT0FBTyxHQUFHLElBQUksY0FBYyxDQUF3QixTQUFTLENBQUMsQ0FBQTtBQUMzRSxNQUFNLENBQUMsTUFBTSxZQUFZLEdBQUcsSUFBSSxjQUFjLENBQWMsY0FBYyxDQUFDLENBQUE7QUFDM0UsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUFHLElBQUksY0FBYyxDQUFjLGFBQWEsRUFBRTtJQUN2RSxPQUFPO1FBQ0osT0FBTyxFQUFFLENBQUE7SUFDWixDQUFDO0NBQ0gsQ0FBQyxDQUFBO0FBQ0YsTUFBTSxDQUFDLE1BQU0sTUFBTSxHQUFHLElBQUksY0FBYyxDQUFDLFFBQVEsRUFBRTtJQUNoRCxPQUFPO1FBQ0osT0FBTyxJQUFJLE9BQU8sRUFBYyxDQUFBO0lBQ25DLENBQUM7Q0FDSCxDQUFDLENBQUE7QUFFRixNQUFNLE9BQU8sY0FBYztJQTZCeEIsWUFBb0IsT0FBVztRQUFYLFlBQU8sR0FBUCxPQUFPLENBQUk7UUE1Qi9CLFdBQU0sR0FBcUMsRUFBRSxDQUFBO1FBQzdDLGVBQVUsR0FB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SUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsS0FBSyxDQUFDLENBQUE7Z0JBQ3JELE1BQUs7YUFDUDtZQUFDLE9BQU8sQ0FBQyxFQUFFO2dCQUNULEtBQUssR0FBRyxDQUFDLENBQUE7YUFDWDtTQUNIO1FBQ0QsTUFBTSxLQUFLLENBQUE7SUFDZCxDQUFDO0NBR0giLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge0Vycm9ySGFuZGxlciwgaW5qZWN0LCBJbmplY3RhYmxlLCBJbmplY3Rpb25Ub2tlbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7T2JzZXJ2YWJsZSwgT3BlcmF0b3JGdW5jdGlvbiwgU3ViamVjdCwgU3Vic2NyaXB0aW9uLCBzd2l0Y2hBbGx9IGZyb20gXCJyeGpzXCI7XG5pbXBvcnQge0FjdGlvbk1ldGFkYXRhLCBFdmVudFR5cGUsIFN0b3JlQ29uZmlnLCBTdG9yZUV2ZW50fSBmcm9tIFwiLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQge2dldEVycm9ySGFuZGxlcnN9IGZyb20gXCIuL21ldGFkYXRhXCI7XG5pbXBvcnQge3RyYWNrfSBmcm9tIFwiLi9wcm94eVwiO1xuaW1wb3J0IHtVSUR9IGZyb20gXCIuL3V0aWxzXCI7XG5cbmV4cG9ydCBjb25zdCBBQ1RJT04gPSBuZXcgSW5qZWN0aW9uVG9rZW48QWN0aW9uTWV0YWRhdGE+KFwiQUNUSU9OXCIpXG5leHBvcnQgY29uc3QgQ09OVEVYVCA9IG5ldyBJbmplY3Rpb25Ub2tlbjx7IGluc3RhbmNlOiB1bmtub3duIH0+KFwiQ09OVEVYVFwiKVxuZXhwb3J0IGNvbnN0IFNUT1JFX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxTdG9yZUNvbmZpZz4oXCJTVE9SRV9DT05GSUdcIilcbmV4cG9ydCBjb25zdCBST09UX0NPTkZJRyA9IG5ldyBJbmplY3Rpb25Ub2tlbjxTdG9yZUNvbmZpZz4oXCJST09UX0NPTkZJR1wiLCB7XG4gICBmYWN0b3J5KCkge1xuICAgICAgcmV0dXJuIHt9XG4gICB9XG59KVxuZXhwb3J0IGNvbnN0IEVWRU5UUyA9IG5ldyBJbmplY3Rpb25Ub2tlbihcIkVWRU5UU1wiLCB7XG4gICBmYWN0b3J5KCkge1xuICAgICAgcmV0dXJuIG5ldyBTdWJqZWN0PFN0b3JlRXZlbnQ+KClcbiAgIH1cbn0pXG5cbmV4cG9ydCBjbGFzcyBFdmVudFNjaGVkdWxlciB7XG4gICBldmVudHM6IFN0b3JlRXZlbnQ8YW55LCBhbnksIGFueSwgYW55PltdID0gW11cbiAgIGRpc3BhdGNoZXIgPSBpbmplY3QoRVZFTlRTKVxuICAgZ2V0SWQgPSBpbmplY3QoVUlEKVxuXG4gICBzY2hlZHVsZSh0eXBlOiBFdmVudFR5cGUsIG5hbWU6IHN0cmluZywgdmFsdWU6IHVua25vd24sIGNoYW5nZXM6IE1hcDxhbnksIGFueT4pIHtcbiAgICAgIHRoaXMuZXZlbnRzLnB1c2goe1xuICAgICAgICAgaWQ6IHRoaXMuZ2V0SWQoKSxcbiAgICAgICAgIHRpbWVzdGFtcDogRGF0ZS5ub3coKSxcbiAgICAgICAgIHR5cGUsXG4gICAgICAgICBjb250ZXh0OiB0aGlzLmNvbnRleHQsXG4gICAgICAgICBuYW1lLFxuICAgICAgICAgdmFsdWUsXG4gICAgICAgICBjaGFuZ2VzXG4gICAgICB9KVxuICAgfVxuXG4gICBmbHVzaCgpIHtcbiAgICAgIGNvbnN0IGV2ZW50cyA9IHRoaXMuZXZlbnRzXG4gICAgICBpZiAoZXZlbnRzLmxlbmd0aCkge1xuICAgICAgICAgbGV0IGV2ZW50XG4gICAgICAgICB0aGlzLmV2ZW50cyA9IFtdXG4gICAgICAgICB3aGlsZSAoZXZlbnQgPSBldmVudHMuc2hpZnQoKSkge1xuICAgICAgICAgICAgdGhpcy5kaXNwYXRjaGVyLm5leHQoZXZlbnQpXG4gICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcy5ldmVudHMubGVuZ3RoID4gMFxuICAgfVxuXG4gICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbnRleHQ6IHt9KSB7fVxufVxuXG5ASW5qZWN0YWJsZSgpXG5leHBvcnQgY2xhc3MgRWZmZWN0U2NoZWR1bGVyIHtcbiAgIHNvdXJjZSA9IG5ldyBTdWJqZWN0PE9ic2VydmFibGU8YW55Pj4oKVxuICAgcXVldWU6IGFueVtdID0gW11cbiAgIG9wZXJhdG9yPzogT3BlcmF0b3JGdW5jdGlvbjxPYnNlcnZhYmxlPGFueT4sIGFueT5cbiAgIGNvbm5lY3RlZCA9IGZhbHNlXG4gICBzdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFlcbiAgIHBlbmRpbmcgPSBuZXcgU2V0XG4gICBjbG9zZWQgPSBmYWxzZVxuXG4gICBuZXh0KHNvdXJjZTogT2JzZXJ2YWJsZTxhbnk+KSB7XG4gICAgICB0aGlzLmNvbm5lY3QoKVxuICAgICAgdGhpcy5zb3VyY2UubmV4dChzb3VyY2UpXG4gICB9XG5cbiAgIGVucXVldWUoc291cmNlOiBPYnNlcnZhYmxlPGFueT4pIHtcbiAgICAgIHRoaXMucXVldWUucHVzaChzb3VyY2UpXG4gICB9XG5cbiAgIGRlcXVldWUoKSB7XG4gICAgICBsZXQgZWZmZWN0OiBhbnlcbiAgICAgIGlmICh0aGlzLnBlbmRpbmcuc2l6ZSA9PT0gMCkge1xuICAgICAgICAgd2hpbGUgKGVmZmVjdCA9IHRoaXMucXVldWUuc2hpZnQoKSkge1xuICAgICAgICAgICAgdGhpcy5uZXh0KGVmZmVjdClcbiAgICAgICAgIH1cbiAgICAgIH1cbiAgIH1cblxuICAgY29ubmVjdCgpIHtcbiAgICAgIGlmICghdGhpcy5jb25uZWN0ZWQgJiYgIXRoaXMuY2xvc2VkKSB7XG4gICAgICAgICB0aGlzLmNvbm5lY3RlZCA9IHRydWVcbiAgICAgICAgIHRoaXMuc3Vic2NyaXB0aW9uID0gdGhpcy5zb3VyY2UucGlwZSh0aGlzLm9wZXJhdG9yID8/IHN3aXRjaEFsbCgpKS5zdWJzY3JpYmUoKVxuICAgICAgICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKCgpID0+IHRoaXMuY29ubmVjdGVkID0gZmFsc2UpXG4gICAgICB9XG4gICB9XG5cbiAgIGFkZFBlbmRpbmcocHJvbWlzZTogUHJvbWlzZTxhbnk+KSB7XG4gICAgICB0aGlzLnBlbmRpbmcuYWRkKHByb21pc2UpXG4gICAgICBwcm9taXNlLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgICAgdGhpcy5wZW5kaW5nLmRlbGV0ZShwcm9taXNlKVxuICAgICAgICAgdGhpcy5kZXF1ZXVlKClcbiAgICAgIH0pXG4gICB9XG5cbiAgIG5nT25EZXN0cm95KCkge1xuICAgICAgdGhpcy5jbG9zZWQgPSB0cnVlXG4gICAgICB0aGlzLnNvdXJjZS5jb21wbGV0ZSgpXG4gICAgICB0aGlzLnN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpXG4gICB9XG59XG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBUZWFyZG93biB7XG4gICBzdWJzY3JpcHRpb25zOiBTdWJzY3JpcHRpb25bXSA9IFtdXG5cbiAgIHVuc3Vic2NyaWJlKCkge1xuICAgICAgbGV0IHN1YnNjcmlwdGlvblxuICAgICAgd2hpbGUgKHN1YnNjcmlwdGlvbiA9IHRoaXMuc3Vic2NyaXB0aW9ucy5zaGlmdCgpKSB7XG4gICAgICAgICBzdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKVxuICAgICAgfVxuICAgfVxuXG4gICBuZ09uRGVzdHJveSgpIHtcbiAgICAgIHRoaXMudW5zdWJzY3JpYmUoKVxuICAgfVxufVxuXG5leHBvcnQgY2xhc3MgQ2hhbmdlcyB7XG4gICBnZXQgdmFsdWUoKSB7XG4gICAgICByZXR1cm4gdHJhY2sodGhpcy50YXJnZXQuX19uZ1NpbXBsZUNoYW5nZXNfXz8ucHJldmlvdXMpID8/IHt9XG4gICB9XG5cbiAgIGNvbnN0cnVjdG9yKHByaXZhdGUgdGFyZ2V0OiBhbnkpIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBTdG9yZUVycm9ySGFuZGxlciBpbXBsZW1lbnRzIEVycm9ySGFuZGxlciB7XG4gICBoYW5kbGVFcnJvcihlcnJvcjogdW5rbm93bikge1xuICAgICAgY29uc3QgZXJyb3JIYW5kbGVycyA9IGdldEVycm9ySGFuZGxlcnModGhpcy5wcm90b3R5cGUpXG4gICAgICBmb3IgKGNvbnN0IGhhbmRsZXIgb2YgZXJyb3JIYW5kbGVycykge1xuICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHRoaXMuaW5zdGFuY2VbaGFuZGxlci5rZXldLmNhbGwodGhpcy5pbnN0YW5jZSwgZXJyb3IpXG4gICAgICAgICAgICBicmVha1xuICAgICAgICAgfSBjYXRjaCAoZSkge1xuICAgICAgICAgICAgZXJyb3IgPSBlXG4gICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvclxuICAgfVxuXG4gICBjb25zdHJ1Y3Rvcihwcml2YXRlIHByb3RvdHlwZTogYW55LCBwcml2YXRlIGluc3RhbmNlOiBhbnkpIHt9XG59XG4iXX0=