@supersoniks/concorde 4.7.0 → 4.7.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ai/AGENTS.md CHANGED
@@ -47,6 +47,10 @@ Skill **`concorde-imports`** : section « Dans le dépôt Concorde ».
47
47
 
48
48
  Skill **`concorde-get-set-dp`** : chemins sans placeholder **`${…}`** / **`{$…}`** pour `get` / `set` / `dp` ; chemins JS évalués OK ; clés dynamiques → décorateurs, `dp(idRésolu)`, ou **`sub(clé)`** dans les templates Lit.
49
49
 
50
+ ## Migration Subscriber / sonic-fetch
51
+
52
+ Skill **`concorde`** — section **« Piège migration Subscriber → LitElement »** : ne pas laisser des `@property` orphelines après retrait du mixin ; `@get` + `@subscribe` feuille ; `apiConfigKey` en modale ; sync des noms de props pour les `Endpoint` dynamiques.
53
+
50
54
  ## Documentation
51
55
 
52
56
  Fichiers `.md` dans le package : `node_modules/@supersoniks/concorde/src/` (composants, décorateurs, getting-started).
@@ -47,3 +47,13 @@ Placeholder `${prop}` = chaîne normale, résolu depuis le composant hôte.
47
47
 
48
48
  - **Scope** : `<sonic-scope serviceURL="…">` · `@get(endpoint)` ou `@get(endpoint, apiConfigKey)` — skills `concorde-scope`
49
49
  - **Theme** : `<sonic-theme background color font>` · `--sc-*` — skill `concorde-theme`
50
+
51
+ ## Migration Subscriber / sonic-fetch (piège fréquent)
52
+
53
+ - Retirer `extends Subscriber` **sans** `@subscribe` sur chaque champ affiché → UI vide (props orphelines).
54
+ - Remplacer `sonic-fetch` : `@get` + alimenter le DP ; UI en `@subscribe` feuille ou hôte `Subscriber` + `dataProvider`/`subDataProvider`.
55
+ - `@get` + placeholders `${prop}` : propriétés homonymes sur l'hôte (ou sync dans `willUpdate`).
56
+ - Modale / portal : `@get(endpoint, apiConfigKey)` si pas de `serviceURL` ascendant.
57
+ - `@subscribe` → préférer `@state()`, pas `@property`.
58
+
59
+ Détail : skill `concorde` — section « Piège migration Subscriber → LitElement ».
@@ -31,6 +31,14 @@ Placeholder `${prop}` dans une chaîne normale : `"users.${userIndex}"`.
31
31
  - **Scope** (`sonic-scope`) : `serviceURL`, `formDataProvider`, icônes — skill `concorde-scope`
32
32
  - **Theme** (`sonic-theme`) : `--sc-*` tokens, dark mode — skill `concorde-theme`
33
33
  - `@get(endpoint)` sans clé config → hérite scope ; `@get(endpoint, apiConfigKey)` → DataProvider
34
+ - Modale / portal : préférer `apiConfigKey` si pas de scope DOM fiable
35
+
36
+ ## Migration Subscriber / sonic-fetch
37
+
38
+ - Ne pas retirer `Subscriber` sans `@subscribe` feuille par feuille sur chaque champ du `render()`.
39
+ - `sonic-fetch` → `@get` + DP ; `@subscribe` ou hôte `Subscriber` avec `dataProvider`/`subDataProvider`.
40
+ - Placeholders Endpoint = propriétés homonymes sur l'hôte (`checkCode` → copier vers `code` si besoin).
41
+ - `@subscribe` + `@state()`, pas `@property` pour la lecture DP.
34
42
 
35
43
  ## Navigation
36
44
 
@@ -3,6 +3,7 @@ name: concorde
3
3
  description: >-
4
4
  Composants Web Concorde (Lit) : DataProvider, scope, theme, Endpoint,
5
5
  formDataProvider, sonic-list/sonic-queue, @subscribe/@handle/@get.
