@ng-atomic/core 19.0.0-preview.8 → 19.1.0

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.
@@ -1,129 +1,144 @@
1
1
  import * as i0 from '@angular/core';
2
- import { InjectionToken, Injector, runInInjectionContext, inject, Injectable, EventEmitter, isSignal, computed, Pipe, PLATFORM_ID, ViewContainerRef, DestroyRef, ElementRef, input, reflectComponentType, Output, Directive, ApplicationRef } from '@angular/core';
2
+ import { Injectable, InjectionToken, Injector, runInInjectionContext, inject, EventEmitter, isSignal, computed, Pipe, PLATFORM_ID, ViewContainerRef, DestroyRef, ElementRef, input, output, reflectComponentType, Directive, ApplicationRef } from '@angular/core';
3
+ import { merge } from 'lodash-es';
4
+ import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
3
5
  import Ajv from 'ajv';
4
6
  import { plainToInstance } from 'class-transformer';
5
7
  import { validateSync } from 'class-validator';
6
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
7
8
  import { isPlatformBrowser } from '@angular/common';
8
9
  import { SIGNAL } from '@angular/core/primitives/signals';
9
10
  import { isObservable, lastValueFrom } from 'rxjs';
10
11
  import { ActivatedRoute } from '@angular/router';
11
12
 
