@arikajs/foundation 0.0.3 → 0.0.5
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/README.md +25 -23
- package/dist/ObjectPool.d.ts +9 -0
- package/dist/ObjectPool.d.ts.map +1 -0
- package/dist/ObjectPool.js +25 -0
- package/dist/ObjectPool.js.map +1 -0
- package/dist/application/Application.d.ts +47 -15
- package/dist/application/Application.d.ts.map +1 -1
- package/dist/application/Application.js +121 -50
- package/dist/application/Application.js.map +1 -1
- package/dist/container/Container.d.ts +22 -0
- package/dist/container/Container.d.ts.map +1 -1
- package/dist/container/Container.js +60 -7
- package/dist/container/Container.js.map +1 -1
- package/dist/contracts/Application.d.ts +5 -0
- package/dist/contracts/Application.d.ts.map +1 -1
- package/dist/examples/basic.d.ts +3 -0
- package/dist/examples/basic.d.ts.map +1 -0
- package/dist/examples/basic.js +110 -0
- package/dist/examples/basic.js.map +1 -0
- package/dist/index.d.ts +2 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -6
- package/dist/index.js.map +1 -1
- package/dist/src/ObjectPool.d.ts +9 -0
- package/dist/src/ObjectPool.d.ts.map +1 -0
- package/dist/src/ObjectPool.js +25 -0
- package/dist/src/ObjectPool.js.map +1 -0
- package/dist/src/application/Application.d.ts +105 -0
- package/dist/src/application/Application.d.ts.map +1 -0
- package/dist/src/application/Application.js +267 -0
- package/dist/src/application/Application.js.map +1 -0
- package/dist/src/container/Container.d.ts +61 -0
- package/dist/src/container/Container.d.ts.map +1 -0
- package/dist/src/container/Container.js +126 -0
- package/dist/src/container/Container.js.map +1 -0
- package/dist/src/contracts/Application.d.ts +20 -0
- package/dist/src/contracts/Application.d.ts.map +1 -0
- package/dist/src/contracts/Application.js +3 -0
- package/dist/src/contracts/Application.js.map +1 -0
- package/dist/src/contracts/Kernel.d.ts +24 -0
- package/dist/src/contracts/Kernel.d.ts.map +1 -0
- package/dist/src/contracts/Kernel.js +3 -0
- package/dist/src/contracts/Kernel.js.map +1 -0
- package/dist/src/index.d.ts +8 -0
- package/dist/src/index.d.ts.map +1 -0
- package/dist/src/index.js +28 -0
- package/dist/src/index.js.map +1 -0
- package/dist/src/providers/ServiceProvider.d.ts +25 -0
- package/dist/src/providers/ServiceProvider.d.ts.map +1 -0
- package/dist/src/providers/ServiceProvider.js +26 -0
- package/dist/src/providers/ServiceProvider.js.map +1 -0
- package/dist/tests/application.test.d.ts +2 -0
- package/dist/tests/application.test.d.ts.map +1 -0
- package/dist/tests/application.test.js +213 -0
- package/dist/tests/application.test.js.map +1 -0
- package/dist/tests/config.test.d.ts +2 -0
- package/dist/tests/config.test.d.ts.map +1 -0
- package/dist/tests/config.test.js +120 -0
- package/dist/tests/config.test.js.map +1 -0
- package/dist/tests/config_helper.test.d.ts +2 -0
- package/dist/tests/config_helper.test.d.ts.map +1 -0
- package/dist/tests/config_helper.test.js +46 -0
- package/dist/tests/config_helper.test.js.map +1 -0
- package/dist/tests/container.test.d.ts +2 -0
- package/dist/tests/container.test.d.ts.map +1 -0
- package/dist/tests/container.test.js +94 -0
- package/dist/tests/container.test.js.map +1 -0
- package/dist/tests/env.test.d.ts +2 -0
- package/dist/tests/env.test.d.ts.map +1 -0
- package/dist/tests/env.test.js +101 -0
- package/dist/tests/env.test.js.map +1 -0
- package/dist/tests/provider.test.d.ts +2 -0
- package/dist/tests/provider.test.d.ts.map +1 -0
- package/dist/tests/provider.test.js +87 -0
- package/dist/tests/provider.test.js.map +1 -0
- package/dist/tests/timezone.test.d.ts +2 -0
- package/dist/tests/timezone.test.d.ts.map +1 -0
- package/dist/tests/timezone.test.js +47 -0
- package/dist/tests/timezone.test.js.map +1 -0
- package/package.json +13 -11
- package/dist/config/Repository.d.ts +0 -41
- package/dist/config/Repository.d.ts.map +0 -1
- package/dist/config/Repository.js +0 -140
- package/dist/config/Repository.js.map +0 -1
- package/dist/support/EnvLoader.d.ts +0 -15
- package/dist/support/EnvLoader.d.ts.map +0 -1
- package/dist/support/EnvLoader.js +0 -58
- package/dist/support/EnvLoader.js.map +0 -1
- package/dist/support/config.d.ts +0 -18
- package/dist/support/config.d.ts.map +0 -1
- package/dist/support/config.js +0 -29
- package/dist/support/config.js.map +0 -1
- package/dist/support/env.d.ts +0 -9
- package/dist/support/env.d.ts.map +0 -1
- package/dist/support/env.js +0 -32
- package/dist/support/env.js.map +0 -1
package/README.md
CHANGED
|
@@ -21,7 +21,7 @@ app.boot();
|
|
|
21
21
|
app.run();
|
|
22
22
|
```
|
|
23
23
|
|
|
24
|
-
Arika Foundation is
|
|
24
|
+
Arika Foundation is the cornerstone of ArikaJS: everything else in the framework sits on top of this.
|
|
25
25
|
|
|
26
26
|
---
|
|
27
27
|
|
|
@@ -59,7 +59,7 @@ The goal of this package is to stay **small, focused, and stable**, forming the
|
|
|
59
59
|
- Resolve services by string token or class
|
|
60
60
|
|
|
61
61
|
- **Service Provider System**
|
|
62
|
-
-
|
|
62
|
+
- Elegant `ServiceProvider` abstraction
|
|
63
63
|
- `register()` for bindings
|
|
64
64
|
- `boot()` for runtime logic
|
|
65
65
|
- Deterministic order: all `register()` run before any `boot()`
|
|
@@ -346,7 +346,7 @@ const appName = app.config().get('app.name');
|
|
|
346
346
|
|
|
347
347
|
## Environment Variables
|
|
348
348
|
|
|
349
|
-
Arika Foundation provides a lightweight environment variable loader and helper,
|
|
349
|
+
Arika Foundation provides a lightweight environment variable loader and helper, with a fluent API.
|
|
350
350
|
|
|
351
351
|
If a `.env` file exists at the application base path, it will be automatically loaded during application bootstrap.
|
|
352
352
|
|
|
@@ -540,25 +540,27 @@ export interface Kernel {
|
|
|
540
540
|
Higher-level packages (e.g. `@arikajs/http`, `@arikajs/cli`) will implement these interfaces and plug into the `Application` lifecycle.
|
|
541
541
|
|
|
542
542
|
---
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
543
|
+
## 🏗 Architecture
|
|
544
|
+
|
|
545
|
+
```text
|
|
546
|
+
foundation/
|
|
547
|
+
├── src/
|
|
548
|
+
│ ├── application
|
|
549
|
+
│ │ └── Application.ts
|
|
550
|
+
│ ├── container
|
|
551
|
+
│ │ └── Container.ts
|
|
552
|
+
│ ├── contracts
|
|
553
|
+
│ │ ├── Application.ts
|
|
554
|
+
│ │ └── Kernel.ts
|
|
555
|
+
│ ├── providers
|
|
556
|
+
│ │ └── ServiceProvider.ts
|
|
557
|
+
│ ├── support
|
|
558
|
+
│ └── index.ts
|
|
559
|
+
├── tests/
|
|
560
|
+
├── package.json
|
|
561
|
+
├── tsconfig.json
|
|
562
|
+
└── README.md
|
|
563
|
+
```
|
|
562
564
|
|
|
563
565
|
Your ArikaJS apps that consume this package will typically have:
|
|
564
566
|
|
|
@@ -598,4 +600,4 @@ Before submitting a PR:
|
|
|
598
600
|
|
|
599
601
|
## License
|
|
600
602
|
|
|
601
|
-
`@arikajs/foundation` is open-sourced software licensed under the **MIT license**.
|
|
603
|
+
`@arikajs/foundation` is open-sourced software licensed under the **MIT license**.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export declare class ObjectPool<T> {
|
|
2
|
+
private pool;
|
|
3
|
+
private factory;
|
|
4
|
+
private resetFn;
|
|
5
|
+
constructor(factory: () => T, resetFn: (obj: T) => void, initialCapacity?: number);
|
|
6
|
+
acquire(): T;
|
|
7
|
+
release(obj: T): void;
|
|
8
|
+
}
|
|
9
|
+
//# sourceMappingURL=ObjectPool.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectPool.d.ts","sourceRoot":"","sources":["../src/ObjectPool.ts"],"names":[],"mappings":"AAAA,qBAAa,UAAU,CAAC,CAAC;IACrB,OAAO,CAAC,IAAI,CAAW;IACvB,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,OAAO,CAAmB;gBAEtB,OAAO,EAAE,MAAM,CAAC,EAAE,OAAO,EAAE,CAAC,GAAG,EAAE,CAAC,KAAK,IAAI,EAAE,eAAe,SAAM;IAQvE,OAAO,IAAI,CAAC;IAOZ,OAAO,CAAC,GAAG,EAAE,CAAC,GAAG,IAAI;CAI/B"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ObjectPool = void 0;
|
|
4
|
+
class ObjectPool {
|
|
5
|
+
constructor(factory, resetFn, initialCapacity = 200) {
|
|
6
|
+
this.pool = [];
|
|
7
|
+
this.factory = factory;
|
|
8
|
+
this.resetFn = resetFn;
|
|
9
|
+
for (let i = 0; i < initialCapacity; i++) {
|
|
10
|
+
this.pool.push(this.factory());
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
acquire() {
|
|
14
|
+
if (this.pool.length > 0) {
|
|
15
|
+
return this.pool.pop();
|
|
16
|
+
}
|
|
17
|
+
return this.factory();
|
|
18
|
+
}
|
|
19
|
+
release(obj) {
|
|
20
|
+
this.resetFn(obj);
|
|
21
|
+
this.pool.push(obj);
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
exports.ObjectPool = ObjectPool;
|
|
25
|
+
//# sourceMappingURL=ObjectPool.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ObjectPool.js","sourceRoot":"","sources":["../src/ObjectPool.ts"],"names":[],"mappings":";;;AAAA,MAAa,UAAU;IAKnB,YAAY,OAAgB,EAAE,OAAyB,EAAE,eAAe,GAAG,GAAG;QAJtE,SAAI,GAAQ,EAAE,CAAC;QAKnB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,eAAe,EAAE,CAAC,EAAE,EAAE,CAAC;YACvC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC;QACnC,CAAC;IACL,CAAC;IAEM,OAAO;QACV,IAAI,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,IAAI,CAAC,IAAI,CAAC,GAAG,EAAG,CAAC;QAC5B,CAAC;QACD,OAAO,IAAI,CAAC,OAAO,EAAE,CAAC;IAC1B,CAAC;IAEM,OAAO,CAAC,GAAM;QACjB,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAClB,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACxB,CAAC;CACJ;AAxBD,gCAwBC"}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Container, Token, Factory } from '../container/Container';
|
|
2
2
|
import { ServiceProvider } from '../providers/ServiceProvider';
|
|
3
|
-
import { Repository } from '
|
|
3
|
+
import { Repository } from '@arikajs/config';
|
|
4
4
|
/**
|
|
5
5
|
* Application is the core runtime of ArikaJS.
|
|
6
6
|
*
|
|
@@ -16,7 +16,13 @@ export declare class Application {
|
|
|
16
16
|
private readonly configRepository;
|
|
17
17
|
private providers;
|
|
18
18
|
private booted;
|
|
19
|
+
private static instance;
|
|
20
|
+
private terminatingCallbacks;
|
|
19
21
|
constructor(basePath: string);
|
|
22
|
+
/**
|
|
23
|
+
* Get the globally available application instance.
|
|
24
|
+
*/
|
|
25
|
+
static getInstance(): Application;
|
|
20
26
|
/**
|
|
21
27
|
* Get the base path of the application.
|
|
22
28
|
*/
|
|
@@ -29,6 +35,38 @@ export declare class Application {
|
|
|
29
35
|
* Access the configuration repository.
|
|
30
36
|
*/
|
|
31
37
|
config(): Repository;
|
|
38
|
+
/**
|
|
39
|
+
* Alias for make() - resolves a service from the container.
|
|
40
|
+
*/
|
|
41
|
+
make<T>(token: Token<T>): T;
|
|
42
|
+
/**
|
|
43
|
+
* Bind a transient service.
|
|
44
|
+
*/
|
|
45
|
+
bind<T>(token: Token<T>, factory: Factory<T>): void;
|
|
46
|
+
/**
|
|
47
|
+
* Bind a singleton service.
|
|
48
|
+
*/
|
|
49
|
+
singleton<T>(token: Token<T>, factory: Factory<T>): void;
|
|
50
|
+
/**
|
|
51
|
+
* Register an existing instance.
|
|
52
|
+
*/
|
|
53
|
+
instance<T>(token: Token<T>, value: T): void;
|
|
54
|
+
/**
|
|
55
|
+
* Register an alias for a token.
|
|
56
|
+
*/
|
|
57
|
+
alias(token: Token, alias: Token): void;
|
|
58
|
+
/**
|
|
59
|
+
* Tag a token.
|
|
60
|
+
*/
|
|
61
|
+
tag(token: Token, tag: string): void;
|
|
62
|
+
/**
|
|
63
|
+
* Resolve all tagged services.
|
|
64
|
+
*/
|
|
65
|
+
tagged<T = any>(tag: string): T[];
|
|
66
|
+
/**
|
|
67
|
+
* Extend a service.
|
|
68
|
+
*/
|
|
69
|
+
extend<T = any>(token: Token<T>, callback: (instance: T) => T): void;
|
|
32
70
|
/**
|
|
33
71
|
* Register a service provider.
|
|
34
72
|
* Can accept a class (will be instantiated) or an instance.
|
|
@@ -41,30 +79,24 @@ export declare class Application {
|
|
|
41
79
|
boot(): Promise<void>;
|
|
42
80
|
/**
|
|
43
81
|
* Run the application.
|
|
44
|
-
* This is intentionally minimal in foundation - higher layers
|
|
45
|
-
* (HTTP/CLI) will override or extend this behavior.
|
|
46
82
|
*/
|
|
47
83
|
run(): Promise<void>;
|
|
48
84
|
/**
|
|
49
|
-
*
|
|
85
|
+
* Gracefully terminate the application.
|
|
50
86
|
*/
|
|
51
|
-
|
|
87
|
+
terminate(): Promise<void>;
|
|
52
88
|
/**
|
|
53
|
-
*
|
|
89
|
+
* Register a callback to be run when the application is terminating.
|
|
54
90
|
*/
|
|
55
|
-
|
|
56
|
-
/**
|
|
57
|
-
* Register an existing instance.
|
|
58
|
-
*/
|
|
59
|
-
instance<T>(token: Token<T>, value: T): void;
|
|
60
|
-
/**
|
|
61
|
-
* Resolve a service from the container.
|
|
62
|
-
*/
|
|
63
|
-
make<T>(token: Token<T>): T;
|
|
91
|
+
onTerminate(callback: () => void | Promise<void>): void;
|
|
64
92
|
/**
|
|
65
93
|
* Alias for make() - resolves a service from the container.
|
|
66
94
|
*/
|
|
67
95
|
resolve<T>(token: Token<T>): T;
|
|
96
|
+
/**
|
|
97
|
+
* Check if a service is registered in the container.
|
|
98
|
+
*/
|
|
99
|
+
has(token: Token): boolean;
|
|
68
100
|
/**
|
|
69
101
|
* Check if the application has been booted.
|
|
70
102
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../src/application/Application.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"Application.d.ts","sourceRoot":"","sources":["../../src/application/Application.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAE,KAAK,EAAE,OAAO,EAAE,MAAM,wBAAwB,CAAC;AACnE,OAAO,EAAE,eAAe,EAAE,MAAM,8BAA8B,CAAC;AAC/D,OAAO,EAAE,UAAU,EAAkC,MAAM,iBAAiB,CAAC;AAE7E;;;;;;;;GAQG;AACH,qBAAa,WAAW;IACtB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAY;IACtC,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,gBAAgB,CAAa;IAC9C,OAAO,CAAC,SAAS,CAAyB;IAC1C,OAAO,CAAC,MAAM,CAAS;IACvB,OAAO,CAAC,MAAM,CAAC,QAAQ,CAA4B;IACnD,OAAO,CAAC,oBAAoB,CAAsC;gBAEtD,QAAQ,EAAE,MAAM;IA2C5B;;OAEG;WACW,WAAW,IAAI,WAAW;IAOxC;;OAEG;IACH,WAAW,IAAI,MAAM;IAIrB;;OAEG;IACH,YAAY,IAAI,SAAS;IAIzB;;OAEG;IACH,MAAM,IAAI,UAAU;IAIpB;;OAEG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IAqB3B;;OAEG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAInD;;OAEG;IACH,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAIxD;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAI5C;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAIvC;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAIpC;;OAEG;IACH,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE;IAIjC;;OAEG;IACH,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI;IAIpE;;;OAGG;IACH,QAAQ,CACN,QAAQ,EACJ,eAAe,GACf,CAAC,KAAK,GAAG,EAAE,WAAW,KAAK,eAAe,CAAC,GAC9C,IAAI;IAeP;;;OAGG;IACG,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAkC3B;;OAEG;IACG,GAAG,IAAI,OAAO,CAAC,IAAI,CAAC;IAM1B;;OAEG;IACG,SAAS,IAAI,OAAO,CAAC,IAAI,CAAC;IAMhC;;OAEG;IACH,WAAW,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI;IAIvD;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IAI9B;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;IAI1B;;OAEG;IACH,QAAQ,IAAI,OAAO;CAGpB"}
|
|
@@ -34,12 +34,11 @@ var __importStar = (this && this.__importStar) || (function () {
|
|
|
34
34
|
})();
|
|
35
35
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
36
36
|
exports.Application = void 0;
|
|
37
|
+
const fs = __importStar(require("fs"));
|
|
37
38
|
const path = __importStar(require("path"));
|
|
38
39
|
const Container_1 = require("../container/Container");
|
|
39
40
|
const ServiceProvider_1 = require("../providers/ServiceProvider");
|
|
40
|
-
const
|
|
41
|
-
const EnvLoader_1 = require("../support/EnvLoader");
|
|
42
|
-
const config_1 = require("../support/config");
|
|
41
|
+
const config_1 = require("@arikajs/config");
|
|
43
42
|
/**
|
|
44
43
|
* Application is the core runtime of ArikaJS.
|
|
45
44
|
*
|
|
@@ -53,20 +52,51 @@ class Application {
|
|
|
53
52
|
constructor(basePath) {
|
|
54
53
|
this.providers = [];
|
|
55
54
|
this.booted = false;
|
|
55
|
+
this.terminatingCallbacks = [];
|
|
56
56
|
this.basePath = path.resolve(basePath);
|
|
57
57
|
this.container = new Container_1.Container();
|
|
58
|
-
this.configRepository = new
|
|
58
|
+
this.configRepository = new config_1.Repository();
|
|
59
|
+
Application.instance = this;
|
|
59
60
|
// Register the config repository in the global support helper
|
|
60
61
|
(0, config_1.setConfigRepository)(this.configRepository);
|
|
61
62
|
// Register the application, container, and config for injection
|
|
62
63
|
this.container.instance(Application, this);
|
|
63
64
|
this.container.instance(Container_1.Container, this.container);
|
|
64
|
-
this.container.instance(
|
|
65
|
+
this.container.instance(config_1.Repository, this.configRepository);
|
|
66
|
+
this.container.alias(config_1.Repository, 'config');
|
|
65
67
|
// Load environment variables from .env if it exists
|
|
66
|
-
|
|
67
|
-
// Load configuration
|
|
68
|
-
const
|
|
69
|
-
|
|
68
|
+
config_1.EnvLoader.load(this.basePath);
|
|
69
|
+
// Load configuration
|
|
70
|
+
const cachedConfigPath = path.join(this.basePath, 'bootstrap', 'cache', 'config.json');
|
|
71
|
+
if (fs.existsSync(cachedConfigPath)) {
|
|
72
|
+
try {
|
|
73
|
+
const cachedData = fs.readFileSync(cachedConfigPath, 'utf8');
|
|
74
|
+
this.configRepository = new config_1.Repository(JSON.parse(cachedData));
|
|
75
|
+
}
|
|
76
|
+
catch (e) {
|
|
77
|
+
console.error('Failed to load cached config, falling back to directory loading...', e);
|
|
78
|
+
const configPath = path.join(this.basePath, 'config');
|
|
79
|
+
this.configRepository.loadConfigDirectory(configPath);
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
else {
|
|
83
|
+
const configPath = path.join(this.basePath, 'config');
|
|
84
|
+
this.configRepository.loadConfigDirectory(configPath);
|
|
85
|
+
}
|
|
86
|
+
// Apply timezone from config to the Node.js process
|
|
87
|
+
const timezone = this.configRepository.get('app.timezone');
|
|
88
|
+
if (timezone) {
|
|
89
|
+
process.env.TZ = timezone;
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Get the globally available application instance.
|
|
94
|
+
*/
|
|
95
|
+
static getInstance() {
|
|
96
|
+
if (!this.instance) {
|
|
97
|
+
throw new Error('Application instance has not been created yet.');
|
|
98
|
+
}
|
|
99
|
+
return this.instance;
|
|
70
100
|
}
|
|
71
101
|
/**
|
|
72
102
|
* Get the base path of the application.
|
|
@@ -86,6 +116,68 @@ class Application {
|
|
|
86
116
|
config() {
|
|
87
117
|
return this.configRepository;
|
|
88
118
|
}
|
|
119
|
+
/**
|
|
120
|
+
* Alias for make() - resolves a service from the container.
|
|
121
|
+
*/
|
|
122
|
+
make(token) {
|
|
123
|
+
// Check the container first — explicit bindings always win
|
|
124
|
+
if (this.container.has(token)) {
|
|
125
|
+
return this.container.make(token);
|
|
126
|
+
}
|
|
127
|
+
// If it's a config token (e.g. 'config.app.name'),
|
|
128
|
+
// fall back to the configuration repository
|
|
129
|
+
if (typeof token === 'string' && token.startsWith('config.')) {
|
|
130
|
+
const configKey = token.substring(7);
|
|
131
|
+
const value = this.configRepository.get(configKey);
|
|
132
|
+
if (value !== undefined) {
|
|
133
|
+
return value;
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
// Final attempt — let the container throw if not found
|
|
137
|
+
return this.container.make(token);
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Bind a transient service.
|
|
141
|
+
*/
|
|
142
|
+
bind(token, factory) {
|
|
143
|
+
this.container.bind(token, factory);
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* Bind a singleton service.
|
|
147
|
+
*/
|
|
148
|
+
singleton(token, factory) {
|
|
149
|
+
this.container.singleton(token, factory);
|
|
150
|
+
}
|
|
151
|
+
/**
|
|
152
|
+
* Register an existing instance.
|
|
153
|
+
*/
|
|
154
|
+
instance(token, value) {
|
|
155
|
+
this.container.instance(token, value);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Register an alias for a token.
|
|
159
|
+
*/
|
|
160
|
+
alias(token, alias) {
|
|
161
|
+
this.container.alias(token, alias);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Tag a token.
|
|
165
|
+
*/
|
|
166
|
+
tag(token, tag) {
|
|
167
|
+
this.container.tag(token, tag);
|
|
168
|
+
}
|
|
169
|
+
/**
|
|
170
|
+
* Resolve all tagged services.
|
|
171
|
+
*/
|
|
172
|
+
tagged(tag) {
|
|
173
|
+
return this.container.tagged(tag);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Extend a service.
|
|
177
|
+
*/
|
|
178
|
+
extend(token, callback) {
|
|
179
|
+
this.container.extend(token, callback);
|
|
180
|
+
}
|
|
89
181
|
/**
|
|
90
182
|
* Register a service provider.
|
|
91
183
|
* Can accept a class (will be instantiated) or an instance.
|
|
@@ -116,74 +208,52 @@ class Application {
|
|
|
116
208
|
await provider.boot();
|
|
117
209
|
}
|
|
118
210
|
// Phase 3: Apply runtime configuration
|
|
119
|
-
//
|
|
120
|
-
if (!this.configRepository.get('app.key')) {
|
|
121
|
-
throw new Error('Application key (APP_KEY) is not set. Please run "arika key:generate" to generate one.');
|
|
122
|
-
}
|
|
123
|
-
// Apply timezone from config to the Node.js process
|
|
211
|
+
// Re-apply timezone in case it was changed after construction
|
|
124
212
|
const timezone = this.configRepository.get('app.timezone');
|
|
125
213
|
if (timezone) {
|
|
126
214
|
process.env.TZ = timezone;
|
|
127
215
|
}
|
|
216
|
+
// Validate APP_KEY (unless in debug/local mode)
|
|
217
|
+
if (!this.configRepository.get('app.key') && process.env.NODE_ENV === 'production') {
|
|
218
|
+
throw new Error('Application key (APP_KEY) is not set. Please run "arika key:generate" to generate one.');
|
|
219
|
+
}
|
|
128
220
|
// Mark config as booted (read-only)
|
|
129
221
|
this.configRepository.markAsBooted();
|
|
130
222
|
this.booted = true;
|
|
131
223
|
}
|
|
132
224
|
/**
|
|
133
225
|
* Run the application.
|
|
134
|
-
* This is intentionally minimal in foundation - higher layers
|
|
135
|
-
* (HTTP/CLI) will override or extend this behavior.
|
|
136
226
|
*/
|
|
137
227
|
async run() {
|
|
138
228
|
if (!this.booted) {
|
|
139
229
|
await this.boot();
|
|
140
230
|
}
|
|
141
|
-
// In foundation, run() is a no-op
|
|
142
|
-
// HTTP/CLI kernels will implement actual run logic
|
|
143
|
-
}
|
|
144
|
-
/**
|
|
145
|
-
* Bind a transient service.
|
|
146
|
-
*/
|
|
147
|
-
bind(token, factory) {
|
|
148
|
-
this.container.bind(token, factory);
|
|
149
231
|
}
|
|
150
232
|
/**
|
|
151
|
-
*
|
|
233
|
+
* Gracefully terminate the application.
|
|
152
234
|
*/
|
|
153
|
-
|
|
154
|
-
this.
|
|
235
|
+
async terminate() {
|
|
236
|
+
for (const callback of this.terminatingCallbacks) {
|
|
237
|
+
await callback();
|
|
238
|
+
}
|
|
155
239
|
}
|
|
156
240
|
/**
|
|
157
|
-
* Register
|
|
241
|
+
* Register a callback to be run when the application is terminating.
|
|
158
242
|
*/
|
|
159
|
-
|
|
160
|
-
this.
|
|
243
|
+
onTerminate(callback) {
|
|
244
|
+
this.terminatingCallbacks.push(callback);
|
|
161
245
|
}
|
|
162
246
|
/**
|
|
163
|
-
*
|
|
247
|
+
* Alias for make() - resolves a service from the container.
|
|
164
248
|
*/
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
if (this.container.has(token)) {
|
|
168
|
-
return this.container.make(token);
|
|
169
|
-
}
|
|
170
|
-
// Otherwise, if it's a config token (e.g. 'config.app.name'),
|
|
171
|
-
// try to resolve it from the configuration repository
|
|
172
|
-
if (typeof token === 'string' && token.startsWith('config.')) {
|
|
173
|
-
const configKey = token.substring(7);
|
|
174
|
-
const value = this.configRepository.get(configKey);
|
|
175
|
-
if (value !== undefined) {
|
|
176
|
-
return value;
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
// Fall back to standard container resolution (which might throw)
|
|
180
|
-
return this.container.make(token);
|
|
249
|
+
resolve(token) {
|
|
250
|
+
return this.make(token);
|
|
181
251
|
}
|
|
182
252
|
/**
|
|
183
|
-
*
|
|
253
|
+
* Check if a service is registered in the container.
|
|
184
254
|
*/
|
|
185
|
-
|
|
186
|
-
return this.container.
|
|
255
|
+
has(token) {
|
|
256
|
+
return this.container.has(token);
|
|
187
257
|
}
|
|
188
258
|
/**
|
|
189
259
|
* Check if the application has been booted.
|
|
@@ -193,4 +263,5 @@ class Application {
|
|
|
193
263
|
}
|
|
194
264
|
}
|
|
195
265
|
exports.Application = Application;
|
|
266
|
+
Application.instance = null;
|
|
196
267
|
//# sourceMappingURL=Application.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Application.js","sourceRoot":"","sources":["../../src/application/Application.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,2CAA6B;AAC7B,sDAAmE;AACnE,kEAA+D;AAC/D,
|
|
1
|
+
{"version":3,"file":"Application.js","sourceRoot":"","sources":["../../src/application/Application.ts"],"names":[],"mappings":"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"}
|
|
@@ -10,6 +10,9 @@ export type Factory<T = any> = (container: Container) => T;
|
|
|
10
10
|
*/
|
|
11
11
|
export declare class Container {
|
|
12
12
|
private bindings;
|
|
13
|
+
private aliases;
|
|
14
|
+
private tags;
|
|
15
|
+
private extenders;
|
|
13
16
|
/**
|
|
14
17
|
* Bind a token to a factory. Produces a new instance on every resolution.
|
|
15
18
|
*/
|
|
@@ -23,10 +26,29 @@ export declare class Container {
|
|
|
23
26
|
* Directly register an existing instance for a token.
|
|
24
27
|
*/
|
|
25
28
|
instance<T>(token: Token<T>, value: T): void;
|
|
29
|
+
/**
|
|
30
|
+
* Create an alias for a token.
|
|
31
|
+
*/
|
|
32
|
+
alias(token: Token, alias: Token): void;
|
|
33
|
+
/**
|
|
34
|
+
* Assign a tag to a given token.
|
|
35
|
+
*/
|
|
36
|
+
tag(token: Token, tag: string): void;
|
|
37
|
+
/**
|
|
38
|
+
* Resolve all bindings associated with a given tag.
|
|
39
|
+
*/
|
|
40
|
+
tagged<T = any>(tag: string): T[];
|
|
41
|
+
/**
|
|
42
|
+
* Extend a binding in the container.
|
|
43
|
+
*/
|
|
44
|
+
extend<T = any>(token: Token<T>, callback: (instance: T) => T): void;
|
|
26
45
|
/**
|
|
27
46
|
* Resolve a token from the container.
|
|
28
47
|
*/
|
|
29
48
|
make<T>(token: Token<T>): T;
|
|
49
|
+
private getAlias;
|
|
50
|
+
private applyExtenders;
|
|
51
|
+
private instantiate;
|
|
30
52
|
/**
|
|
31
53
|
* Alias for make() - resolves a token from the container.
|
|
32
54
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../src/container/Container.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAE3E,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;AAQ3D;;;;;;;GAOG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAA6B;
|
|
1
|
+
{"version":3,"file":"Container.d.ts","sourceRoot":"","sources":["../../src/container/Container.ts"],"names":[],"mappings":"AAAA,MAAM,MAAM,KAAK,CAAC,CAAC,GAAG,GAAG,IAAI,MAAM,GAAG,MAAM,GAAG,CAAC,KAAK,GAAG,IAAI,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC,CAAC;AAE3E,MAAM,MAAM,OAAO,CAAC,CAAC,GAAG,GAAG,IAAI,CAAC,SAAS,EAAE,SAAS,KAAK,CAAC,CAAC;AAQ3D;;;;;;;GAOG;AACH,qBAAa,SAAS;IACpB,OAAO,CAAC,QAAQ,CAA6B;IAC7C,OAAO,CAAC,OAAO,CAA2B;IAC1C,OAAO,CAAC,IAAI,CAA8B;IAC1C,OAAO,CAAC,SAAS,CAAgD;IAEjE;;OAEG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAInD;;;OAGG;IACH,SAAS,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAAG,IAAI;IAIxD;;OAEG;IACH,QAAQ,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,GAAG,IAAI;IAQ5C;;OAEG;IACH,KAAK,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,GAAG,IAAI;IAIvC;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,GAAG,IAAI;IAOpC;;OAEG;IACH,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,GAAG,EAAE,MAAM,GAAG,CAAC,EAAE;IAKjC;;OAEG;IACH,MAAM,CAAC,CAAC,GAAG,GAAG,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,EAAE,QAAQ,EAAE,CAAC,QAAQ,EAAE,CAAC,KAAK,CAAC,GAAG,IAAI;IAQpE;;OAEG;IACH,IAAI,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IA0B3B,OAAO,CAAC,QAAQ;IAIhB,OAAO,CAAC,cAAc;IAKtB,OAAO,CAAC,WAAW;IAMnB;;OAEG;IACH,OAAO,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;IAI9B;;OAEG;IACH,GAAG,CAAC,KAAK,EAAE,KAAK,GAAG,OAAO;CAG3B"}
|
|
@@ -12,6 +12,9 @@ exports.Container = void 0;
|
|
|
12
12
|
class Container {
|
|
13
13
|
constructor() {
|
|
14
14
|
this.bindings = new Map();
|
|
15
|
+
this.aliases = new Map();
|
|
16
|
+
this.tags = new Map();
|
|
17
|
+
this.extenders = new Map();
|
|
15
18
|
}
|
|
16
19
|
/**
|
|
17
20
|
* Bind a token to a factory. Produces a new instance on every resolution.
|
|
@@ -36,25 +39,75 @@ class Container {
|
|
|
36
39
|
instance: value,
|
|
37
40
|
});
|
|
38
41
|
}
|
|
42
|
+
/**
|
|
43
|
+
* Create an alias for a token.
|
|
44
|
+
*/
|
|
45
|
+
alias(token, alias) {
|
|
46
|
+
this.aliases.set(alias, token);
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Assign a tag to a given token.
|
|
50
|
+
*/
|
|
51
|
+
tag(token, tag) {
|
|
52
|
+
if (!this.tags.has(tag)) {
|
|
53
|
+
this.tags.set(tag, []);
|
|
54
|
+
}
|
|
55
|
+
this.tags.get(tag)?.push(token);
|
|
56
|
+
}
|
|
57
|
+
/**
|
|
58
|
+
* Resolve all bindings associated with a given tag.
|
|
59
|
+
*/
|
|
60
|
+
tagged(tag) {
|
|
61
|
+
const tokens = this.tags.get(tag) || [];
|
|
62
|
+
return tokens.map(token => this.make(token));
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* Extend a binding in the container.
|
|
66
|
+
*/
|
|
67
|
+
extend(token, callback) {
|
|
68
|
+
const originalToken = this.getAlias(token);
|
|
69
|
+
if (!this.extenders.has(originalToken)) {
|
|
70
|
+
this.extenders.set(originalToken, []);
|
|
71
|
+
}
|
|
72
|
+
this.extenders.get(originalToken)?.push(callback);
|
|
73
|
+
}
|
|
39
74
|
/**
|
|
40
75
|
* Resolve a token from the container.
|
|
41
76
|
*/
|
|
42
77
|
make(token) {
|
|
43
|
-
|
|
78
|
+
const originalToken = this.getAlias(token);
|
|
79
|
+
let binding = this.bindings.get(originalToken);
|
|
44
80
|
if (!binding) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
return new token(this);
|
|
81
|
+
if (typeof originalToken === 'function') {
|
|
82
|
+
return this.instantiate(originalToken);
|
|
48
83
|
}
|
|
49
84
|
throw new Error(`Container: no binding found for token "${String(token)}"`);
|
|
50
85
|
}
|
|
86
|
+
let instance;
|
|
51
87
|
if (binding.singleton) {
|
|
52
88
|
if (binding.instance === undefined) {
|
|
53
89
|
binding.instance = binding.factory(this);
|
|
90
|
+
binding.instance = this.applyExtenders(originalToken, binding.instance);
|
|
54
91
|
}
|
|
55
|
-
|
|
92
|
+
instance = binding.instance;
|
|
56
93
|
}
|
|
57
|
-
|
|
94
|
+
else {
|
|
95
|
+
instance = binding.factory(this);
|
|
96
|
+
instance = this.applyExtenders(originalToken, instance);
|
|
97
|
+
}
|
|
98
|
+
return instance;
|
|
99
|
+
}
|
|
100
|
+
getAlias(token) {
|
|
101
|
+
return this.aliases.get(token) || token;
|
|
102
|
+
}
|
|
103
|
+
applyExtenders(token, instance) {
|
|
104
|
+
const extenders = this.extenders.get(token) || [];
|
|
105
|
+
return extenders.reduce((inst, extender) => extender(inst), instance);
|
|
106
|
+
}
|
|
107
|
+
instantiate(constructor) {
|
|
108
|
+
// Basic automatic injection (assumes constructor only takes container)
|
|
109
|
+
// In the future, this will use Reflect metadata for property/param injection
|
|
110
|
+
return new constructor(this);
|
|
58
111
|
}
|
|
59
112
|
/**
|
|
60
113
|
* Alias for make() - resolves a token from the container.
|
|
@@ -66,7 +119,7 @@ class Container {
|
|
|
66
119
|
* Check whether a token has been registered.
|
|
67
120
|
*/
|
|
68
121
|
has(token) {
|
|
69
|
-
return this.bindings.has(token);
|
|
122
|
+
return this.bindings.has(this.getAlias(token));
|
|
70
123
|
}
|
|
71
124
|
}
|
|
72
125
|
exports.Container = Container;
|