{"_id":"@c-a-f/infrastructure-angular","_rev":"2-f3ccdea1bf020790a6434b98b5330e0e","name":"@c-a-f/infrastructure-angular","dist-tags":{"latest":"1.0.2"},"versions":{"1.0.1":{"name":"@c-a-f/infrastructure-angular","version":"1.0.1","keywords":["clean-architecture-frontend","clean-architecture","caf","infrastructure","angular","routing","ploc","usecase","devtools"],"author":{"name":"ali aslani","email":"aliaslani.mm@gmail.com"},"license":"MIT","_id":"@c-a-f/infrastructure-angular@1.0.1","maintainers":[{"name":"ialiaslani","email":"aliaslani.mm@gmail.com"}],"homepage":"https://github.com/ialiaslani/caf#readme","bugs":{"url":"https://github.com/ialiaslani/caf/issues"},"dist":{"shasum":"bae1b95611ce5e19cf56ddab5fbf02b67cfbacd4","tarball":"https://registry.npmjs.org/@c-a-f/infrastructure-angular/-/infrastructure-angular-1.0.1.tgz","fileCount":50,"integrity":"sha512-LOj3imyncNxHoB6qf/qndzTh8PcPvG0yWYlV7NNmuFGbcTgNI5Y1GKfb+rTGeTgv2xe3s6EEJJj/ayIJNTECtQ==","signatures":[{"sig":"MEUCIQDbr5vpZvY5Tq1YaU3qwK+ElkIYVMGxyrgP+KTwMfyt9wIgFVaVI3Hqykmp7r9Ji+vE7DeqJn6xBTq+/hgZrihBuqY=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":36218},"main":"./.build/index.js","type":"module","types":"./.build/index.d.ts","module":"./.build/index.js","exports":{".":{"node":"./.build/index.js","types":"./.build/index.d.ts","import":"./.build/index.js","default":"./.build/index.js"}},"gitHead":"ca2feba4757534a4a130717ea50c4df2e2ff01e6","scripts":{"test":"vitest run","build":"tsc --build","start":"tsc --watch","test:watch":"vitest","prepublishOnly":"npm run build"},"_npmUser":{"name":"ialiaslani","email":"aliaslani.mm@gmail.com"},"repository":{"url":"git+https://github.com/ialiaslani/caf.git","type":"git"},"_npmVersion":"10.9.2","description":"Angular-specific infrastructure adapters for CAF (routing, Ploc, UseCase, Provider, ErrorBoundary, DevTools).","directories":{},"_nodeVersion":"22.13.0","dependencies":{"@c-a-f/core":"^1.0.3"},"_hasShrinkwrap":false,"devDependencies":{"vitest":"^2.1.0","happy-dom":"^15.11.7","@angular/core":"^21.1.5","@angular/common":"^21.1.5","@angular/router":"^21.1.5","@angular/compiler":"^21.1.5","@angular/platform-browser":"^21.1.5"},"peerDependencies":{"rxjs":">=7.0.0","@angular/core":">=18.0.0","@angular/router":">=18.0.0"},"_npmOperationalInternal":{"tmp":"tmp/infrastructure-angular_1.0.1_1771671157886_0.004878406335834917","host":"s3://npm-registry-packages-npm-production"}},"1.0.2":{"name":"@c-a-f/infrastructure-angular","type":"module","version":"1.0.2","description":"Angular-specific infrastructure adapters for CAF (routing, Ploc, UseCase, Provider, ErrorBoundary, DevTools).","keywords":["clean-architecture-frontend","clean-architecture","caf","infrastructure","angular","routing","ploc","usecase","devtools"],"author":{"name":"ali aslani","email":"aliaslani.mm@gmail.com"},"license":"MIT","homepage":"https://docs-caf.vercel.app/docs/packages/infrastructure-angular","repository":{"type":"git","url":"git+https://github.com/ialiaslani/caf.git"},"main":"./.build/index.js","module":"./.build/index.js","types":"./.build/index.d.ts","exports":{".":{"types":"./.build/index.d.ts","import":"./.build/index.js","node":"./.build/index.js","default":"./.build/index.js"}},"scripts":{"build":"tsc --build","start":"tsc --watch","prepublishOnly":"npm run build","test":"vitest run","test:watch":"vitest"},"dependencies":{"@c-a-f/core":"^1.0.3"},"peerDependencies":{"@angular/core":">=18.0.0","@angular/router":">=18.0.0","rxjs":">=7.0.0"},"devDependencies":{"@angular/common":"^21.1.5","@angular/compiler":"^21.1.5","@angular/core":"^21.1.5","@angular/platform-browser":"^21.1.5","@angular/router":"^21.1.5","happy-dom":"^15.11.7","vitest":"^2.1.0"},"_id":"@c-a-f/infrastructure-angular@1.0.2","gitHead":"c754b6d68b1a5b1196bb202e70c962ea7c3de87e","bugs":{"url":"https://github.com/ialiaslani/caf/issues"},"_nodeVersion":"22.13.0","_npmVersion":"10.9.2","dist":{"integrity":"sha512-TQ49qr29yMOeg5m5wRRfGNG5Ndcd8J/P8j61Br2y6LmNikb0iVJxH1kXZmTnVeaEdB/Lc5RmVPIdjLieg4i8Hw==","shasum":"744f40d5c75c0e1812fbef0541396d613968c4bf","tarball":"https://registry.npmjs.org/@c-a-f/infrastructure-angular/-/infrastructure-angular-1.0.2.tgz","fileCount":50,"unpackedSize":36180,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEYCIQDs+cQ1eG12jjScxcxjLk506Ld2QgYfLMBWMwAGo8lPbwIhAP6gm0LA+7tJxSM4R5FgUpNJeFMqRM+pTBWlyd9z3HRf"}]},"_npmUser":{"name":"ialiaslani","email":"aliaslani.mm@gmail.com"},"directories":{},"maintainers":[{"name":"ialiaslani","email":"aliaslani.mm@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/infrastructure-angular_1.0.2_1771679893832_0.217095958914163"},"_hasShrinkwrap":false}},"time":{"created":"2026-02-21T10:52:37.783Z","modified":"2026-02-21T13:18:14.155Z","1.0.1":"2026-02-21T10:52:38.039Z","1.0.2":"2026-02-21T13:18:13.989Z"},"bugs":{"url":"https://github.com/ialiaslani/caf/issues"},"author":{"name":"ali aslani","email":"aliaslani.mm@gmail.com"},"license":"MIT","homepage":"https://docs-caf.vercel.app/docs/packages/infrastructure-angular","keywords":["clean-architecture-frontend","clean-architecture","caf","infrastructure","angular","routing","ploc","usecase","devtools"],"repository":{"type":"git","url":"git+https://github.com/ialiaslani/caf.git"},"description":"Angular-specific infrastructure adapters for CAF (routing, Ploc, UseCase, Provider, ErrorBoundary, DevTools).","maintainers":[{"name":"ialiaslani","email":"aliaslani.mm@gmail.com"}],"readme":"# @c-a-f/infrastructure-angular\r\n\r\nAngular-specific infrastructure adapters for CAF — routing, Ploc, UseCase, Provider, ErrorBoundary, and DevTools (feature parity with React and Vue packages).\r\n\r\n**Documentation:** [@c-a-f/infrastructure-angular docs](https://docs-caf.vercel.app/docs/packages/infrastructure-angular)\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install @c-a-f/infrastructure-angular @angular/router\r\n```\r\n\r\n## Usage\r\n\r\n### injectRouteManager / injectRouteRepository\r\n\r\nSame API shape as React (`useRouteManager` / `useRouteRepository`) and Vue composables. Use `injectRouteManager()` in injection context to get a `RouteManager`; use `injectRouteRepository()` when you need a `RouteRepository` and will build `RouteManager` yourself. Optionally provide `ROUTE_MANAGER_AUTH_OPTIONS` in app config to enable login redirect:\r\n\r\n```typescript\r\nimport { injectRouteManager, ROUTE_MANAGER_AUTH_OPTIONS } from '@c-a-f/infrastructure-angular';\r\nimport { RouteManagerAuthOptions } from '@c-a-f/core';\r\nimport { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';\r\nimport { provideRouter } from '@angular/router';\r\nimport { routes } from './app.routes';\r\n\r\nconst authOptions: RouteManagerAuthOptions = {\r\n  loginPath: '/login',\r\n  isLoggedIn: () => !!localStorage.getItem('token'),\r\n};\r\n\r\nexport const appConfig: ApplicationConfig = {\r\n  providers: [\r\n    provideZoneChangeDetection(),\r\n    provideRouter(routes),\r\n    { provide: ROUTE_MANAGER_AUTH_OPTIONS, useValue: authOptions },\r\n  ],\r\n};\r\n```\r\n\r\n```typescript\r\nimport { injectRouteManager } from '@c-a-f/infrastructure-angular';\r\n\r\n@Injectable({ providedIn: 'root' })\r\nexport class MyService {\r\n  private routeManager = injectRouteManager();\r\n\r\n  navigate() {\r\n    this.routeManager.changeRoute('/dashboard');\r\n  }\r\n}\r\n```\r\n\r\nWith a custom `RouteRepository` (mirrors `useRouteRepository` + `new RouteManager(repo)` in React/Vue):\r\n\r\n```typescript\r\nimport { injectRouteRepository } from '@c-a-f/infrastructure-angular';\r\nimport { RouteManager } from '@c-a-f/core';\r\n\r\nconst routeRepository = injectRouteRepository();\r\nconst routeManager = new RouteManager(routeRepository, authOptions);\r\n```\r\n\r\n### RouteHandler\r\n\r\nAngular `RouteRepository` implementation (injected by `injectRouteRepository()`). Use directly only if you need to provide a custom implementation; otherwise use `injectRouteRepository()`.\r\n\r\n### Provider (CAF context)\r\n\r\nProvide Plocs and UseCases by key so any descendant can inject them:\r\n\r\n```typescript\r\nimport { provideCAF, injectPlocFromContext, injectUseCaseFromContext } from '@c-a-f/infrastructure-angular';\r\n\r\n// In app.config.ts\r\nexport const appConfig: ApplicationConfig = {\r\n  providers: [\r\n    provideCAF({\r\n      plocs: { user: userPloc },\r\n      useCases: { createUser: createUserUseCase },\r\n    }),\r\n  ],\r\n};\r\n\r\n// In a component\r\nconst userPloc = injectPlocFromContext<UserPloc>('user');\r\nconst createUser = injectUseCaseFromContext<[CreateUserInput], User>('createUser');\r\n```\r\n\r\n### Ploc\r\n\r\nSubscribe to a Ploc's state in Angular using `plocToObservable` and `toSignal`:\r\n\r\n```typescript\r\nimport { plocToObservable } from '@c-a-f/infrastructure-angular';\r\nimport { toSignal } from '@angular/core/rxjs-interop';\r\n\r\nexport class UserComponent {\r\n  private userPloc = injectPlocFromContext<UserPloc>('user')!;\r\n  state = toSignal(plocToObservable(this.userPloc));\r\n}\r\n```\r\n\r\nWhen using `@angular/build:application` (esbuild), `inject()` may not be available in component constructors due to pre-bundling. Use `getPlocFromContext(injector, key)` and `getUseCaseFromContext(injector, key)` instead, passing the component's `Injector` (injected via the constructor).\r\n\r\n### UseCase\r\n\r\nWrap a UseCase with `UseCaseState` for loading/error/data signals. Call `destroy()` in `ngOnDestroy`:\r\n\r\n```typescript\r\nimport { UseCaseState } from '@c-a-f/infrastructure-angular';\r\n\r\nexport class CreateUserComponent implements OnDestroy {\r\n  runner = new UseCaseState(this.createUserUseCase);\r\n\r\n  async submit() {\r\n    const result = await this.runner.execute({ name: 'John', email: 'j@example.com' });\r\n    if (result) { /* success */ }\r\n  }\r\n\r\n  ngOnDestroy() {\r\n    this.runner.destroy();\r\n  }\r\n}\r\n```\r\n\r\nTemplate: `runner.loading()`, `runner.error()`, `runner.data()`.\r\n\r\n### Error boundary\r\n\r\nAngular has no component-level error boundary. Use `CAFErrorHandler` and `CAFErrorService` to capture errors and show a fallback:\r\n\r\n```typescript\r\nimport { CAFErrorHandler, CAFErrorService } from '@c-a-f/infrastructure-angular';\r\nimport { ErrorHandler } from '@angular/core';\r\n\r\n// app.config.ts\r\nproviders: [{ provide: ErrorHandler, useClass: CAFErrorHandler }]\r\n\r\n// In your root or layout component\r\nexport class AppComponent {\r\n  errorService = inject(CAFErrorService);\r\n}\r\n```\r\n\r\nTemplate: show fallback when `errorService.error()` is non-null and call `errorService.resetError()` to clear.\r\n\r\n### DevTools\r\n\r\nMinimal DevTools service for enabling/disabling and tracking Plocs:\r\n\r\n```typescript\r\nimport { CAFDevToolsService } from '@c-a-f/infrastructure-angular';\r\n\r\n// Inject and enable in dev\r\ndevTools = inject(CAFDevToolsService);\r\nthis.devTools.enable();\r\nthis.devTools.trackPloc(userPloc, 'UserPloc');\r\n```\r\n\r\n## Exports\r\n\r\n- **Routing:** `injectRouteManager`, `injectRouteRepository`, `ROUTE_MANAGER_AUTH_OPTIONS`, `RouteHandler`\r\n- **Provider:** `CAF_CONTEXT`, `provideCAF`, `injectCAFContext`, `injectPlocFromContext`, `injectUseCaseFromContext`, `getPlocFromContext`, `getUseCaseFromContext`\r\n- **Ploc:** `plocToObservable`\r\n- **UseCase:** `UseCaseState`\r\n- **ErrorBoundary:** `CAFErrorService`, `CAFErrorHandler`\r\n- **DevTools:** `CAFDevToolsService`\r\n\r\n## Dependencies\r\n\r\n- `@c-a-f/core` — Core primitives\r\n- `@angular/core` — Angular core (peer)\r\n- `@angular/router` — Angular Router (peer)\r\n- `rxjs` — For `plocToObservable` (peer)\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}