Skip to content

feat: $provide config-phase service registration (spec 015)#30

Open
Mgrdich wants to merge 2 commits intomasterfrom
provider-service
Open

feat: $provide config-phase service registration (spec 015)#30
Mgrdich wants to merge 2 commits intomasterfrom
provider-service

Conversation

@Mgrdich
Copy link
Copy Markdown
Owner

@Mgrdich Mgrdich commented May 6, 2026

Summary

  • Adds $provide as a config-phase injectable in config() blocks, exposing the six AngularJS recipes (provider / factory / service / value / constant / decorator). Implements the canonical AngularJS-migration override path (config(['$provide', $p => $p.factory('$exceptionHandler', () => myHandler)])).
  • Activates the spec-014-era skipped test that was waiting for $provide. Spec 014's two [ ] NOT MET criteria flip to [x] as a result.
  • Refactors the registration internals into a single shared helper (src/di/registration.ts → applyRegistrationRecord) that both the chain-time module DSL (loadModule) and the new config-phase $provide injectable route through. Enforces a constant-override guard and a last-wins eviction step uniformly across both APIs.
  • Bonus reconciliation: spec 002 (74 criteria) and spec 003 (47 criteria) — historical specs whose acceptance-criteria checkboxes stayed unchecked despite the implementations shipping long ago — now flipped against the existing test suite. Architecture doc updated to record that .provider/.factory/.../.decorator ships in two paths (chain-time spec 007–008, config-phase spec 015) sharing the new helper.

Notable decisions (recorded in context/spec/015-provide-service/tasks.md)

  • Decorator-on-constant throws (literal recipe !== 'constant' reading of tech-spec §2.6). Can be loosened later if AngularJS-parity demand surfaces.
  • Tech-spec §2.7's <name>Provider dual-write to providerCache was dropped — would have broken run-phase isolation that 5 existing tests guard.
  • Last-wins eviction added to applyRegistrationRecord after Slice 7 surfaced the value → factory short-circuit in run-phase get.

Test plan

  • pnpm lint clean
  • pnpm format:check clean
  • pnpm typecheck clean
  • pnpm test — 48 files / 1687 passed / 5 skipped (was 1640 / 6 pre-spec; +47 net tests)
  • pnpm builddist/types/di/index.d.ts and root dist/types/index.d.ts emit ProvideService + PhaseState; DI subpath dist artifacts (.mjs, .cjs, .map) all present
  • Previously-skipped $provide.factory('$exceptionHandler', ...) test in src/exception-handler/__tests__/di.test.ts now active and green
  • Every spec 014 test passes unchanged (regression guard for the digest "log and continue" + recursion guard contracts)

Follow-ups

  • Re-run /awos:verify on spec 014 to update its tracking — already done in this PR; the two [ ] NOT MET criteria in context/spec/014-exception-handler/functional-spec.md are now [x].
  • The format npm script's unquoted glob (prettier --write src/**/*.ts) doesn't recurse into deeply-nested test files. Quoted form works ('src/**/*.ts'). Worth a small chore PR.

🤖 Generated with Claude Code

Mgrdich and others added 2 commits May 1, 2026 11:32
Co-Authored-By: Claude <noreply@anthropic.com>
Adds `$provide` as a config-phase injectable in `config()` blocks, exposing
the six AngularJS recipes (`provider` / `factory` / `service` / `value` /
`constant` / `decorator`). Closes the canonical override path documented
in every AngularJS migration guide and activates the previously-skipped
`$provide.factory('$exceptionHandler', ...)` test from spec 014.

Implementation highlights:

- `src/di/provide.ts` + `src/di/provide-types.ts` — new internal factory
  `createProvideService(deps, getPhase)` returning the typed `ProvideService`
  interface (mirrors `TypedModule` overloads minus registry-accumulation
  type params per FS §2.10).
- `src/di/registration.ts` — extracted shared per-record helper
  `applyRegistrationRecord` that both `loadModule` and `$provide` route
  through. Enforces the constant-override guard ("Cannot override
  constant ...") uniformly across both APIs and applies a last-wins
  eviction step so non-decorator recipes wipe prior producer entries
  (FS §2.9).
- `src/di/injector.ts` — phase tracking (`let phase: PhaseState`),
  `$provide` self-registers in `providerCache` before Phase 2 and is
  removed before Phase 3.

Decisions recorded in `context/spec/015-provide-service/tasks.md`:

- Decorator-on-constant THROWS (matches §2.6's literal `recipe !==
  'constant'` reading; can be loosened later if AngularJS-parity demand
  surfaces).
- Tech-spec §2.7's `<name>Provider` dual-write to `providerCache` was
  dropped — would have broken run-phase isolation that 5 existing tests
  guard.
- Last-wins eviction added to `applyRegistrationRecord` after Slice 7
  surfaced the `value → factory` short-circuit in run-phase `get`.

Tests: 1687 passing / 5 skipped (was 1640 / 6 pre-spec). Net +47 tests
across `provide.test.ts` (40), `provide-integration.test.ts` (6),
`registration.test.ts` (extended), `di-injector-basics.test.ts` (+3),
plus the activated `$exceptionHandler` test in
`src/exception-handler/__tests__/di.test.ts`.

Docs: TSDoc with canonical override examples on every `ProvideService`
method; `CLAUDE.md` and `src/di/README.md` document the override patterns
and the constant-override + last-wins invariants.

Verification flips ride along (spec corpus reconciliation):

- Spec 014's two `$provide`-dependent criteria flipped to `[x]` (now
  satisfied).
- Spec 002 (74 criteria) and spec 003 (47 criteria) — historical specs
  whose acceptance criteria stayed unchecked despite the implementations
  shipping long ago. Reconciled against the existing test suite; all
  flipped to `[x]`. Status was already `Completed` on both.

Architecture doc updated to note that `.provider/.factory/.../.decorator`
registration ships in two paths (chain-time spec 007–008, config-phase
spec 015) sharing the new `applyRegistrationRecord` helper.

Co-Authored-By: Claude <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant