UNPKG

@tdi2/di-core

Version:

TypeScript Dependency Injection 2 - Core DI framework

204 lines (201 loc) 7.08 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __name = (target, value) => __defProp(target, "name", { value, configurable: true }); var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); // src/context.tsx import * as React from "react"; import { createContext, useContext } from "react"; // src/container.ts var _CompileTimeDIContainer = class _CompileTimeDIContainer { constructor(parent) { __publicField(this, "services", /* @__PURE__ */ new Map()); __publicField(this, "instances", /* @__PURE__ */ new Map()); __publicField(this, "factories", /* @__PURE__ */ new Map()); __publicField(this, "scopes", /* @__PURE__ */ new Map()); __publicField(this, "parent"); this.parent = parent; } register(token, implementation, scope = "singleton") { const tokenKey = this.getTokenKey(token); if (typeof implementation === "function") { try { const result = implementation(this); if (typeof result === "function") { this.factories.set(tokenKey, result); } else { this.services.set(tokenKey, implementation); } } catch (e) { this.services.set(tokenKey, implementation); } } else { this.instances.set(tokenKey, implementation); } this.scopes.set(tokenKey, scope); } resolve(token) { const tokenKey = this.getTokenKey(token); if (this.scopes.get(tokenKey) === "singleton" && this.instances.has(tokenKey)) { return this.instances.get(tokenKey); } if (!this.has(token) && this.parent) { return this.parent.resolve(token); } let instance; if (this.factories.has(tokenKey)) { const factory = this.factories.get(tokenKey); instance = factory(); } else if (this.services.has(tokenKey)) { const constructor = this.services.get(tokenKey); if (typeof constructor === "function") { instance = new constructor(); } else { instance = constructor; } } else { throw new Error(`Service not registered: ${String(token)}`); } if (this.scopes.get(tokenKey) === "singleton") { this.instances.set(tokenKey, instance); } return instance; } has(token) { const tokenKey = this.getTokenKey(token); return this.factories.has(tokenKey) || this.services.has(tokenKey) || this.instances.has(tokenKey) || (this.parent?.has(token) ?? false); } createScope() { return new _CompileTimeDIContainer(this); } // FIXED: Enhanced loadConfiguration method with better logging loadConfiguration(diMap) { console.log("\u{1F527} Loading DI configuration..."); console.log("\u{1F4CB} DI_CONFIG keys:", Object.keys(diMap)); for (const [token, config] of Object.entries(diMap)) { try { if (!config.factory) { console.warn(`\u26A0\uFE0F No factory found for token: ${token}`); continue; } console.log(`\u{1F517} Registering: ${token} -> ${config.implementationClass || "unknown"}`); const factory = config.factory(this); this.factories.set(token, factory); this.scopes.set(token, config.scope); } catch (error) { console.error(`\u274C Failed to register ${token}:`, error); } } console.log("\u2705 DI configuration loaded"); } getTokenKey(token) { return typeof token === "symbol" ? token.toString() : token; } // Enhanced debug method to see what's registered getRegisteredTokens() { const tokens = /* @__PURE__ */ new Set(); this.factories.forEach((_, key) => tokens.add(this.getTokenKey(key))); this.services.forEach((_, key) => tokens.add(this.getTokenKey(key))); this.instances.forEach((_, key) => tokens.add(this.getTokenKey(key))); return Array.from(tokens); } // NEW: Debug method to inspect the current state debugContainer() { console.log("\u{1F50D} Container Debug Info:"); console.log("\u{1F4CB} Factories:", Array.from(this.factories.keys())); console.log("\u{1F3D7}\uFE0F Services:", Array.from(this.services.keys())); console.log("\u{1F4E6} Instances:", Array.from(this.instances.keys())); console.log("\u{1F3AF} Scopes:", Array.from(this.scopes.entries())); } // NEW: Method to register by interface (for enhanced interface-based DI) registerByInterface(interfaceName, implementation, scope = "singleton") { this.register(interfaceName, implementation, scope); } // NEW: Method to resolve by interface resolveByInterface(interfaceName) { return this.resolve(interfaceName); } // NEW: Method to check if interface is registered hasInterface(interfaceName) { return this.has(interfaceName); } }; __name(_CompileTimeDIContainer, "CompileTimeDIContainer"); var CompileTimeDIContainer = _CompileTimeDIContainer; // src/context.tsx import { proxy, useSnapshot } from "valtio"; var DIContext = /* @__PURE__ */ createContext(null); function DIProvider({ container, children }) { const diContainer = container || new CompileTimeDIContainer(); return /* @__PURE__ */ React.createElement(DIContext.Provider, { value: diContainer }, children); } __name(DIProvider, "DIProvider"); function useDI() { const container = useContext(DIContext); if (!container) { throw new Error("useDI must be used within a DIProvider"); } return container; } __name(useDI, "useDI"); function useService(token) { const container = useDI(); const [_] = React.useState(proxy(container.resolve(token))); if (_ === void 0) { throw new Error(`Service not found: ${String(token)}`); } useSnapshot(_); return _; } __name(useService, "useService"); function useOptionalService(token) { const container = useDI(); try { if (container.has(token)) { return container.resolve(token); } return void 0; } catch (error) { console.warn(`Optional service not found: ${String(token)}`); return void 0; } } __name(useOptionalService, "useOptionalService"); function useServices(serviceMap) { const container = useDI(); const services = {}; for (const [key, token] of Object.entries(serviceMap)) { services[key] = container.resolve(token); } return services; } __name(useServices, "useServices"); function useFunctionalDI(dependencies) { const container = useDI(); const services = {}; for (const dep of dependencies) { if (dep.optional) { try { if (container.has(dep.token)) { services[dep.key] = container.resolve(dep.token); } } catch (error) { console.warn(`Optional dependency not available: ${String(dep.token)}`); } } else { services[dep.key] = container.resolve(dep.token); } } return services; } __name(useFunctionalDI, "useFunctionalDI"); export { DIProvider, useDI, useFunctionalDI, useOptionalService, useService, useServices }; //# sourceMappingURL=context.js.map