@portento/core 0.2.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.
package/dist/index.js ADDED
@@ -0,0 +1,774 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ Component: () => Component,
34
+ Injectable: () => Injectable,
35
+ Router: () => Router,
36
+ resetAll: () => resetAll,
37
+ resetClass: () => resetClass,
38
+ resetScope: () => resetScope
39
+ });
40
+ module.exports = __toCommonJS(index_exports);
41
+
42
+ // src/DependencyManagement.ts
43
+ var import_tsyringe = require("tsyringe");
44
+ var import_mobx = require("mobx");
45
+ var DependencyManagement = class _DependencyManagement {
46
+ constructor() {
47
+ // Single global container for all registrations
48
+ this.container = import_tsyringe.container.createChildContainer();
49
+ // Scope tracking maps: className -> Symbol token
50
+ this.rootScope = /* @__PURE__ */ new Map();
51
+ // Router scopes: routerSelector -> (className -> Symbol token)
52
+ this.routerScopes = /* @__PURE__ */ new Map();
53
+ // Component scopes: componentSelector -> (className -> Symbol token)
54
+ this.componentScopes = /* @__PURE__ */ new Map();
55
+ // Component-to-Router membership tracking
56
+ this.componentToRouter = /* @__PURE__ */ new Map();
57
+ // Store class references for re-registration after reset
58
+ this.rootClasses = /* @__PURE__ */ new Map();
59
+ this.routerClasses = /* @__PURE__ */ new Map();
60
+ this.componentClasses = /* @__PURE__ */ new Map();
61
+ (0, import_mobx.configure)({ useProxies: "always" });
62
+ this.container.register("DependencyManagement", {
63
+ useValue: this
64
+ });
65
+ }
66
+ static getInstance() {
67
+ if (!_DependencyManagement.instance) {
68
+ _DependencyManagement.instance = new _DependencyManagement();
69
+ }
70
+ return _DependencyManagement.instance;
71
+ }
72
+ /**
73
+ * Set the current resolution context (used during component instantiation)
74
+ */
75
+ setContext(selector, routerSelector) {
76
+ this.currentSelector = selector;
77
+ this.currentRouterSelector = routerSelector;
78
+ }
79
+ /**
80
+ * Clear the current resolution context
81
+ */
82
+ clearContext() {
83
+ this.currentSelector = void 0;
84
+ this.currentRouterSelector = void 0;
85
+ }
86
+ /**
87
+ * Get current component selector context
88
+ */
89
+ getCurrentSelector() {
90
+ return this.currentSelector;
91
+ }
92
+ /**
93
+ * Get current router selector context
94
+ */
95
+ getCurrentRouterSelector() {
96
+ return this.currentRouterSelector;
97
+ }
98
+ /**
99
+ * Generate a unique Symbol token for a class in a specific scope
100
+ */
101
+ getToken(className, scope) {
102
+ return /* @__PURE__ */ Symbol.for(`${scope}:${className}`);
103
+ }
104
+ /**
105
+ * Setup and register a provider in the root scope
106
+ */
107
+ setupRootContainer(Entity) {
108
+ const className = Entity.name;
109
+ if (!this.rootScope.has(className)) {
110
+ const scopedToken = this.getToken(className, "root");
111
+ this.rootScope.set(className, scopedToken);
112
+ this.rootClasses.set(className, Entity);
113
+ if (!this.container.isRegistered(scopedToken)) {
114
+ this.container.register(
115
+ scopedToken,
116
+ { useClass: Entity },
117
+ { lifecycle: import_tsyringe.Lifecycle.Singleton }
118
+ );
119
+ }
120
+ }
121
+ }
122
+ /**
123
+ * Get the root container (for backward compatibility)
124
+ */
125
+ getRootContainer() {
126
+ return this.container;
127
+ }
128
+ /**
129
+ * Legacy property accessor for backward compatibility
130
+ */
131
+ get root() {
132
+ return this.container;
133
+ }
134
+ /**
135
+ * Setup and register providers in a component scope
136
+ */
137
+ setupComponentContainer(selector, Providers = []) {
138
+ if (!this.componentScopes.has(selector)) {
139
+ this.componentScopes.set(selector, /* @__PURE__ */ new Map());
140
+ this.componentClasses.set(selector, /* @__PURE__ */ new Map());
141
+ }
142
+ const scopeMap = this.componentScopes.get(selector);
143
+ const classMap = this.componentClasses.get(selector);
144
+ if (!scopeMap || !classMap) {
145
+ throw new Error(
146
+ `Failed to create component scope for selector: ${selector}`
147
+ );
148
+ }
149
+ for (const Provider of Providers) {
150
+ const className = Provider.name;
151
+ if (!scopeMap.has(className)) {
152
+ const scopedToken = this.getToken(
153
+ className,
154
+ `component:${selector}`
155
+ );
156
+ scopeMap.set(className, scopedToken);
157
+ classMap.set(className, Provider);
158
+ if (!this.container.isRegistered(scopedToken)) {
159
+ this.container.register(
160
+ scopedToken,
161
+ { useClass: Provider },
162
+ { lifecycle: import_tsyringe.Lifecycle.Singleton }
163
+ );
164
+ }
165
+ }
166
+ }
167
+ }
168
+ /**
169
+ * Get a component-level container by selector (backward compatibility)
170
+ */
171
+ getComponentContainer(selector) {
172
+ if (!this.componentScopes.has(selector)) {
173
+ return void 0;
174
+ }
175
+ return this.container;
176
+ }
177
+ /**
178
+ * Legacy property accessor for backward compatibility
179
+ */
180
+ get component() {
181
+ const legacyMap = /* @__PURE__ */ new Map();
182
+ for (const selector of this.componentScopes.keys()) {
183
+ legacyMap.set(selector, this.container);
184
+ }
185
+ return legacyMap;
186
+ }
187
+ /**
188
+ * Setup and register providers in a router scope, tracking component membership
189
+ */
190
+ setupRouterContainer(Components, Providers, selector) {
191
+ if (!this.routerScopes.has(selector)) {
192
+ this.routerScopes.set(selector, /* @__PURE__ */ new Map());
193
+ this.routerClasses.set(selector, /* @__PURE__ */ new Map());
194
+ }
195
+ const scopeMap = this.routerScopes.get(selector);
196
+ const classMap = this.routerClasses.get(selector);
197
+ if (!scopeMap || !classMap) {
198
+ throw new Error(
199
+ `Failed to create router scope for selector: ${selector}`
200
+ );
201
+ }
202
+ for (const Component2 of Components) {
203
+ const componentName = typeof Component2 === "string" ? Component2 : Component2.name;
204
+ this.componentToRouter.set(componentName, selector);
205
+ }
206
+ for (const Provider of Providers) {
207
+ const className = Provider.name;
208
+ if (!scopeMap.has(className)) {
209
+ const scopedToken = this.getToken(
210
+ className,
211
+ `router:${selector}`
212
+ );
213
+ scopeMap.set(className, scopedToken);
214
+ classMap.set(className, Provider);
215
+ if (!this.container.isRegistered(scopedToken)) {
216
+ this.container.register(
217
+ scopedToken,
218
+ { useClass: Provider },
219
+ { lifecycle: import_tsyringe.Lifecycle.Singleton }
220
+ );
221
+ }
222
+ }
223
+ }
224
+ }
225
+ /**
226
+ * Get the router selector for a component (if registered in a router)
227
+ */
228
+ getRouterForComponent(componentName) {
229
+ return this.componentToRouter.get(componentName);
230
+ }
231
+ /**
232
+ * Fetch a provider from the router container associated with an entity (backward compatibility)
233
+ */
234
+ fetchFromRouterContainer(Entity) {
235
+ const routerSelector = this.getRouterForComponent(
236
+ Entity.name
237
+ );
238
+ if (routerSelector && this.routerScopes.has(routerSelector)) {
239
+ return this.container;
240
+ }
241
+ return void 0;
242
+ }
243
+ /**
244
+ * Get a router-level container by selector (backward compatibility)
245
+ */
246
+ getRouterContainer(selector) {
247
+ if (!this.routerScopes.has(selector)) {
248
+ return void 0;
249
+ }
250
+ return this.container;
251
+ }
252
+ /**
253
+ * Legacy property accessor for backward compatibility
254
+ */
255
+ get router() {
256
+ const legacyMap = /* @__PURE__ */ new Map();
257
+ for (const selector of this.routerScopes.keys()) {
258
+ legacyMap.set(selector, this.container);
259
+ }
260
+ return legacyMap;
261
+ }
262
+ /**
263
+ * Check if a class is a MobX store by looking for MobX symbols
264
+ */
265
+ isMobxStore(instance) {
266
+ const mobxSymbol = "mobx-stored-annotations";
267
+ const symbols = Object.getOwnPropertySymbols(instance);
268
+ return symbols.some((s) => s.description === mobxSymbol);
269
+ }
270
+ /**
271
+ * Resolve a dependency with strict scope isolation:
272
+ * 1. Component scope (if component explicitly registered the provider)
273
+ * 2. Router scope (ONLY if component is part of that router's components array)
274
+ * 3. Root scope (for @Injectable({ providedIn: 'root' }) services)
275
+ *
276
+ * Scope override behavior:
277
+ * - If a root service is re-registered at router/component level, that scope gets a NEW instance
278
+ * - Router-scoped services are ONLY accessible to components within that router
279
+ * - Parent components cannot access child router services
280
+ *
281
+ * Returns undefined if no provider is found in accessible scopes
282
+ */
283
+ resolve(className, componentSelector, routerSelector, componentClassName) {
284
+ if (className === "DependencyManagement") {
285
+ return this.container.resolve("DependencyManagement");
286
+ }
287
+ if (componentSelector) {
288
+ const componentScope = this.componentScopes.get(componentSelector);
289
+ const componentToken = componentScope?.get(className);
290
+ if (componentToken && this.container.isRegistered(componentToken)) {
291
+ return this.container.resolve(componentToken);
292
+ }
293
+ }
294
+ if (routerSelector) {
295
+ const routerScope = this.routerScopes.get(routerSelector);
296
+ const routerToken = routerScope?.get(className);
297
+ if (routerToken && this.container.isRegistered(routerToken)) {
298
+ return this.container.resolve(routerToken);
299
+ }
300
+ }
301
+ const parentRouterSelector = componentClassName ? this.getRouterForComponent(componentClassName) : void 0;
302
+ if (parentRouterSelector && parentRouterSelector !== routerSelector) {
303
+ const parentRouterScope = this.routerScopes.get(parentRouterSelector);
304
+ const parentRouterToken = parentRouterScope?.get(className);
305
+ if (parentRouterToken && this.container.isRegistered(parentRouterToken)) {
306
+ return this.container.resolve(parentRouterToken);
307
+ }
308
+ }
309
+ const rootToken = this.rootScope.get(className);
310
+ if (rootToken && this.container.isRegistered(rootToken)) {
311
+ return this.container.resolve(rootToken);
312
+ }
313
+ return void 0;
314
+ }
315
+ /**
316
+ * Convenience method for resolving dependencies using current context.
317
+ * Use this in component constructors when DependencyManagement is injected.
318
+ *
319
+ * @example
320
+ * constructor(private dm: DependencyManagement) {
321
+ * this.myService = dm.get<MyService>('MyService');
322
+ * }
323
+ */
324
+ get(className) {
325
+ return this.resolve(
326
+ className,
327
+ this.currentSelector,
328
+ this.currentRouterSelector
329
+ );
330
+ }
331
+ /**
332
+ * Resolve a dependency from component, router, or root scope (backward compatibility)
333
+ */
334
+ resolveFromScopes(EntityName, componentContainer, routerContainer) {
335
+ let componentSelector;
336
+ let routerSelector;
337
+ if (componentContainer) {
338
+ for (const [selector, _scopeMap] of this.componentScopes.entries()) {
339
+ componentSelector = selector;
340
+ break;
341
+ }
342
+ }
343
+ if (routerContainer) {
344
+ for (const [selector, _scopeMap] of this.routerScopes.entries()) {
345
+ routerSelector = selector;
346
+ break;
347
+ }
348
+ }
349
+ return this.resolve(EntityName, componentSelector, routerSelector);
350
+ }
351
+ /**
352
+ * Re-register all providers (helper for reset operations)
353
+ */
354
+ reregisterAll() {
355
+ for (const [className, token] of this.rootScope.entries()) {
356
+ const Provider = this.rootClasses.get(className);
357
+ if (Provider) {
358
+ this.container.register(
359
+ token,
360
+ { useClass: Provider },
361
+ { lifecycle: import_tsyringe.Lifecycle.Singleton }
362
+ );
363
+ }
364
+ }
365
+ for (const [selector, routerScope] of this.routerScopes.entries()) {
366
+ const routerClassMap = this.routerClasses.get(selector);
367
+ if (routerClassMap) {
368
+ for (const [className, token] of routerScope.entries()) {
369
+ const Provider = routerClassMap.get(className);
370
+ if (Provider) {
371
+ this.container.register(
372
+ token,
373
+ { useClass: Provider },
374
+ { lifecycle: import_tsyringe.Lifecycle.Singleton }
375
+ );
376
+ }
377
+ }
378
+ }
379
+ }
380
+ for (const [selector, componentScope] of this.componentScopes.entries()) {
381
+ const componentClassMap = this.componentClasses.get(selector);
382
+ if (componentClassMap) {
383
+ for (const [className, token] of componentScope.entries()) {
384
+ const Provider = componentClassMap.get(className);
385
+ if (Provider) {
386
+ this.container.register(
387
+ token,
388
+ { useClass: Provider },
389
+ { lifecycle: import_tsyringe.Lifecycle.Singleton }
390
+ );
391
+ }
392
+ }
393
+ }
394
+ }
395
+ }
396
+ /**
397
+ * Reset all instances in a specific scope
398
+ * Creates fresh container and re-registers all providers
399
+ * Note: Due to tsyringe limitations, this resets ALL scopes but is still useful for cleanup
400
+ */
401
+ resetScope(_scope, _selector) {
402
+ this.container.reset();
403
+ this.container = import_tsyringe.container.createChildContainer();
404
+ this.reregisterAll();
405
+ }
406
+ /**
407
+ * Reset a specific class across all scopes
408
+ * Creates fresh container and re-registers all providers
409
+ * Note: Due to tsyringe limitations, this resets ALL instances
410
+ */
411
+ resetClass(_className) {
412
+ this.container.reset();
413
+ this.container = import_tsyringe.container.createChildContainer();
414
+ this.reregisterAll();
415
+ }
416
+ /**
417
+ * Reset all instances in all scopes
418
+ * This clears all cached singletons but keeps registrations
419
+ */
420
+ resetAll() {
421
+ this.container.clearInstances();
422
+ }
423
+ };
424
+
425
+ // src/decorators/Component.ts
426
+ var import_react = __toESM(require("react"));
427
+ var import_mobx_react = require("mobx-react");
428
+ var import_tsyringe2 = require("tsyringe");
429
+ var componentRegistry = /* @__PURE__ */ new Map();
430
+ var componentReverseRegistry = /* @__PURE__ */ new Map();
431
+ function Component(params) {
432
+ const decorator = function(Entity) {
433
+ (0, import_tsyringe2.injectable)()(Entity);
434
+ class ComponentWrapper extends import_react.default.Component {
435
+ constructor(props) {
436
+ super(props);
437
+ this.entityInstance = null;
438
+ const initialState = {};
439
+ this.state = initialState;
440
+ this.dependencyManagement = DependencyManagement.getInstance();
441
+ this.dependencyManagement.setupComponentContainer(params.selector, [
442
+ ...params.providers || [],
443
+ Entity
444
+ ]);
445
+ const componentContainer = this.dependencyManagement.getComponentContainer(params.selector);
446
+ const routerSelector = this.dependencyManagement.getRouterForComponent(Entity.name);
447
+ const self = this;
448
+ const controller = {
449
+ props,
450
+ get state() {
451
+ return self.state;
452
+ },
453
+ setState: (state) => {
454
+ if (typeof state === "function") {
455
+ this.setState((prevState) => {
456
+ const newState = state(prevState);
457
+ return newState;
458
+ });
459
+ } else {
460
+ this.setState((prevState) => {
461
+ const newState = {
462
+ ...prevState,
463
+ ...state
464
+ };
465
+ return newState;
466
+ });
467
+ }
468
+ },
469
+ forceUpdate: this.forceUpdate.bind(this)
470
+ };
471
+ componentContainer?.register("Controller", { useValue: controller });
472
+ const paramTypes = Reflect.getMetadata(
473
+ "design:paramtypes",
474
+ Entity
475
+ );
476
+ const constructorArgs = [];
477
+ if (paramTypes && paramTypes.length > 0) {
478
+ for (const ParamType of paramTypes) {
479
+ let dependency = this.dependencyManagement.resolve(
480
+ ParamType.name,
481
+ params.selector,
482
+ routerSelector,
483
+ Entity.name
484
+ );
485
+ if (dependency === void 0 && ParamType.name === "Object") {
486
+ dependency = componentContainer?.resolve("Controller");
487
+ }
488
+ constructorArgs.push(dependency);
489
+ }
490
+ }
491
+ this.entityInstance = // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
492
+ new Entity(...constructorArgs) ?? null;
493
+ if (this.entityInstance?.state !== void 0 && this.entityInstance?.state !== null) {
494
+ const entityState = Object.assign(
495
+ {},
496
+ this.entityInstance.state
497
+ );
498
+ Object.assign(this.state, entityState);
499
+ }
500
+ if (this.entityInstance) {
501
+ const prototype = Object.getPrototypeOf(
502
+ this.entityInstance
503
+ );
504
+ Object.getOwnPropertyNames(prototype).forEach((key) => {
505
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, key);
506
+ if (key !== "constructor" && descriptor && typeof descriptor.value === "function") {
507
+ this.entityInstance[key] = descriptor.value.bind(this.entityInstance);
508
+ }
509
+ });
510
+ if ("state" in this.entityInstance) {
511
+ Object.defineProperty(this.entityInstance, "state", {
512
+ get: () => controller.state,
513
+ configurable: true,
514
+ enumerable: true
515
+ });
516
+ }
517
+ }
518
+ }
519
+ componentDidMount() {
520
+ if (this.entityInstance && typeof this.entityInstance.componentDidMount === "function") {
521
+ this.entityInstance.componentDidMount.call(this.entityInstance);
522
+ }
523
+ }
524
+ componentDidUpdate(prevProps, prevState) {
525
+ if (this.entityInstance && typeof this.entityInstance.componentDidUpdate === "function") {
526
+ this.entityInstance.componentDidUpdate.call(
527
+ this.entityInstance,
528
+ prevProps,
529
+ prevState
530
+ );
531
+ }
532
+ }
533
+ componentWillUnmount() {
534
+ if (this.entityInstance && typeof this.entityInstance.componentWillUnmount === "function") {
535
+ this.entityInstance.componentWillUnmount.call(this.entityInstance);
536
+ }
537
+ }
538
+ render() {
539
+ if (!this.entityInstance) {
540
+ return null;
541
+ }
542
+ return this.entityInstance.render.call(this.entityInstance);
543
+ }
544
+ }
545
+ const wrappedComponent = (0, import_mobx_react.observer)(ComponentWrapper);
546
+ const reactComponent = wrappedComponent;
547
+ componentRegistry.set(Entity.name, reactComponent);
548
+ componentReverseRegistry.set(reactComponent, Entity.name);
549
+ return Entity;
550
+ };
551
+ decorator.$provider = (Entity) => {
552
+ const component = componentRegistry.get(Entity.name);
553
+ if (!component) {
554
+ throw new Error(
555
+ `Component ${Entity.name} not found. Make sure to apply @Component decorator first.`
556
+ );
557
+ }
558
+ return component;
559
+ };
560
+ return decorator;
561
+ }
562
+ function getComponentClassName(component) {
563
+ return componentReverseRegistry.get(component);
564
+ }
565
+ Component.$provider = (Entity) => {
566
+ const component = componentRegistry.get(Entity.name);
567
+ if (!component) {
568
+ throw new Error(
569
+ `Component ${Entity.name} not found. Make sure to apply @Component decorator first.`
570
+ );
571
+ }
572
+ return component;
573
+ };
574
+
575
+ // src/decorators/Injectable.ts
576
+ var import_tsyringe3 = require("tsyringe");
577
+ function Injectable(params) {
578
+ return function(Entity) {
579
+ (0, import_tsyringe3.injectable)()(Entity);
580
+ if (params?.providedIn === "root") {
581
+ const dependencyManagement = DependencyManagement.getInstance();
582
+ dependencyManagement.setupRootContainer(Entity);
583
+ }
584
+ return Entity;
585
+ };
586
+ }
587
+
588
+ // src/decorators/Router.ts
589
+ var import_react2 = __toESM(require("react"));
590
+ var import_mobx_react2 = require("mobx-react");
591
+ var import_tsyringe4 = require("tsyringe");
592
+ var routerRegistry = /* @__PURE__ */ new Map();
593
+ var routerReverseRegistry = /* @__PURE__ */ new Map();
594
+ function getRouterClassName(router) {
595
+ return routerReverseRegistry.get(router);
596
+ }
597
+ function Router(params) {
598
+ const decorator = function(Entity) {
599
+ (0, import_tsyringe4.injectable)()(Entity);
600
+ const dependencyManagement = DependencyManagement.getInstance();
601
+ const componentClassNames = params.components.map((comp) => {
602
+ const componentClassName = getComponentClassName(
603
+ comp
604
+ );
605
+ if (componentClassName) {
606
+ return componentClassName;
607
+ }
608
+ const routerClassName = getRouterClassName(
609
+ comp
610
+ );
611
+ if (routerClassName) {
612
+ return routerClassName;
613
+ }
614
+ const classComp = comp;
615
+ return classComp.name || void 0;
616
+ }).filter((name) => name !== void 0);
617
+ dependencyManagement.setupRouterContainer(
618
+ componentClassNames,
619
+ [...params.providers || [], Entity],
620
+ params.selector
621
+ );
622
+ class RouterWrapper extends import_react2.default.Component {
623
+ constructor(props) {
624
+ super(props);
625
+ this.entityInstance = null;
626
+ const initialState = {};
627
+ this.state = initialState;
628
+ this.dependencyManagement = DependencyManagement.getInstance();
629
+ const routerContainerInstance = this.dependencyManagement.getRouterContainer(params.selector);
630
+ const wrapperInstance = this;
631
+ const controller = {
632
+ props,
633
+ get state() {
634
+ return wrapperInstance.state;
635
+ },
636
+ setState: (state) => {
637
+ if (typeof state === "function") {
638
+ this.setState((prevState) => {
639
+ const newState = state(prevState);
640
+ if (this.entityInstance?.state) {
641
+ Object.assign(this.entityInstance.state, newState);
642
+ }
643
+ return newState;
644
+ });
645
+ } else {
646
+ this.setState((prevState) => {
647
+ const newState = {
648
+ ...prevState,
649
+ ...state
650
+ };
651
+ if (this.entityInstance?.state) {
652
+ Object.assign(this.entityInstance.state, newState);
653
+ }
654
+ return newState;
655
+ });
656
+ }
657
+ },
658
+ forceUpdate: this.forceUpdate.bind(this)
659
+ };
660
+ routerContainerInstance?.register("Controller", { useValue: controller });
661
+ const paramTypes = Reflect.getMetadata(
662
+ "design:paramtypes",
663
+ Entity
664
+ );
665
+ const constructorArgs = [];
666
+ if (paramTypes && paramTypes.length > 0) {
667
+ for (const ParamType of paramTypes) {
668
+ let dependency = this.dependencyManagement.resolve(
669
+ ParamType.name,
670
+ void 0,
671
+ // No component selector - this is a router
672
+ params.selector,
673
+ // Own router scope
674
+ Entity.name
675
+ // Pass class name to find parent router if needed
676
+ );
677
+ if (dependency === void 0 && ParamType.name === "Object") {
678
+ dependency = routerContainerInstance?.resolve("Controller");
679
+ }
680
+ constructorArgs.push(dependency);
681
+ }
682
+ }
683
+ this.entityInstance = // eslint-disable-next-line @typescript-eslint/no-unsafe-argument
684
+ new Entity(...constructorArgs) ?? null;
685
+ if (this.entityInstance?.state !== void 0 && this.entityInstance?.state !== null) {
686
+ const entityState = Object.assign(
687
+ {},
688
+ this.entityInstance.state
689
+ );
690
+ Object.assign(this.state, entityState);
691
+ }
692
+ if (this.entityInstance) {
693
+ const prototype = Object.getPrototypeOf(
694
+ this.entityInstance
695
+ );
696
+ Object.getOwnPropertyNames(prototype).forEach((key) => {
697
+ const descriptor = Object.getOwnPropertyDescriptor(prototype, key);
698
+ if (key !== "constructor" && descriptor && typeof descriptor.value === "function") {
699
+ this.entityInstance[key] = descriptor.value.bind(this.entityInstance);
700
+ }
701
+ });
702
+ if ("state" in this.entityInstance) {
703
+ Object.defineProperty(this.entityInstance, "state", {
704
+ get: () => controller.state,
705
+ configurable: true,
706
+ enumerable: true
707
+ });
708
+ }
709
+ }
710
+ }
711
+ componentDidMount() {
712
+ if (this.entityInstance && typeof this.entityInstance.componentDidMount === "function") {
713
+ this.entityInstance.componentDidMount.call(this.entityInstance);
714
+ }
715
+ }
716
+ componentDidUpdate(prevProps, prevState) {
717
+ if (this.entityInstance && typeof this.entityInstance.componentDidUpdate === "function") {
718
+ this.entityInstance.componentDidUpdate.call(
719
+ this.entityInstance,
720
+ prevProps,
721
+ prevState
722
+ );
723
+ }
724
+ }
725
+ componentWillUnmount() {
726
+ if (this.entityInstance && typeof this.entityInstance.componentWillUnmount === "function") {
727
+ this.entityInstance.componentWillUnmount.call(this.entityInstance);
728
+ }
729
+ }
730
+ render() {
731
+ if (!this.entityInstance) {
732
+ return null;
733
+ }
734
+ return this.entityInstance.render.call(this.entityInstance);
735
+ }
736
+ }
737
+ const wrappedComponent = (0, import_mobx_react2.observer)(RouterWrapper);
738
+ const reactComponent = wrappedComponent;
739
+ routerRegistry.set(Entity.name, reactComponent);
740
+ routerReverseRegistry.set(reactComponent, Entity.name);
741
+ return Entity;
742
+ };
743
+ return decorator;
744
+ }
745
+ Router.$provider = (Entity) => {
746
+ const component = routerRegistry.get(Entity.name);
747
+ if (!component) {
748
+ throw new Error(
749
+ `Router ${Entity.name} not found. Make sure to apply @Router decorator first.`
750
+ );
751
+ }
752
+ return component;
753
+ };
754
+
755
+ // src/index.ts
756
+ function resetScope(_scope, _selector) {
757
+ DependencyManagement.getInstance().resetScope(_scope, _selector);
758
+ }
759
+ function resetClass(_className) {
760
+ DependencyManagement.getInstance().resetClass(_className);
761
+ }
762
+ function resetAll() {
763
+ DependencyManagement.getInstance().resetAll();
764
+ }
765
+ // Annotate the CommonJS export names for ESM import in node:
766
+ 0 && (module.exports = {
767
+ Component,
768
+ Injectable,
769
+ Router,
770
+ resetAll,
771
+ resetClass,
772
+ resetScope
773
+ });
774
+ //# sourceMappingURL=index.js.map