12
- class EffectMap extends Map {
13
- get(key, scope = 'host') {
14
- return super.get(this.makeKey(key, scope));
15
- }
16
- set(key, value) {
17
- return super.set(this.makeKey(key, value.props.scope), value);
13
+ class NgAtomicActionLogger {
14
+ log(action, scope = 'default') {
15
+ console.info(`[NgAtomicActionLogger] ${action?.name}`, { action, scope });
18
16
  }
19
- has(key, scope = 'host') {
20
- return super.has(this.makeKey(key, scope));
17
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicActionLogger, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
18
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicActionLogger, providedIn: 'root' });
19
+ }
20
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicActionLogger, decorators: [{
21
+ type: Injectable,
22
+ args: [{ providedIn: 'root' }]
23
+ }] });
24
+
25
+ const DEFAULT_EFFECT_PROPS = {
26
+ dispatch: false,
27
+ scopes: ['host'],
28
+ accessor: (action) => action.payload,
29
+ };
30
+ function normalizeEffectProps(props = {}) {
31
+ // If props has 'scope' but not 'scopes', convert scope to scopes array
32
+ const propsWithScopes = { ...props };
33
+ if ('scope' in props && !('scopes' in props)) {
34
+ propsWithScopes.scopes = props.scope ? [props.scope] : undefined;
35
+ delete propsWithScopes.scope;
21
36
  }
22
- makeKey(key, scope = 'host') {
23
- return `[${scope}]#${key}`;
37
+ const normalizedProps = merge({ ...DEFAULT_EFFECT_PROPS }, propsWithScopes);
38
+ // Ensure scopes is always an array
39
+ if (!normalizedProps.scopes || normalizedProps.scopes.length === 0) {
40
+ normalizedProps.scopes = ['host'];
24
41
  }
25
- }
26
- function Effect(id, { dispatch = false, scope = 'host', accessor = (action) => action.payload, } = {}) {
27
- return function (target, propertyKey, descriptor) {
28
- target['_effectMap'] ??= new EffectMap();
29
- target['_effectMap'].set(id, { key: propertyKey, props: { dispatch, scope, accessor } });
30
- };
42
+ return normalizedProps;
31
43
  }
32
44
  const EFFECT_ENTRY = new InjectionToken('[@ng-atomic/core] EFFECT_ENTRY');
33
- function provideEffect(ActionIds, _effectFactory, options = { dispatch: false }) {
45
+ function provideEffectEntryMulti(useFactory) {
34
46
  return {
35
47
  provide: EFFECT_ENTRY,
36
- useFactory: (injector) => {
37
- return {
38
- actionIds: ActionIds,
39
- effectFactory: (hostInjector) => {
40
- return runInInjectionContext(hostInjector, () => {
41
- return _effectFactory(injector);
42
- });
43
- },
44
- options
45
- };
46
- },
48
+ useFactory,
47
49
  multi: true,
48
- deps: [Injector]
50
+ deps: [Injector],
49
51
  };
50
52
  }
51
- function injectEffectReducer(injector = inject(Injector)) {
52
- const effectEntries = injector.get(EFFECT_ENTRY, [], { optional: true });
53
- const effectEntryMap = new Map();
54
- for (const entry of effectEntries) {
55
- const ids = Array.isArray(entry.actionIds) ? entry.actionIds : [entry.actionIds];
56
- for (const id of ids) {
57
- const effectFactory = () => entry.effectFactory(injector);
58
- effectEntryMap.set(id, { effectFactory, options: entry.options });
53
+ function provideEffect(ActionIds, _effectFactory, props) {
54
+ return provideEffectEntryMulti((factoryInjector) => ({
55
+ actionIds: ActionIds,
56
+ effectFactory: (host) => runInInjectionContext(host, () => _effectFactory(factoryInjector)),
57
+ props: normalizeEffectProps(props),
58
+ }));
59
+ }
60
+ function injectEffectEntries(injector = inject(Injector)) {
61
+ return injector.get(EFFECT_ENTRY, [], { optional: true }).map((entry) => ({
62
+ ...entry, context: { hostInjector: injector, scope: null }
63
+ }));
64
+ }
65
+ const EFFECT_ENTRIES_KEY = Symbol('_effectEntries_');
66
+ function getEffectEntries(target) {
67
+ return target[EFFECT_ENTRIES_KEY] ??= [];
68
+ }
69
+ function Effect(actionId, props = {}) {
70
+ const normalizedProps = normalizeEffectProps(props);
71
+ return function (target, _, descriptor) {
72
+ getEffectEntries(target).push({
73
+ actionIds: [actionId],
74
+ props: normalizedProps,
75
+ effectFactory: () => (payload, context) => descriptor.value.call(context.component, payload),
76
+ context: { hostInjector: Injector.NULL }
77
+ });
78
+ };
79
+ }
80
+ class EffectResolver {
81
+ effectEntryMap = new Map();
82
+ register(effectEntry) {
83
+ const actionIds = Array.isArray(effectEntry.actionIds) ? effectEntry.actionIds : [effectEntry.actionIds];
84
+ for (const actionId of actionIds) {
85
+ for (const scope of effectEntry.props.scopes) {
86
+ const key = this.makeKey(actionId, scope);
87
+ this.effectEntryMap.set(key, {
88
+ effectFactory: () => effectEntry.effectFactory(effectEntry.context.hostInjector),
89
+ props: effectEntry.props,
90
+ });
91
+ }
59
92
  }
60
93
  }
61
- return async (action, hostInjector) => {
62
- const entry = effectEntryMap.get(action.id);
63
- if (entry) {
64
- await runInInjectionContext(hostInjector, () => {
65
- const effect = entry?.effectFactory();
66
- return effect(action.payload, { injector });
67
- });
68
- return { dispatch: false };
69
- }
70
- return { dispatch: true };
71
- };
94
+ registerMany(entries) {
95
+ for (const entry of entries)
96
+ this.register(entry);
97
+ }
98
+ resolve(actionId, scope = 'host') {
99
+ return this.effectEntryMap.get(this.makeKey(actionId, scope));
100
+ }
101
+ makeKey(actionId, scope = 'host') {
102
+ return `[${scope}]#${actionId}`;
103
+ }
72
104
  }
73
-
74
- class NgAtomicActionLogger {
75
- log(action, scope = 'default') {
76
- console.info(`[NgAtomicActionLogger] ${action?.name}`, { action, scope });
105
+ async function applyEffect(resolver, action, context) {
106
+ const entry = resolver.resolve(action.id, context.scope);
107
+ if (entry?.effectFactory) {
108
+ const effect = entry.effectFactory();
109
+ const payload = entry.props.accessor(action);
110
+ await effect(payload, context);
111
+ return { dispatch: entry.props.dispatch };
77
112
  }
78
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicActionLogger, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
79
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicActionLogger, providedIn: 'root' });
113
+ return { dispatch: true };
80
114
  }
81
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicActionLogger, decorators: [{
82
- type: Injectable,
83
- args: [{ providedIn: 'root' }]
84
- }] });
115
+
85
116
  class NgAtomicRootActionStore {
86
117
  logger = inject(NgAtomicActionLogger);
87
- _actions$ = new EventEmitter();
88
- actions$ = this._actions$.asObservable();
118
+ actions$ = new EventEmitter();
119
+ resolver = new EffectResolver();
89
120
  constructor() {
90
- this.actions$.subscribe(action => this.logger.log(action, 'root'));
121
+ this.actions$.pipe(takeUntilDestroyed()).subscribe(action => {
122
+ this.logger.log(action, 'root');
123
+ applyEffect(this.resolver, action, { component: null, scope: 'root' });
124
+ });
91
125
  }
92
- dispatch(action) {
93
- this._actions$.emit(action);
126
+ async dispatch(action) {
127
+ this.actions$.emit(action);
94
128
  }
95
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicRootActionStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
96
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicRootActionStore, providedIn: 'root' });
97
- }
98
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicRootActionStore, decorators: [{
99
- type: Injectable,
100
- args: [{ providedIn: 'root' }]
101
- }], ctorParameters: () => [] });
102
- class NgAtomicInjectorActionStore {
103
- logger = inject(NgAtomicActionLogger);
104
- #rootActionStore = inject(NgAtomicRootActionStore);
105
- async dispatch(injector, action, hostInjector = injector) {
106
- const _action = { ...action, meta: { injector } };
107
- this.logger.log(_action, 'injector');
108
- const reducer = injectEffectReducer(injector);
109
- const effect = await reducer(_action, hostInjector);
110
- if (effect.dispatch) {
111
- const injector_ = injector.get(Injector, null, { skipSelf: true });
112
- if (injector_ && injector_ !== Injector.NULL) {
113
- await this.dispatch(injector_, _action, hostInjector);
114
- }
115
- else {
116
- await this.#rootActionStore.dispatch(_action);
117
- }
118
- }
129
+ register(effectEntry) {
130
+ this.resolver.register(effectEntry);
119
131
  }
120
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicInjectorActionStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
121
- static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicInjectorActionStore, providedIn: 'root' });
132
+ registerMany(effectEntries) {
133
+ this.resolver.registerMany(effectEntries);
134
+ }
135
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicRootActionStore, deps: [], target: i0.ɵɵFactoryTarget.Injectable });
136
+ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicRootActionStore, providedIn: 'root' });
122
137
  }