6
+ @subscribe feuille par feuille (pas d’objet parent + getters).
6
7
  Imports courts (@supersoniks/concorde/menu, /list, /utils…).
7
8
  ---
8
9
 
@@ -143,6 +144,83 @@ count = 0;
143
144
  subscribedCount = 0;
144
145
  ```
145
146
 
147
+ ### Règle impérative — une souscription par valeur affichée
148
+
149
+ Sur un composant **`LitElement`** métier, chaque donnée lue dans `render()` doit avoir **son propre** `@subscribe` + `@state()` (ou `@property` si besoin explicite) sur le **publisher feuille** — jamais un abonnement à l’objet parent + getters.
150
+
151
+ | Anti-pattern | Pourquoi |
152
+ |--------------|----------|
153
+ | `@subscribe(dpKeys.currentSession)` + `get edito()` | Si seul `edito` change (même référence `Session`), Lit peut **ne pas** re-rendre |
154
+ | `@subscribe` sur un parent + `sub()` enfant pour le détail | Mélange deux modèles ; préférer des feuilles cohérentes |
155
+
156
+ ```typescript
157
+ // ❌ — re-render non garanti sur sous-clés
158
+ @subscribe(dpKeys.currentSession)
159
+ @state() session?: Session;
160
+ get edito() { return this.session?.edito; }
161
+
162
+ // ✅ — une propriété réactive par champ du template
163
+ @subscribe(dpKeys.currentSession.slug)
164
+ @state() slug = "";
165
+
166
+ @subscribe(dpKeys.currentSession.edito)
167
+ @state() edito: Edito | null = null;
168
+
169
+ @subscribe(dpKeys.currentSession.settings)
170
+ @state() settings: SettingsSessionAPI | null = null;
171
+ ```
172
+
173
+ **Navigation typée** : chaîner `DataProviderKey` — `dpKeys.currentSession.edito` → `"app.currentSession.edito"`.
174
+
175
+ **Granularité** : descendre jusqu’à la **feuille** réellement affichée si les mutations ne remplacent pas l’objet intermédiaire (ex. `@subscribe(dpKeys.currentSession.edito.title)` si seul `title` change sans nouvel objet `edito`).
176
+
177
+ **Templates** : même règle avec `sub(dpKeys.currentSession.edito.title)` plutôt que `sub(dpKeys.currentSession)` + accès JS.
178
+
179
+ ### Cas hybride — hôte `Subscriber` + enfants sonic
180
+
181
+ Des composants catalogue (`sonic-event-location-hall`, `sonic-date`, `sonic-product-title`, …) remontent l’arbre pour `dataProvider` et utilisent le **template filling** du mixin `Subscriber` — pas un `@subscribe` local.
182
+
183
+ | Situation | Approche |
184
+ |-----------|----------|
185
+ | Composant métier **sans** enfants `Subscriber` | `LitElement` + `@subscribe` **feuille par feuille** |
186
+ | Composant **hôte** d’enfants sonic `Subscriber` | `extends Subscriber(LitElement)` + `@property` remplies par template filling ; **exposer** `dataProvider` aux descendants |
187
+
188
+ **`dataProvider` imbriqué** (éviter la clé plate `"app.currentSession"`) :
189
+
190
+ ```html
191
+ <mon-composant-hote dataProvider="app" subDataProvider="currentSession"></mon-composant-hote>
192
+ ```
193
+
194
+ Après `initPublisher`, refléter le chemin résolu sur l’attribut (ex. `app/currentSession`) pour que les **enfants** héritent le bon publisher — ils ne lisent pas `subDataProvider` sur l’ancêtre.
195
+
196
+ **Liste / queue** : chaque ligne a son publisher — l’hôte **hérite** de l’ancêtre ; ne pas forcer `app.currentSession` sur un item de liste.
197
+
198
+ ### Piège migration `Subscriber` → `LitElement` (checklist)
199
+
200
+ Lors du remplacement de `sonic-fetch` ou du retrait du mixin `Subscriber` sur un composant **métier** :
201
+
202
+ | Étape | Vérification |
203
+ |-------|----------------|
204
+ | Champs affichés dans `render()` | Chaque `@property` autrefois remplie par template filling → **`@subscribe(dpKey.feuille)` + `@state()`** (pas laisser des `@property` orphelins) |
205
+ | Enfant d’un `@get` | `@get` + `@publish`/`@handle` vers le DataProvider cible ; l’UI lit ce DP via `@subscribe`, pas via des props vides |
206
+ | Placeholders `Endpoint` | Les noms `${prop}` doivent exister sur l’hôte (`@property` ou copie dans `willUpdate` si le scan utilise un autre nom, ex. `checkCode` → `code`) |
207
+ | Modale / portal | `@get(endpoint, apiConfigKey)` si pas de `serviceURL` ascendant fiable (`Modal` → `Theme.getPopContainer()`) |
208
+ | Remplacement `sonic-fetch` | Expliciter `dataProvider` + `subDataProvider` sur les hôtes `Subscriber` enfants (ex. `app` + `currentScanTicket`) |
209
+
210
+ ```typescript
211
+ // ❌ — Subscriber retiré, props jamais alimentées
212
+ export class TicketInfos extends LitElement {
213
+ @property({ type: Object }) owner = {};
214
+ render() { return html`${this.owner?.firstName}`; }
215
+ }
216
+
217
+ // ✅ — une souscription par champ affiché
218
+ @subscribe(dpKeys.currentScanTicket.owner)
219
+ @state() owner: Contact = {};
220
+ ```
221
+
222
+ **`@subscribe` + décorateur Lit** : préférer **`@state()`** (pas `@property`) pour les champs purement lus depuis le DataProvider.
223
+
146
224
  ## formDataProvider
147
225
 
148
226
  ```html
