Ajouter @lightweight-sdk/service-registry (packages/common) #2

Merged
kyuno merged 4 commits from feat/service-registry-package into main 2026-09-18 20:56:44 +02:00
Owner

Résumé

Nouveau package @lightweight-sdk/service-registry (packages/common/) : registre de services en singleton avec injection par décorateurs.

  • ServiceRepository — singleton central. Un uid unique (crypto.randomUUID(), isomorphe) est généré à l'enregistrement de chaque service ; une seule instance partagée par service.
  • @RegisterService() — décorateur de classe. Instancie (constructeur sans argument obligatoire) et enregistre automatiquement la classe décorée.
  • @Service(target) — décorateur de propriété. Injection paresseuse et mémoïsée par référence de classe : la résolution se fait au premier accès à la propriété (pas à la décoration), donc insensible à l'ordre d'évaluation des modules entre un service et ses consommateurs. Après le premier accès, la propriété est remplacée par la valeur résolue.

16 tests (Vitest), docs:check passe sans aucun avertissement (couverture TSDoc complète, contrairement à web-component qui reste exclu).

Corrections connexes trouvées en implémentant

  • tsconfig.base.json : useDefineForClassFields: false ajouté. Avec target: ES2022, ce flag vaut true par défaut, ce qui réinitialise silencieusement tout champ de classe sans initialiseur (logger!: T;) à undefined sur l'instance à la construction — masquant l'accesseur posé sur le prototype par n'importe quel décorateur de propriété (@Service ici, et @LinkToDom dans web-component, qui fonctionnait par chance car jamais exercé par un test). Documenté dans spec/architecture.md.
  • scripts/create-package.mjs : execFileSync('pnpm', …) ne résout pas le shim .cmd de pnpm sous Windows sans shell: true — trouvé en ré-utilisant le script pour scaffolder ce package (ENOENT). Corrigé pour les deux appels (pnpm install, pnpm exec biome check --write).

Vérifié localement

pnpm lint, pnpm build, pnpm test (16/16), pnpm docs:check passent tous. pnpm changeset status confirme le bump minor pour ce nouveau package.

🤖 Generated with Claude Code

## Résumé Nouveau package `@lightweight-sdk/service-registry` (`packages/common/`) : registre de services en singleton avec injection par décorateurs. - **`ServiceRepository`** — singleton central. Un uid unique (`crypto.randomUUID()`, isomorphe) est généré à l'enregistrement de chaque service ; une seule instance partagée par service. - **`@RegisterService()`** — décorateur de classe. Instancie (constructeur sans argument obligatoire) et enregistre automatiquement la classe décorée. - **`@Service(target)`** — décorateur de propriété. Injection **paresseuse et mémoïsée** par référence de classe : la résolution se fait au premier accès à la propriété (pas à la décoration), donc insensible à l'ordre d'évaluation des modules entre un service et ses consommateurs. Après le premier accès, la propriété est remplacée par la valeur résolue. 16 tests (Vitest), `docs:check` passe sans aucun avertissement (couverture TSDoc complète, contrairement à `web-component` qui reste exclu). ## Corrections connexes trouvées en implémentant - **`tsconfig.base.json`** : `useDefineForClassFields: false` ajouté. Avec `target: ES2022`, ce flag vaut `true` par défaut, ce qui réinitialise silencieusement tout champ de classe sans initialiseur (`logger!: T;`) à `undefined` **sur l'instance** à la construction — masquant l'accesseur posé sur le prototype par n'importe quel décorateur de propriété (`@Service` ici, et `@LinkToDom` dans `web-component`, qui fonctionnait par chance car jamais exercé par un test). Documenté dans `spec/architecture.md`. - **`scripts/create-package.mjs`** : `execFileSync('pnpm', …)` ne résout pas le shim `.cmd` de pnpm sous Windows sans `shell: true` — trouvé en ré-utilisant le script pour scaffolder ce package (`ENOENT`). Corrigé pour les deux appels (`pnpm install`, `pnpm exec biome check --write`). ## Vérifié localement `pnpm lint`, `pnpm build`, `pnpm test` (16/16), `pnpm docs:check` passent tous. `pnpm changeset status` confirme le bump `minor` pour ce nouveau package. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
kyuno added 1 commit 2026-09-18 14:00:18 +02:00
Ajouter @lightweight-sdk/service-registry (packages/common)
Some checks failed
CI / build-lint-test (pull_request) Failing after 29s
10bc209038
Registre de services en singleton avec injection par decorateurs :
- ServiceRepository : singleton central, uid genere automatiquement
  (crypto.randomUUID) a l'enregistrement, une seule instance partagee
  par service.
