@ersbeth/picoflow 1.0.1 → 1.1.0

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.
Files changed (180) hide show
  1. package/.cursor/plans/unifier-flowresource-avec-flowderivation-c9506e24.plan.md +372 -0
  2. package/README.md +17 -1
  3. package/biome.json +4 -1
  4. package/dist/picoflow.js +1129 -661
  5. package/dist/types/flow/base/flowDisposable.d.ts +67 -0
  6. package/dist/types/flow/base/flowDisposable.d.ts.map +1 -0
  7. package/dist/types/flow/base/flowEffect.d.ts +127 -0
  8. package/dist/types/flow/base/flowEffect.d.ts.map +1 -0
  9. package/dist/types/flow/base/flowGraph.d.ts +97 -0
  10. package/dist/types/flow/base/flowGraph.d.ts.map +1 -0
  11. package/dist/types/flow/base/flowSignal.d.ts +134 -0
  12. package/dist/types/flow/base/flowSignal.d.ts.map +1 -0
  13. package/dist/types/flow/base/flowTracker.d.ts +15 -0
  14. package/dist/types/flow/base/flowTracker.d.ts.map +1 -0
  15. package/dist/types/flow/base/index.d.ts +7 -0
  16. package/dist/types/flow/base/index.d.ts.map +1 -0
  17. package/dist/types/flow/base/utils.d.ts +20 -0
  18. package/dist/types/flow/base/utils.d.ts.map +1 -0
  19. package/dist/types/{advanced/array.d.ts → flow/collections/flowArray.d.ts} +50 -12
  20. package/dist/types/flow/collections/flowArray.d.ts.map +1 -0
  21. package/dist/types/flow/collections/flowMap.d.ts +224 -0
  22. package/dist/types/flow/collections/flowMap.d.ts.map +1 -0
  23. package/dist/types/flow/collections/index.d.ts +3 -0
  24. package/dist/types/flow/collections/index.d.ts.map +1 -0
  25. package/dist/types/flow/index.d.ts +4 -0
  26. package/dist/types/flow/index.d.ts.map +1 -0
  27. package/dist/types/flow/nodes/async/flowConstantAsync.d.ts +137 -0
  28. package/dist/types/flow/nodes/async/flowConstantAsync.d.ts.map +1 -0
  29. package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts +137 -0
  30. package/dist/types/flow/nodes/async/flowDerivationAsync.d.ts.map +1 -0
  31. package/dist/types/flow/nodes/async/flowNodeAsync.d.ts +343 -0
  32. package/dist/types/flow/nodes/async/flowNodeAsync.d.ts.map +1 -0
  33. package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts +81 -0
  34. package/dist/types/flow/nodes/async/flowReadonlyAsync.d.ts.map +1 -0
  35. package/dist/types/flow/nodes/async/flowStateAsync.d.ts +111 -0
  36. package/dist/types/flow/nodes/async/flowStateAsync.d.ts.map +1 -0
  37. package/dist/types/flow/nodes/async/index.d.ts +6 -0
  38. package/dist/types/flow/nodes/async/index.d.ts.map +1 -0
  39. package/dist/types/flow/nodes/index.d.ts +3 -0
  40. package/dist/types/flow/nodes/index.d.ts.map +1 -0
  41. package/dist/types/flow/nodes/sync/flowConstant.d.ts +108 -0
  42. package/dist/types/flow/nodes/sync/flowConstant.d.ts.map +1 -0
  43. package/dist/types/flow/nodes/sync/flowDerivation.d.ts +100 -0
  44. package/dist/types/flow/nodes/sync/flowDerivation.d.ts.map +1 -0
  45. package/dist/types/flow/nodes/sync/flowNode.d.ts +314 -0
  46. package/dist/types/flow/nodes/sync/flowNode.d.ts.map +1 -0
  47. package/dist/types/flow/nodes/sync/flowReadonly.d.ts +57 -0
  48. package/dist/types/flow/nodes/sync/flowReadonly.d.ts.map +1 -0
  49. package/dist/types/flow/nodes/sync/flowState.d.ts +96 -0
  50. package/dist/types/flow/nodes/sync/flowState.d.ts.map +1 -0
  51. package/dist/types/flow/nodes/sync/index.d.ts +6 -0
  52. package/dist/types/flow/nodes/sync/index.d.ts.map +1 -0
  53. package/dist/types/index.d.ts +1 -4
  54. package/dist/types/index.d.ts.map +1 -1
  55. package/dist/types/solid/converters.d.ts +34 -44
  56. package/dist/types/solid/converters.d.ts.map +1 -1
  57. package/dist/types/solid/primitives.d.ts +1 -0
  58. package/dist/types/solid/primitives.d.ts.map +1 -1
  59. package/docs/.vitepress/config.mts +1 -1
  60. package/docs/api/typedoc-sidebar.json +81 -1
  61. package/package.json +60 -58
  62. package/src/flow/base/flowDisposable.ts +71 -0
  63. package/src/flow/base/flowEffect.ts +171 -0
  64. package/src/flow/base/flowGraph.ts +288 -0
  65. package/src/flow/base/flowSignal.ts +207 -0
  66. package/src/flow/base/flowTracker.ts +17 -0
  67. package/src/flow/base/index.ts +6 -0
  68. package/src/flow/base/utils.ts +19 -0
  69. package/src/flow/collections/flowArray.ts +409 -0
  70. package/src/flow/collections/flowMap.ts +398 -0
  71. package/src/flow/collections/index.ts +2 -0
  72. package/src/flow/index.ts +3 -0
  73. package/src/flow/nodes/async/flowConstantAsync.ts +142 -0
  74. package/src/flow/nodes/async/flowDerivationAsync.ts +143 -0
  75. package/src/flow/nodes/async/flowNodeAsync.ts +474 -0
  76. package/src/flow/nodes/async/flowReadonlyAsync.ts +81 -0
  77. package/src/flow/nodes/async/flowStateAsync.ts +116 -0
  78. package/src/flow/nodes/async/index.ts +5 -0
  79. package/src/flow/nodes/await/advanced/index.ts +5 -0
  80. package/src/{advanced → flow/nodes/await/advanced}/resource.ts +37 -3
  81. package/src/{advanced → flow/nodes/await/advanced}/resourceAsync.ts +35 -3
  82. package/src/{advanced → flow/nodes/await/advanced}/stream.ts +40 -2
  83. package/src/{advanced → flow/nodes/await/advanced}/streamAsync.ts +38 -3
  84. package/src/flow/nodes/await/flowConstantAwait.ts +154 -0
  85. package/src/flow/nodes/await/flowDerivationAwait.ts +154 -0
  86. package/src/flow/nodes/await/flowNodeAwait.ts +508 -0
  87. package/src/flow/nodes/await/flowReadonlyAwait.ts +89 -0
  88. package/src/flow/nodes/await/flowStateAwait.ts +130 -0
  89. package/src/flow/nodes/await/index.ts +5 -0
  90. package/src/flow/nodes/index.ts +3 -0
  91. package/src/flow/nodes/sync/flowConstant.ts +111 -0
  92. package/src/flow/nodes/sync/flowDerivation.ts +105 -0
  93. package/src/flow/nodes/sync/flowNode.ts +439 -0
  94. package/src/flow/nodes/sync/flowReadonly.ts +57 -0
  95. package/src/flow/nodes/sync/flowState.ts +101 -0
  96. package/src/flow/nodes/sync/index.ts +5 -0
  97. package/src/index.ts +1 -47
  98. package/src/solid/converters.ts +59 -198
  99. package/src/solid/primitives.ts +4 -0
  100. package/test/base/flowEffect.test.ts +108 -0
  101. package/test/base/flowGraph.test.ts +485 -0
  102. package/test/base/flowSignal.test.ts +372 -0
  103. package/test/collections/flowArray.asyncStates.test.ts +1553 -0
  104. package/test/collections/flowArray.scalars.test.ts +1129 -0
  105. package/test/collections/flowArray.states.test.ts +1365 -0
  106. package/test/collections/flowMap.asyncStates.test.ts +1105 -0
  107. package/test/collections/flowMap.scalars.test.ts +877 -0
  108. package/test/collections/flowMap.states.test.ts +1097 -0
  109. package/test/nodes/async/flowConstantAsync.test.ts +860 -0
  110. package/test/nodes/async/flowDerivationAsync.test.ts +1517 -0
  111. package/test/nodes/async/flowStateAsync.test.ts +1387 -0
  112. package/test/{resource.test.ts → nodes/await/advanced/resource.test.ts} +21 -19
  113. package/test/{resourceAsync.test.ts → nodes/await/advanced/resourceAsync.test.ts} +3 -1
  114. package/test/{stream.test.ts → nodes/await/advanced/stream.test.ts} +30 -28
  115. package/test/{streamAsync.test.ts → nodes/await/advanced/streamAsync.test.ts} +16 -14
  116. package/test/nodes/await/flowConstantAwait.test.ts +643 -0
  117. package/test/nodes/await/flowDerivationAwait.test.ts +1583 -0
  118. package/test/nodes/await/flowStateAwait.test.ts +999 -0
  119. package/test/nodes/mixed/derivation.test.ts +1527 -0
  120. package/test/nodes/sync/flowConstant.test.ts +620 -0
  121. package/test/nodes/sync/flowDerivation.test.ts +1373 -0
  122. package/test/nodes/sync/flowState.test.ts +945 -0
  123. package/test/solid/converters.test.ts +721 -0
  124. package/test/solid/primitives.test.ts +1031 -0
  125. package/tsconfig.json +2 -1
  126. package/vitest.config.ts +7 -1
  127. package/IMPLEMENTATION_GUIDE.md +0 -1578
  128. package/dist/types/advanced/array.d.ts.map +0 -1
  129. package/dist/types/advanced/index.d.ts +0 -9
  130. package/dist/types/advanced/index.d.ts.map +0 -1
  131. package/dist/types/advanced/map.d.ts +0 -166
  132. package/dist/types/advanced/map.d.ts.map +0 -1
  133. package/dist/types/advanced/resource.d.ts +0 -78
  134. package/dist/types/advanced/resource.d.ts.map +0 -1
  135. package/dist/types/advanced/resourceAsync.d.ts +0 -56
  136. package/dist/types/advanced/resourceAsync.d.ts.map +0 -1
  137. package/dist/types/advanced/stream.d.ts +0 -117
  138. package/dist/types/advanced/stream.d.ts.map +0 -1
  139. package/dist/types/advanced/streamAsync.d.ts +0 -97
  140. package/dist/types/advanced/streamAsync.d.ts.map +0 -1
  141. package/dist/types/basic/constant.d.ts +0 -60
  142. package/dist/types/basic/constant.d.ts.map +0 -1
  143. package/dist/types/basic/derivation.d.ts +0 -89
  144. package/dist/types/basic/derivation.d.ts.map +0 -1
  145. package/dist/types/basic/disposable.d.ts +0 -82
  146. package/dist/types/basic/disposable.d.ts.map +0 -1
  147. package/dist/types/basic/effect.d.ts +0 -67
  148. package/dist/types/basic/effect.d.ts.map +0 -1
  149. package/dist/types/basic/index.d.ts +0 -10
  150. package/dist/types/basic/index.d.ts.map +0 -1
  151. package/dist/types/basic/observable.d.ts +0 -83
  152. package/dist/types/basic/observable.d.ts.map +0 -1
  153. package/dist/types/basic/signal.d.ts +0 -69
  154. package/dist/types/basic/signal.d.ts.map +0 -1
  155. package/dist/types/basic/state.d.ts +0 -47
  156. package/dist/types/basic/state.d.ts.map +0 -1
  157. package/dist/types/basic/trackingContext.d.ts +0 -33
  158. package/dist/types/basic/trackingContext.d.ts.map +0 -1
  159. package/dist/types/creators.d.ts +0 -340
  160. package/dist/types/creators.d.ts.map +0 -1
  161. package/src/advanced/array.ts +0 -222
  162. package/src/advanced/index.ts +0 -12
  163. package/src/advanced/map.ts +0 -193
  164. package/src/basic/constant.ts +0 -97
  165. package/src/basic/derivation.ts +0 -147
  166. package/src/basic/disposable.ts +0 -86
  167. package/src/basic/effect.ts +0 -104
  168. package/src/basic/index.ts +0 -9
  169. package/src/basic/observable.ts +0 -109
  170. package/src/basic/signal.ts +0 -145
  171. package/src/basic/state.ts +0 -60
  172. package/src/basic/trackingContext.ts +0 -45
  173. package/src/creators.ts +0 -395
  174. package/test/array.test.ts +0 -600
  175. package/test/constant.test.ts +0 -44
  176. package/test/derivation.test.ts +0 -539
  177. package/test/effect.test.ts +0 -29
  178. package/test/map.test.ts +0 -240
  179. package/test/signal.test.ts +0 -72
  180. package/test/state.test.ts +0 -212