@@ -189,7 +267,7 @@ Propriétés Lit (recommandé) :
189
267
 
190
268
  | Besoin | API |
191
269
  |--------|-----|
192
- | Lire | `@subscribe(dpKey.field)` + `@state()` |
270
+ | Lire (affichage Lit) | `@subscribe(dpKey.leaf)` + `@state()` — **une fois par champ** du `render()` |
193
271
  | Effet typé | `@handle(dpKey.a, …)` |
194
272
  | API HTTP | `@get(Endpoint)` ou `@get(Endpoint, apiConfigKey)` |
195
273
  | Écriture classe (hors form) | `@publish` |
@@ -202,8 +280,10 @@ Propriétés Lit (recommandé) :
202
280
  | `PublisherManager.get(…)` | `get(…)` ou `set(…)` |
203
281
  | « publisher » | DataProvider |
204
282
  | `sonic-input` + `@input` | `formDataProvider` + `name` |
205
- | `sonic-fetch` | `sonic-queue` + filtre, ou `@get` |
206
- | `extends Subscriber(LitElement)` | `LitElement` + `@subscribe` / `sub()` |
283
+ | `sonic-fetch` | `sonic-queue` + filtre, ou `@get` + `@publish`/`@handle` + `@subscribe` / hôte `Subscriber` |
284
+ | `extends Subscriber(LitElement)` (métier seul) | `LitElement` + `@subscribe` feuille par feuille / `sub()` — **ne pas oublier** les champs template-filled |
285
+ | `extends Subscriber` (hôte d’enfants sonic) | Conserver `Subscriber` + `dataProvider` / `subDataProvider` corrects |
286
+ | `@get` dans modale | `@get(endpoint, apiConfigKey)` si config API hors scope DOM |
207
287
  | `data-bind` HTML | `@subscribe` / `sub()` |
208
288
  | `@bind` décorateur | `@subscribe` + `DataProviderKey` (lecture) ou `@publish` (écriture) |
209
289
  | `@onAssign` | `@handle` + `DataProviderKey` |
package/build-infos.json CHANGED
@@ -1 +1 @@
1
- {"date":1780500767}
1
+ {"date":1780585258}