- @RegisterService() : decorateur de classe, instancie et enregistre
  automatiquement la classe decoree (constructeur sans argument).
- @Service(target) : decorateur de propriete, injection paresseuse et
  memoisee par reference de classe (resolution au premier acces, pas
  a la decoration - insensible a l'ordre d'evaluation des modules).

Fix connexe dans tsconfig.base.json : useDefineForClassFields desactive
(target ES2022 l'active par defaut), sinon un champ de classe sans
initialiseur est reinitialise a undefined sur l'instance a la
construction et masque l'accesseur pose sur le prototype par un
decorateur de propriete - touche @Service ici et @LinkToDom dans
web-component. Documente dans spec/architecture.md.

Fix connexe dans scripts/create-package.mjs : execFileSync('pnpm', ...)
ne resout pas le shim .cmd de pnpm sous Windows sans shell: true
(trouve en re-testant le script sur ce package).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno added 1 commit 2026-09-18 14:06:29 +02:00
Corriger pnpm-lock.yaml : entree manquante pour service-registry
All checks were successful
CI / build-lint-test (pull_request) Successful in 34s
f0f57f170c
pnpm 12.4.2 n'ecrivait pas d'entree importers pour
packages/common/service-registry dans le lockfile, meme apres
suppression complete du lockfile et du cache d'etat pnpm puis
reinstallation (pnpm ls -r reconnaissait pourtant bien le package).
CI echouait avec --frozen-lockfile (erreur has no importers[...] entry),
alors que le pnpm install local sans --frozen-lockfile ne se
plaignait de rien.

Cause probable : ce package ne declarait aucune dependency ni
devDependency propre. Remede : declarer explicitement quelques
devDependencies (typescript, vitest, @types/node via catalog:), meme
deja hoistees depuis la racine. create-package.mjs generera desormais
ces devDependencies par defaut pour tout nouveau package, et le
troubleshooting est documente dans spec/ci-cd.md.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno added 1 commit 2026-09-18 14:22:13 +02:00
uid fourni par le developpeur au lieu d'etre auto-genere
All checks were successful
CI / build-lint-test (pull_request) Successful in 37s
7d11dd1426
@RegisterService(uid) et @Service<T>(uid) prennent desormais l'uid en
parametre explicite, choisi par l'appelant, plutot que de le generer
automatiquement (crypto.randomUUID) et de resoudre par reference de
classe. ServiceRepository simplifie en consequence : une seule map
uid -> instance (plus de WeakMap constructeur -> uid, resolveClass/
getUidForClass/hasClass supprimes, devenus inutiles).

@Service ne peut plus inferer le type depuis une reference de classe :
a annoter la propriete ou a typer explicitement (@Service<T>(uid)).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno added 1 commit 2026-09-18 14:31:50 +02:00
Simplifier : retirer le generique de @Service, ajouter services
All checks were successful
CI / build-lint-test (pull_request) Successful in 34s
544614add7
- @Service(uid) n'a plus de parametre generique : un decorateur de
  propriete legacy ne peut de toute facon pas changer le type du champ
  qu'il decore, seule son annotation compte. Le generique n'apportait
  rien.
- Nouvelle constante exportee services = ServiceRepository.getInstance(),
  instance prete a l'emploi : services.get<T>(uid), services.has(uid),
  services.register(uid, Classe). C'est desormais le point d'entree
  recommande plutot que ServiceRepository.getInstance() directement.
- ServiceRepository.resolve() renomme en get() pour matcher
  services.get<T>(uid).
- resetForTesting() vide la map en place (Map.clear()) au lieu de
  jeter l'instance singleton, pour que la constante services capturee
  au chargement du module reste valide apres un reset dans les tests.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
kyuno merged commit 38aa956fde into main 2026-09-18 20:56:44 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference: kyuno/lightweight-sdk#2
No description provided.