@vorra/core 0.3.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 ADDED
@@ -0,0 +1,15 @@
1
+ ## 0.3.0 (2026-04-12)
2
+
3
+ ### 🚀 Features
4
+
5
+ - add @for directive for reactive list rendering ([#9](https://github.com/ubergeoff/forge/pull/9))
6
+
7
+ ### ❤️ Thank You
8
+
9
+ - Claude Sonnet 4.6
10
+ - Geoffrey Le Roux
11
+ - ubergeoff @ubergeoff
12
+
13
+ ## 0.2.0 (2026-04-12)
14
+
15
+ This was a version bump only for core to align it with other projects, there were no code changes.
@@ -0,0 +1,31 @@
1
+ "use strict";
2
+ //#region rolldown:runtime
3
+ var __create = Object.create;
4
+ var __defProp = Object.defineProperty;
5
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
6
+ var __getOwnPropNames = Object.getOwnPropertyNames;
7
+ var __getProtoOf = Object.getPrototypeOf;
8
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
9
+ var __copyProps = (to, from, except, desc) => {
10
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
11
+ key = keys[i];
12
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
13
+ get: ((k) => from[k]).bind(null, key),
14
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
15
+ });
16
+ }
17
+ return to;
18
+ };
19
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", {
20
+ value: mod,
21
+ enumerable: true
22
+ }) : target, mod));
23
+
24
+ //#endregion
25
+
26
+ Object.defineProperty(exports, '__toESM', {
27
+ enumerable: true,
28
+ get: function () {
29
+ return __toESM;
30
+ }
31
+ });
package/dist/di.cjs ADDED
@@ -0,0 +1,273 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ //#region src/di.ts
3
+ const INJECTABLE_META = /* @__PURE__ */ new WeakMap();
4
+ /**
5
+ * Marks a class as injectable and configures where it is provided.
6
+ *
7
+ * @example
8
+ * \@Injectable({ providedIn: 'root' })
9
+ * class UserService {
10
+ * readonly users = signal<User[]>([]);
11
+ * }
12
+ */
13
+ function Injectable(options = {}) {
14
+ return (target) => {
15
+ const ctor = target;
16
+ const existing = INJECTABLE_META.get(ctor);
17
+ INJECTABLE_META.set(ctor, {
18
+ providedIn: options.providedIn ?? "root",
19
+ deps: existing?.deps ?? []
20
+ });
21
+ };
22
+ }
23
+ /**
24
+ * Declares the constructor dependencies for a class, enabling DI without
25
+ * TypeScript decorator metadata (emitDecoratorMetadata).
26
+ *
27
+ * @example
28
+ * \@Injectable({ providedIn: 'root' })
29
+ * \@Inject([HttpClient, AuthService])
30
+ * class UserService {
31
+ * constructor(private http: HttpClient, private auth: AuthService) {}
32
+ * }
33
+ */
34
+ function Inject(deps) {
35
+ return (target) => {
36
+ const ctor = target;
37
+ const existing = INJECTABLE_META.get(ctor);
38
+ if (existing) existing.deps = deps;
39
+ else INJECTABLE_META.set(ctor, {
40
+ providedIn: "root",
41
+ deps
42
+ });
43
+ };
44
+ }
45
+ let tokenIdCounter = 0;
46
+ /**
47
+ * A typed token used to inject values that aren't class instances — configs,
48
+ * primitives, interfaces, or abstract types.
49
+ *
50
+ * @example
51
+ * const API_URL = new InjectionToken<string>('API_URL', {
52
+ * providedIn: 'root',
53
+ * factory: () => 'https://api.example.com',
54
+ * });
55
+ *
56
+ * // Later:
57
+ * const url = inject(API_URL); // → 'https://api.example.com'
58
+ */
59
+ var InjectionToken = class {
60
+ constructor(description, options) {
61
+ this.id = ++tokenIdCounter;
62
+ this.description = description;
63
+ this.options = options;
64
+ }
65
+ toString() {
66
+ return `InjectionToken(${this.description})`;
67
+ }
68
+ };
69
+ const NOT_FOUND = Symbol("NOT_FOUND");
70
+ /**
71
+ * A hierarchical container that resolves and caches provider instances.
72
+ * Child injectors delegate to their parent when a token isn't found locally.
73
+ */
74
+ var Injector = class Injector {
75
+ constructor(providers = [], parent = null) {
76
+ this.parent = parent;
77
+ this.instances = /* @__PURE__ */ new Map();
78
+ this.resolving = /* @__PURE__ */ new Set();
79
+ this.providers = /* @__PURE__ */ new Map();
80
+ for (const p of providers) this.providers.set(p.provide, p);
81
+ }
82
+ get(token, optional = false) {
83
+ const result = this.resolve(token);
84
+ if (result === NOT_FOUND) {
85
+ if (optional) return null;
86
+ throw new Error(`[Vorra DI] No provider found for ${tokenName(token)}. Did you forget @Injectable() or to add it to your providers array?`);
87
+ }
88
+ return result;
89
+ }
90
+ resolve(token) {
91
+ if (this.instances.has(token)) return this.instances.get(token);
92
+ if (this.resolving.has(token)) throw new Error(`[Vorra DI] Circular dependency detected while resolving ${tokenName(token)}.`);
93
+ const provider = this.providers.get(token);
94
+ if (provider) {
95
+ this.resolving.add(token);
96
+ try {
97
+ const instance = this.instantiate(provider);
98
+ this.instances.set(token, instance);
99
+ return instance;
100
+ } finally {
101
+ this.resolving.delete(token);
102
+ }
103
+ }
104
+ if (token instanceof InjectionToken && token.options?.factory) {
105
+ const instance = runInContext(this, token.options.factory);
106
+ this.instances.set(token, instance);
107
+ return instance;
108
+ }
109
+ if (typeof token === "function") {
110
+ const meta = INJECTABLE_META.get(token);
111
+ if (meta) {
112
+ const targetInjector = this.resolveProvidedIn(meta.providedIn);
113
+ if (targetInjector === this) {
114
+ this.resolving.add(token);
115
+ try {
116
+ const instance = this.instantiateClass(token, meta.deps);
117
+ this.instances.set(token, instance);
118
+ return instance;
119
+ } finally {
120
+ this.resolving.delete(token);
121
+ }
122
+ } else if (targetInjector) return targetInjector.resolve(token);
123
+ }
124
+ }
125
+ if (this.parent) return this.parent.resolve(token);
126
+ return NOT_FOUND;
127
+ }
128
+ instantiate(provider) {
129
+ if ("useValue" in provider) return provider.useValue;
130
+ if ("useExisting" in provider) return this.get(provider.useExisting);
131
+ if ("useFactory" in provider) {
132
+ const deps = (provider.deps ?? []).map((dep) => this.get(dep));
133
+ return provider.useFactory(...deps);
134
+ }
135
+ const deps = (provider.deps ?? []).map((dep) => this.get(dep));
136
+ return new provider.useClass(...deps);
137
+ }
138
+ instantiateClass(ctor, deps) {
139
+ return new ctor(...deps.map((dep) => this.get(dep)));
140
+ }
141
+ resolveProvidedIn(providedIn) {
142
+ if (providedIn === "root") return getRootInjector();
143
+ if (providedIn === "component") return this;
144
+ if (providedIn instanceof Injector) return providedIn;
145
+ return null;
146
+ }
147
+ /**
148
+ * Creates a child injector that inherits from this one.
149
+ * Child providers shadow parent providers for the same token.
150
+ */
151
+ createChild(providers = []) {
152
+ return new Injector(providers, this);
153
+ }
154
+ /**
155
+ * Destroys this injector — calls onDestroy() on any instances that
156
+ * implement it, then clears all cached instances.
157
+ */
158
+ destroy() {
159
+ for (const instance of this.instances.values()) if (instance !== null && typeof instance === "object" && typeof instance.onDestroy === "function") instance.onDestroy();
160
+ this.instances.clear();
161
+ this.providers.clear();
162
+ }
163
+ };
164
+ let _rootInjector = null;
165
+ function getRootInjector() {
166
+ if (!_rootInjector) _rootInjector = new Injector();
167
+ return _rootInjector;
168
+ }
169
+ /**
170
+ * Bootstraps the application by creating the root injector with the given
171
+ * providers. Should be called once at app startup.
172
+ *
173
+ * @example
174
+ * bootstrapApp([
175
+ * { provide: API_URL, useValue: 'https://api.example.com' },
176
+ * ]);
177
+ */
178
+ function bootstrapApp(providers = []) {
179
+ _rootInjector = new Injector(providers);
180
+ return _rootInjector;
181
+ }
182
+ /** Resets the root injector — primarily useful in tests. */
183
+ function resetRootInjector() {
184
+ _rootInjector?.destroy();
185
+ _rootInjector = null;
186
+ }
187
+ /**
188
+ * The active injector context for inject() calls.
189
+ * Set during component/service instantiation.
190
+ */
191
+ let activeInjector = null;
192
+ /**
193
+ * Runs a function within a specific injector context, making inject() calls
194
+ * inside resolve against that injector.
195
+ */
196
+ function runInContext(injector, fn) {
197
+ const prev = activeInjector;
198
+ activeInjector = injector;
199
+ try {
200
+ return fn();
201
+ } finally {
202
+ activeInjector = prev;
203
+ }
204
+ }
205
+ /**
206
+ * Returns the currently active injector, or null if called outside an
207
+ * injection context.
208
+ */
209
+ function getActiveInjector() {
210
+ return activeInjector;
211
+ }
212
+ function inject(token, options = {}) {
213
+ if (!activeInjector) throw new Error("[Vorra DI] inject() called outside of an injection context. inject() can only be used during component or service construction.");
214
+ return activeInjector.get(token, options.optional);
215
+ }
216
+ function tokenName(token) {
217
+ if (token instanceof InjectionToken) return token.toString();
218
+ if (typeof token === "function") return token.name || "(anonymous class)";
219
+ return String(token);
220
+ }
221
+ /**
222
+ * Registers a cleanup callback to run when the injector that owns this
223
+ * service instance is destroyed.
224
+ *
225
+ * Call this inside a service constructor (within an injection context).
226
+ *
227
+ * @example
228
+ * \@Injectable({ providedIn: 'root' })
229
+ * class WebSocketService {
230
+ * #ws: WebSocket;
231
+ * constructor() {
232
+ * this.#ws = new WebSocket('wss://...');
233
+ * onDestroy(() => this.#ws.close());
234
+ * }
235
+ * }
236
+ */
237
+ function onDestroy(fn) {
238
+ if (!activeInjector) throw new Error("[Vorra DI] onDestroy() must be called within an injection context.");
239
+ new InjectionToken(`__destroyRef__`);
240
+ getOrCreateDestroyRef(activeInjector).callbacks.push(fn);
241
+ }
242
+ const destroyRefs = /* @__PURE__ */ new WeakMap();
243
+ function getOrCreateDestroyRef(injector) {
244
+ if (!destroyRefs.has(injector)) destroyRefs.set(injector, { callbacks: [] });
245
+ return destroyRefs.get(injector);
246
+ }
247
+ /**
248
+ * Runs all onDestroy callbacks registered against an injector.
249
+ * Called automatically by Injector.destroy(), but also exported for
250
+ * use in the component runtime.
251
+ */
252
+ function runDestroyCallbacks(injector) {
253
+ const ref = destroyRefs.get(injector);
254
+ if (ref) {
255
+ for (const cb of ref.callbacks) cb();
256
+ ref.callbacks = [];
257
+ }
258
+ }
259
+ //#endregion
260
+ exports.Inject = Inject;
261
+ exports.Injectable = Injectable;
262
+ exports.InjectionToken = InjectionToken;
263
+ exports.Injector = Injector;
264
+ exports.bootstrapApp = bootstrapApp;
265
+ exports.getActiveInjector = getActiveInjector;
266
+ exports.getRootInjector = getRootInjector;
267
+ exports.inject = inject;
268
+ exports.onDestroy = onDestroy;
269
+ exports.resetRootInjector = resetRootInjector;
270
+ exports.runDestroyCallbacks = runDestroyCallbacks;
271
+ exports.runInContext = runInContext;
272
+
273
+ //# sourceMappingURL=di.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di.cjs","names":[],"sources":["../src/di.ts"],"sourcesContent":["// =============================================================================\r\n// Vorra DI System\r\n// Injectable / InjectionToken / inject() / Injector / runInContext()\r\n// =============================================================================\r\n\r\nimport type { WritableSignal, ReadonlySignal } from './reactivity';\r\n\r\n// ---------------------------------------------------------------------------\r\n// Types\r\n// ---------------------------------------------------------------------------\r\n\r\n/** Where a provider is instantiated in the injector tree. */\r\nexport type ProvidedIn = 'root' | 'component' | Injector;\r\n\r\nexport interface InjectableOptions {\r\n providedIn?: ProvidedIn;\r\n}\r\n\r\n/** Describes how to provide a value for a given token. */\r\nexport type Provider<T> =\r\n | ClassProvider<T>\r\n | ValueProvider<T>\r\n | FactoryProvider<T>\r\n | ExistingProvider<T>;\r\n\r\nexport interface ClassProvider<T> {\r\n provide: Token<T>;\r\n useClass: new (...args: unknown[]) => T;\r\n deps?: Token<unknown>[];\r\n}\r\n\r\nexport interface ValueProvider<T> {\r\n provide: Token<T>;\r\n useValue: T;\r\n}\r\n\r\nexport interface FactoryProvider<T> {\r\n provide: Token<T>;\r\n useFactory: (...args: unknown[]) => T;\r\n deps?: Token<unknown>[];\r\n}\r\n\r\nexport interface ExistingProvider<T> {\r\n provide: Token<T>;\r\n useExisting: Token<T>;\r\n}\r\n\r\n/** Anything that can be used as a DI token. */\r\nexport type Token<T> =\r\n | (new (...args: unknown[]) => T)\r\n | InjectionToken<T>\r\n | AbstractToken<T>;\r\n\r\n/** Marker interface for abstract class tokens. */\r\nexport interface AbstractToken<T> {\r\n readonly __tokenType: T;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// INJECTABLE_META — metadata store for @Injectable classes\r\n// ---------------------------------------------------------------------------\r\n\r\nconst INJECTABLE_META = new WeakMap<\r\n new (...args: unknown[]) => unknown,\r\n { providedIn: ProvidedIn; deps: Token<unknown>[] }\r\n>();\r\n\r\n// ---------------------------------------------------------------------------\r\n// @Injectable decorator\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Marks a class as injectable and configures where it is provided.\r\n *\r\n * @example\r\n * \\@Injectable({ providedIn: 'root' })\r\n * class UserService {\r\n * readonly users = signal<User[]>([]);\r\n * }\r\n */\r\nexport function Injectable(options: InjectableOptions = {}): ClassDecorator {\r\n return (target: unknown) => {\r\n const ctor = target as new (...args: unknown[]) => unknown;\r\n const existing = INJECTABLE_META.get(ctor);\r\n INJECTABLE_META.set(ctor, {\r\n providedIn: options.providedIn ?? 'root',\r\n deps: existing?.deps ?? [],\r\n });\r\n };\r\n}\r\n\r\n/**\r\n * Declares the constructor dependencies for a class, enabling DI without\r\n * TypeScript decorator metadata (emitDecoratorMetadata).\r\n *\r\n * @example\r\n * \\@Injectable({ providedIn: 'root' })\r\n * \\@Inject([HttpClient, AuthService])\r\n * class UserService {\r\n * constructor(private http: HttpClient, private auth: AuthService) {}\r\n * }\r\n */\r\nexport function Inject(deps: Token<unknown>[]): ClassDecorator {\r\n return (target: unknown) => {\r\n const ctor = target as new (...args: unknown[]) => unknown;\r\n const existing = INJECTABLE_META.get(ctor);\r\n if (existing) {\r\n existing.deps = deps;\r\n } else {\r\n INJECTABLE_META.set(ctor, { providedIn: 'root', deps });\r\n }\r\n };\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// InjectionToken\r\n// ---------------------------------------------------------------------------\r\n\r\nlet tokenIdCounter = 0;\r\n\r\n/**\r\n * A typed token used to inject values that aren't class instances — configs,\r\n * primitives, interfaces, or abstract types.\r\n *\r\n * @example\r\n * const API_URL = new InjectionToken<string>('API_URL', {\r\n * providedIn: 'root',\r\n * factory: () => 'https://api.example.com',\r\n * });\r\n *\r\n * // Later:\r\n * const url = inject(API_URL); // → 'https://api.example.com'\r\n */\r\nexport class InjectionToken<T> {\r\n readonly __tokenType!: T; // phantom type only — never assigned at runtime\r\n readonly id: number;\r\n readonly description: string;\r\n readonly options?: {\r\n providedIn?: ProvidedIn;\r\n factory?: () => T;\r\n };\r\n\r\n constructor(\r\n description: string,\r\n options?: { providedIn?: ProvidedIn; factory?: () => T }\r\n ) {\r\n this.id = ++tokenIdCounter;\r\n this.description = description;\r\n this.options = options;\r\n }\r\n\r\n toString(): string {\r\n return `InjectionToken(${this.description})`;\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Injector\r\n// ---------------------------------------------------------------------------\r\n\r\nconst NOT_FOUND = Symbol('NOT_FOUND');\r\nconst CIRCULAR = Symbol('CIRCULAR');\r\n\r\n/**\r\n * A hierarchical container that resolves and caches provider instances.\r\n * Child injectors delegate to their parent when a token isn't found locally.\r\n */\r\nexport class Injector {\r\n private readonly instances = new Map<Token<unknown>, unknown>();\r\n private readonly resolving = new Set<Token<unknown>>();\r\n private readonly providers = new Map<Token<unknown>, Provider<unknown>>();\r\n\r\n constructor(\r\n providers: Provider<unknown>[] = [],\r\n private readonly parent: Injector | null = null\r\n ) {\r\n for (const p of providers) {\r\n this.providers.set(p.provide, p);\r\n }\r\n }\r\n\r\n /**\r\n * Resolves a token to its instance. Throws if the token cannot be resolved\r\n * and `optional` is false (the default).\r\n */\r\n get<T>(token: Token<T>, optional?: false): T;\r\n get<T>(token: Token<T>, optional: true): T | null;\r\n get<T>(token: Token<T>, optional = false): T | null {\r\n const result = this.resolve(token);\r\n if (result === NOT_FOUND) {\r\n if (optional) return null;\r\n throw new Error(\r\n `[Vorra DI] No provider found for ${tokenName(token)}. ` +\r\n `Did you forget @Injectable() or to add it to your providers array?`\r\n );\r\n }\r\n return result as T;\r\n }\r\n\r\n private resolve<T>(token: Token<T>): T | typeof NOT_FOUND {\r\n // 1. Return cached instance\r\n if (this.instances.has(token)) {\r\n return this.instances.get(token) as T;\r\n }\r\n\r\n // 2. Circular dependency guard\r\n if (this.resolving.has(token)) {\r\n throw new Error(\r\n `[Vorra DI] Circular dependency detected while resolving ${tokenName(token)}.`\r\n );\r\n }\r\n\r\n // 3. Check local provider registry\r\n const provider = this.providers.get(token);\r\n if (provider) {\r\n this.resolving.add(token);\r\n try {\r\n const instance = this.instantiate(provider) as T;\r\n this.instances.set(token, instance);\r\n return instance;\r\n } finally {\r\n this.resolving.delete(token);\r\n }\r\n }\r\n\r\n // 4. Handle InjectionToken with a factory (self-providing tokens)\r\n if (token instanceof InjectionToken && token.options?.factory) {\r\n const instance = runInContext(this, token.options.factory) as T;\r\n this.instances.set(token, instance);\r\n return instance;\r\n }\r\n\r\n // 5. Handle @Injectable classes with providedIn: 'root' / this injector\r\n if (typeof token === 'function') {\r\n const meta = INJECTABLE_META.get(token as new (...args: unknown[]) => unknown);\r\n if (meta) {\r\n const targetInjector = this.resolveProvidedIn(meta.providedIn);\r\n if (targetInjector === this) {\r\n this.resolving.add(token);\r\n try {\r\n const instance = this.instantiateClass(\r\n token as new (...args: unknown[]) => T,\r\n meta.deps\r\n );\r\n this.instances.set(token, instance);\r\n return instance;\r\n } finally {\r\n this.resolving.delete(token);\r\n }\r\n } else if (targetInjector) {\r\n // Delegate to the appropriate injector in the tree\r\n return targetInjector.resolve(token);\r\n }\r\n }\r\n }\r\n\r\n // 6. Delegate to parent\r\n if (this.parent) {\r\n return this.parent.resolve(token);\r\n }\r\n\r\n return NOT_FOUND as typeof NOT_FOUND;\r\n }\r\n\r\n private instantiate<T>(provider: Provider<T>): T {\r\n if ('useValue' in provider) {\r\n return provider.useValue;\r\n }\r\n\r\n if ('useExisting' in provider) {\r\n return this.get(provider.useExisting);\r\n }\r\n\r\n if ('useFactory' in provider) {\r\n const deps = (provider.deps ?? []).map(dep => this.get(dep));\r\n return provider.useFactory(...deps) as T;\r\n }\r\n\r\n // useClass\r\n const deps = (provider.deps ?? []).map(dep => this.get(dep));\r\n return new provider.useClass(...deps) as T;\r\n }\r\n\r\n private instantiateClass<T>(\r\n ctor: new (...args: unknown[]) => T,\r\n deps: Token<unknown>[]\r\n ): T {\r\n const resolved = deps.map(dep => this.get(dep));\r\n return new ctor(...resolved);\r\n }\r\n\r\n private resolveProvidedIn(providedIn: ProvidedIn): Injector | null {\r\n if (providedIn === 'root') return getRootInjector();\r\n if (providedIn === 'component') return this;\r\n if (providedIn instanceof Injector) return providedIn;\r\n return null;\r\n }\r\n\r\n /**\r\n * Creates a child injector that inherits from this one.\r\n * Child providers shadow parent providers for the same token.\r\n */\r\n createChild(providers: Provider<unknown>[] = []): Injector {\r\n return new Injector(providers, this);\r\n }\r\n\r\n /**\r\n * Destroys this injector — calls onDestroy() on any instances that\r\n * implement it, then clears all cached instances.\r\n */\r\n destroy(): void {\r\n for (const instance of this.instances.values()) {\r\n if (\r\n instance !== null &&\r\n typeof instance === 'object' &&\r\n typeof (instance as { onDestroy?: () => void }).onDestroy === 'function'\r\n ) {\r\n (instance as { onDestroy: () => void }).onDestroy();\r\n }\r\n }\r\n this.instances.clear();\r\n this.providers.clear();\r\n }\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Root injector (app-level singleton)\r\n// ---------------------------------------------------------------------------\r\n\r\nlet _rootInjector: Injector | null = null;\r\n\r\nexport function getRootInjector(): Injector {\r\n if (!_rootInjector) {\r\n _rootInjector = new Injector();\r\n }\r\n return _rootInjector;\r\n}\r\n\r\n/**\r\n * Bootstraps the application by creating the root injector with the given\r\n * providers. Should be called once at app startup.\r\n *\r\n * @example\r\n * bootstrapApp([\r\n * { provide: API_URL, useValue: 'https://api.example.com' },\r\n * ]);\r\n */\r\nexport function bootstrapApp(providers: Provider<unknown>[] = []): Injector {\r\n _rootInjector = new Injector(providers);\r\n return _rootInjector;\r\n}\r\n\r\n/** Resets the root injector — primarily useful in tests. */\r\nexport function resetRootInjector(): void {\r\n _rootInjector?.destroy();\r\n _rootInjector = null;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Injection context\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * The active injector context for inject() calls.\r\n * Set during component/service instantiation.\r\n */\r\nlet activeInjector: Injector | null = null;\r\n\r\n/**\r\n * Runs a function within a specific injector context, making inject() calls\r\n * inside resolve against that injector.\r\n */\r\nexport function runInContext<T>(injector: Injector, fn: () => T): T {\r\n const prev = activeInjector;\r\n activeInjector = injector;\r\n try {\r\n return fn();\r\n } finally {\r\n activeInjector = prev;\r\n }\r\n}\r\n\r\n/**\r\n * Returns the currently active injector, or null if called outside an\r\n * injection context.\r\n */\r\nexport function getActiveInjector(): Injector | null {\r\n return activeInjector;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// inject()\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Resolves a token from the current injection context.\r\n * Must be called during component or service construction.\r\n *\r\n * @example\r\n * \\@Injectable({ providedIn: 'root' })\r\n * class DashboardComponent {\r\n * private users = inject(UserService);\r\n * private apiUrl = inject(API_URL);\r\n * }\r\n */\r\nexport function inject<T>(token: Token<T>, options?: { optional?: false }): T;\r\nexport function inject<T>(token: Token<T>, options: { optional: true }): T | null;\r\nexport function inject<T>(\r\n token: Token<T>,\r\n options: { optional?: boolean } = {}\r\n): T | null {\r\n if (!activeInjector) {\r\n throw new Error(\r\n `[Vorra DI] inject() called outside of an injection context. ` +\r\n `inject() can only be used during component or service construction.`\r\n );\r\n }\r\n return activeInjector.get(token, options.optional as true) as T | null;\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// Helper: resolve token display name for error messages\r\n// ---------------------------------------------------------------------------\r\n\r\nfunction tokenName(token: Token<unknown>): string {\r\n if (token instanceof InjectionToken) return token.toString();\r\n if (typeof token === 'function') return token.name || '(anonymous class)';\r\n return String(token);\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// onDestroy() — lifecycle hook helper for services\r\n// ---------------------------------------------------------------------------\r\n\r\n/**\r\n * Registers a cleanup callback to run when the injector that owns this\r\n * service instance is destroyed.\r\n *\r\n * Call this inside a service constructor (within an injection context).\r\n *\r\n * @example\r\n * \\@Injectable({ providedIn: 'root' })\r\n * class WebSocketService {\r\n * #ws: WebSocket;\r\n * constructor() {\r\n * this.#ws = new WebSocket('wss://...');\r\n * onDestroy(() => this.#ws.close());\r\n * }\r\n * }\r\n */\r\nexport function onDestroy(fn: () => void): void {\r\n if (!activeInjector) {\r\n throw new Error('[Vorra DI] onDestroy() must be called within an injection context.');\r\n }\r\n // Attach the cleanup to a sentinel object in the injector under a unique token\r\n const token = new InjectionToken<DestroyRef>(`__destroyRef__`);\r\n // We piggyback on a shared DestroyRef list attached to the active injector\r\n getOrCreateDestroyRef(activeInjector).callbacks.push(fn);\r\n}\r\n\r\n// ---------------------------------------------------------------------------\r\n// DestroyRef — internal lifecycle tracking\r\n// ---------------------------------------------------------------------------\r\n\r\ninterface DestroyRef {\r\n callbacks: (() => void)[];\r\n}\r\n\r\nconst destroyRefs = new WeakMap<Injector, DestroyRef>();\r\n\r\nfunction getOrCreateDestroyRef(injector: Injector): DestroyRef {\r\n if (!destroyRefs.has(injector)) {\r\n destroyRefs.set(injector, { callbacks: [] });\r\n }\r\n return destroyRefs.get(injector)!;\r\n}\r\n\r\n/**\r\n * Runs all onDestroy callbacks registered against an injector.\r\n * Called automatically by Injector.destroy(), but also exported for\r\n * use in the component runtime.\r\n */\r\nexport function runDestroyCallbacks(injector: Injector): void {\r\n const ref = destroyRefs.get(injector);\r\n if (ref) {\r\n for (const cb of ref.callbacks) cb();\r\n ref.callbacks = [];\r\n }\r\n}\r\n"],"mappings":"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"}
package/dist/di.d.ts ADDED
@@ -0,0 +1,175 @@
1
+ /** Where a provider is instantiated in the injector tree. */
2
+ export type ProvidedIn = 'root' | 'component' | Injector;
3
+ export interface InjectableOptions {
4
+ providedIn?: ProvidedIn;
5
+ }
6
+ /** Describes how to provide a value for a given token. */
7
+ export type Provider<T> = ClassProvider<T> | ValueProvider<T> | FactoryProvider<T> | ExistingProvider<T>;
8
+ export interface ClassProvider<T> {
9
+ provide: Token<T>;
10
+ useClass: new (...args: unknown[]) => T;
11
+ deps?: Token<unknown>[];
12
+ }
13
+ export interface ValueProvider<T> {
14
+ provide: Token<T>;
15
+ useValue: T;
16
+ }
17
+ export interface FactoryProvider<T> {
18
+ provide: Token<T>;
19
+ useFactory: (...args: unknown[]) => T;
20
+ deps?: Token<unknown>[];
21
+ }
22
+ export interface ExistingProvider<T> {
23
+ provide: Token<T>;
24
+ useExisting: Token<T>;
25
+ }
26
+ /** Anything that can be used as a DI token. */
27
+ export type Token<T> = (new (...args: unknown[]) => T) | InjectionToken<T> | AbstractToken<T>;
28
+ /** Marker interface for abstract class tokens. */
29
+ export interface AbstractToken<T> {
30
+ readonly __tokenType: T;
31
+ }
32
+ /**
33
+ * Marks a class as injectable and configures where it is provided.
34
+ *
35
+ * @example
36
+ * \@Injectable({ providedIn: 'root' })
37
+ * class UserService {
38
+ * readonly users = signal<User[]>([]);
39
+ * }
40
+ */
41
+ export declare function Injectable(options?: InjectableOptions): ClassDecorator;
42
+ /**
43
+ * Declares the constructor dependencies for a class, enabling DI without
44
+ * TypeScript decorator metadata (emitDecoratorMetadata).
45
+ *
46
+ * @example
47
+ * \@Injectable({ providedIn: 'root' })
48
+ * \@Inject([HttpClient, AuthService])
49
+ * class UserService {
50
+ * constructor(private http: HttpClient, private auth: AuthService) {}
51
+ * }
52
+ */
53
+ export declare function Inject(deps: Token<unknown>[]): ClassDecorator;
54
+ /**
55
+ * A typed token used to inject values that aren't class instances — configs,
56
+ * primitives, interfaces, or abstract types.
57
+ *
58
+ * @example
59
+ * const API_URL = new InjectionToken<string>('API_URL', {
60
+ * providedIn: 'root',
61
+ * factory: () => 'https://api.example.com',
62
+ * });
63
+ *
64
+ * // Later:
65
+ * const url = inject(API_URL); // → 'https://api.example.com'
66
+ */
67
+ export declare class InjectionToken<T> {
68
+ readonly __tokenType: T;
69
+ readonly id: number;
70
+ readonly description: string;
71
+ readonly options?: {
72
+ providedIn?: ProvidedIn;
73
+ factory?: () => T;
74
+ };
75
+ constructor(description: string, options?: {
76
+ providedIn?: ProvidedIn;
77
+ factory?: () => T;
78
+ });
79
+ toString(): string;
80
+ }
81
+ /**
82
+ * A hierarchical container that resolves and caches provider instances.
83
+ * Child injectors delegate to their parent when a token isn't found locally.
84
+ */
85
+ export declare class Injector {
86
+ private readonly parent;
87
+ private readonly instances;
88
+ private readonly resolving;
89
+ private readonly providers;
90
+ constructor(providers?: Provider<unknown>[], parent?: Injector | null);
91
+ /**
92
+ * Resolves a token to its instance. Throws if the token cannot be resolved
93
+ * and `optional` is false (the default).
94
+ */
95
+ get<T>(token: Token<T>, optional?: false): T;
96
+ get<T>(token: Token<T>, optional: true): T | null;
97
+ private resolve;
98
+ private instantiate;
99
+ private instantiateClass;
100
+ private resolveProvidedIn;
101
+ /**
102
+ * Creates a child injector that inherits from this one.
103
+ * Child providers shadow parent providers for the same token.
104
+ */
105
+ createChild(providers?: Provider<unknown>[]): Injector;
106
+ /**
107
+ * Destroys this injector — calls onDestroy() on any instances that
108
+ * implement it, then clears all cached instances.
109
+ */
110
+ destroy(): void;
111
+ }
112
+ export declare function getRootInjector(): Injector;
113
+ /**
114
+ * Bootstraps the application by creating the root injector with the given
115
+ * providers. Should be called once at app startup.
116
+ *
117
+ * @example
118
+ * bootstrapApp([
119
+ * { provide: API_URL, useValue: 'https://api.example.com' },
120
+ * ]);
121
+ */
122
+ export declare function bootstrapApp(providers?: Provider<unknown>[]): Injector;
123
+ /** Resets the root injector — primarily useful in tests. */
124
+ export declare function resetRootInjector(): void;
125
+ /**
126
+ * Runs a function within a specific injector context, making inject() calls
127
+ * inside resolve against that injector.
128
+ */
129
+ export declare function runInContext<T>(injector: Injector, fn: () => T): T;
130
+ /**
131
+ * Returns the currently active injector, or null if called outside an
132
+ * injection context.
133
+ */
134
+ export declare function getActiveInjector(): Injector | null;
135
+ /**
136
+ * Resolves a token from the current injection context.
137
+ * Must be called during component or service construction.
138
+ *
139
+ * @example
140
+ * \@Injectable({ providedIn: 'root' })
141
+ * class DashboardComponent {
142
+ * private users = inject(UserService);
143
+ * private apiUrl = inject(API_URL);
144
+ * }
145
+ */
146
+ export declare function inject<T>(token: Token<T>, options?: {
147
+ optional?: false;
148
+ }): T;
149
+ export declare function inject<T>(token: Token<T>, options: {
150
+ optional: true;
151
+ }): T | null;
152
+ /**
153
+ * Registers a cleanup callback to run when the injector that owns this
154
+ * service instance is destroyed.
155
+ *
156
+ * Call this inside a service constructor (within an injection context).
157
+ *
158
+ * @example
159
+ * \@Injectable({ providedIn: 'root' })
160
+ * class WebSocketService {
161
+ * #ws: WebSocket;
162
+ * constructor() {
163
+ * this.#ws = new WebSocket('wss://...');
164
+ * onDestroy(() => this.#ws.close());
165
+ * }
166
+ * }
167
+ */
168
+ export declare function onDestroy(fn: () => void): void;
169
+ /**
170
+ * Runs all onDestroy callbacks registered against an injector.
171
+ * Called automatically by Injector.destroy(), but also exported for
172
+ * use in the component runtime.
173
+ */
174
+ export declare function runDestroyCallbacks(injector: Injector): void;
175
+ //# sourceMappingURL=di.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"di.d.ts","sourceRoot":"","sources":["../src/di.ts"],"names":[],"mappings":"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"}