{"_id":"@ambrosia-unce/core","_rev":"2-5dedc04a7ae463c14bf58e6bb5e2f08e","name":"@ambrosia-unce/core","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@ambrosia-unce/core","version":"1.0.0","keywords":["dependency-injection","di","ioc","inversion-of-control","typescript","bun","decorators","ambrosia"],"author":{"name":"Ambrosia Framework"},"license":"MIT","_id":"@ambrosia-unce/core@1.0.0","maintainers":[{"name":"funnybunny_unce","email":"funnybunny.unce@gmail.com"}],"homepage":"https://github.com/ambrosia-unce/ambrosia/tree/master/packages/core","bugs":{"url":"https://github.com/ambrosia-unce/ambrosia/issues"},"dist":{"shasum":"c0ea82cc2367cfb4130a7df627c50cba05704240","tarball":"https://registry.npmjs.org/@ambrosia-unce/core/-/core-1.0.0.tgz","fileCount":126,"integrity":"sha512-868yDdgzY/cJIl7hnffCHT+J4fGXL/6B3ufDpetYf5thNxNWQ0o2B3XETMw6JpQR6JNaKyE/IkL4qGq0JrtuvQ==","signatures":[{"sig":"MEQCIEVkWPqSNOq729PC3SV7kT53YxMaa/McQ2mIf6D2GE6HAiAHea7X45XNrdpo0+8kPlKgCAFFR3uDzGe85SdYjjvQOg==","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ambrosia-unce%2fcore@1.0.0","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"unpackedSize":269639},"main":"./dist/index.js","type":"module","types":"./dist/index.d.ts","module":"./dist/index.js","engines":{"bun":">=1.3.6"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.js"}},"gitHead":"d86ee39512a468e7c5413e9c243c07849306455e","scripts":{"test":"bun test","bench":"bun run benchmarks/run-all.ts","build":"bun run build.ts","test:unit":"bun test tests/unit","typecheck":"tsc --noEmit","bench:core":"bun test ./benchmarks/suites/01-core-di.bench.ts","test:watch":"bun test --watch","bench:async":"bun test ./benchmarks/suites/04-async.bench.ts","bench:watch":"bun test --watch ./benchmarks/suites/*.bench.ts","bench:memory":"bun test ./benchmarks/suites/05-memory.bench.ts","bench:scopes":"bun test ./benchmarks/suites/02-scopes.bench.ts","example:auto":"bun run examples/auto-registration-example.ts","bench:compare":"bun run benchmarks/compare.ts","bench:plugins":"bun test ./benchmarks/suites/03-plugins.bench.ts","test:coverage":"bun test --coverage","example:errors":"bun run examples/error-handling-example.ts","prepublishOnly":"bun run typecheck && bun run build","bench:real-world":"bun test ./benchmarks/suites/06-real-world.bench.ts","example:circular":"bun run examples/circular-dependency-solutions.ts","test:integration":"bun test tests/integration"},"_npmUser":{"name":"funnybunny_unce","email":"funnybunny.unce@gmail.com"},"repository":{"url":"git+https://github.com/ambrosia-unce/ambrosia.git","type":"git","directory":"packages/core"},"_npmVersion":"10.8.2","description":"Lightweight decorator-based Dependency Injection container for TypeScript and Bun","directories":{},"_nodeVersion":"20.20.1","dependencies":{"reflect-metadata":"^0.2.2"},"publishConfig":{"access":"public"},"_hasShrinkwrap":false,"devDependencies":{"@types/bun":"latest"},"peerDependencies":{"typescript":"^5"},"_npmOperationalInternal":{"tmp":"tmp/core_1.0.0_1774566993370_0.7347911144286148","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@ambrosia-unce/core","version":"1.0.1","description":"Lightweight decorator-based Dependency Injection container for TypeScript and Bun","type":"module","license":"MIT","author":{"name":"Ambrosia Framework"},"homepage":"https://github.com/ambrosia-unce/ambrosia/tree/master/packages/core","repository":{"type":"git","url":"git+https://github.com/ambrosia-unce/ambrosia.git","directory":"packages/core"},"bugs":{"url":"https://github.com/ambrosia-unce/ambrosia/issues"},"keywords":["dependency-injection","di","ioc","inversion-of-control","typescript","bun","decorators","ambrosia"],"engines":{"bun":">=1.3.6"},"main":"./dist/index.js","module":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"import":"./dist/index.js","types":"./dist/index.d.ts"}},"scripts":{"build":"bun run build.ts","prepublishOnly":"bun run typecheck && bun run build","test":"bun test","test:watch":"bun test --watch","test:coverage":"bun test --coverage","test:unit":"bun test tests/unit","test:integration":"bun test tests/integration","typecheck":"tsc --noEmit","bench":"bun run benchmarks/run-all.ts","bench:core":"bun test ./benchmarks/suites/01-core-di.bench.ts","bench:scopes":"bun test ./benchmarks/suites/02-scopes.bench.ts","bench:plugins":"bun test ./benchmarks/suites/03-plugins.bench.ts","bench:async":"bun test ./benchmarks/suites/04-async.bench.ts","bench:memory":"bun test ./benchmarks/suites/05-memory.bench.ts","bench:real-world":"bun test ./benchmarks/suites/06-real-world.bench.ts","bench:compare":"bun run benchmarks/compare.ts","bench:watch":"bun test --watch ./benchmarks/suites/*.bench.ts","example:errors":"bun run examples/error-handling-example.ts","example:circular":"bun run examples/circular-dependency-solutions.ts","example:auto":"bun run examples/auto-registration-example.ts"},"devDependencies":{"@types/bun":"latest"},"peerDependencies":{"typescript":"^5"},"publishConfig":{"access":"public"},"dependencies":{"reflect-metadata":"^0.2.2"},"_id":"@ambrosia-unce/core@1.0.1","gitHead":"623e54bd30bbb3e8ce80ad7cedb8fd0cd9daf9ee","_nodeVersion":"20.20.1","_npmVersion":"10.8.2","dist":{"integrity":"sha512-Ix0AtxYDvdN2phULuDA2WskE2Pcr08fWwYl5NADThe8+RdOsWfFYxdw7iFMsRjK4xJAVhX96IpE+GyPlEU9J+Q==","shasum":"3c2aee6917d4a8706ee7a152c75f4fc182494836","tarball":"https://registry.npmjs.org/@ambrosia-unce/core/-/core-1.0.1.tgz","fileCount":126,"unpackedSize":269639,"attestations":{"url":"https://registry.npmjs.org/-/npm/v1/attestations/@ambrosia-unce%2fcore@1.0.1","provenance":{"predicateType":"https://slsa.dev/provenance/v1"}},"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEQCIDsxC+8rGZCfRBFXiH+l3xuZWEwvMtA88PvtMAtPHcqGAiB/oYJepeO7xBG+QPdh7fo2c/pzo0MgUuBrE9JNNFrYbw=="}]},"_npmUser":{"name":"funnybunny_unce","email":"funnybunny.unce@gmail.com"},"directories":{},"maintainers":[{"name":"funnybunny_unce","email":"funnybunny.unce@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/core_1.0.1_1774600003837_0.5088840220782793"},"_hasShrinkwrap":false}},"time":{"created":"2026-03-26T23:16:33.227Z","modified":"2026-03-27T08:26:44.327Z","1.0.0":"2026-03-26T23:16:33.599Z","1.0.1":"2026-03-27T08:26:43.978Z"},"bugs":{"url":"https://github.com/ambrosia-unce/ambrosia/issues"},"author":{"name":"Ambrosia Framework"},"license":"MIT","homepage":"https://github.com/ambrosia-unce/ambrosia/tree/master/packages/core","keywords":["dependency-injection","di","ioc","inversion-of-control","typescript","bun","decorators","ambrosia"],"repository":{"type":"git","url":"git+https://github.com/ambrosia-unce/ambrosia.git","directory":"packages/core"},"description":"Lightweight decorator-based Dependency Injection container for TypeScript and Bun","maintainers":[{"name":"funnybunny_unce","email":"funnybunny.unce@gmail.com"}],"readme":"# @ambrosia-unce/core\n\nA powerful and flexible Dependency Injection container for TypeScript applications, built for the Bun runtime.\n\n## Features\n\n- **Constructor Injection** -- automatic dependency resolution via constructor parameters\n- **Property Injection** -- inject dependencies into class properties with `@Autowired()`\n- **InjectionToken** -- type-safe tokens for interfaces and configuration objects\n- **Multiple Scopes** -- Singleton, Transient, and Request (via AsyncLocalStorage)\n- **Factory Providers** -- flexible dependency creation with factory functions\n- **Auto-resolve Circular Dependencies** -- automatic resolution using lazy proxies with console warnings\n- **Pack System** -- a module composition unit with providers, exports, imports, and lifecycle hooks\n- **Plugin System** -- hook into container lifecycle events (resolve, init, register) without modifying the core\n- **TypeScript First** -- full type safety throughout the API\n- **Bun Native** -- optimized for the Bun runtime\n\n## Installation\n\n```bash\nbun add @ambrosia-unce/core reflect-metadata\n```\n\n## Quick Start\n\n```typescript\nimport \"reflect-metadata\";\nimport { Container, Injectable } from \"@ambrosia-unce/core\";\n\n@Injectable()\nclass Logger {\n  log(message: string) {\n    console.log(message);\n  }\n}\n\n@Injectable()\nclass UserService {\n  constructor(private logger: Logger) {}\n\n  getUser(id: number) {\n    this.logger.log(`Getting user ${id}`);\n    return { id, name: \"John\" };\n  }\n}\n\nconst container = new Container();\nconst userService = container.resolve(UserService);\nuserService.getUser(123);\n```\n\n## Key Concepts\n\n### Constructor Injection\n\nDependencies are automatically resolved through constructor parameters:\n\n```typescript\n@Injectable()\nclass Database {\n  connect() { /* ... */ }\n}\n\n@Injectable()\nclass UserService {\n  constructor(private db: Database) {}\n  // Database is automatically injected!\n}\n```\n\n### Property Injection\n\nInject dependencies into class properties using `@Autowired()`:\n\n```typescript\n@Injectable()\nclass UserController {\n  @Autowired()\n  private logger!: Logger;\n\n  @Autowired()\n  @Optional()\n  private cache?: CacheService;\n}\n```\n\n### InjectionToken\n\nType-safe tokens for interfaces and configuration objects:\n\n```typescript\ninterface AppConfig {\n  port: number;\n}\n\nconst CONFIG = new InjectionToken<AppConfig>(\"AppConfig\");\n\ncontainer.registerValue(CONFIG, { port: 3000 });\n\n@Injectable()\nclass ApiServer {\n  constructor(@Inject(CONFIG) private config: AppConfig) {}\n}\n```\n\n### Scopes\n\nControl the lifecycle of your dependencies:\n\n```typescript\n// Singleton (default) -- one instance for the entire application\n@Injectable({ scope: Scope.SINGLETON })\nclass Database {}\n\n// Transient -- a new instance on every resolve call\n@Injectable({ scope: Scope.TRANSIENT })\nclass RequestHandler {}\n\n// Request -- one instance per HTTP request (via AsyncLocalStorage)\n@Injectable({ scope: Scope.REQUEST })\nclass RequestContext {}\n```\n\n### Factory Providers\n\nUse factory functions for custom dependency creation logic:\n\n```typescript\ncontainer.registerFactory(\n  CacheService,\n  (c) => {\n    const cache = new CacheService();\n    cache.initialize();\n    return cache;\n  },\n  Scope.SINGLETON\n);\n```\n\n### Pack System\n\nPacks are the unit of composition in Ambrosia. A `PackDefinition` declares providers, exports (for encapsulation), imports, and lifecycle hooks:\n\n```typescript\nimport { definePack } from \"@ambrosia-unce/core\";\n\nconst LoggingPack = definePack({\n  meta: { name: \"logging\", version: \"1.0.0\" },\n  providers: [LoggingService],\n  exports: [LoggingService],\n});\n\nconst AppPack = definePack({\n  meta: { name: \"app\" },\n  imports: [LoggingPack],\n  providers: [UserService, OrderService],\n  exports: [UserService],\n  async onInit(container) {\n    const logger = container.resolve(LoggingService);\n    logger.log(\"App pack initialized\");\n  },\n  async onDestroy() {\n    // Graceful cleanup on shutdown\n  },\n});\n```\n\nPacks support conditional and lazy imports for advanced scenarios:\n\n```typescript\nconst AppPack = definePack({\n  imports: [\n    CorePack,\n    process.env.CACHE_ENABLED && CachePack, // conditional import\n  ],\n  lazyImports: () => [FeaturePack], // lazy import to break circular pack dependencies\n});\n```\n\n### Auto-resolve Circular Dependencies\n\nEnable automatic resolution of circular dependencies using lazy proxies:\n\n```typescript\nconst container = new Container({ autoResolveCircular: true });\n\n// Circular dependencies are now resolved automatically\n// with a warning instead of an error\n```\n\nWhen a circular dependency is detected, the container:\n\n- Logs a warning to the console\n- Creates a lazy proxy for the circular dependency\n- Allows the application to continue running\n\n## API\n\n### Container\n\n```typescript\n// Create a container\nconst container = new Container();\nconst containerWithAutoResolve = new Container({ autoResolveCircular: true });\n\n// Register providers\ncontainer.register(UserService);\ncontainer.registerClass(AbstractService, ConcreteService);\ncontainer.registerValue(CONFIG, { port: 3000 });\ncontainer.registerFactory(Cache, (c) => new Cache());\n\n// Resolve dependencies\nconst service = container.resolve(UserService);\nconst optional = container.resolveOptional(OptionalService);\n\n// Async resolution\nconst asyncService = await container.resolveAsync(AsyncService);\n```\n\n### Decorators\n\n```typescript\n@Injectable({ scope: Scope.SINGLETON })  // Mark a class as injectable\n@Inject(token)                           // Specify a token for a constructor parameter\n@Autowired()                             // Inject into a property\n@Optional()                              // Mark a dependency as optional\n@Implements(AbstractClass)               // Bind an abstract class to its concrete implementation\n```\n\n## Requirements\n\n- TypeScript >= 5.0\n- Bun >= 1.3.6 (or Node.js >= 18 with an appropriate bundler)\n- `experimentalDecorators: true` in tsconfig.json\n- `emitDecoratorMetadata: true` in tsconfig.json\n\n## License\n\nMIT\n","readmeFilename":"README.md"}