@jscutlery/microwave 0.5.5 → 0.5.9

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.
@@ -166,7 +166,7 @@ function applyStrategy(componentType, strategy) {
166
166
  },
167
167
  });
168
168
  }
169
- function _bindComponentToEngine(componentType, { onCreate }) {
169
+ function _bindComponentToEngine(componentType, { onCreate, }) {
170
170
  decorateComponent(componentType, {
171
171
  onCreate(component, changeDetectionFns) {
172
172
  getEngine(component).setChangeDetectionFns(changeDetectionFns);
@@ -1 +1 @@
1
- {"version":3,"file":"jscutlery-microwave.mjs","sources":["../../../../packages/microwave/src/lib/core/engine.ts","../../../../packages/microwave/src/lib/devkit.ts","../../../../packages/microwave/src/lib/shared/decorator.ts","../../../../packages/microwave/src/lib/apply-strategy.ts","../../../../packages/microwave/src/lib/strategies/local.ts","../../../../packages/microwave/src/lib/strategies/sync.ts","../../../../packages/microwave/src/lib/strategies/asap.ts","../../../../packages/microwave/src/lib/strategies/async.ts","../../../../packages/microwave/src/lib/strategies/raf.ts","../../../../packages/microwave/src/lib/microwave.ts","../../../../packages/microwave/src/jscutlery-microwave.ts"],"sourcesContent":["import {\n BehaviorSubject,\n map,\n mapTo,\n Observable,\n ReplaySubject,\n take,\n} from 'rxjs';\nimport { ChangeDetectionFns } from './change-detection-fns';\n\n/**\n * This should stay decoupled from Angular.\n *\n * @param component an instance of anything\n * @returns an set of methods and observables that respectively\n * control and represent the state of the object.\n */\nexport function getEngine<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(\n component: COMPONENT\n): MicrowaveEngine<COMPONENT, K> {\n /* Memoize engine. */\n const microwavedComponent = component as Microwaved<COMPONENT>;\n const engine = microwavedComponent[_ENGINE_SYMBOL];\n if (engine != null) {\n return engine;\n }\n\n const destroyed$ = new ReplaySubject<void>(1);\n const initialized$ = new ReplaySubject<void>(1);\n const state$ = new BehaviorSubject<Partial<COMPONENT>>({});\n let changeDetectionFns: ChangeDetectionFns;\n\n return (microwavedComponent[_ENGINE_SYMBOL] = {\n destroyed$: destroyed$.pipe(take(1)),\n initialized$: initialized$.pipe(take(1)),\n changed$: state$.pipe(mapTo(undefined)),\n detach() {\n changeDetectionFns.detach();\n },\n detectChanges() {\n changeDetectionFns.detectChanges();\n },\n markDestroyed() {\n destroyed$.next();\n },\n markInitialized() {\n initialized$.next();\n },\n setChangeDetectionFns(_changeDetectionFns: ChangeDetectionFns) {\n changeDetectionFns = _changeDetectionFns;\n },\n getProperty(property) {\n return state$.value[property];\n },\n setProperty(property, value) {\n /* Don't set value if it didn't change.\n * This is more performant than `distinctUntilChanged` all over the place. */\n if (state$.value[property] === value) {\n return;\n }\n\n state$.next({ ...state$.value, [property]: value });\n },\n watchProperty(property) {\n return state$.pipe(map((state) => state[property]));\n },\n });\n}\n\nexport const _ENGINE_SYMBOL = Symbol('MicrowaveEngine');\n\nexport type Microwaved<T, K extends keyof T = keyof T> = T & {\n [_ENGINE_SYMBOL]?: MicrowaveEngine<T, K>;\n};\n\nexport interface MicrowaveEngine<T, K extends keyof T> {\n /**\n * Functions below form the strategy facade.\n */\n destroyed$: Observable<void>;\n /* Tells when component is initialized (ngOnInit). */\n initialized$: Observable<void>;\n /* Tells if some property changed. */\n changed$: Observable<void>;\n detach(): void;\n detectChanges(): void;\n\n /**\n * Functions below are used to bind with component.\n */\n setChangeDetectionFns(changeDetectionFns: ChangeDetectionFns): void;\n markDestroyed(): void;\n markInitialized(): void;\n getProperty<PROP extends K>(property: PROP): T[PROP] | undefined;\n setProperty<PROP extends K>(property: PROP, value: T[PROP]): void;\n watchProperty<PROP extends K>(\n property: PROP\n ): Observable<T[PROP] | undefined>;\n}\n\nexport type MicrowaveSubjectsMap<T, K extends keyof T> = Map<\n K,\n BehaviorSubject<T[K]>\n>;\n\nexport function _getPropertySubject<T, K extends keyof T, PROP extends K>(\n subjectsMap: MicrowaveSubjectsMap<T, K>,\n property: PROP\n): BehaviorSubject<T[PROP]> {\n let subject = subjectsMap.get(property);\n\n if (subject == null) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n subject = new BehaviorSubject(undefined as any);\n subjectsMap.set(property, subject);\n }\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return subject as any;\n}\n","import { getEngine, MicrowaveEngine } from './core/engine';\n\nexport function getStrategyDevKit<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(\n component: COMPONENT\n): StrategyDevKit<COMPONENT, K> {\n const { changed$, destroyed$, initialized$, detach, detectChanges } =\n getEngine(component);\n return { changed$, destroyed$, initialized$, detach, detectChanges };\n}\n\nexport type StrategyDevKit<T, K extends keyof T = keyof T> = Pick<\n MicrowaveEngine<T, K>,\n 'changed$' | 'destroyed$' | 'initialized$' | 'detach' | 'detectChanges'\n>;\n\nexport type Strategy<T> = (strategyDevKit: StrategyDevKit<T>) => void;\n","import { ChangeDetectorRef, Type, ɵɵdirectiveInject } from '@angular/core';\nimport { ChangeDetectionFns } from '../core/change-detection-fns';\n\n/**\n * Decorate Angular components with custom hooks.\n *\n * @param componentType the component class to decorate.\n * @param hooks\n */\nexport function decorateComponent<T, K extends keyof T = keyof T>(\n componentType: IvyComponentType<T>,\n hooks: DecoratorHooks<T>\n) {\n const {\n onCreate,\n onInit,\n onDestroy,\n onPropertyDeclare,\n onPropertyGet,\n onPropertySet,\n } = hooks;\n\n if (!componentType.ɵfac) {\n throw new Error(\n `${componentType.name} is either not a component or not compiled.`\n );\n }\n\n /**\n * Override component factory.\n */\n const factory = _decorate(\n componentType.ɵfac,\n /*\n * Override getters & setters.\n */\n (factoryFn: () => T) => () => {\n /* Grab change detector to control it. */\n const cdr = ɵɵdirectiveInject(ChangeDetectorRef);\n\n const component = factoryFn();\n\n /**\n * Notify about creation.\n */\n onCreate(component, {\n detach() {\n cdr.detach();\n },\n detectChanges() {\n cdr.detectChanges();\n },\n });\n\n /**\n * This will only list initialized properties.\n * That's the reason why all properties should be initialized\n * when using Microwave.\n */\n for (const property of Object.getOwnPropertyNames(\n component\n ) as Array<K>) {\n /**\n * Notify when property is discovered.\n */\n onPropertyDeclare(component, property, component[property]);\n\n Object.defineProperty(component, property, {\n set(value) {\n /**\n * Call setter.\n */\n onPropertySet(component, property, value);\n },\n get() {\n /**\n * Call getter.\n */\n return onPropertyGet(component, property);\n },\n });\n }\n\n return component;\n }\n );\n\n /**\n * Override factory with the newly decorated one.\n */\n Object.defineProperty(componentType, 'ɵfac', {\n get() {\n return factory;\n },\n });\n\n /**\n * Link hooks.\n */\n _spyOnMethod(componentType, 'ngOnInit', onInit);\n _spyOnMethod(componentType, 'ngOnDestroy', onDestroy);\n}\n\nexport interface DecoratorHooks<T, K extends keyof T = keyof T> {\n /**\n * Hook called when a new component is created.\n *\n * @param component the created component.\n * @param args change detection functions for controlling change detection.\n */\n onCreate(component: T, args: ChangeDetectionFns): void;\n\n /**\n * Hook called when a new component is initialized.\n *\n * @param component the created component.\n */\n onInit(component: T): void;\n\n /**\n * Hook called just before the real ngOnDestroy (if implemented) is called.\n */\n onDestroy(component: T): void;\n\n /**\n * Hook called when a property is discovered.\n * This is the opportunity to grab the initial value before\n * the property is replaced by getters and setters.\n */\n onPropertyDeclare(component: T, property: K, value: T[K]): void;\n\n /**\n * Hook called to retrieve a property.\n */\n onPropertyGet(component: T, property: K): T[K] | undefined;\n\n /**\n * Hook called to set a property.\n */\n onPropertySet(component: T, property: K, value: T[K]): void;\n}\n\nexport interface IvyComponentType<T> extends Type<T> {\n ɵfac?: () => T;\n}\n\nexport function _spyOnMethod<T>(\n klass: Type<T>,\n methodName: string,\n callback: (instance: T) => void\n) {\n const proto = klass.prototype;\n proto[methodName] = _decorate(\n proto[methodName],\n (wrappedMethod: () => void) => {\n return function (this: T) {\n callback(this);\n return wrappedMethod?.bind(this)?.();\n };\n }\n );\n}\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function _decorate<F extends (...args: any[]) => any>(\n fn: F,\n decorator: (fn: F) => F\n) {\n return decorator(fn);\n}\n","import { getEngine } from './core/engine';\nimport { getStrategyDevKit, Strategy } from './devkit';\nimport { decorateComponent, IvyComponentType } from './shared/decorator';\n\nexport function applyStrategy<T>(\n componentType: IvyComponentType<T>,\n strategy: Strategy<T>\n) {\n _bindComponentToEngine(componentType, {\n onCreate(component) {\n strategy(getStrategyDevKit(component));\n },\n });\n}\n\nexport function _bindComponentToEngine<T>(\n componentType: IvyComponentType<T>,\n { onCreate }: { onCreate: (component: T) => void }\n) {\n decorateComponent(componentType, {\n onCreate(component, changeDetectionFns) {\n getEngine(component).setChangeDetectionFns(changeDetectionFns);\n onCreate(component);\n },\n onInit(component) {\n getEngine(component).markInitialized();\n },\n onDestroy(component) {\n getEngine(component).markDestroyed();\n },\n onPropertyDeclare(component, property, value) {\n getEngine(component).setProperty(property, value);\n },\n onPropertyGet(component, property) {\n return getEngine(component).getProperty(property);\n },\n onPropertySet(component, property, value) {\n getEngine(component).setProperty(property, value);\n },\n });\n}\n","import { concat, MonoTypeOperatorFunction, takeUntil } from 'rxjs';\nimport { Strategy } from '../devkit';\n\n/**\n * Creates a change detection strategy which is local to the component.\n * It implements optional coalescing which can be customized using `coalescer` parameter.\n *\n * @example createLocalStrategy()\n * @example createLocalStrategy({coalescer: audit(() => Promise.resolve())})\n *\n * @returns a strategy that can be used with Microwave decorator.\n */\nexport const createLocalStrategy =\n ({\n coalescer,\n }: { coalescer?: MonoTypeOperatorFunction<void> } = {}): Strategy<unknown> =>\n ({ initialized$, changed$, destroyed$, detach, detectChanges }) => {\n /**\n * Detach change detection as we want to take control.\n */\n detach();\n\n /**\n * Trigger change detection initially and on property changes.\n * Coalesce through micro-tasks.\n */\n let source$ = concat(initialized$, changed$);\n\n if (coalescer != null) {\n source$ = source$.pipe(coalescer);\n }\n\n source$.pipe(takeUntil(destroyed$)).subscribe(() => detectChanges());\n };\n","import { createLocalStrategy } from './local';\nimport { Strategy } from '../devkit';\n\nexport const syncStrategy: Strategy<unknown> = createLocalStrategy();\n","import { audit } from 'rxjs';\nimport { Strategy } from '../devkit';\nimport { createLocalStrategy } from './local';\n\n/**\n * A strategy that coalesces changes using microtask scheduling.\n */\nexport const asapStrategy: Strategy<unknown> = createLocalStrategy({\n coalescer: audit(() => Promise.resolve()),\n});\n","import { audit, timer } from 'rxjs';\nimport { Strategy } from '../devkit';\nimport { createLocalStrategy } from './local';\n\n/**\n * A strategy that coalesces changes using macrotask scheduling.\n */\nexport const asyncStrategy: Strategy<unknown> = createLocalStrategy({\n coalescer: audit(() => timer(0)),\n});\n","import { audit, animationFrames } from 'rxjs';\nimport { Strategy } from '../devkit';\nimport { createLocalStrategy } from './local';\n\n/**\n * A strategy that coalesces changes using requestAnimationFrame scheduler.\n */\nexport const rafStrategy: Strategy<unknown> = createLocalStrategy({\n coalescer: audit(() => animationFrames()),\n});\n","import { Observable, takeUntil } from 'rxjs';\nimport { applyStrategy } from './apply-strategy';\nimport { getEngine } from './core/engine';\nimport { IvyComponentType } from './shared/decorator';\nimport { asapStrategy } from './strategies';\n\nexport function Microwave({ strategy = asapStrategy } = {}) {\n return function MicrowaveDecorator<T>(componentType: IvyComponentType<T>) {\n applyStrategy(componentType, strategy);\n };\n}\n\nexport function watch<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(\n component: COMPONENT,\n property: K\n): Observable<COMPONENT[K] | undefined> {\n const { destroyed$, watchProperty } = getEngine(component);\n return watchProperty(property).pipe(takeUntil(destroyed$));\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵɵdirectiveInject"],"mappings":"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"}
1
+ {"version":3,"file":"jscutlery-microwave.mjs","sources":["../../../../packages/microwave/src/lib/core/engine.ts","../../../../packages/microwave/src/lib/devkit.ts","../../../../packages/microwave/src/lib/shared/decorator.ts","../../../../packages/microwave/src/lib/apply-strategy.ts","../../../../packages/microwave/src/lib/strategies/local.ts","../../../../packages/microwave/src/lib/strategies/sync.ts","../../../../packages/microwave/src/lib/strategies/asap.ts","../../../../packages/microwave/src/lib/strategies/async.ts","../../../../packages/microwave/src/lib/strategies/raf.ts","../../../../packages/microwave/src/lib/microwave.ts","../../../../packages/microwave/src/jscutlery-microwave.ts"],"sourcesContent":["import {\n BehaviorSubject,\n map,\n mapTo,\n Observable,\n ReplaySubject,\n take,\n} from 'rxjs';\nimport { ChangeDetectionFns } from './change-detection-fns';\n/**\n * This should stay decoupled from Angular.\n *\n * @param component an instance of anything\n * @returns an set of methods and observables that respectively\n * control and represent the state of the object.\n */\nexport function getEngine<\n COMPONENT,\n K extends keyof COMPONENT = keyof COMPONENT,\n>(component: COMPONENT): MicrowaveEngine<COMPONENT, K> {\n /* Memoize engine. */\n const microwavedComponent = component as Microwaved<COMPONENT>;\n const engine = microwavedComponent[_ENGINE_SYMBOL];\n if (engine != null) {\n return engine;\n }\n const destroyed$ = new ReplaySubject<void>(1);\n const initialized$ = new ReplaySubject<void>(1);\n const state$ = new BehaviorSubject<Partial<COMPONENT>>({});\n let changeDetectionFns: ChangeDetectionFns;\n return (microwavedComponent[_ENGINE_SYMBOL] = {\n destroyed$: destroyed$.pipe(take(1)),\n initialized$: initialized$.pipe(take(1)),\n changed$: state$.pipe(mapTo(undefined)),\n detach() {\n changeDetectionFns.detach();\n },\n detectChanges() {\n changeDetectionFns.detectChanges();\n },\n markDestroyed() {\n destroyed$.next();\n },\n markInitialized() {\n initialized$.next();\n },\n setChangeDetectionFns(_changeDetectionFns: ChangeDetectionFns) {\n changeDetectionFns = _changeDetectionFns;\n },\n getProperty(property) {\n return state$.value[property];\n },\n setProperty(property, value) {\n /* Don't set value if it didn't change.\n * This is more performant than `distinctUntilChanged` all over the place. */\n if (state$.value[property] === value) {\n return;\n }\n state$.next({ ...state$.value, [property]: value });\n },\n watchProperty(property) {\n return state$.pipe(map((state) => state[property]));\n },\n });\n}\nexport const _ENGINE_SYMBOL = Symbol('MicrowaveEngine');\nexport type Microwaved<T, K extends keyof T = keyof T> = T & {\n [_ENGINE_SYMBOL]?: MicrowaveEngine<T, K>;\n};\nexport interface MicrowaveEngine<T, K extends keyof T> {\n /**\n * Functions below form the strategy facade.\n */\n destroyed$: Observable<void>;\n /* Tells when component is initialized (ngOnInit). */\n initialized$: Observable<void>;\n /* Tells if some property changed. */\n changed$: Observable<void>;\n detach(): void;\n detectChanges(): void;\n /**\n * Functions below are used to bind with component.\n */\n setChangeDetectionFns(changeDetectionFns: ChangeDetectionFns): void;\n markDestroyed(): void;\n markInitialized(): void;\n getProperty<PROP extends K>(property: PROP): T[PROP] | undefined;\n setProperty<PROP extends K>(property: PROP, value: T[PROP]): void;\n watchProperty<PROP extends K>(\n property: PROP,\n ): Observable<T[PROP] | undefined>;\n}\nexport type MicrowaveSubjectsMap<T, K extends keyof T> = Map<\n K,\n BehaviorSubject<T[K]>\n>;\nexport function _getPropertySubject<T, K extends keyof T, PROP extends K>(\n subjectsMap: MicrowaveSubjectsMap<T, K>,\n property: PROP,\n): BehaviorSubject<T[PROP]> {\n let subject = subjectsMap.get(property);\n if (subject == null) {\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n subject = new BehaviorSubject(undefined as any);\n subjectsMap.set(property, subject);\n }\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n return subject as any;\n}\n","import { getEngine, MicrowaveEngine } from './core/engine';\nexport function getStrategyDevKit<\n COMPONENT,\n K extends keyof COMPONENT = keyof COMPONENT,\n>(component: COMPONENT): StrategyDevKit<COMPONENT, K> {\n const { changed$, destroyed$, initialized$, detach, detectChanges } =\n getEngine(component);\n return { changed$, destroyed$, initialized$, detach, detectChanges };\n}\nexport type StrategyDevKit<T, K extends keyof T = keyof T> = Pick<\n MicrowaveEngine<T, K>,\n 'changed$' | 'destroyed$' | 'initialized$' | 'detach' | 'detectChanges'\n>;\nexport type Strategy<T> = (strategyDevKit: StrategyDevKit<T>) => void;\n","import { ChangeDetectorRef, Type, ɵɵdirectiveInject } from '@angular/core';\nimport { ChangeDetectionFns } from '../core/change-detection-fns';\n/**\n * Decorate Angular components with custom hooks.\n *\n * @param componentType the component class to decorate.\n * @param hooks\n */\nexport function decorateComponent<T, K extends keyof T = keyof T>(\n componentType: IvyComponentType<T>,\n hooks: DecoratorHooks<T>,\n) {\n const {\n onCreate,\n onInit,\n onDestroy,\n onPropertyDeclare,\n onPropertyGet,\n onPropertySet,\n } = hooks;\n if (!componentType.ɵfac) {\n throw new Error(\n `${componentType.name} is either not a component or not compiled.`,\n );\n }\n /**\n * Override component factory.\n */\n const factory = _decorate(\n componentType.ɵfac,\n /*\n * Override getters & setters.\n */\n (factoryFn: () => T) => () => {\n /* Grab change detector to control it. */\n const cdr = ɵɵdirectiveInject(ChangeDetectorRef);\n const component = factoryFn();\n /**\n * Notify about creation.\n */\n onCreate(component, {\n detach() {\n cdr.detach();\n },\n detectChanges() {\n cdr.detectChanges();\n },\n });\n /**\n * This will only list initialized properties.\n * That's the reason why all properties should be initialized\n * when using Microwave.\n */\n for (const property of Object.getOwnPropertyNames(\n component,\n ) as Array<K>) {\n /**\n * Notify when property is discovered.\n */\n onPropertyDeclare(component, property, component[property]);\n Object.defineProperty(component, property, {\n set(value) {\n /**\n * Call setter.\n */\n onPropertySet(component, property, value);\n },\n get() {\n /**\n * Call getter.\n */\n return onPropertyGet(component, property);\n },\n });\n }\n return component;\n },\n );\n /**\n * Override factory with the newly decorated one.\n */\n Object.defineProperty(componentType, 'ɵfac', {\n get() {\n return factory;\n },\n });\n /**\n * Link hooks.\n */\n _spyOnMethod(componentType, 'ngOnInit', onInit);\n _spyOnMethod(componentType, 'ngOnDestroy', onDestroy);\n}\nexport interface DecoratorHooks<T, K extends keyof T = keyof T> {\n /**\n * Hook called when a new component is created.\n *\n * @param component the created component.\n * @param args change detection functions for controlling change detection.\n */\n onCreate(component: T, args: ChangeDetectionFns): void;\n /**\n * Hook called when a new component is initialized.\n *\n * @param component the created component.\n */\n onInit(component: T): void;\n /**\n * Hook called just before the real ngOnDestroy (if implemented) is called.\n */\n onDestroy(component: T): void;\n /**\n * Hook called when a property is discovered.\n * This is the opportunity to grab the initial value before\n * the property is replaced by getters and setters.\n */\n onPropertyDeclare(component: T, property: K, value: T[K]): void;\n /**\n * Hook called to retrieve a property.\n */\n onPropertyGet(component: T, property: K): T[K] | undefined;\n /**\n * Hook called to set a property.\n */\n onPropertySet(component: T, property: K, value: T[K]): void;\n}\nexport interface IvyComponentType<T> extends Type<T> {\n ɵfac?: () => T;\n}\nexport function _spyOnMethod<T>(\n klass: Type<T>,\n methodName: string,\n callback: (instance: T) => void,\n) {\n const proto = klass.prototype;\n proto[methodName] = _decorate(\n proto[methodName],\n (wrappedMethod: () => void) => {\n return function (this: T) {\n callback(this);\n return wrappedMethod?.bind(this)?.();\n };\n },\n );\n}\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport function _decorate<F extends (...args: any[]) => any>(\n fn: F,\n decorator: (fn: F) => F,\n) {\n return decorator(fn);\n}\n","import { getEngine } from './core/engine';\nimport { getStrategyDevKit, Strategy } from './devkit';\nimport { decorateComponent, IvyComponentType } from './shared/decorator';\nexport function applyStrategy<T>(\n componentType: IvyComponentType<T>,\n strategy: Strategy<T>,\n) {\n _bindComponentToEngine(componentType, {\n onCreate(component) {\n strategy(getStrategyDevKit(component));\n },\n });\n}\nexport function _bindComponentToEngine<T>(\n componentType: IvyComponentType<T>,\n {\n onCreate,\n }: {\n onCreate: (component: T) => void;\n },\n) {\n decorateComponent(componentType, {\n onCreate(component, changeDetectionFns) {\n getEngine(component).setChangeDetectionFns(changeDetectionFns);\n onCreate(component);\n },\n onInit(component) {\n getEngine(component).markInitialized();\n },\n onDestroy(component) {\n getEngine(component).markDestroyed();\n },\n onPropertyDeclare(component, property, value) {\n getEngine(component).setProperty(property, value);\n },\n onPropertyGet(component, property) {\n return getEngine(component).getProperty(property);\n },\n onPropertySet(component, property, value) {\n getEngine(component).setProperty(property, value);\n },\n });\n}\n","import { concat, MonoTypeOperatorFunction, takeUntil } from 'rxjs';\nimport { Strategy } from '../devkit';\n/**\n * Creates a change detection strategy which is local to the component.\n * It implements optional coalescing which can be customized using `coalescer` parameter.\n *\n * @example createLocalStrategy()\n * @example createLocalStrategy({coalescer: audit(() => Promise.resolve())})\n *\n * @returns a strategy that can be used with Microwave decorator.\n */\nexport const createLocalStrategy =\n ({\n coalescer,\n }: {\n coalescer?: MonoTypeOperatorFunction<void>;\n } = {}): Strategy<unknown> =>\n ({ initialized$, changed$, destroyed$, detach, detectChanges }) => {\n /**\n * Detach change detection as we want to take control.\n */\n detach();\n /**\n * Trigger change detection initially and on property changes.\n * Coalesce through micro-tasks.\n */\n let source$ = concat(initialized$, changed$);\n if (coalescer != null) {\n source$ = source$.pipe(coalescer);\n }\n source$.pipe(takeUntil(destroyed$)).subscribe(() => detectChanges());\n };\n","import { createLocalStrategy } from './local';\nimport { Strategy } from '../devkit';\nexport const syncStrategy: Strategy<unknown> = createLocalStrategy();\n","import { audit } from 'rxjs';\nimport { Strategy } from '../devkit';\nimport { createLocalStrategy } from './local';\n/**\n * A strategy that coalesces changes using microtask scheduling.\n */\nexport const asapStrategy: Strategy<unknown> = createLocalStrategy({\n coalescer: audit(() => Promise.resolve()),\n});\n","import { audit, timer } from 'rxjs';\nimport { Strategy } from '../devkit';\nimport { createLocalStrategy } from './local';\n/**\n * A strategy that coalesces changes using macrotask scheduling.\n */\nexport const asyncStrategy: Strategy<unknown> = createLocalStrategy({\n coalescer: audit(() => timer(0)),\n});\n","import { audit, animationFrames } from 'rxjs';\nimport { Strategy } from '../devkit';\nimport { createLocalStrategy } from './local';\n/**\n * A strategy that coalesces changes using requestAnimationFrame scheduler.\n */\nexport const rafStrategy: Strategy<unknown> = createLocalStrategy({\n coalescer: audit(() => animationFrames()),\n});\n","import { Observable, takeUntil } from 'rxjs';\nimport { applyStrategy } from './apply-strategy';\nimport { getEngine } from './core/engine';\nimport { IvyComponentType } from './shared/decorator';\nimport { asapStrategy } from './strategies';\nexport function Microwave({ strategy = asapStrategy } = {}) {\n return function MicrowaveDecorator<T>(componentType: IvyComponentType<T>) {\n applyStrategy(componentType, strategy);\n };\n}\nexport function watch<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(\n component: COMPONENT,\n property: K,\n): Observable<COMPONENT[K] | undefined> {\n const { destroyed$, watchProperty } = getEngine(component);\n return watchProperty(property).pipe(takeUntil(destroyed$));\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":["ɵɵdirectiveInject"],"mappings":"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"}
package/package.json CHANGED
@@ -1,19 +1,19 @@
1
1
  {
2
2
  "name": "@jscutlery/microwave",
3
- "version": "0.5.5",
3
+ "version": "0.5.9",
4
4
  "peerDependencies": {
5
- "@angular/common": "^14.0.2",
6
- "@angular/core": "^14.0.2",
5
+ "@angular/common": ">=14.0.0 <22.0.0",
6
+ "@angular/core": ">=14.0.0 <22.0.0",
7
7
  "rxjs": "^7.0.0"
8
8
  },
9
9
  "module": "fesm2022/jscutlery-microwave.mjs",
10
- "typings": "index.d.ts",
10
+ "typings": "types/jscutlery-microwave.d.ts",
11
11
  "exports": {
12
12
  "./package.json": {
13
13
  "default": "./package.json"
14
14
  },
15
15
  ".": {
16
- "types": "./index.d.ts",
16
+ "types": "./types/jscutlery-microwave.d.ts",
17
17
  "default": "./fesm2022/jscutlery-microwave.mjs"
18
18
  }
19
19
  },
@@ -0,0 +1,79 @@
1
+ import { Observable, MonoTypeOperatorFunction } from 'rxjs';
2
+ import * as _jscutlery_microwave from '@jscutlery/microwave';
3
+ import { Type } from '@angular/core';
4
+
5
+ /**
6
+ * An alternative to ChangeDetectorRef to stay loosely coupled.
7
+ * Plus, this functions can be destructured as they don't use `this`.
8
+ * Let's try to reduce the surface and not expose all functions
9
+ * if we don't need them.
10
+ */
11
+ interface ChangeDetectionFns {
12
+ detach(): void;
13
+ detectChanges(): void;
14
+ }
15
+
16
+ interface MicrowaveEngine<T, K extends keyof T> {
17
+ /**
18
+ * Functions below form the strategy facade.
19
+ */
20
+ destroyed$: Observable<void>;
21
+ initialized$: Observable<void>;
22
+ changed$: Observable<void>;
23
+ detach(): void;
24
+ detectChanges(): void;
25
+ /**
26
+ * Functions below are used to bind with component.
27
+ */
28
+ setChangeDetectionFns(changeDetectionFns: ChangeDetectionFns): void;
29
+ markDestroyed(): void;
30
+ markInitialized(): void;
31
+ getProperty<PROP extends K>(property: PROP): T[PROP] | undefined;
32
+ setProperty<PROP extends K>(property: PROP, value: T[PROP]): void;
33
+ watchProperty<PROP extends K>(property: PROP): Observable<T[PROP] | undefined>;
34
+ }
35
+
36
+ type StrategyDevKit<T, K extends keyof T = keyof T> = Pick<MicrowaveEngine<T, K>, 'changed$' | 'destroyed$' | 'initialized$' | 'detach' | 'detectChanges'>;
37
+ type Strategy<T> = (strategyDevKit: StrategyDevKit<T>) => void;
38
+
39
+ interface IvyComponentType<T> extends Type<T> {
40
+ ɵfac?: () => T;
41
+ }
42
+
43
+ declare function Microwave({ strategy }?: {
44
+ strategy?: _jscutlery_microwave.Strategy<unknown> | undefined;
45
+ }): <T>(componentType: IvyComponentType<T>) => void;
46
+ declare function watch<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(component: COMPONENT, property: K): Observable<COMPONENT[K] | undefined>;
47
+
48
+ /**
49
+ * Creates a change detection strategy which is local to the component.
50
+ * It implements optional coalescing which can be customized using `coalescer` parameter.
51
+ *
52
+ * @example createLocalStrategy()
53
+ * @example createLocalStrategy({coalescer: audit(() => Promise.resolve())})
54
+ *
55
+ * @returns a strategy that can be used with Microwave decorator.
56
+ */
57
+ declare const createLocalStrategy: ({ coalescer, }?: {
58
+ coalescer?: MonoTypeOperatorFunction<void>;
59
+ }) => Strategy<unknown>;
60
+
61
+ declare const syncStrategy: Strategy<unknown>;
62
+
63
+ /**
64
+ * A strategy that coalesces changes using microtask scheduling.
65
+ */
66
+ declare const asapStrategy: Strategy<unknown>;
67
+
68
+ /**
69
+ * A strategy that coalesces changes using macrotask scheduling.
70
+ */
71
+ declare const asyncStrategy: Strategy<unknown>;
72
+
73
+ /**
74
+ * A strategy that coalesces changes using requestAnimationFrame scheduler.
75
+ */
76
+ declare const rafStrategy: Strategy<unknown>;
77
+
78
+ export { Microwave, asapStrategy, asyncStrategy, createLocalStrategy, rafStrategy, syncStrategy, watch };
79
+ export type { Strategy, StrategyDevKit };
package/index.d.ts DELETED
@@ -1,3 +0,0 @@
1
- export { Strategy, StrategyDevKit } from './lib/devkit';
2
- export { Microwave, watch } from './lib/microwave';
3
- export { asapStrategy, asyncStrategy, createLocalStrategy, rafStrategy, syncStrategy, } from './lib/strategies';
@@ -1,6 +0,0 @@
1
- import { Strategy } from './devkit';
2
- import { IvyComponentType } from './shared/decorator';
3
- export declare function applyStrategy<T>(componentType: IvyComponentType<T>, strategy: Strategy<T>): void;
4
- export declare function _bindComponentToEngine<T>(componentType: IvyComponentType<T>, { onCreate }: {
5
- onCreate: (component: T) => void;
6
- }): void;
@@ -1,10 +0,0 @@
1
- /**
2
- * An alternative to ChangeDetectorRef to stay loosely coupled.
3
- * Plus, this functions can be destructured as they don't use `this`.
4
- * Let's try to reduce the surface and not expose all functions
5
- * if we don't need them.
6
- */
7
- export interface ChangeDetectionFns {
8
- detach(): void;
9
- detectChanges(): void;
10
- }
@@ -1,35 +0,0 @@
1
- import { BehaviorSubject, Observable } from 'rxjs';
2
- import { ChangeDetectionFns } from './change-detection-fns';
3
- /**
4
- * This should stay decoupled from Angular.
5
- *
6
- * @param component an instance of anything
7
- * @returns an set of methods and observables that respectively
8
- * control and represent the state of the object.
9
- */
10
- export declare function getEngine<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(component: COMPONENT): MicrowaveEngine<COMPONENT, K>;
11
- export declare const _ENGINE_SYMBOL: unique symbol;
12
- export type Microwaved<T, K extends keyof T = keyof T> = T & {
13
- [_ENGINE_SYMBOL]?: MicrowaveEngine<T, K>;
14
- };
15
- export interface MicrowaveEngine<T, K extends keyof T> {
16
- /**
17
- * Functions below form the strategy facade.
18
- */
19
- destroyed$: Observable<void>;
20
- initialized$: Observable<void>;
21
- changed$: Observable<void>;
22
- detach(): void;
23
- detectChanges(): void;
24
- /**
25
- * Functions below are used to bind with component.
26
- */
27
- setChangeDetectionFns(changeDetectionFns: ChangeDetectionFns): void;
28
- markDestroyed(): void;
29
- markInitialized(): void;
30
- getProperty<PROP extends K>(property: PROP): T[PROP] | undefined;
31
- setProperty<PROP extends K>(property: PROP, value: T[PROP]): void;
32
- watchProperty<PROP extends K>(property: PROP): Observable<T[PROP] | undefined>;
33
- }
34
- export type MicrowaveSubjectsMap<T, K extends keyof T> = Map<K, BehaviorSubject<T[K]>>;
35
- export declare function _getPropertySubject<T, K extends keyof T, PROP extends K>(subjectsMap: MicrowaveSubjectsMap<T, K>, property: PROP): BehaviorSubject<T[PROP]>;
package/lib/devkit.d.ts DELETED
@@ -1,4 +0,0 @@
1
- import { MicrowaveEngine } from './core/engine';
2
- export declare function getStrategyDevKit<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(component: COMPONENT): StrategyDevKit<COMPONENT, K>;
3
- export type StrategyDevKit<T, K extends keyof T = keyof T> = Pick<MicrowaveEngine<T, K>, 'changed$' | 'destroyed$' | 'initialized$' | 'detach' | 'detectChanges'>;
4
- export type Strategy<T> = (strategyDevKit: StrategyDevKit<T>) => void;
@@ -1,6 +0,0 @@
1
- import { Observable } from 'rxjs';
2
- import { IvyComponentType } from './shared/decorator';
3
- export declare function Microwave({ strategy }?: {
4
- strategy?: import("@jscutlery/microwave").Strategy<unknown> | undefined;
5
- }): <T>(componentType: IvyComponentType<T>) => void;
6
- export declare function watch<COMPONENT, K extends keyof COMPONENT = keyof COMPONENT>(component: COMPONENT, property: K): Observable<COMPONENT[K] | undefined>;
@@ -1,47 +0,0 @@
1
- import { Type } from '@angular/core';
2
- import { ChangeDetectionFns } from '../core/change-detection-fns';
3
- /**
4
- * Decorate Angular components with custom hooks.
5
- *
6
- * @param componentType the component class to decorate.
7
- * @param hooks
8
- */
9
- export declare function decorateComponent<T, K extends keyof T = keyof T>(componentType: IvyComponentType<T>, hooks: DecoratorHooks<T>): void;
10
- export interface DecoratorHooks<T, K extends keyof T = keyof T> {
11
- /**
12
- * Hook called when a new component is created.
13
- *
14
- * @param component the created component.
15
- * @param args change detection functions for controlling change detection.
16
- */
17
- onCreate(component: T, args: ChangeDetectionFns): void;
18
- /**
19
- * Hook called when a new component is initialized.
20
- *
21
- * @param component the created component.
22
- */
23
- onInit(component: T): void;
24
- /**
25
- * Hook called just before the real ngOnDestroy (if implemented) is called.
26
- */
27
- onDestroy(component: T): void;
28
- /**
29
- * Hook called when a property is discovered.
30
- * This is the opportunity to grab the initial value before
31
- * the property is replaced by getters and setters.
32
- */
33
- onPropertyDeclare(component: T, property: K, value: T[K]): void;
34
- /**
35
- * Hook called to retrieve a property.
36
- */
37
- onPropertyGet(component: T, property: K): T[K] | undefined;
38
- /**
39
- * Hook called to set a property.
40
- */
41
- onPropertySet(component: T, property: K, value: T[K]): void;
42
- }
43
- export interface IvyComponentType<T> extends Type<T> {
44
- ɵfac?: () => T;
45
- }
46
- export declare function _spyOnMethod<T>(klass: Type<T>, methodName: string, callback: (instance: T) => void): void;
47
- export declare function _decorate<F extends (...args: any[]) => any>(fn: F, decorator: (fn: F) => F): F;
@@ -1,5 +0,0 @@
1
- import { Strategy } from '../devkit';
2
- /**
3
- * A strategy that coalesces changes using microtask scheduling.
4
- */
5
- export declare const asapStrategy: Strategy<unknown>;
@@ -1,5 +0,0 @@
1
- import { Strategy } from '../devkit';
2
- /**
3
- * A strategy that coalesces changes using macrotask scheduling.
4
- */
5
- export declare const asyncStrategy: Strategy<unknown>;
@@ -1,5 +0,0 @@
1
- export { createLocalStrategy } from './local';
2
- export { syncStrategy } from './sync';
3
- export { asapStrategy } from './asap';
4
- export { asyncStrategy } from './async';
5
- export { rafStrategy } from './raf';
@@ -1,14 +0,0 @@
1
- import { MonoTypeOperatorFunction } from 'rxjs';
2
- import { Strategy } from '../devkit';
3
- /**
4
- * Creates a change detection strategy which is local to the component.
5
- * It implements optional coalescing which can be customized using `coalescer` parameter.
6
- *
7
- * @example createLocalStrategy()
8
- * @example createLocalStrategy({coalescer: audit(() => Promise.resolve())})
9
- *
10
- * @returns a strategy that can be used with Microwave decorator.
11
- */
12
- export declare const createLocalStrategy: ({ coalescer, }?: {
13
- coalescer?: MonoTypeOperatorFunction<void>;
14
- }) => Strategy<unknown>;
@@ -1,5 +0,0 @@
1
- import { Strategy } from '../devkit';
2
- /**
3
- * A strategy that coalesces changes using requestAnimationFrame scheduler.
4
- */
5
- export declare const rafStrategy: Strategy<unknown>;
@@ -1,2 +0,0 @@
1
- import { Strategy } from '../devkit';
2
- export declare const syncStrategy: Strategy<unknown>;