123
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicInjectorActionStore, decorators: [{
138
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicRootActionStore, decorators: [{
124
139
  type: Injectable,
125
140
  args: [{ providedIn: 'root' }]
126
- }] });
141
+ }], ctorParameters: () => [] });
127
142
 
128
143
  function resolveActions(actions, ...args) {
129
144
  if (typeof actions === 'function') {
@@ -178,6 +193,12 @@ function proxyFakeComputedInputValueFn(inputValueFn) {
178
193
  function computeFake(valueOrFakeComputed) {
179
194
  return isFakeComputed(valueOrFakeComputed) ? valueOrFakeComputed() : valueOrFakeComputed;
180
195
  }
196
+ function isSignalOrFakeComputed(value) {
197
+ return isSignal(value) || isFakeComputed(value);
198
+ }
199
+ function computeFakeV2(valueOrFakeComputed) {
200
+ return isSignalOrFakeComputed(valueOrFakeComputed) ? computeFakeV2(valueOrFakeComputed()) : valueOrFakeComputed;
201
+ }
181
202
  function proxyFakeComputedInputs(target, inputs) {
182
203
  inputs.filter(input => isSignal(target[input])).forEach(input => {
183
204
  target[input] = proxyFakeComputedInputValueFn(target[input]);
@@ -215,10 +236,10 @@ class CallPipe {
215
236
  transform(value) {
216
237
  return call(value);
217
238
  }
218
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: CallPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
219
- static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "19.1.4", ngImport: i0, type: CallPipe, isStandalone: true, name: "call" });
239
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: CallPipe, deps: [], target: i0.ɵɵFactoryTarget.Pipe });
240
+ static ɵpipe = i0.ɵɵngDeclarePipe({ minVersion: "14.0.0", version: "20.0.5", ngImport: i0, type: CallPipe, isStandalone: true, name: "call" });
220
241
  }
221
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: CallPipe, decorators: [{
242
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: CallPipe, decorators: [{
222
243
  type: Pipe,
223
244
  args: [{ name: 'call', standalone: true, pure: true }]
224
245
  }] });
@@ -235,6 +256,9 @@ function provideComponent(abstract, typeOrFactory) {
235
256
  }
236
257
  return { provide: abstract[TOKEN], useValue: loadComponentType };
237
258
  }
259
+ function makeProvideComopnentConfigure(abstract) {
260
+ return (typeOrFactory) => provideComponent(abstract, typeOrFactory);
261
+ }
238
262
  function TokenizedType() {
239
263
  return function (type) {
240
264
  type[TOKEN] = new InjectionToken(type.name);
@@ -281,11 +305,8 @@ class InjectableComponent {
281
305
  #component = null;
282
306
  #componentMirror = null;
283
307
  injectable = input(false, { transform: (value) => value === '' ? true : value });
284
- // readonly __action = ɵoutput<Action>({alias: 'action'});
285
- __action = new EventEmitter();
286
- dispatch(action) {
287
- this.__action.emit(action);
288
- }
308
+ // TOTO: 消すと一部のActionEffectが動かなくなる。おそらくバインディングの問題。
309
+ __action = output({ alias: 'action' });
289
310
  get #inputs() {
290
311
  return getInputs(this.constructor);
291
312
  }
@@ -319,12 +340,24 @@ class InjectableComponent {
319
340
  get propNames() {
320
341
  return this.#inputs.map(input => input.propName);
321
342
  }
343
+ get injected() {
344
+ return this.#component?.instance ?? null;
345
+ }
322
346
  proxyFakeComputedInputs() {
323
347
  proxyFakeComputedInputs(this, this.propNames);
324
348
  }
325
349
  #bindOutputs() {
326
350
  for (const output of this.#outputs) {
327
- this.#component.instance[output.propName]?.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((value) => this[output.propName].emit(value));
351
+ const outputFn = this.#component.instance?.[output.propName];
352
+ if (!outputFn) {
353
+ continue;
354
+ }
355
+ else if (outputFn instanceof EventEmitter) {
356
+ outputFn.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe((value) => this[output.propName].emit(value));
357
+ }
358
+ else {
359
+ outputFn.subscribe((value) => this[output.propName].emit(value));
360
+ }
328
361
  }
329
362
  }
330
363
  #bindEvents() {
@@ -373,19 +406,16 @@ class InjectableComponent {
373
406
  }
374
407
  }
375
408
  }
376
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InjectableComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
377
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.1.4", type: InjectableComponent, isStandalone: true, inputs: { injectable: { classPropertyName: "injectable", publicName: "injectable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { __action: "action" }, usesOnChanges: true, ngImport: i0 });
409
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: InjectableComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
410
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.5", type: InjectableComponent, isStandalone: true, inputs: { injectable: { classPropertyName: "injectable", publicName: "injectable", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { __action: "action" }, usesOnChanges: true, ngImport: i0 });
378
411
  }
