@devcraft-ts/diadem 0.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.
- package/CHANGELOG.md +22 -0
- package/LICENSE +21 -0
- package/README.md +306 -0
- package/dist/auto-discovery-5IV22D5D.cjs +73 -0
- package/dist/auto-discovery-5IV22D5D.cjs.map +1 -0
- package/dist/auto-discovery-RPCKK3PB.js +68 -0
- package/dist/auto-discovery-RPCKK3PB.js.map +1 -0
- package/dist/chunk-72YY5X6T.cjs +683 -0
- package/dist/chunk-72YY5X6T.cjs.map +1 -0
- package/dist/chunk-FHQRDO5C.cjs +187 -0
- package/dist/chunk-FHQRDO5C.cjs.map +1 -0
- package/dist/chunk-RTX6B4YY.js +681 -0
- package/dist/chunk-RTX6B4YY.js.map +1 -0
- package/dist/chunk-W7NA3ZZF.js +169 -0
- package/dist/chunk-W7NA3ZZF.js.map +1 -0
- package/dist/cli.cjs +821 -0
- package/dist/cli.cjs.map +1 -0
- package/dist/cli.js +815 -0
- package/dist/cli.js.map +1 -0
- package/dist/container-C1FFn9_4.d.cts +249 -0
- package/dist/container-C1FFn9_4.d.ts +249 -0
- package/dist/index.cjs +145 -0
- package/dist/index.cjs.map +1 -0
- package/dist/index.d.cts +304 -0
- package/dist/index.d.ts +304 -0
- package/dist/index.js +71 -0
- package/dist/index.js.map +1 -0
- package/dist/setup/index.cjs +87 -0
- package/dist/setup/index.cjs.map +1 -0
- package/dist/setup/index.d.cts +81 -0
- package/dist/setup/index.d.ts +81 -0
- package/dist/setup/index.js +75 -0
- package/dist/setup/index.js.map +1 -0
- package/package.json +92 -0
package/dist/index.cjs
ADDED
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var chunk72YY5X6T_cjs = require('./chunk-72YY5X6T.cjs');
|
|
4
|
+
var chunkFHQRDO5C_cjs = require('./chunk-FHQRDO5C.cjs');
|
|
5
|
+
|
|
6
|
+
// src/core/index.ts
|
|
7
|
+
var decorators = {
|
|
8
|
+
singleton: chunkFHQRDO5C_cjs.singleton,
|
|
9
|
+
factory: chunkFHQRDO5C_cjs.factory,
|
|
10
|
+
lazy: chunkFHQRDO5C_cjs.lazy,
|
|
11
|
+
lazySingleton: chunkFHQRDO5C_cjs.lazySingleton
|
|
12
|
+
};
|
|
13
|
+
function createContainerBuilder() {
|
|
14
|
+
const container = new chunk72YY5X6T_cjs.DiademContainer();
|
|
15
|
+
const builder = {
|
|
16
|
+
register: (token, implementation) => {
|
|
17
|
+
container.register(token, implementation);
|
|
18
|
+
return builder;
|
|
19
|
+
},
|
|
20
|
+
registerSingleton: (token, factory2) => {
|
|
21
|
+
container.registerSingleton(token, factory2);
|
|
22
|
+
return builder;
|
|
23
|
+
},
|
|
24
|
+
registerFactory: (token, factory2) => {
|
|
25
|
+
container.registerFactory(token, factory2);
|
|
26
|
+
return builder;
|
|
27
|
+
},
|
|
28
|
+
build: () => container
|
|
29
|
+
};
|
|
30
|
+
return builder;
|
|
31
|
+
}
|
|
32
|
+
function createMockContainer(mocks = /* @__PURE__ */ new Map()) {
|
|
33
|
+
const container = new chunk72YY5X6T_cjs.DiademContainer();
|
|
34
|
+
mocks.forEach((implementation, token) => {
|
|
35
|
+
container.register(token, implementation);
|
|
36
|
+
});
|
|
37
|
+
container.setReady();
|
|
38
|
+
return container;
|
|
39
|
+
}
|
|
40
|
+
function isDIContainer(obj) {
|
|
41
|
+
if (typeof obj !== "object" || obj === null) {
|
|
42
|
+
return false;
|
|
43
|
+
}
|
|
44
|
+
const c = obj;
|
|
45
|
+
return typeof c.register === "function" && typeof c.resolve === "function" && typeof c.isReady === "function";
|
|
46
|
+
}
|
|
47
|
+
function isDiademContainer(obj) {
|
|
48
|
+
if (!isDIContainer(obj)) {
|
|
49
|
+
return false;
|
|
50
|
+
}
|
|
51
|
+
const c = obj;
|
|
52
|
+
return typeof c.autoRegisterDiscovered === "function" && typeof c.getDiagnostics === "function";
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// src/index.ts
|
|
56
|
+
var DI_VERSION = "0.1.0";
|
|
57
|
+
var DI_FEATURES = [
|
|
58
|
+
"type-safe",
|
|
59
|
+
"ssr-safe",
|
|
60
|
+
"decorator-driven",
|
|
61
|
+
"auto-registration",
|
|
62
|
+
"environment-aware",
|
|
63
|
+
"server-safe",
|
|
64
|
+
"no-global-state",
|
|
65
|
+
"metadata-based",
|
|
66
|
+
"zero-dependencies"
|
|
67
|
+
];
|
|
68
|
+
|
|
69
|
+
Object.defineProperty(exports, "DiademContainer", {
|
|
70
|
+
enumerable: true,
|
|
71
|
+
get: function () { return chunk72YY5X6T_cjs.DiademContainer; }
|
|
72
|
+
});
|
|
73
|
+
Object.defineProperty(exports, "configureManifest", {
|
|
74
|
+
enumerable: true,
|
|
75
|
+
get: function () { return chunkFHQRDO5C_cjs.configureManifest; }
|
|
76
|
+
});
|
|
77
|
+
Object.defineProperty(exports, "consoleLogger", {
|
|
78
|
+
enumerable: true,
|
|
79
|
+
get: function () { return chunkFHQRDO5C_cjs.consoleLogger; }
|
|
80
|
+
});
|
|
81
|
+
Object.defineProperty(exports, "factory", {
|
|
82
|
+
enumerable: true,
|
|
83
|
+
get: function () { return chunkFHQRDO5C_cjs.factory; }
|
|
84
|
+
});
|
|
85
|
+
Object.defineProperty(exports, "getDIMetadata", {
|
|
86
|
+
enumerable: true,
|
|
87
|
+
get: function () { return chunkFHQRDO5C_cjs.getDIMetadata; }
|
|
88
|
+
});
|
|
89
|
+
Object.defineProperty(exports, "getDIRegistrationStats", {
|
|
90
|
+
enumerable: true,
|
|
91
|
+
get: function () { return chunkFHQRDO5C_cjs.getDIRegistrationStats; }
|
|
92
|
+
});
|
|
93
|
+
Object.defineProperty(exports, "getLogger", {
|
|
94
|
+
enumerable: true,
|
|
95
|
+
get: function () { return chunkFHQRDO5C_cjs.getLogger; }
|
|
96
|
+
});
|
|
97
|
+
Object.defineProperty(exports, "getManifest", {
|
|
98
|
+
enumerable: true,
|
|
99
|
+
get: function () { return chunkFHQRDO5C_cjs.getManifest; }
|
|
100
|
+
});
|
|
101
|
+
Object.defineProperty(exports, "hasDIMetadata", {
|
|
102
|
+
enumerable: true,
|
|
103
|
+
get: function () { return chunkFHQRDO5C_cjs.hasDIMetadata; }
|
|
104
|
+
});
|
|
105
|
+
Object.defineProperty(exports, "hasManifest", {
|
|
106
|
+
enumerable: true,
|
|
107
|
+
get: function () { return chunkFHQRDO5C_cjs.hasManifest; }
|
|
108
|
+
});
|
|
109
|
+
Object.defineProperty(exports, "isClassRegisteredForEnvironment", {
|
|
110
|
+
enumerable: true,
|
|
111
|
+
get: function () { return chunkFHQRDO5C_cjs.isClassRegisteredForEnvironment; }
|
|
112
|
+
});
|
|
113
|
+
Object.defineProperty(exports, "lazy", {
|
|
114
|
+
enumerable: true,
|
|
115
|
+
get: function () { return chunkFHQRDO5C_cjs.lazy; }
|
|
116
|
+
});
|
|
117
|
+
Object.defineProperty(exports, "lazySingleton", {
|
|
118
|
+
enumerable: true,
|
|
119
|
+
get: function () { return chunkFHQRDO5C_cjs.lazySingleton; }
|
|
120
|
+
});
|
|
121
|
+
Object.defineProperty(exports, "noopLogger", {
|
|
122
|
+
enumerable: true,
|
|
123
|
+
get: function () { return chunkFHQRDO5C_cjs.noopLogger; }
|
|
124
|
+
});
|
|
125
|
+
Object.defineProperty(exports, "resetManifest", {
|
|
126
|
+
enumerable: true,
|
|
127
|
+
get: function () { return chunkFHQRDO5C_cjs.resetManifest; }
|
|
128
|
+
});
|
|
129
|
+
Object.defineProperty(exports, "setLogger", {
|
|
130
|
+
enumerable: true,
|
|
131
|
+
get: function () { return chunkFHQRDO5C_cjs.setLogger; }
|
|
132
|
+
});
|
|
133
|
+
Object.defineProperty(exports, "singleton", {
|
|
134
|
+
enumerable: true,
|
|
135
|
+
get: function () { return chunkFHQRDO5C_cjs.singleton; }
|
|
136
|
+
});
|
|
137
|
+
exports.DI_FEATURES = DI_FEATURES;
|
|
138
|
+
exports.DI_VERSION = DI_VERSION;
|
|
139
|
+
exports.createContainerBuilder = createContainerBuilder;
|
|
140
|
+
exports.createMockContainer = createMockContainer;
|
|
141
|
+
exports.decorators = decorators;
|
|
142
|
+
exports.isDIContainer = isDIContainer;
|
|
143
|
+
exports.isDiademContainer = isDiademContainer;
|
|
144
|
+
//# sourceMappingURL=index.cjs.map
|
|
145
|
+
//# sourceMappingURL=index.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/core/index.ts","../src/index.ts"],"names":["singleton","factory","lazy","lazySingleton","DiademContainer"],"mappings":";;;;;;AAmEO,IAAM,UAAA,GAAa;AAAA,aACxBA,2BAAA;AAAA,WACAC,yBAAA;AAAA,QACAC,sBAAA;AAAA,iBACAC;AACF;AA0CO,SAAS,sBAAA,GAA2C;AACzD,EAAA,MAAM,SAAA,GAAY,IAAIC,iCAAA,EAAgB;AAEtC,EAAA,MAAM,OAAA,GAA4B;AAAA,IAChC,QAAA,EAAU,CAAI,KAAA,EAAuB,cAAA,KAAsB;AACzD,MAAA,SAAA,CAAU,QAAA,CAAS,OAAO,cAAc,CAAA;AACxC,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IACA,iBAAA,EAAmB,CACjB,KAAA,EACAH,QAAAA,KACG;AACH,MAAA,SAAA,CAAU,iBAAA,CAAkB,OAAOA,QAAO,CAAA;AAC1C,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IACA,eAAA,EAAiB,CAAI,KAAA,EAAuBA,QAAAA,KAA+B;AACzE,MAAA,SAAA,CAAU,eAAA,CAAgB,OAAOA,QAAO,CAAA;AACxC,MAAA,OAAO,OAAA;AAAA,IACT,CAAA;AAAA,IAEA,OAAO,MAAM;AAAA,GACf;AAEA,EAAA,OAAO,OAAA;AACT;AAGO,SAAS,mBAAA,CACd,KAAA,mBAAQ,IAAI,GAAA,EAAmC,EAC9B;AACjB,EAAA,MAAM,SAAA,GAAY,IAAIG,iCAAA,EAAgB;AAGtC,EAAA,KAAA,CAAM,OAAA,CAAQ,CAAC,cAAA,EAAgB,KAAA,KAAU;AACvC,IAAA,SAAA,CAAU,QAAA,CAAS,OAAO,cAAc,CAAA;AAAA,EAC1C,CAAC,CAAA;AAED,EAAA,SAAA,CAAU,QAAA,EAAS;AACnB,EAAA,OAAO,SAAA;AACT;AAKO,SAAS,cAAc,GAAA,EAAkC;AAC9D,EAAA,IAAI,OAAO,GAAA,KAAQ,QAAA,IAAY,GAAA,KAAQ,IAAA,EAAM;AAC3C,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,OACE,OAAO,CAAA,CAAE,QAAA,KAAa,UAAA,IACtB,OAAO,EAAE,OAAA,KAAY,UAAA,IACrB,OAAO,CAAA,CAAE,OAAA,KAAY,UAAA;AAEzB;AAEO,SAAS,kBAAkB,GAAA,EAAsC;AACtE,EAAA,IAAI,CAAC,aAAA,CAAc,GAAG,CAAA,EAAG;AACvB,IAAA,OAAO,KAAA;AAAA,EACT;AACA,EAAA,MAAM,CAAA,GAAI,GAAA;AACV,EAAA,OACE,OAAO,CAAA,CAAE,sBAAA,KAA2B,UAAA,IACpC,OAAO,EAAE,cAAA,KAAmB,UAAA;AAEhC;;;ACtJO,IAAM,UAAA,GAAa;AAEnB,IAAM,WAAA,GAAc;AAAA,EACzB,WAAA;AAAA,EACA,UAAA;AAAA,EACA,kBAAA;AAAA,EACA,mBAAA;AAAA,EACA,mBAAA;AAAA,EACA,aAAA;AAAA,EACA,iBAAA;AAAA,EACA,gBAAA;AAAA,EACA;AACF","file":"index.cjs","sourcesContent":["/**\n * Core DI System - Core Module Exports\n *\n * This module exports the fundamental building blocks of the dependency injection system:\n * - Container implementation\n * - Decorators for service registration\n * - Type definitions\n *\n * @example\n * ```typescript\n * import { DiademContainer, singleton, factory } from 'app/infrastructure/di/core'\n * ```\n */\n\n// Import for local usage\nimport type { Constructor, DIContainer } from './container'\nimport { DiademContainer } from './container'\nimport { factory, lazy, lazySingleton, singleton } from './decorators'\n\n// Container and types\nexport {\n DiademContainer,\n type Constructor,\n type DIContainer,\n type Disposable,\n type LifecycleType,\n type Token\n} from './container'\n\n// Decorators for auto-registration\nexport {\n factory,\n getDIMetadata,\n getDIRegistrationStats,\n hasDIMetadata,\n isClassRegisteredForEnvironment,\n lazy,\n lazySingleton,\n singleton,\n type LifecycleType as DecoratorLifecycleType,\n type DIMetadata\n} from './decorators'\n\n// Type definitions\nexport type { AbstractConstructor } from './types'\n\n// Pluggable logging (silent by default)\nexport { consoleLogger, getLogger, noopLogger, setLogger } from './logger'\nexport type { Logger } from './logger'\n\n// Service manifest contract + injection seam\nexport {\n configureManifest,\n getManifest,\n hasManifest,\n resetManifest\n} from './manifest'\nexport type {\n ImportedService,\n ServiceDependency,\n ServiceManifestEntry,\n ServiceManifestModule\n} from './manifest'\n\n/**\n * Common decorator combinations for convenience\n */\nexport const decorators = {\n singleton,\n factory,\n lazy,\n lazySingleton\n} as const\n\n/**\n * Type helpers for better developer experience\n */\n\n// Helper type to extract the implementation type from a constructor token\nexport type ResolvedType<T> = T extends Constructor<infer U> ? U : never\n\n// Helper type for multiple dependency resolution\nexport type ResolvedTypes<T extends ReadonlyArray<Constructor<unknown>>> = {\n [K in keyof T]: T[K] extends Constructor<infer U> ? U : never\n}\n\n// Helper type for service factory functions\nexport type ServiceFactory<T> = () => T\n\n// Helper type for environment-aware service registration\nexport interface EnvironmentConfig {\n environment?: string\n modules: Array<Record<string, unknown>>\n}\n\n/**\n * Utility functions for advanced usage\n */\n\n/** Fluent builder returned by {@link createContainerBuilder}. */\nexport interface ContainerBuilder {\n register: <T>(token: Constructor<T>, implementation: T) => ContainerBuilder\n registerSingleton: <T>(\n token: Constructor<T>,\n factory: ServiceFactory<T>\n ) => ContainerBuilder\n registerFactory: <T>(\n token: Constructor<T>,\n factory: ServiceFactory<T>\n ) => ContainerBuilder\n build: () => DiademContainer\n}\n\n// Create a type-safe container builder\nexport function createContainerBuilder(): ContainerBuilder {\n const container = new DiademContainer()\n\n const builder: ContainerBuilder = {\n register: <T>(token: Constructor<T>, implementation: T) => {\n container.register(token, implementation)\n return builder\n },\n registerSingleton: <T>(\n token: Constructor<T>,\n factory: ServiceFactory<T>\n ) => {\n container.registerSingleton(token, factory)\n return builder\n },\n registerFactory: <T>(token: Constructor<T>, factory: ServiceFactory<T>) => {\n container.registerFactory(token, factory)\n return builder\n },\n\n build: () => container\n }\n\n return builder\n}\n\n// Create a mock container for testing\nexport function createMockContainer(\n mocks = new Map<Constructor<unknown>, unknown>()\n): DiademContainer {\n const container = new DiademContainer()\n\n // Register all mocks\n mocks.forEach((implementation, token) => {\n container.register(token, implementation)\n })\n\n container.setReady()\n return container\n}\n\n/**\n * Type guards for runtime type checking\n */\nexport function isDIContainer(obj: unknown): obj is DIContainer {\n if (typeof obj !== 'object' || obj === null) {\n return false\n }\n const c = obj as Record<string, unknown>\n return (\n typeof c.register === 'function' &&\n typeof c.resolve === 'function' &&\n typeof c.isReady === 'function'\n )\n}\n\nexport function isDiademContainer(obj: unknown): obj is DiademContainer {\n if (!isDIContainer(obj)) {\n return false\n }\n const c = obj as unknown as Record<string, unknown>\n return (\n typeof c.autoRegisterDiscovered === 'function' &&\n typeof c.getDiagnostics === 'function'\n )\n}\n","/**\n * Diadem — main entry point.\n *\n * A build-time, manifest-driven DI container. SSR-safe and framework-agnostic:\n * registration metadata lives on classes, never in global state.\n *\n * ```typescript\n * import {\n * DiademContainer,\n * configureManifest,\n * singleton,\n * factory\n * } from '@devcraft-ts/diadem'\n * import * as manifest from './generated/service-manifest'\n *\n * configureManifest(manifest)\n * const container = new DiademContainer()\n * await container.autoRegisterDiscovered(process.env.NODE_ENV)\n * const service = container.resolve(IMyService)\n * ```\n */\n\n// Core DI functionality (container, decorators, manifest contract, logging).\n// Setup helpers live at 'diadem/setup'.\nexport * from './core'\n\n/**\n * Version and metadata\n */\nexport const DI_VERSION = '0.1.0'\n\nexport const DI_FEATURES = [\n 'type-safe',\n 'ssr-safe',\n 'decorator-driven',\n 'auto-registration',\n 'environment-aware',\n 'server-safe',\n 'no-global-state',\n 'metadata-based',\n 'zero-dependencies'\n] as const\n"]}
|
package/dist/index.d.cts
ADDED
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import { A as AbstractConstructor, C as ConcreteConstructor, a as Constructor, D as DiademContainer, b as DIContainer } from './container-C1FFn9_4.cjs';
|
|
2
|
+
export { c as Disposable, L as LifecycleType, T as Token } from './container-C1FFn9_4.cjs';
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Decorator-driven DI registration using class metadata instead of global state.
|
|
6
|
+
* This approach is SSR-safe and avoids global state issues.
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
type LifecycleType = 'singleton' | 'factory' | 'lazy' | 'lazySingleton';
|
|
10
|
+
interface DIMetadata {
|
|
11
|
+
token: AbstractConstructor;
|
|
12
|
+
lifecycle: LifecycleType;
|
|
13
|
+
environment?: string;
|
|
14
|
+
}
|
|
15
|
+
/**
|
|
16
|
+
* Get DI metadata from a class constructor
|
|
17
|
+
*/
|
|
18
|
+
declare function getDIMetadata(target: ConcreteConstructor): DIMetadata | null;
|
|
19
|
+
/**
|
|
20
|
+
* Check if a class has DI metadata
|
|
21
|
+
*/
|
|
22
|
+
declare function hasDIMetadata(target: ConcreteConstructor): boolean;
|
|
23
|
+
/**
|
|
24
|
+
* Decorator to register a class as a singleton.
|
|
25
|
+
* The class will be instantiated once per container and reused.
|
|
26
|
+
*
|
|
27
|
+
* @param token The interface/abstract class token to register the implementation against
|
|
28
|
+
* @param env Optional environment filter. If provided, the class will only be registered in that environment.
|
|
29
|
+
*
|
|
30
|
+
* @example
|
|
31
|
+
* ```typescript
|
|
32
|
+
* @singleton(IMyService)
|
|
33
|
+
* class MyService implements IMyService {
|
|
34
|
+
* // implementation
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* @singleton(IService, 'production')
|
|
38
|
+
* class ProductionOnlyService implements IService {
|
|
39
|
+
* // only registered in production environment
|
|
40
|
+
* }
|
|
41
|
+
* ```
|
|
42
|
+
*/
|
|
43
|
+
declare function singleton<T>(token: AbstractConstructor<T>, env?: string): <U extends ConcreteConstructor<T>>(target: U) => U;
|
|
44
|
+
/**
|
|
45
|
+
* Decorator to register a class as a factory.
|
|
46
|
+
* A new instance will be created each time the dependency is resolved.
|
|
47
|
+
*
|
|
48
|
+
* @param token The interface/abstract class token to register the implementation against
|
|
49
|
+
* @param env Optional environment filter. If provided, the class will only be registered in that environment.
|
|
50
|
+
*
|
|
51
|
+
* @example
|
|
52
|
+
* ```typescript
|
|
53
|
+
* @factory(ITransientService)
|
|
54
|
+
* class TransientService implements ITransientService {
|
|
55
|
+
* // new instance created on each resolve
|
|
56
|
+
* }
|
|
57
|
+
* ```
|
|
58
|
+
*/
|
|
59
|
+
declare function factory<T>(token: AbstractConstructor<T>, env?: string): <U extends ConcreteConstructor<T>>(target: U) => U;
|
|
60
|
+
/**
|
|
61
|
+
* Decorator to register a class as lazy.
|
|
62
|
+
* The class will be instantiated only when first resolved, then a new instance on each subsequent resolve.
|
|
63
|
+
*
|
|
64
|
+
* @param token The interface/abstract class token to register the implementation against
|
|
65
|
+
* @param env Optional environment filter. If provided, the class will only be registered in that environment.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```typescript
|
|
69
|
+
* @lazy(IExpensiveService)
|
|
70
|
+
* class ExpensiveService implements IExpensiveService {
|
|
71
|
+
* // only instantiated when first needed
|
|
72
|
+
* }
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
declare function lazy<T>(token: AbstractConstructor<T>, env?: string): <U extends ConcreteConstructor<T>>(target: U) => U;
|
|
76
|
+
/**
|
|
77
|
+
* Decorator to register a class as a lazy singleton.
|
|
78
|
+
* The class will be instantiated only when first resolved, then reused.
|
|
79
|
+
*
|
|
80
|
+
* @param token The interface/abstract class token to register the implementation against
|
|
81
|
+
* @param env Optional environment filter. If provided, the class will only be registered in that environment.
|
|
82
|
+
*
|
|
83
|
+
* @example
|
|
84
|
+
* ```typescript
|
|
85
|
+
* @lazySingleton(IDatabaseConnection)
|
|
86
|
+
* class DatabaseConnection implements IDatabaseConnection {
|
|
87
|
+
* // instantiated only when first needed, then reused
|
|
88
|
+
* }
|
|
89
|
+
* ```
|
|
90
|
+
*/
|
|
91
|
+
declare function lazySingleton<T>(token: AbstractConstructor<T>, env?: string): <U extends ConcreteConstructor<T>>(target: U) => U;
|
|
92
|
+
/**
|
|
93
|
+
* Auto-discovery helper that scans for decorated classes in the current context.
|
|
94
|
+
* This can be used to automatically find all decorated classes without manual imports.
|
|
95
|
+
*
|
|
96
|
+
* @param modules Array of module objects to scan
|
|
97
|
+
* @returns Combined array of all decorated classes found
|
|
98
|
+
// Auto-discovery from modules removed - use manifest-based auto-discovery instead
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Get registration statistics for debugging
|
|
102
|
+
*/
|
|
103
|
+
declare function getDIRegistrationStats(classes: ConcreteConstructor[]): {
|
|
104
|
+
total: number;
|
|
105
|
+
singletons: number;
|
|
106
|
+
factories: number;
|
|
107
|
+
lazy: number;
|
|
108
|
+
lazySingletons: number;
|
|
109
|
+
environments: string[];
|
|
110
|
+
};
|
|
111
|
+
/**
|
|
112
|
+
* Check if a class is registered for a specific environment.
|
|
113
|
+
*/
|
|
114
|
+
declare function isClassRegisteredForEnvironment(ClassConstructor: ConcreteConstructor, environment?: string): boolean;
|
|
115
|
+
|
|
116
|
+
/**
|
|
117
|
+
* Pluggable logging for Diadem.
|
|
118
|
+
*
|
|
119
|
+
* A library must not write to stdout/stderr unless asked to. By default Diadem
|
|
120
|
+
* uses a no-op logger and stays completely silent. Opt into diagnostics by
|
|
121
|
+
* registering a logger (e.g. the built-in {@link consoleLogger}, or your own
|
|
122
|
+
* pino/winston adapter):
|
|
123
|
+
*
|
|
124
|
+
* ```ts
|
|
125
|
+
* import { setLogger, consoleLogger } from '@devcraft-ts/diadem'
|
|
126
|
+
* setLogger(consoleLogger)
|
|
127
|
+
* ```
|
|
128
|
+
*/
|
|
129
|
+
interface Logger {
|
|
130
|
+
debug(...args: unknown[]): void;
|
|
131
|
+
info(...args: unknown[]): void;
|
|
132
|
+
warn(...args: unknown[]): void;
|
|
133
|
+
error(...args: unknown[]): void;
|
|
134
|
+
}
|
|
135
|
+
/** A logger that discards everything. The default. */
|
|
136
|
+
declare const noopLogger: Logger;
|
|
137
|
+
/** A logger that writes to the global `console`. Opt-in. */
|
|
138
|
+
declare const consoleLogger: Logger;
|
|
139
|
+
/**
|
|
140
|
+
* Set the active logger. Pass `null` to reset to the silent no-op logger.
|
|
141
|
+
*/
|
|
142
|
+
declare function setLogger(logger: Logger | null): void;
|
|
143
|
+
/** Get the active logger. Internal call sites log through this. */
|
|
144
|
+
declare function getLogger(): Logger;
|
|
145
|
+
|
|
146
|
+
/**
|
|
147
|
+
* Service manifest contract + injection seam.
|
|
148
|
+
*
|
|
149
|
+
* Diadem is a *build-time* DI container: a generator scans the consumer's
|
|
150
|
+
* source, extracts each service's constructor dependencies, topologically
|
|
151
|
+
* sorts them, and emits a manifest module. That generated module is NOT part
|
|
152
|
+
* of this package — it lives in the consumer's project. This file defines the
|
|
153
|
+
* shape such a module must conform to, and the seam through which it is plugged
|
|
154
|
+
* in at runtime.
|
|
155
|
+
*
|
|
156
|
+
* Usage in a consuming app:
|
|
157
|
+
* ```ts
|
|
158
|
+
* import { configureManifest } from '@devcraft-ts/diadem'
|
|
159
|
+
* import * as manifest from './generated/service-manifest'
|
|
160
|
+
*
|
|
161
|
+
* configureManifest(manifest)
|
|
162
|
+
* ```
|
|
163
|
+
*
|
|
164
|
+
* See `examples/basic.ts` for a complete, runnable example.
|
|
165
|
+
*/
|
|
166
|
+
|
|
167
|
+
/** A single constructor parameter of a service, as analysed at build time. */
|
|
168
|
+
interface ServiceDependency {
|
|
169
|
+
paramName: string;
|
|
170
|
+
paramIndex: number;
|
|
171
|
+
typeName: string;
|
|
172
|
+
isOptional: boolean;
|
|
173
|
+
isReadonly?: boolean;
|
|
174
|
+
isPrivate?: boolean;
|
|
175
|
+
/** Class name of the service that implements this dependency, if internal. */
|
|
176
|
+
implementingService?: string;
|
|
177
|
+
/** True when the dependency is not managed by the container. */
|
|
178
|
+
external?: boolean;
|
|
179
|
+
}
|
|
180
|
+
/** One service entry in the build-time manifest. */
|
|
181
|
+
interface ServiceManifestEntry {
|
|
182
|
+
className: string;
|
|
183
|
+
importPath: string;
|
|
184
|
+
lifecycle: 'dependency' | 'singleton' | 'factory' | 'lazy' | 'lazySingleton';
|
|
185
|
+
environment?: string;
|
|
186
|
+
exported: boolean;
|
|
187
|
+
filePath: string;
|
|
188
|
+
registrationOrder: number;
|
|
189
|
+
dependencies: ServiceDependency[];
|
|
190
|
+
resolvedDependencies: ServiceDependency[];
|
|
191
|
+
}
|
|
192
|
+
/** A loaded service class, paired with the manifest entry it came from. */
|
|
193
|
+
interface ImportedService {
|
|
194
|
+
entry: ServiceManifestEntry;
|
|
195
|
+
serviceClass: AbstractConstructor;
|
|
196
|
+
}
|
|
197
|
+
/**
|
|
198
|
+
* The shape of a generated manifest module. A consumer's build step emits a
|
|
199
|
+
* module exporting these members; pass that module to {@link configureManifest}.
|
|
200
|
+
*/
|
|
201
|
+
interface ServiceManifestModule {
|
|
202
|
+
SERVICE_MANIFEST: ServiceManifestEntry[];
|
|
203
|
+
SERVICE_CLASSES: Record<string, AbstractConstructor>;
|
|
204
|
+
SERVICES_BY_ENVIRONMENT?: Record<string, ServiceManifestEntry[]>;
|
|
205
|
+
MANIFEST_STATS?: unknown;
|
|
206
|
+
getServicesForEnvironment: (environment?: string) => ServiceManifestEntry[];
|
|
207
|
+
importService: (entry: ServiceManifestEntry) => Promise<AbstractConstructor>;
|
|
208
|
+
importAllServices: (entries: ServiceManifestEntry[]) => Promise<ImportedService[]>;
|
|
209
|
+
}
|
|
210
|
+
/**
|
|
211
|
+
* Register the generated manifest module so the container can discover and
|
|
212
|
+
* autowire services. Call once at application startup, before constructing a
|
|
213
|
+
* container that relies on auto-discovery.
|
|
214
|
+
*/
|
|
215
|
+
declare function configureManifest(manifest: ServiceManifestModule): void;
|
|
216
|
+
/** Returns the configured manifest, or null if none has been registered. */
|
|
217
|
+
declare function getManifest(): ServiceManifestModule | null;
|
|
218
|
+
/** True when a manifest has been registered via {@link configureManifest}. */
|
|
219
|
+
declare function hasManifest(): boolean;
|
|
220
|
+
/** Clear the registered manifest. Primarily useful in tests. */
|
|
221
|
+
declare function resetManifest(): void;
|
|
222
|
+
|
|
223
|
+
/**
|
|
224
|
+
* Core DI System - Core Module Exports
|
|
225
|
+
*
|
|
226
|
+
* This module exports the fundamental building blocks of the dependency injection system:
|
|
227
|
+
* - Container implementation
|
|
228
|
+
* - Decorators for service registration
|
|
229
|
+
* - Type definitions
|
|
230
|
+
*
|
|
231
|
+
* @example
|
|
232
|
+
* ```typescript
|
|
233
|
+
* import { DiademContainer, singleton, factory } from 'app/infrastructure/di/core'
|
|
234
|
+
* ```
|
|
235
|
+
*/
|
|
236
|
+
|
|
237
|
+
/**
|
|
238
|
+
* Common decorator combinations for convenience
|
|
239
|
+
*/
|
|
240
|
+
declare const decorators: {
|
|
241
|
+
readonly singleton: typeof singleton;
|
|
242
|
+
readonly factory: typeof factory;
|
|
243
|
+
readonly lazy: typeof lazy;
|
|
244
|
+
readonly lazySingleton: typeof lazySingleton;
|
|
245
|
+
};
|
|
246
|
+
/**
|
|
247
|
+
* Type helpers for better developer experience
|
|
248
|
+
*/
|
|
249
|
+
type ResolvedType<T> = T extends Constructor<infer U> ? U : never;
|
|
250
|
+
type ResolvedTypes<T extends ReadonlyArray<Constructor<unknown>>> = {
|
|
251
|
+
[K in keyof T]: T[K] extends Constructor<infer U> ? U : never;
|
|
252
|
+
};
|
|
253
|
+
type ServiceFactory<T> = () => T;
|
|
254
|
+
interface EnvironmentConfig {
|
|
255
|
+
environment?: string;
|
|
256
|
+
modules: Array<Record<string, unknown>>;
|
|
257
|
+
}
|
|
258
|
+
/**
|
|
259
|
+
* Utility functions for advanced usage
|
|
260
|
+
*/
|
|
261
|
+
/** Fluent builder returned by {@link createContainerBuilder}. */
|
|
262
|
+
interface ContainerBuilder {
|
|
263
|
+
register: <T>(token: Constructor<T>, implementation: T) => ContainerBuilder;
|
|
264
|
+
registerSingleton: <T>(token: Constructor<T>, factory: ServiceFactory<T>) => ContainerBuilder;
|
|
265
|
+
registerFactory: <T>(token: Constructor<T>, factory: ServiceFactory<T>) => ContainerBuilder;
|
|
266
|
+
build: () => DiademContainer;
|
|
267
|
+
}
|
|
268
|
+
declare function createContainerBuilder(): ContainerBuilder;
|
|
269
|
+
declare function createMockContainer(mocks?: Map<Constructor<unknown>, unknown>): DiademContainer;
|
|
270
|
+
/**
|
|
271
|
+
* Type guards for runtime type checking
|
|
272
|
+
*/
|
|
273
|
+
declare function isDIContainer(obj: unknown): obj is DIContainer;
|
|
274
|
+
declare function isDiademContainer(obj: unknown): obj is DiademContainer;
|
|
275
|
+
|
|
276
|
+
/**
|
|
277
|
+
* Diadem — main entry point.
|
|
278
|
+
*
|
|
279
|
+
* A build-time, manifest-driven DI container. SSR-safe and framework-agnostic:
|
|
280
|
+
* registration metadata lives on classes, never in global state.
|
|
281
|
+
*
|
|
282
|
+
* ```typescript
|
|
283
|
+
* import {
|
|
284
|
+
* DiademContainer,
|
|
285
|
+
* configureManifest,
|
|
286
|
+
* singleton,
|
|
287
|
+
* factory
|
|
288
|
+
* } from '@devcraft-ts/diadem'
|
|
289
|
+
* import * as manifest from './generated/service-manifest'
|
|
290
|
+
*
|
|
291
|
+
* configureManifest(manifest)
|
|
292
|
+
* const container = new DiademContainer()
|
|
293
|
+
* await container.autoRegisterDiscovered(process.env.NODE_ENV)
|
|
294
|
+
* const service = container.resolve(IMyService)
|
|
295
|
+
* ```
|
|
296
|
+
*/
|
|
297
|
+
|
|
298
|
+
/**
|
|
299
|
+
* Version and metadata
|
|
300
|
+
*/
|
|
301
|
+
declare const DI_VERSION = "0.1.0";
|
|
302
|
+
declare const DI_FEATURES: readonly ["type-safe", "ssr-safe", "decorator-driven", "auto-registration", "environment-aware", "server-safe", "no-global-state", "metadata-based", "zero-dependencies"];
|
|
303
|
+
|
|
304
|
+
export { AbstractConstructor, Constructor, type ContainerBuilder, DIContainer, type DIMetadata, DI_FEATURES, DI_VERSION, type LifecycleType as DecoratorLifecycleType, DiademContainer, type EnvironmentConfig, type ImportedService, type Logger, type ResolvedType, type ResolvedTypes, type ServiceDependency, type ServiceFactory, type ServiceManifestEntry, type ServiceManifestModule, configureManifest, consoleLogger, createContainerBuilder, createMockContainer, decorators, factory, getDIMetadata, getDIRegistrationStats, getLogger, getManifest, hasDIMetadata, hasManifest, isClassRegisteredForEnvironment, isDIContainer, isDiademContainer, lazy, lazySingleton, noopLogger, resetManifest, setLogger, singleton };
|