@@ -0,0 +1,372 @@
1
+ <!-- c9506e24-37d6-4d95-a937-545ccc76fe61 744135bd-5bf9-4a27-9006-1c9cfd4392d8 -->
2
+ # Plan d'implémentation : Unification FlowResource avec FlowDerivation (approche intégrée)
3
+
4
+ ## 1. Modifications d'API
5
+
6
+ ### 1.1 FlowDerivation - Option `synchrone` et méthode `refresh()`
7
+
8
+ **Fichier**: `src/basic/derivation.ts`
9
+
10
+ **Modifications du constructeur**:
11
+
12
+ ```typescript
13
+ constructor(
14
+ compute: (t: TrackingContext) => T | Promise<T>,
15
+ options?: {
16
+ synchrone?: boolean; // Si true avec fonction async, retourne T | undefined
17
+ }
18
+ )
19
+ ```
20
+
21
+ **Nouvelle méthode**:
22
+
23
+ ```typescript
24
+ public refresh(): void
25
+ ```
26
+
27
+ **Comportement avec `synchrone: true`**:
28
+
29
+ - Quand `synchrone: true` est fourni avec une fonction async (`Promise<T>`):
30
+ - Le type de retour devient `FlowDerivation<T | undefined>` au lieu de `FlowDerivation<Promise<T>>`
31
+ - Retourne `undefined` initialement, puis `T` une fois la Promise résolue
32
+ - Compare les valeurs avec `===` avant de notifier (évite notifications inutiles)
33
+ - Gère les erreurs de Promise (throw)
34
+ - Quand `synchrone: true` est fourni avec une fonction synchrone:
35
+ - Erreur de type TypeScript (incompatibilité de types)
36
+ - `refresh()` marque comme dirty et notifie (même comportement que sans option)
37
+
38
+ **Usage**:
39
+
40
+ ```typescript
41
+ // Dérivation async normale
42
+ const $userAsync = derivation(async (t) => await fetchUser());
43
+ const userPromise = $userAsync.pick(); // Promise<User>
44
+
45
+ // Dérivation async synchronisée
46
+ const $user = derivation(async (t) => await fetchUser(), { synchrone: true });
47
+ const user = $user.pick(); // User | undefined
48
+
49
+ // Refresh
50
+ $user.refresh(); // Marque comme dirty
51
+ await $user.pick(); // Déclenche le recalcul et attend
52
+ ```
53
+
54
+ ### 1.2 Suppression de FlowSynchronizer
55
+
56
+ **Changement d'approche**:
57
+
58
+ - Plus besoin de classe `FlowSynchronizer` séparée
59
+ - La synchronisation est intégrée directement dans `FlowDerivation`
60
+
61
+ ### 1.3 Modifications des creators
62
+
63
+ **Fichier**: `src/creators.ts`
64
+
65
+ **Changements**:
66
+
67
+ 1. **`resourceAsync()`** - Simplifié:
68
+ ```typescript
69
+ // Avant: retourne FlowResourceAsync
70
+ // Après: retourne FlowDerivation<Promise<T>>
71
+ export function resourceAsync<T>(fn: () => Promise<T>): FlowDerivation<Promise<T>> {
72
+ return derivation(() => fn());
73
+ }
74
+ ```
75
+
76
+ 2. **`resource()`** - Utilise l'option `synchrone`:
77
+ ```typescript
78
+ // Avant: retourne FlowResource
79
+ // Après: retourne FlowDerivation<T | undefined>
80
+ export function resource<T>(fn: () => Promise<T>): FlowDerivation<T | undefined> {
81
+ return derivation(() => fn(), { synchrone: true });
82
+ }
83
+ ```
84
+
85
+
86
+ ### 1.4 Exports
87
+
88
+ **Fichiers**: `src/advanced/index.ts`, `src/index.ts`
89
+
90
+ **Suppressions** (après migration):
91
+
92
+ - `FlowResource` (remplacé par `FlowDerivation` avec `synchrone: true`)
93
+ - `FlowResourceAsync` (remplacé par `FlowDerivation<Promise<T>>`)
94
+ - Plus besoin d'exporter `FlowSynchronizer`
95
+
96
+ ### 1.5 Rétrocompatibilité
97
+
98
+ **Impact**:
99
+
100
+ - Les types de retour changent, mais l'API reste compatible fonctionnellement
101
+ - `resource()` et `resourceAsync()` continuent de fonctionner de la même manière
102
+ - Les tests existants doivent continuer de passer (avec ajustements de types si nécessaire)
103
+
104
+ ## 2. Implémentations détaillées
105
+
106
+ ### 2.1 FlowDerivation - Support de l'option `synchrone`
107
+
108
+ **Fichier**: `src/basic/derivation.ts`
109
+
110
+ **Modifications du constructeur**:
111
+
112
+ ```typescript
113
+ constructor(
114
+ compute: (t: TrackingContext) => T | Promise<T>,
115
+ options?: { synchrone?: boolean }
116
+ ) {
117
+ super();
118
+ this._compute = compute;
119
+ this._trackedContext = new TrackingContext(this);
120
+ this._synchrone = options?.synchrone ?? false;
121
+
122
+ // Si synchrone est activé, on doit gérer les Promises différemment
123
+ if (this._synchrone) {
124
+ // Initialiser la valeur à undefined pour le mode synchrone
125
+ this._value = undefined as T;
126
+ }
127
+ }
128
+ ```
129
+
130
+ **Modifications de `_getRaw()`**:
131
+
132
+ ```typescript
133
+ protected _getRaw(): T {
134
+ if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
135
+
136
+ this._initLazy();
137
+ this._update();
138
+
139
+ if (this._synchrone) {
140
+ // En mode synchrone, la valeur peut être undefined si la Promise n'est pas encore résolue
141
+ return this._value as T;
142
+ }
143
+
144
+ return this._value;
145
+ }
146
+ ```
147
+
148
+ **Modifications de `_update()` pour gérer la synchronisation**:
149
+
150
+ ```typescript
151
+ private _update(): void {
152
+ if (this._dirty) {
153
+ // Store current dependencies
154
+ const dependencies = [...this._dependencies];
155
+
156
+ // Clear current dependencies, compute and retrack dependencies
157
+ this._dependencies.clear();
158
+ const computedValue = this._compute(this._trackedContext);
159
+
160
+ if (this._synchrone && computedValue instanceof Promise) {
161
+ // Mode synchrone avec Promise
162
+ this._handleSyncPromise(computedValue as Promise<T>);
163
+ } else {
164
+ // Mode normal
165
+ this._value = computedValue;
166
+ }
167
+
168
+ // Unsubscribe from dependencies that are no longer needed
169
+ const dependenciesToRemove = dependencies.filter(
170
+ (dependency) => !this._dependencies.has(dependency),
171
+ );
172
+ dependenciesToRemove.forEach((dependency) => {
173
+ dependency._unregisterDependency(this);
174
+ });
175
+
176
+ this._dirty = false;
177
+ }
178
+ }
179
+ ```
180
+
181
+ **Nouvelle méthode `_handleSyncPromise()`**:
182
+
183
+ ```typescript
184
+ private async _handleSyncPromise(promise: Promise<T>): Promise<void> {
185
+ // Marquer cette Promise comme la Promise courante
186
+ this._currentPromise = promise;
187
+
188
+ try {
189
+ const value = await promise;
190
+
191
+ // Vérifier que c'est toujours la Promise courante (éviter les race conditions)
192
+ if (this._currentPromise !== promise) {
193
+ return; // Une nouvelle Promise a été créée, ignorer cette résolution
194
+ }
195
+
196
+ // Comparer avec la valeur actuelle pour éviter les notifications inutiles
197
+ if (value === this._value) {
198
+ return;
199
+ }
200
+
201
+ // Mettre à jour la valeur et notifier
202
+ this._value = value as T;
203
+ this._notify();
204
+ } catch (error) {
205
+ // Vérifier que c'est toujours la Promise courante
206
+ if (this._currentPromise !== promise) {
207
+ return; // Une nouvelle Promise a été créée, ignorer cette erreur
208
+ }
209
+
210
+ // Throw l'erreur
211
+ throw error;
212
+ }
213
+ }
214
+ ```
215
+
216
+ **Nouvelle méthode `refresh()`**:
217
+
218
+ ```typescript
219
+ public refresh(): void {
220
+ if (this._disposed) throw new Error("[PicoFlow] Primitive is disposed");
221
+
222
+ // Marquer comme dirty (le recalcul se fera au prochain accès)
223
+ this._dirty = true;
224
+
225
+ // Notifier les dépendants pour qu'ils se marquent aussi comme dirty
226
+ this._notify();
227
+ }
228
+ ```
229
+
230
+ **Nouveaux champs privés**:
231
+
232
+ ```typescript
233
+ private _synchrone: boolean;
234
+ private _currentPromise?: Promise<T>;
235
+ ```
236
+
237
+ **Points d'attention**:
238
+
239
+ 1. **Type safety**: Le type de retour doit être `FlowDerivation<T | undefined>` quand `synchrone: true` avec une fonction async
240
+ 2. **Gestion des Promises**: En mode synchrone, les Promises sont gérées de manière asynchrone dans `_handleSyncPromise()`
241
+ 3. **Comparaison de valeurs**: Utiliser `===` uniquement en mode synchrone
242
+ 4. **Race conditions**: Utiliser `_currentPromise` pour tracker la Promise courante
243
+ 5. **Initialisation**: En mode synchrone, initialiser `_value` à `undefined`
244
+ 6. **Lazy evaluation**: Le comportement lazy reste le même, mais la résolution de Promise est asynchrone
245
+
246
+ ### 2.2 Mise à jour des creators
247
+
248
+ **Fichier**: `src/creators.ts`
249
+
250
+ **Implémentation `resourceAsync()`**:
251
+
252
+ ```typescript
253
+ export function resourceAsync<T>(fn: () => Promise<T>): FlowDerivation<Promise<T>> {
254
+ return derivation(() => fn());
255
+ }
256
+ ```
257
+
258
+ **Points d'attention**:
259
+
260
+ - La fonction `fn` ne reçoit pas de `TrackingContext` (comportement actuel)
261
+ - Retourne directement une `FlowDerivation<Promise<T>>`
262
+
263
+ **Implémentation `resource()`**:
264
+
265
+ ```typescript
266
+ export function resource<T>(fn: () => Promise<T>): FlowDerivation<T | undefined> {
267
+ return derivation(() => fn(), { synchrone: true });
268
+ }
269
+ ```
270
+
271
+ **Points d'attention**:
272
+
273
+ - Utilise l'option `synchrone: true` pour activer le mode synchrone
274
+ - Retourne `FlowDerivation<T | undefined>`
275
+
276
+ ### 2.3 Mise à jour des exports
277
+
278
+ **Fichier**: `src/advanced/index.ts`
279
+
280
+ **Modifications**:
281
+
282
+ ```typescript
283
+ // Supprimer (après migration complète)
284
+ // export { FlowResource } from "./resource";
285
+ // export { FlowResourceAsync } from "./resourceAsync";
286
+ // Plus besoin de FlowSynchronizer
287
+ ```
288
+
289
+ **Fichier**: `src/index.ts`
290
+
291
+ **Modifications**:
292
+
293
+ ```typescript
294
+ // Supprimer FlowResource et FlowResourceAsync des exports
295
+ export {
296
+ FlowArray,
297
+ type FlowArrayAction,
298
+ FlowMap,
299
+ FlowStream,
300
+ FlowStreamAsync,
301
+ // FlowResource, // À supprimer
302
+ // FlowResourceAsync, // À supprimer
303
+ ...
304
+ } from "./advanced/";
305
+ ```
306
+
307
+ ### 2.4 Migration des tests
308
+
309
+ **Fichiers**: `test/resource.test.ts`, `test/resourceAsync.test.ts`
310
+
311
+ **Actions**:
312
+
313
+ 1. Mettre à jour les imports pour utiliser `FlowDerivation`
314
+ 2. Adapter les types de retour des fonctions `resource()` et `resourceAsync()`
315
+ 3. Adapter les appels à `refresh()` : `resource.refresh()` puis `await resource.pick()` si nécessaire
316
+ 4. Vérifier que tous les tests passent avec la nouvelle implémentation
317
+ 5. Potentiellement fusionner les tests si la logique est similaire
318
+
319
+ **Points d'attention**:
320
+
321
+ - Les tests de `resource()` doivent maintenant tester `FlowDerivation<T | undefined>` avec `synchrone: true`
322
+ - Les tests de `resourceAsync()` doivent tester `FlowDerivation<Promise<T>>`
323
+ - Vérifier que le comportement lazy est toujours correct
324
+ - Vérifier que la comparaison de valeurs fonctionne en mode synchrone
325
+ - Vérifier que les race conditions sont gérées correctement
326
+
327
+ ### 2.5 Suppression des anciennes classes
328
+
329
+ **Fichiers**: `src/advanced/resource.ts`, `src/advanced/resourceAsync.ts`
330
+
331
+ **Actions** (après vérification que tout fonctionne):
332
+
333
+ 1. Supprimer `src/advanced/resource.ts`
334
+ 2. Supprimer `src/advanced/resourceAsync.ts`
335
+ 3. Nettoyer les exports dans `src/advanced/index.ts`
336
+
337
+ **Points d'attention**:
338
+
339
+ - Ne supprimer qu'après avoir vérifié que tous les tests passent
340
+ - Vérifier qu'aucun code externe n'importe directement ces classes
341
+ - Mettre à jour la documentation si nécessaire
342
+
343
+ ## 3. Ordre d'implémentation recommandé
344
+
345
+ 1. **Étape 1**: Ajouter l'option `synchrone` et la méthode `refresh()` à `FlowDerivation` et tester
346
+ 2. **Étape 2**: Implémenter la gestion des Promises en mode synchrone avec comparaison de valeurs
347
+ 3. **Étape 3**: Mettre à jour les creators `resource()` et `resourceAsync()`
348
+ 4. **Étape 4**: Mettre à jour les exports
349
+ 5. **Étape 5**: Migrer et adapter les tests
350
+ 6. **Étape 6**: Supprimer les anciennes classes `FlowResource` et `FlowResourceAsync`
351
+
352
+ ## 4. Cas limites à tester
353
+
354
+ 1. **Race conditions**: Appels multiples rapides à `refresh()` avec mode synchrone
355
+ 2. **Erreurs async**: Promises rejetées dans les derivations en mode synchrone
356
+ 3. **Lazy initialization**: Vérifier que le fetch ne se fait qu'au premier accès
357
+ 4. **Comparaison de valeurs**: Vérifier que les notifications ne se déclenchent que si la valeur change (mode synchrone uniquement)
358
+ 5. **Disposal**: Vérifier le cleanup correct
359
+ 6. **Dérivations sync avec refresh()**: Vérifier que ça fonctionne aussi pour les derivations non-async
360
+ 7. **Refresh puis accès**: Vérifier que `refresh()` puis `pick()`/`get()` déclenche bien le recalcul
361
+ 8. **Refresh sur dérivation non-initialisée**: Vérifier que `refresh()` fonctionne même si la dérivation n'a pas encore été accédée
362
+ 9. **Mode synchrone avec fonction sync**: Vérifier que TypeScript lève une erreur de type
363
+ 10. **Plusieurs Promises successives**: Vérifier que seule la dernière Promise résolue met à jour la valeur
364
+
365
+ ### To-dos
366
+
367
+ - [ ] Ajouter la méthode refresh() à FlowDerivation dans src/basic/derivation.ts avec gestion des derivations sync et async
368
+ - [ ] Créer la classe FlowSynchronizer dans src/advanced/synchronizer.ts avec lazy initialization, gestion des race conditions, et comparaison de valeurs
369
+ - [ ] Mettre à jour resource() et resourceAsync() dans src/creators.ts pour utiliser FlowDerivation et FlowSynchronizer
370
+ - [ ] Mettre à jour les exports dans src/advanced/index.ts et src/index.ts pour exporter FlowSynchronizer et supprimer FlowResource/FlowResourceAsync
371
+ - [ ] Adapter les tests dans test/resource.test.ts et test/resourceAsync.test.ts pour la nouvelle API
372
+ - [ ] Supprimer src/advanced/resource.ts et src/advanced/resourceAsync.ts après vérification
package/README.md CHANGED
@@ -23,4 +23,20 @@ For comprehensive guides and API documentation, visit the [official website](htt
23
23
 
24
24
  ## License
25
25
 
26
- This project is licensed under the [MIT License](LICENSE).
26
+ This project is licensed under the [MIT License](LICENSE).
27
+
28
+ ## TODO
29
+
30
+ - [x] implement refresh on derivations
31
+ - [x] add tests for refresh
32
+ - [x] improve tests for array / maps
33
+ - [x] use same API for array and maps
34
+ - [x] use async API for array updates
35
+ - [x] manage unified disposal in collections
36
+ - [ ] fix tests
37
+ - [ ] implement sets
38
+ - [x] implement await nodes
39
+ - [ ] add tests for await nodes
40
+ - [ ] add tests for raw nodes
41
+ - [ ] replace resources by await nodes
42
+ - [ ] think about streams
package/biome.json CHANGED
@@ -15,7 +15,10 @@
15
15
  "linter": {
16
16
  "enabled": true,
17
17
  "rules": {
18
- "recommended": true
18
+ "recommended": true,
19
+ "complexity": {
20
+ "noStaticOnlyClass": "off"
21
+ }
19
22
  }
20
23
  },
21
24
  "javascript": {