379
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: InjectableComponent, decorators: [{
412
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: InjectableComponent, decorators: [{
380
413
  type: Directive,
381
414
  args: [{
382
415
  standalone: true,
383
416
  // host: {ngSkipHydration: 'true'}
384
417
  }]
385
- }], ctorParameters: () => [], propDecorators: { __action: [{
386
- type: Output,
387
- args: ['action']
388
- }] } });
418
+ }], ctorParameters: () => [] });
389
419
 
390
420
  function applyValueToInputField(instance, inputSignalNode, privateName, value) {
391
421
  if (inputSignalNode !== null) {
@@ -418,7 +448,11 @@ function updateInput(instance, propName, updater) {
418
448
  async function wrapLoadChildren(loadChildrenCallback) {
419
449
  const children = await loadChildrenCallback();
420
450
  const _children = isObservable(children) ? await lastValueFrom(children) : children;
421
- const __children = 'default' in _children ? _children.default : _children;
451
+ const __children = 'default' in _children
452
+ ? _children.default
453
+ : 'routes' in _children
454
+ ? _children.routes
455
+ : _children;
422
456
  return __children;
423
457
  }
424
458
  function recursiveWrapRoute(route, ...wrappers) {
@@ -500,73 +534,101 @@ class DebugDirective {
500
534
  this.el.nativeElement.style.outlineOffset = '-1px';
501
535
  this.el.nativeElement.style.position = 'relative';
502
536
  }
503
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: DebugDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
504
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "19.1.4", type: DebugDirective, isStandalone: true, selector: "debug", inputs: { isDebug: { classPropertyName: "isDebug", publicName: "isDebug", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
537
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DebugDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
538
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "20.0.5", type: DebugDirective, isStandalone: true, selector: "debug", inputs: { isDebug: { classPropertyName: "isDebug", publicName: "isDebug", isSignal: true, isRequired: false, transformFunction: null }, label: { classPropertyName: "label", publicName: "label", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0 });
505
539
  }
506
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: DebugDirective, decorators: [{
540
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: DebugDirective, decorators: [{
507
541
  type: Directive,
508
542
  args: [{ standalone: true, selector: 'debug' }]
509
543
  }] });
510
544
 
511
- function injectIsRouteComponent(component) {
512
- const route = inject(ActivatedRoute);
513
- const currentComponent = route.snapshot.component;
514
- return currentComponent === component.constructor;
545
+ class NgAtomicHostActionStore {
546
+ logger = inject(NgAtomicActionLogger);
547
+ root = inject(NgAtomicRootActionStore);
548
+ appRef = inject(ApplicationRef);
549
+ route = inject(ActivatedRoute);
550
+ injector = inject(Injector);
551
+ async dispatch(action, context) {
552
+ this.logger.log(action, context.scope);
553
+ if (context.scope === 'root') {
554
+ return this.root.dispatch(action);
555
+ }
556
+ const resolver = new EffectResolver();
557
+ const entries = [...getEffectEntries(context?.component), ...injectEffectEntries(this.injector)];
558
+ resolver.registerMany(entries);
559
+ const result = await applyEffect(resolver, action, context);
560
+ if (!result.dispatch)
561
+ return;
562
+ if (this.isBootstrapOrRouteComponent(context)) {
563
+ return this.dispatchToParentInjector(action, context);
564
+ }
565
+ else {
566
+ return context.component.__action.emit(action);
567
+ }
568
+ }
569
+ async dispatchToParentInjector(action, context, injector = this.injector) {
570
+ this.logger.log(action, 'injector');
571
+ const parentInjector = injector.get(Injector, null, { skipSelf: true });
572
+ if (parentInjector && parentInjector !== Injector.NULL) {
573
+ const effectEntries = injectEffectEntries(parentInjector);
574
+ const resolver = new EffectResolver();
575
+ resolver.registerMany(effectEntries);
576
+ const result = await applyEffect(resolver, action, context);
577
+ if (result.dispatch) {
578
+ await this.dispatchToParentInjector(action, context, parentInjector);
579
+ }
580
+ }
581
+ else {
582
+ await this.root.dispatch(action);
583
+ }
584
+ }
585
+ isBootstrapOrRouteComponent(context) {
586
+ return this.isBootstrapComponent(context) || this.isRouteComponent(context);
587
+ }
588
+ isRouteComponent(context) {
589
+ return this.route.snapshot.component === context.component.constructor;
590
+ }
591
+ isBootstrapComponent(context) {
592
+ return this.appRef.components.some(component => component.instance === context.component);
593
+ }
594
+ registerRootEffectEntries(component) {
595
+ const entries = [...getEffectEntries(component), ...injectEffectEntries(this.injector)]
596
+ .filter(entry => entry.props.scopes.includes('root'));
597
+ this.root.registerMany(entries);
598
+ }
599
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicHostActionStore, deps: [], target: i0.ɵɵFactoryTarget.Directive });
600
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.5", type: NgAtomicHostActionStore, isStandalone: true, ngImport: i0 });
515
601
  }
602
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicHostActionStore, decorators: [{
603
+ type: Directive,
604
+ args: [{ standalone: true }]
605
+ }] });
516
606
  class NgAtomicComponent extends InjectableComponent {
517
- #rootActionStore = inject(NgAtomicRootActionStore);
518
- #injectorActionStore = inject(NgAtomicInjectorActionStore);
519
- #destroyRef = inject(DestroyRef);
520
- #el = inject(ElementRef);
521
- #injector = inject(Injector);
522
- #logger = inject(NgAtomicActionLogger);
523
- #isRouteComponent = injectIsRouteComponent(this);
524
- #appRef = inject(ApplicationRef);
607
+ actionStore = inject(NgAtomicHostActionStore);
608
+ logger = inject(NgAtomicActionLogger);
525
609
  __injector = inject(Injector);
610
+ __action = output({ alias: 'action' });
611
+ #el = inject(ElementRef);
526
612
  get selector() {
527
613
  return this.#el.nativeElement.tagName.toLowerCase();
528
614
  }
529
- get #isBootstrapComponent() {
530
- return this.#appRef.components.some(component => component.instance === this);
531
- }
532
615
  constructor() {
533
616
  super();
534
- this.#rootActionStore.actions$.pipe(takeUntilDestroyed(this.#destroyRef)).subscribe(action => this.effect(action, 'root'));
535
- }
536
- async dispatch(action, scope = 'host', componentId = null) {
537
- const _action = { ...action, meta: { componentId, selector: this.selector } };
538
- this.#logger.log(_action, scope);
539
- const dispatch = await this.effect(_action, scope);
540
- if (dispatch) {
541
- if (scope === 'root') {
542
- return this.#rootActionStore.dispatch(_action);
543
- }
544
- else if (this.#isRouteComponent || this.#isBootstrapComponent) {
545
- return this.#injectorActionStore.dispatch(this.#injector, _action);
546
- }
547
- else {
548
- return super.dispatch(_action);
549
- }
550
- }
617
+ this.actionStore.registerRootEffectEntries(this);
551
618
  }
552
- async effect(action, scope = 'host') {
553
- // MEMO(@nontangent): _effectMapをpropertyに持つとEffectが機能しなくなる
554
- const effectMap = (this['_effectMap'] ?? new EffectMap());
555
- const effect = effectMap.get(action.id, scope);
556
- if (effect?.key && effect?.props?.scope === scope) {
557
- await this[effect.key](effect.props.accessor(action));
558
- return !!effect?.props?.dispatch;
559
- }
560
- return true;
619
+ async dispatch(action_, scope = 'host', componentId = null) {
620
+ const action = { ...action_, meta: { componentId, selector: this.selector } };
621
+ return this.actionStore.dispatch(action, { component: this, scope });
561
622
  }
562
- static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
563
- static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "19.1.4", type: NgAtomicComponent, isStandalone: true, usesInheritance: true, hostDirectives: [{ directive: DebugDirective }], ngImport: i0 });
623
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicComponent, deps: [], target: i0.ɵɵFactoryTarget.Directive });
624
+ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "20.0.5", type: NgAtomicComponent, isStandalone: true, outputs: { __action: "action" }, usesInheritance: true, hostDirectives: [{ directive: NgAtomicHostActionStore }, { directive: DebugDirective }], ngImport: i0 });
564
625
  }
565
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImport: i0, type: NgAtomicComponent, decorators: [{
626
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.0.5", ngImport: i0, type: NgAtomicComponent, decorators: [{
566
627
  type: Directive,
567
628
  args: [{
568
629
  standalone: true,
569
630
  hostDirectives: [
631
+ NgAtomicHostActionStore,
570
632
  DebugDirective,
571
633
  ],
572
634
  }]
@@ -576,5 +638,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.1.4", ngImpor
576
638
  * Generated bundle index. Do not edit.
577
639
  */
578
640
 
579
- export { CallPipe, DebugDirective, EFFECT_ENTRY, Effect, EffectMap, FAKE_COMPUTED, HostType, InjectableComponent, NG_ATOMIC_DEBUG, NgAtomicActionLogger, NgAtomicComponent, NgAtomicInjectorActionStore, NgAtomicRootActionStore, TOKEN, TokenizedType, _computed, applyToInput, compute, computeFake, createAction, fakeComputed, getInputs, getInputsByComponentRef, getMeta, getOutputs, getOutputsByInstance, getToken, injectEffectReducer, isFakeComputed, provideComponent, provideEffect, proxyFakeComputedInputValueFn, proxyFakeComputedInputs, recursiveWrapRoute, recursiveWrapRoutes, resolveActions, updateInput, withNgAtomicDebug, wrapActions, wrapLoadChildren };
641
+ export { CallPipe, DEFAULT_EFFECT_PROPS, DebugDirective, Effect, EffectResolver, FAKE_COMPUTED, HostType, InjectableComponent, NG_ATOMIC_DEBUG, NgAtomicActionLogger, NgAtomicComponent, NgAtomicHostActionStore, NgAtomicRootActionStore, TOKEN, TokenizedType, _computed, applyEffect, applyToInput, compute, computeFake, computeFakeV2, createAction, fakeComputed, getEffectEntries, getInputs, getInputsByComponentRef, getMeta, getOutputs, getOutputsByInstance, getToken, injectEffectEntries, isFakeComputed, isSignalOrFakeComputed, makeProvideComopnentConfigure, normalizeEffectProps, provideComponent, provideEffect, proxyFakeComputedInputValueFn, proxyFakeComputedInputs, recursiveWrapRoute, recursiveWrapRoutes, resolveActions, updateInput, withNgAtomicDebug, wrapActions, wrapLoadChildren };
580
642
  //# sourceMappingURL=ng-atomic-core.mjs.map