@ngstato/core 0.1.1 → 0.2.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.
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/store.ts","../src/types.ts","../src/http.ts","../src/helpers/abortable.ts","../src/helpers/debounced.ts","../src/helpers/throttled.ts","../src/helpers/retryable.ts","../src/helpers/from-stream.ts","../src/helpers/optimistic.ts","../src/devtools.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// ─────────────────────────────────────────────────────\r\n// @ngstato/core — createStore()\r\n// Le moteur principal de Stato\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport type {\r\n StatoStoreConfig,\r\n StatoHooks,\r\n StateSlice\r\n} from './types'\r\n\r\n// ─────────────────────────────────────────────────────\r\n// CLASSE INTERNE — jamais exposée directement\r\n// ─────────────────────────────────────────────────────\r\n\r\nclass StatoStore<S extends object> {\r\n\r\n // Le state interne — jamais accessible directement\r\n private _state: StateSlice<S>\r\n\r\n // Les abonnés — notifiés à chaque changement\r\n private _subscribers: Set<(state: StateSlice<S>) => void> = new Set()\r\n\r\n // Les actions enregistrées\r\n private _actions: Record<string, Function> = {}\r\n\r\n // Les computed enregistrés\r\n private _computed: Record<string, () => unknown> = {}\r\n\r\n // Les cleanups à appeler à la destruction\r\n private _cleanups: Array<() => void> = []\r\n\r\n // Les hooks lifecycle\r\n private _hooks: StatoHooks<any>\r\n\r\n constructor(config: StatoStoreConfig<S>) {\r\n // 1. Extraire le state initial — tout sauf actions/computed/hooks\r\n const { actions, computed, hooks, ...initialState } = config\r\n this._state = initialState as StateSlice<S>\r\n this._hooks = hooks ?? {}\r\n\r\n // 2. Enregistrer les actions\r\n if (actions) {\r\n for (const [name, fn] of Object.entries(actions)) {\r\n this._actions[name] = fn\r\n }\r\n }\r\n\r\n // 3. Enregistrer les computed\r\n if (computed) {\r\n for (const [name, fn] of Object.entries(computed)) {\r\n if (typeof fn === 'function') {\r\n this._computed[name] = () => (fn as Function)(this._state)\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ── Lire le state ──────────────────────────────────\r\n getState(): Readonly<StateSlice<S>> {\r\n return { ...this._state }\r\n }\r\n\r\n // ── Modifier le state — usage interne uniquement ───\r\n private _setState(partial: Partial<StateSlice<S>>) {\r\n // Copie immutable — on ne modifie jamais l'objet original\r\n this._state = { ...this._state, ...partial }\r\n this._notify()\r\n }\r\n\r\n // ── Notifier tous les abonnés ──────────────────────\r\n private _notify() {\r\n for (const subscriber of this._subscribers) {\r\n subscriber({ ...this._state })\r\n }\r\n }\r\n\r\n // ── S'abonner aux changements ──────────────────────\r\n subscribe(fn: (state: StateSlice<S>) => void): () => void {\r\n this._subscribers.add(fn)\r\n // Retourne une fonction de désabonnement\r\n return () => this._subscribers.delete(fn)\r\n }\r\n\r\n // ── Exécuter une action ────────────────────────────\r\nasync dispatch(actionName: string, ...args: unknown[]) {\r\n const action = this._actions[actionName]\r\n if (!action) {\r\n throw new Error(`[Stato] Action \"${actionName}\" introuvable`)\r\n }\r\n\r\n // Hook onAction — avant l'exécution\r\n this._hooks.onAction?.(actionName, args)\r\n\r\n const start = Date.now()\r\n const prevState = { ...this._state }\r\n\r\n const stateProxy = new Proxy({ ...this._state } as any, {\r\n set: (target, key, value) => {\r\n target[key] = value\r\n this._setState({ [key]: value } as any)\r\n return true\r\n }\r\n })\r\n\r\n try {\r\n await action(stateProxy, ...args)\r\n\r\n // Hook onActionDone — après l'exécution\r\n this._hooks.onActionDone?.(actionName, Date.now() - start)\r\n\r\n // Hook onStateChange — si le state a changé\r\n this._hooks.onStateChange?.(prevState as any, { ...this._state } as any)\r\n\r\n } catch (error) {\r\n // Hook onError — si une erreur est lancée\r\n this._hooks.onError?.(error as Error, actionName)\r\n throw error // on remonte l'erreur quand même\r\n }\r\n}\r\n\r\n // ── Lire une valeur computed ───────────────────────\r\n getComputed(name: string): unknown {\r\n const fn = this._computed[name]\r\n if (!fn) throw new Error(`[Stato] Computed \"${name}\" introuvable`)\r\n return fn()\r\n }\r\n\r\n // ── Enregistrer un cleanup (pour fromStream) ───────\r\n registerCleanup(fn: () => void) {\r\n this._cleanups.push(fn)\r\n }\r\n\r\n // ── Lifecycle — appelé par l'adaptateur Angular ────\r\n init(publicStore: any) {\r\n this._hooks.onInit?.(publicStore)\r\n }\r\n\r\n destroy(publicStore: any) {\r\n this._hooks.onDestroy?.(publicStore)\r\n // Nettoyer tous les streams ouverts\r\n for (const cleanup of this._cleanups) {\r\n cleanup()\r\n }\r\n this._cleanups = []\r\n this._subscribers.clear()\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FONCTION PUBLIQUE — createStore()\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createStore<S extends object>(config: S & StatoStoreConfig<S>) {\r\n\r\n // Créer l'instance interne\r\n const store = new StatoStore<S>(config as StatoStoreConfig<S>)\r\n\r\n // Construire l'objet public\r\n // Les propriétés du state sont accessibles directement\r\n // Les actions sont exposées sans le paramètre state\r\n const publicStore: any = {\r\n // Accès au store interne — pour les adaptateurs Angular/React/Vue\r\n __store__: store,\r\n\r\n // S'abonner aux changements\r\n subscribe: store.subscribe.bind(store),\r\n\r\n // Lire le state complet\r\n getState: store.getState.bind(store),\r\n\r\n // Enregistrer un cleanup\r\n registerCleanup: store.registerCleanup.bind(store),\r\n }\r\n\r\n // Exposer chaque propriété du state\r\n const initialState = store.getState()\r\n for (const key of Object.keys(initialState as object)) {\r\n Object.defineProperty(publicStore, key, {\r\n get: () => store.getState()[key as keyof typeof initialState],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n\r\n // Exposer chaque action\r\n const { actions, computed } = config as StatoStoreConfig<S>\r\n\r\n if (actions) {\r\n for (const name of Object.keys(actions)) {\r\n publicStore[name] = (...args: unknown[]) => store.dispatch(name, ...args)\r\n }\r\n }\r\n\r\n // Exposer chaque computed\r\n if (computed) {\r\n for (const name of Object.keys(computed)) {\r\n Object.defineProperty(publicStore, name, {\r\n get: () => store.getComputed(name),\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n return publicStore\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// store.on() — réactions inter-stores\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function on<S extends object>(\r\n sourceAction: Function,\r\n handler: (state: S) => void | Promise<void>\r\n) {\r\n // Sera implémenté dans v0.2\r\n // après que le core soit stable\r\n console.warn('[Stato] store.on() disponible en v0.2')\r\n}","// ─────────────────────────────────────────────────────\r\n// TYPES PUBLICS DE @ngstato/core\r\n// ─────────────────────────────────────────────────────\r\n\r\n// Le state de base — tout sauf actions, computed, hooks\r\nexport type StateSlice<T> = Omit<T, 'actions' | 'computed' | 'hooks'>\r\n\r\n// Une action — sync ou async\r\nexport type Action<S> = (state: S, ...args: any[]) => void | Promise<void> | (() => void)\r\n\r\n// Map d'actions\r\nexport type ActionsMap<S> = Record<string, Action<S>>\r\n\r\n// Computed — dérivé du state local\r\nexport type ComputedFn<S> = (state: S) => unknown\r\n\r\n// Hooks lifecycle\r\nexport interface StatoHooks<S> {\r\n // Lifecycle du store\r\n onInit?: (store: S) => void | Promise<void>\r\n onDestroy?: (store: S) => void | Promise<void>\r\n\r\n // Lifecycle des actions\r\n onAction?: (name: string, args: unknown[]) => void\r\n onActionDone?: (name: string, duration: number) => void\r\n onError?: (error: Error, actionName: string) => void\r\n\r\n // Lifecycle du state\r\n onStateChange?: (prev: S, next: S) => void\r\n}\r\n\r\n// Configuration du store\r\nexport interface StatoStoreConfig<S extends object> {\r\n actions?: ActionsMap<StateSlice<S>>\r\n computed?: Record<string, ComputedFn<StateSlice<S>> | unknown[]>\r\n hooks?: StatoHooks<any>\r\n [key: string]: unknown\r\n}\r\n\r\n// Instance publique du store\r\nexport type StatoStoreInstance<S extends object> = {\r\n // readonly — on ne peut lire, jamais écrire directement\r\n readonly [K in keyof StateSlice<S>]: StateSlice<S>[K]\r\n} & {\r\n // Les actions sont exposées sans le paramètre state\r\n [K in keyof S as S[K] extends Function ? K : never]:\r\n S[K] extends (state: any, ...args: infer A) => infer R\r\n ? (...args: A) => R\r\n : never\r\n}\r\n\r\n// Configuration du client HTTP\r\nexport interface StatoConfig {\r\n baseUrl?: string\r\n timeout?: number\r\n headers?: Record<string, string>\r\n auth?: () => string | null | undefined\r\n}\r\n\r\n// Erreur HTTP\r\nexport class StatoHttpError extends Error {\r\n constructor(\r\n public status: number,\r\n public body: string\r\n ) {\r\n super(`HTTP ${status}: ${body}`)\r\n this.name = 'StatoHttpError'\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — StatoHttp\r\n// Client HTTP natif — fetch + baseUrl + auth + timeout\r\n// Zero dépendance — pas de HttpClient Angular\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport type { StatoConfig } from './types'\r\nimport { StatoHttpError } from './types'\r\n\r\n// ─────────────────────────────────────────────────────\r\n// OPTIONS PAR REQUÊTE\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface RequestOptions {\r\n params?: Record<string, string | number | boolean>\r\n headers?: Record<string, string>\r\n signal?: AbortSignal // pour abortable()\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// CLASSE PRINCIPALE\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport class StatoHttp {\r\n\r\n private _config: StatoConfig\r\n\r\n constructor(config: StatoConfig = {}) {\r\n this._config = config\r\n }\r\n\r\n // ── GET ───────────────────────────────────────────\r\n get<T = unknown>(url: string, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('GET', url, undefined, options)\r\n }\r\n\r\n // ── POST ──────────────────────────────────────────\r\n post<T = unknown>(url: string, body?: unknown, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('POST', url, body, options)\r\n }\r\n\r\n // ── PUT ───────────────────────────────────────────\r\n put<T = unknown>(url: string, body?: unknown, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('PUT', url, body, options)\r\n }\r\n\r\n // ── PATCH ─────────────────────────────────────────\r\n patch<T = unknown>(url: string, body?: unknown, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('PATCH', url, body, options)\r\n }\r\n\r\n // ── DELETE ────────────────────────────────────────\r\n delete<T = unknown>(url: string, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('DELETE', url, undefined, options)\r\n }\r\n\r\n // ── MOTEUR INTERNE ────────────────────────────────\r\n private async _request<T>(\r\n method: string,\r\n url: string,\r\n body?: unknown,\r\n options?: RequestOptions\r\n ): Promise<T> {\r\n\r\n // 1. Construire l'URL complète avec baseUrl + params\r\n const fullUrl = this._buildUrl(url, options?.params)\r\n\r\n // 2. Récupérer le token auth si configuré\r\n const token = this._config.auth?.()\r\n\r\n // 3. Construire les headers\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n ...this._config.headers,\r\n ...options?.headers,\r\n ...(token ? { Authorization: `Bearer ${token}` } : {})\r\n }\r\n\r\n // 4. Configurer le timeout si défini\r\n let signal = options?.signal\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined\r\n\r\n if (this._config.timeout && !signal) {\r\n const controller = new AbortController()\r\n signal = controller.signal\r\n timeoutId = setTimeout(\r\n () => controller.abort(),\r\n this._config.timeout\r\n )\r\n }\r\n\r\n // 5. Exécuter la requête\r\n try {\r\n const response = await fetch(fullUrl, {\r\n method,\r\n headers,\r\n signal,\r\n ...(body !== undefined\r\n ? { body: JSON.stringify(body) }\r\n : {}\r\n )\r\n })\r\n\r\n // 6. Gérer les erreurs HTTP automatiquement\r\n if (!response.ok) {\r\n const errorBody = await response.text()\r\n throw new StatoHttpError(response.status, errorBody)\r\n }\r\n\r\n // 7. Réponse vide — ex: DELETE 204\r\n const contentType = response.headers.get('content-type')\r\n if (\r\n response.status === 204 ||\r\n !contentType?.includes('application/json')\r\n ) {\r\n return undefined as T\r\n }\r\n\r\n // 8. Parser le JSON\r\n return response.json() as Promise<T>\r\n\r\n } finally {\r\n // Toujours nettoyer le timeout\r\n if (timeoutId) clearTimeout(timeoutId)\r\n }\r\n }\r\n\r\n // ── CONSTRUIRE L'URL AVEC PARAMS ──────────────────\r\n private _buildUrl(\r\n path: string,\r\n params?: Record<string, string | number | boolean>\r\n ): string {\r\n\r\n // Si l'URL est absolue — on ne préfixe pas baseUrl\r\n const url = path.startsWith('http')\r\n ? path\r\n : `${this._config.baseUrl ?? ''}${path}`\r\n\r\n // Ajouter les query params si présents\r\n if (!params || Object.keys(params).length === 0) return url\r\n\r\n const qs = new URLSearchParams(\r\n Object.entries(params).map(([k, v]) => [k, String(v)])\r\n ).toString()\r\n\r\n return `${url}?${qs}`\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FACTORY FUNCTION — createHttp()\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createHttp(config: StatoConfig = {}): StatoHttp {\r\n return new StatoHttp(config)\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// INSTANCE GLOBALE — http\r\n// Utilisée dans les actions des stores\r\n// Configurée via provideStato()\r\n// ─────────────────────────────────────────────────────\r\n\r\nlet _globalHttp: StatoHttp = new StatoHttp()\r\n\r\nexport function configureHttp(config: StatoConfig): void {\r\n _globalHttp = new StatoHttp(config)\r\n}\r\n\r\n// L'objet http — utilisé dans les actions\r\n// await http.get('/api/users')\r\nexport const http = {\r\n get: <T>(url: string, options?: RequestOptions) =>\r\n _globalHttp.get<T>(url, options),\r\n\r\n post: <T>(url: string, body?: unknown, options?: RequestOptions) =>\r\n _globalHttp.post<T>(url, body, options),\r\n\r\n put: <T>(url: string, body?: unknown, options?: RequestOptions) =>\r\n _globalHttp.put<T>(url, body, options),\r\n\r\n patch: <T>(url: string, body?: unknown, options?: RequestOptions) =>\r\n _globalHttp.patch<T>(url, body, options),\r\n\r\n delete: <T>(url: string, options?: RequestOptions) =>\r\n _globalHttp.delete<T>(url, options),\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — abortable()\r\n// Annule automatiquement la requête précédente\r\n// Remplace switchMap de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface AbortableOptions {\r\n signal: AbortSignal\r\n}\r\n\r\nexport function abortable<S, A extends unknown[]>(\r\n fn: (state: S, ...args: [...A, AbortableOptions]) => Promise<void>\r\n) {\r\n let controller: AbortController | null = null\r\n\r\n return async (state: S, ...args: A): Promise<void> => {\r\n // Annuler la requête précédente si elle tourne encore\r\n if (controller) {\r\n controller.abort()\r\n }\r\n\r\n // Créer un nouveau controller pour cette requête\r\n controller = new AbortController()\r\n const signal = controller.signal\r\n\r\n try {\r\n await fn(state, ...args, { signal } as any)\r\n } catch (error: any) {\r\n // Ignorer silencieusement les erreurs d'annulation\r\n if (error?.name === 'AbortError') return\r\n throw error\r\n } finally {\r\n controller = null\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — debounced()\r\n// Attend que l'utilisateur arrête de taper\r\n// Remplace debounceTime de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function debounced<S, A extends unknown[]>(\r\n fn: (state: S, ...args: A) => void | Promise<void>,\r\n ms: number = 300\r\n) {\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n\r\n return (state: S, ...args: A): Promise<void> => {\r\n // Annuler le timer précédent\r\n if (timer) clearTimeout(timer)\r\n\r\n // Retourner une Promise qui se résout après le délai\r\n return new Promise((resolve, reject) => {\r\n timer = setTimeout(async () => {\r\n try {\r\n await fn(state, ...args)\r\n resolve()\r\n } catch (error) {\r\n reject(error)\r\n } finally {\r\n timer = null\r\n }\r\n }, ms)\r\n })\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — throttled()\r\n// Limite la fréquence d'exécution d'une action\r\n// Remplace throttleTime de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function throttled<S, A extends unknown[]>(\r\n fn: (state: S, ...args: A) => void | Promise<void>,\r\n ms: number = 300\r\n) {\r\n let lastCall = 0\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n\r\n return async (state: S, ...args: A): Promise<void> => {\r\n const now = Date.now()\r\n const remaining = ms - (now - lastCall)\r\n\r\n if (remaining <= 0) {\r\n // Assez de temps passé — on exécute immédiatement\r\n lastCall = now\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n await fn(state, ...args)\r\n } else {\r\n // Trop tôt — on planifie pour la fin du délai\r\n if (timer) clearTimeout(timer)\r\n return new Promise((resolve, reject) => {\r\n timer = setTimeout(async () => {\r\n lastCall = Date.now()\r\n timer = null\r\n try {\r\n await fn(state, ...args)\r\n resolve()\r\n } catch (error) {\r\n reject(error)\r\n }\r\n }, remaining)\r\n })\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — retryable()\r\n// Réessaie automatiquement en cas d'échec\r\n// Remplace retryWhen de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface RetryOptions {\r\n attempts: number // nombre de tentatives\r\n backoff: 'fixed' | 'exponential' // stratégie de délai\r\n delay?: number // délai de base en ms (défaut 1000)\r\n onRetry?: (attempt: number, error: Error) => void // callback optionnel\r\n}\r\n\r\nexport function retryable<S, A extends unknown[]>(\r\n fn: (state: S, ...args: A) => Promise<void>,\r\n options: RetryOptions = {\r\n attempts: 3,\r\n backoff: 'exponential',\r\n delay: 1000\r\n }\r\n) {\r\n return async (state: S, ...args: A): Promise<void> => {\r\n const { attempts, backoff, delay = 1000, onRetry } = options\r\n\r\n for (let i = 0; i < attempts; i++) {\r\n try {\r\n await fn(state, ...args)\r\n return // succès — on sort immédiatement\r\n\r\n } catch (error) {\r\n const isLastAttempt = i === attempts - 1\r\n\r\n // Dernière tentative — on remonte l'erreur\r\n if (isLastAttempt) throw error\r\n\r\n // Calculer le délai avant la prochaine tentative\r\n const waitMs = backoff === 'exponential'\r\n ? delay * Math.pow(2, i) // 1s, 2s, 4s, 8s...\r\n : delay // fixe : toujours 1s\r\n\r\n // Callback optionnel — pour logger ou afficher un message\r\n onRetry?.(i + 1, error as Error)\r\n\r\n // Attendre avant de réessayer\r\n await new Promise(resolve => setTimeout(resolve, waitMs))\r\n }\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — fromStream()\r\n// Pont entre un flux Observable/callback et le state\r\n// Pour : Firebase, Supabase, WebSocket, SSE\r\n// RxJS optionnel — pas obligatoire\r\n// ─────────────────────────────────────────────────────\r\n\r\n// Interface minimale d'un Observable\r\n// Compatible RxJS sans l'importer\r\nexport interface StatoObservable<T> {\r\n subscribe(observer: {\r\n next?: (value: T) => void\r\n error?: (error: unknown) => void\r\n complete?: () => void\r\n }): { unsubscribe(): void }\r\n}\r\n\r\nexport interface StreamOptions {\r\n // Appelé quand le stream se termine normalement\r\n onComplete?: () => void\r\n // Appelé quand le stream rencontre une erreur\r\n onError?: (error: unknown) => void\r\n}\r\n\r\nexport function fromStream<S, T>(\r\n // setupFn — retourne l'Observable ou le flux\r\n setupFn: (state: S) => StatoObservable<T>,\r\n // updateFn — appelé à chaque valeur émise\r\n updateFn: (state: S, value: T) => void,\r\n options?: StreamOptions\r\n) {\r\n return (state: S): (() => void) => {\r\n // Démarrer le flux\r\n const stream$ = setupFn(state)\r\n const subscription = stream$.subscribe({\r\n\r\n next: (value: T) => {\r\n // Mettre à jour le state à chaque émission\r\n updateFn(state, value)\r\n },\r\n\r\n error: (error: unknown) => {\r\n options?.onError?.(error)\r\n },\r\n\r\n complete: () => {\r\n options?.onComplete?.()\r\n }\r\n })\r\n\r\n // Retourner la fonction de cleanup\r\n // appelée automatiquement à la destruction du store\r\n return () => subscription.unsubscribe()\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — optimistic()\r\n// Mise à jour optimiste avec rollback automatique\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function optimistic<S, A extends unknown[]>(\r\n // Action immédiate — modifie le state sans attendre\r\n immediate: (state: S, ...args: A) => void,\r\n // Confirmation API — si elle échoue → rollback\r\n confirm: (state: S, ...args: A) => Promise<void>\r\n) {\r\n return async (state: S, ...args: A): Promise<void> => {\r\n // 1. Snapshot du state AVANT la modification\r\n const snapshot = { ...(state as object) } as S\r\n\r\n // 2. Appliquer la modification immédiatement\r\n immediate(state, ...args)\r\n\r\n try {\r\n // 3. Confirmer avec l'API\r\n await confirm(state, ...args)\r\n // Succès — le state optimiste est correct, rien à faire\r\n\r\n } catch (error) {\r\n // 4. Échec — restaurer le state d'avant\r\n Object.assign(state as object, snapshot)\r\n throw error\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — DevTools\r\n// Logique pure — pas de dépendance Angular\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface ActionLog {\r\n id: number\r\n name: string\r\n args: unknown[]\r\n duration: number\r\n status: 'success' | 'error'\r\n error?: string\r\n prevState: unknown\r\n nextState: unknown\r\n at: string\r\n}\r\n\r\nexport interface DevToolsState {\r\n logs: ActionLog[]\r\n isOpen: boolean\r\n maxLogs: number\r\n}\r\n\r\nexport interface DevToolsInstance {\r\n state: DevToolsState\r\n logAction: (log: Omit<ActionLog, 'id' | 'at'>) => void\r\n clear: () => void\r\n open: () => void\r\n close: () => void\r\n toggle: () => void\r\n subscribe: (cb: (state: DevToolsState) => void) => () => void\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FACTORY\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createDevTools(maxLogs = 50): DevToolsInstance {\r\n let counter = 0\r\n\r\n const state: DevToolsState = {\r\n logs: [],\r\n isOpen: false,\r\n maxLogs\r\n }\r\n\r\n const listeners = new Set<(state: DevToolsState) => void>()\r\n\r\n function notify() {\r\n listeners.forEach(cb => cb({ ...state, logs: [...state.logs] }))\r\n }\r\n\r\n return {\r\n state,\r\n\r\n logAction(log) {\r\n const entry: ActionLog = {\r\n ...log,\r\n id: ++counter,\r\n at: new Date().toISOString()\r\n }\r\n\r\n state.logs = [entry, ...state.logs].slice(0, maxLogs)\r\n notify()\r\n },\r\n\r\n clear() {\r\n state.logs = []\r\n notify()\r\n },\r\n\r\n open() {\r\n state.isOpen = true\r\n notify()\r\n },\r\n\r\n close() {\r\n state.isOpen = false\r\n notify()\r\n },\r\n\r\n toggle() {\r\n state.isOpen = !state.isOpen\r\n notify()\r\n },\r\n\r\n subscribe(cb) {\r\n listeners.add(cb)\r\n return () => listeners.delete(cb)\r\n }\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// INSTANCE GLOBALE — singleton partagé entre tous les stores\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport const devTools = createDevTools()\r\n\r\n// ─────────────────────────────────────────────────────\r\n// PLUGIN — connecte un store aux DevTools\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function connectDevTools(store: any, storeName: string) {\r\n if (!devTools) return\r\n\r\n let prevState: any = {}\r\n\r\n // Accès aux hooks via __store__\r\n const internalStore = store.__store__\r\n\r\n if (!internalStore) return\r\n\r\n // Sauvegarder les hooks existants\r\n const existingHooks = { ...internalStore['_hooks'] }\r\n\r\n // Remplacer les hooks\r\n internalStore['_hooks'] = {\r\n ...existingHooks,\r\n\r\n onAction(name: string, args: unknown[]) {\r\n prevState = store.getState()\r\n existingHooks.onAction?.(name, args)\r\n },\r\n\r\n onActionDone(name: string, duration: number) {\r\n const nextState = store.getState()\r\n devTools.logAction({\r\n name: `[${storeName}] ${name}`,\r\n args: [],\r\n duration,\r\n status: 'success',\r\n prevState: { ...prevState },\r\n nextState: { ...nextState }\r\n })\r\n existingHooks.onActionDone?.(name, duration)\r\n },\r\n\r\n onError(error: Error, actionName: string) {\r\n devTools.logAction({\r\n name: `[${storeName}] ${actionName}`,\r\n args: [],\r\n duration: 0,\r\n status: 'error',\r\n error: error.message,\r\n prevState: { ...prevState },\r\n nextState: { ...prevState }\r\n })\r\n existingHooks.onError?.(error, actionName)\r\n },\r\n\r\n onStateChange: existingHooks.onStateChange\r\n }\r\n}"]}
1
+ {"version":3,"sources":["../src/store.ts","../src/types.ts","../src/http.ts","../src/helpers/abortable.ts","../src/helpers/debounced.ts","../src/helpers/throttled.ts","../src/helpers/retryable.ts","../src/helpers/from-stream.ts","../src/helpers/optimistic.ts","../src/helpers/with-persist.ts","../src/devtools.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["// ─────────────────────────────────────────────────────\r\n// @ngstato/core — createStore()\r\n// Le moteur principal de Stato\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport type {\r\n StatoStoreConfig,\r\n StatoHooks,\r\n StateSlice,\r\n EffectEntry\r\n} from './types'\r\n\r\n// ─────────────────────────────────────────────────────\r\n// CLASSE INTERNE — jamais exposée directement\r\n// ─────────────────────────────────────────────────────\r\n\r\nclass StatoStore<S extends object> {\r\n\r\n // Le state interne — jamais accessible directement\r\n private _state: StateSlice<S>\r\n\r\n // Les abonnés — notifiés à chaque changement\r\n private _subscribers: Set<(state: StateSlice<S>) => void> = new Set()\r\n\r\n // Les actions enregistrées\r\n private _actions: Record<string, Function> = {}\r\n\r\n // Les computed enregistrés\r\n private _computed: Record<string, () => unknown> = {}\r\n private _selectors: Record<string, () => unknown> = {}\r\n\r\n // Les cleanups à appeler à la destruction\r\n private _cleanups: Array<() => void> = []\r\n\r\n // Les hooks lifecycle\r\n private _hooks: StatoHooks<any>\r\n private _publicStore: any = null\r\n private _effects: Array<{\r\n deps: (state: StateSlice<S>) => unknown | unknown[]\r\n run: Function\r\n prevDeps?: unknown[]\r\n hasRun: boolean\r\n cleanup?: () => void\r\n running: boolean\r\n rerunRequested: boolean\r\n }> = []\r\n\r\n private _createMemoizedSelector(fn: Function): () => unknown {\r\n let initialized = false\r\n let cachedResult: unknown\r\n let trackedKeys: string[] = []\r\n let trackedValues: unknown[] = []\r\n\r\n return () => {\r\n if (initialized && trackedKeys.length) {\r\n const unchanged = trackedKeys.every((key, index) =>\r\n Object.is((this._state as any)[key], trackedValues[index])\r\n )\r\n if (unchanged) return cachedResult\r\n }\r\n\r\n const reads = new Set<string>()\r\n const trackingState = new Proxy(this._state as any, {\r\n get: (target, prop, receiver) => {\r\n if (typeof prop === 'string' && prop in target) {\r\n reads.add(prop)\r\n }\r\n return Reflect.get(target, prop, receiver)\r\n }\r\n })\r\n\r\n const result = fn(trackingState)\r\n\r\n trackedKeys = Array.from(reads)\r\n trackedValues = trackedKeys.map((key) => (this._state as any)[key])\r\n cachedResult = result\r\n initialized = true\r\n\r\n return result\r\n }\r\n }\r\n\r\n constructor(config: StatoStoreConfig<S>) {\r\n // 1. Extraire le state initial — tout sauf actions/computed/hooks\r\n const { actions, computed, selectors, effects, hooks, ...initialState } = config\r\n this._state = initialState as StateSlice<S>\r\n this._hooks = hooks ?? {}\r\n\r\n // 2. Enregistrer les actions\r\n if (actions) {\r\n for (const [name, fn] of Object.entries(actions)) {\r\n this._actions[name] = fn\r\n }\r\n }\r\n\r\n // 3. Enregistrer les computed\r\n if (computed) {\r\n for (const [name, fn] of Object.entries(computed)) {\r\n if (typeof fn === 'function') {\r\n this._computed[name] = () => (fn as Function)(this._state)\r\n }\r\n }\r\n }\r\n\r\n // 4. Enregistrer les selectors memoïzés\r\n if (selectors) {\r\n for (const [name, fn] of Object.entries(selectors)) {\r\n if (typeof fn === 'function') {\r\n this._selectors[name] = this._createMemoizedSelector(fn as Function)\r\n }\r\n }\r\n }\r\n\r\n if (effects) {\r\n for (const entry of effects) {\r\n const [deps, run] = entry as EffectEntry<StateSlice<S>>\r\n if (typeof deps === 'function' && typeof run === 'function') {\r\n this._effects.push({\r\n deps,\r\n run,\r\n hasRun: false,\r\n running: false,\r\n rerunRequested: false\r\n })\r\n }\r\n }\r\n }\r\n }\r\n\r\n // ── Lire le state ──────────────────────────────────\r\n getState(): Readonly<StateSlice<S>> {\r\n return { ...this._state }\r\n }\r\n\r\n // ── Modifier le state — usage interne uniquement ───\r\n private _setState(partial: Partial<StateSlice<S>>) {\r\n // Copie immutable — on ne modifie jamais l'objet original\r\n this._state = { ...this._state, ...partial }\r\n this._runEffects()\r\n this._notify()\r\n }\r\n\r\n private _normalizeDeps(value: unknown | unknown[]): unknown[] {\r\n return Array.isArray(value) ? value : [value]\r\n }\r\n\r\n private _depsChanged(prev: unknown[] | undefined, next: unknown[]): boolean {\r\n if (!prev) return true\r\n if (prev.length !== next.length) return true\r\n for (let i = 0; i < next.length; i++) {\r\n if (!Object.is(prev[i], next[i])) return true\r\n }\r\n return false\r\n }\r\n\r\n private _runEffects(force = false) {\r\n for (const effect of this._effects) {\r\n const depsValue = effect.deps(this._state)\r\n const depsArray = this._normalizeDeps(depsValue)\r\n const shouldRun = force || this._depsChanged(effect.prevDeps, depsArray)\r\n if (!shouldRun) continue\r\n\r\n const execute = async () => {\r\n if (effect.running) {\r\n effect.rerunRequested = true\r\n return\r\n }\r\n\r\n effect.running = true\r\n effect.rerunRequested = false\r\n const prevDepsValue = effect.prevDeps\r\n effect.prevDeps = depsArray\r\n\r\n try {\r\n effect.cleanup?.()\r\n const maybeCleanup = await effect.run(depsValue, {\r\n state: { ...this._state },\r\n store: this._publicStore,\r\n prevDepsValue\r\n })\r\n effect.cleanup = typeof maybeCleanup === 'function' ? maybeCleanup : undefined\r\n effect.hasRun = true\r\n } catch (error) {\r\n this._hooks.onError?.(error as Error, 'effect')\r\n } finally {\r\n effect.running = false\r\n if (effect.rerunRequested) {\r\n this._runEffects()\r\n }\r\n }\r\n }\r\n\r\n void execute()\r\n }\r\n }\r\n\r\n // ── Notifier tous les abonnés ──────────────────────\r\n private _notify() {\r\n for (const subscriber of this._subscribers) {\r\n subscriber({ ...this._state })\r\n }\r\n }\r\n\r\n // ── S'abonner aux changements ──────────────────────\r\n subscribe(fn: (state: StateSlice<S>) => void): () => void {\r\n this._subscribers.add(fn)\r\n // Retourne une fonction de désabonnement\r\n return () => this._subscribers.delete(fn)\r\n }\r\n\r\n // ── Exécuter une action ────────────────────────────\r\nasync dispatch(actionName: string, ...args: unknown[]) {\r\n const action = this._actions[actionName]\r\n if (!action) {\r\n throw new Error(`[Stato] Action \"${actionName}\" introuvable`)\r\n }\r\n\r\n // Hook onAction — avant l'exécution\r\n this._hooks.onAction?.(actionName, args)\r\n\r\n const start = Date.now()\r\n const prevState = { ...this._state }\r\n\r\n const stateProxy = new Proxy({ ...this._state } as any, {\r\n set: (target, key, value) => {\r\n target[key] = value\r\n this._setState({ [key]: value } as any)\r\n return true\r\n }\r\n })\r\n\r\n try {\r\n await action(stateProxy, ...args)\r\n\r\n // Hook onActionDone — après l'exécution\r\n this._hooks.onActionDone?.(actionName, Date.now() - start)\r\n\r\n // Hook onStateChange — si le state a changé\r\n this._hooks.onStateChange?.(prevState as any, { ...this._state } as any)\r\n\r\n } catch (error) {\r\n // Hook onError — si une erreur est lancée\r\n this._hooks.onError?.(error as Error, actionName)\r\n throw error // on remonte l'erreur quand même\r\n }\r\n}\r\n\r\n // ── Lire une valeur computed ───────────────────────\r\n getComputed(name: string): unknown {\r\n const fn = this._computed[name]\r\n if (!fn) throw new Error(`[Stato] Computed \"${name}\" introuvable`)\r\n return fn()\r\n }\r\n\r\n getSelector(name: string): unknown {\r\n const fn = this._selectors[name]\r\n if (!fn) throw new Error(`[Stato] Selector \"${name}\" introuvable`)\r\n return fn()\r\n }\r\n\r\n // ── Enregistrer un cleanup (pour fromStream) ───────\r\n registerCleanup(fn: () => void) {\r\n this._cleanups.push(fn)\r\n }\r\n\r\n hydrate(partial: Partial<StateSlice<S>>) {\r\n this._setState(partial)\r\n }\r\n\r\n setPublicStore(publicStore: any) {\r\n this._publicStore = publicStore\r\n this._runEffects(true)\r\n }\r\n\r\n // ── Lifecycle — appelé par l'adaptateur Angular ────\r\n init(publicStore: any) {\r\n this._publicStore = publicStore\r\n this._hooks.onInit?.(publicStore)\r\n this._runEffects(true)\r\n }\r\n\r\n destroy(publicStore: any) {\r\n this._hooks.onDestroy?.(publicStore)\r\n for (const effect of this._effects) {\r\n effect.cleanup?.()\r\n effect.cleanup = undefined\r\n }\r\n // Nettoyer tous les streams ouverts\r\n for (const cleanup of this._cleanups) {\r\n cleanup()\r\n }\r\n this._cleanups = []\r\n this._subscribers.clear()\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FONCTION PUBLIQUE — createStore()\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createStore<S extends object>(config: S & StatoStoreConfig<S>) {\r\n\r\n // Créer l'instance interne\r\n const store = new StatoStore<S>(config as StatoStoreConfig<S>)\r\n\r\n // Construire l'objet public\r\n // Les propriétés du state sont accessibles directement\r\n // Les actions sont exposées sans le paramètre state\r\n const publicStore: any = {\r\n // Accès au store interne — pour les adaptateurs Angular/React/Vue\r\n __store__: store,\r\n\r\n // S'abonner aux changements\r\n subscribe: store.subscribe.bind(store),\r\n\r\n // Lire le state complet\r\n getState: store.getState.bind(store),\r\n\r\n // Enregistrer un cleanup\r\n registerCleanup: store.registerCleanup.bind(store),\r\n }\r\n\r\n // Exposer chaque propriété du state\r\n const initialState = store.getState()\r\n for (const key of Object.keys(initialState as object)) {\r\n Object.defineProperty(publicStore, key, {\r\n get: () => store.getState()[key as keyof typeof initialState],\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n\r\n // Exposer chaque action\r\n const { actions, computed, selectors } = config as StatoStoreConfig<S>\r\n\r\n if (actions) {\r\n for (const name of Object.keys(actions)) {\r\n publicStore[name] = (...args: unknown[]) => store.dispatch(name, ...args)\r\n }\r\n }\r\n\r\n // Exposer chaque computed\r\n if (computed) {\r\n for (const name of Object.keys(computed)) {\r\n Object.defineProperty(publicStore, name, {\r\n get: () => store.getComputed(name),\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n if (selectors) {\r\n for (const name of Object.keys(selectors)) {\r\n Object.defineProperty(publicStore, name, {\r\n get: () => store.getSelector(name),\r\n enumerable: true,\r\n configurable: true\r\n })\r\n }\r\n }\r\n\r\n store.setPublicStore(publicStore)\r\n\r\n return publicStore\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// store.on() — réactions inter-stores\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function on<S extends object>(\r\n sourceAction: Function,\r\n handler: (state: S) => void | Promise<void>\r\n) {\r\n // Sera implémenté dans v0.2\r\n // après que le core soit stable\r\n console.warn('[Stato] store.on() disponible en v0.2')\r\n}","// ─────────────────────────────────────────────────────\r\n// TYPES PUBLICS DE @ngstato/core\r\n// ─────────────────────────────────────────────────────\r\n\r\n// Le state de base — tout sauf actions/computed/selectors/hooks\r\nexport type StateSlice<T> = Omit<T, 'actions' | 'computed' | 'selectors' | 'hooks'>\r\n\r\n// Une action — sync ou async\r\nexport type Action<S> = (state: S, ...args: any[]) => void | Promise<void> | (() => void)\r\n\r\n// Map d'actions\r\nexport type ActionsMap<S> = Record<string, Action<S>>\r\n\r\n// Computed — dérivé du state local\r\nexport type ComputedFn<S> = (state: S) => unknown\r\nexport type SelectorFn<S> = (state: S) => unknown\r\nexport type EffectDepsFn<S> = (state: S) => unknown | unknown[]\r\nexport type EffectCleanup = void | (() => void)\r\nexport type EffectRunner<S> = (\r\n depsValue: unknown | unknown[],\r\n ctx: { state: Readonly<S>; store: any; prevDepsValue?: unknown | unknown[] }\r\n) => EffectCleanup | Promise<EffectCleanup>\r\nexport type EffectEntry<S> = [EffectDepsFn<S>, EffectRunner<S>]\r\n\r\n// Hooks lifecycle\r\nexport interface StatoHooks<S> {\r\n // Lifecycle du store\r\n onInit?: (store: S) => void | Promise<void>\r\n onDestroy?: (store: S) => void | Promise<void>\r\n\r\n // Lifecycle des actions\r\n onAction?: (name: string, args: unknown[]) => void\r\n onActionDone?: (name: string, duration: number) => void\r\n onError?: (error: Error, actionName: string) => void\r\n\r\n // Lifecycle du state\r\n onStateChange?: (prev: S, next: S) => void\r\n}\r\n\r\n// Configuration du store\r\nexport interface StatoStoreConfig<S extends object> {\r\n actions?: ActionsMap<StateSlice<S>>\r\n computed?: Record<string, ComputedFn<StateSlice<S>> | unknown[]>\r\n selectors?: Record<string, SelectorFn<StateSlice<S>> | unknown[]>\r\n effects?: EffectEntry<StateSlice<S>>[]\r\n hooks?: StatoHooks<any>\r\n [key: string]: unknown\r\n}\r\n\r\n// Instance publique du store\r\nexport type StatoStoreInstance<S extends object> = {\r\n // readonly — on ne peut lire, jamais écrire directement\r\n readonly [K in keyof StateSlice<S>]: StateSlice<S>[K]\r\n} & {\r\n // Les actions sont exposées sans le paramètre state\r\n [K in keyof S as S[K] extends Function ? K : never]:\r\n S[K] extends (state: any, ...args: infer A) => infer R\r\n ? (...args: A) => R\r\n : never\r\n}\r\n\r\n// Configuration du client HTTP\r\nexport interface StatoConfig {\r\n baseUrl?: string\r\n timeout?: number\r\n headers?: Record<string, string>\r\n auth?: () => string | null | undefined\r\n}\r\n\r\n// Erreur HTTP\r\nexport class StatoHttpError extends Error {\r\n constructor(\r\n public status: number,\r\n public body: string\r\n ) {\r\n super(`HTTP ${status}: ${body}`)\r\n this.name = 'StatoHttpError'\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — StatoHttp\r\n// Client HTTP natif — fetch + baseUrl + auth + timeout\r\n// Zero dépendance — pas de HttpClient Angular\r\n// ─────────────────────────────────────────────────────\r\n\r\nimport type { StatoConfig } from './types'\r\nimport { StatoHttpError } from './types'\r\n\r\n// ─────────────────────────────────────────────────────\r\n// OPTIONS PAR REQUÊTE\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface RequestOptions {\r\n params?: Record<string, string | number | boolean>\r\n headers?: Record<string, string>\r\n signal?: AbortSignal // pour abortable()\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// CLASSE PRINCIPALE\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport class StatoHttp {\r\n\r\n private _config: StatoConfig\r\n\r\n constructor(config: StatoConfig = {}) {\r\n this._config = config\r\n }\r\n\r\n // ── GET ───────────────────────────────────────────\r\n get<T = unknown>(url: string, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('GET', url, undefined, options)\r\n }\r\n\r\n // ── POST ──────────────────────────────────────────\r\n post<T = unknown>(url: string, body?: unknown, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('POST', url, body, options)\r\n }\r\n\r\n // ── PUT ───────────────────────────────────────────\r\n put<T = unknown>(url: string, body?: unknown, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('PUT', url, body, options)\r\n }\r\n\r\n // ── PATCH ─────────────────────────────────────────\r\n patch<T = unknown>(url: string, body?: unknown, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('PATCH', url, body, options)\r\n }\r\n\r\n // ── DELETE ────────────────────────────────────────\r\n delete<T = unknown>(url: string, options?: RequestOptions): Promise<T> {\r\n return this._request<T>('DELETE', url, undefined, options)\r\n }\r\n\r\n // ── MOTEUR INTERNE ────────────────────────────────\r\n private async _request<T>(\r\n method: string,\r\n url: string,\r\n body?: unknown,\r\n options?: RequestOptions\r\n ): Promise<T> {\r\n\r\n // 1. Construire l'URL complète avec baseUrl + params\r\n const fullUrl = this._buildUrl(url, options?.params)\r\n\r\n // 2. Récupérer le token auth si configuré\r\n const token = this._config.auth?.()\r\n\r\n // 3. Construire les headers\r\n const headers: Record<string, string> = {\r\n 'Content-Type': 'application/json',\r\n ...this._config.headers,\r\n ...options?.headers,\r\n ...(token ? { Authorization: `Bearer ${token}` } : {})\r\n }\r\n\r\n // 4. Configurer le timeout si défini\r\n let signal = options?.signal\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined\r\n\r\n if (this._config.timeout && !signal) {\r\n const controller = new AbortController()\r\n signal = controller.signal\r\n timeoutId = setTimeout(\r\n () => controller.abort(),\r\n this._config.timeout\r\n )\r\n }\r\n\r\n // 5. Exécuter la requête\r\n try {\r\n const response = await fetch(fullUrl, {\r\n method,\r\n headers,\r\n signal,\r\n ...(body !== undefined\r\n ? { body: JSON.stringify(body) }\r\n : {}\r\n )\r\n })\r\n\r\n // 6. Gérer les erreurs HTTP automatiquement\r\n if (!response.ok) {\r\n const errorBody = await response.text()\r\n throw new StatoHttpError(response.status, errorBody)\r\n }\r\n\r\n // 7. Réponse vide — ex: DELETE 204\r\n const contentType = response.headers.get('content-type')\r\n if (\r\n response.status === 204 ||\r\n !contentType?.includes('application/json')\r\n ) {\r\n return undefined as T\r\n }\r\n\r\n // 8. Parser le JSON\r\n return response.json() as Promise<T>\r\n\r\n } finally {\r\n // Toujours nettoyer le timeout\r\n if (timeoutId) clearTimeout(timeoutId)\r\n }\r\n }\r\n\r\n // ── CONSTRUIRE L'URL AVEC PARAMS ──────────────────\r\n private _buildUrl(\r\n path: string,\r\n params?: Record<string, string | number | boolean>\r\n ): string {\r\n\r\n // Si l'URL est absolue — on ne préfixe pas baseUrl\r\n const url = path.startsWith('http')\r\n ? path\r\n : `${this._config.baseUrl ?? ''}${path}`\r\n\r\n // Ajouter les query params si présents\r\n if (!params || Object.keys(params).length === 0) return url\r\n\r\n const qs = new URLSearchParams(\r\n Object.entries(params).map(([k, v]) => [k, String(v)])\r\n ).toString()\r\n\r\n return `${url}?${qs}`\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FACTORY FUNCTION — createHttp()\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createHttp(config: StatoConfig = {}): StatoHttp {\r\n return new StatoHttp(config)\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// INSTANCE GLOBALE — http\r\n// Utilisée dans les actions des stores\r\n// Configurée via provideStato()\r\n// ─────────────────────────────────────────────────────\r\n\r\nlet _globalHttp: StatoHttp = new StatoHttp()\r\n\r\nexport function configureHttp(config: StatoConfig): void {\r\n _globalHttp = new StatoHttp(config)\r\n}\r\n\r\n// L'objet http — utilisé dans les actions\r\n// await http.get('/api/users')\r\nexport const http = {\r\n get: <T>(url: string, options?: RequestOptions) =>\r\n _globalHttp.get<T>(url, options),\r\n\r\n post: <T>(url: string, body?: unknown, options?: RequestOptions) =>\r\n _globalHttp.post<T>(url, body, options),\r\n\r\n put: <T>(url: string, body?: unknown, options?: RequestOptions) =>\r\n _globalHttp.put<T>(url, body, options),\r\n\r\n patch: <T>(url: string, body?: unknown, options?: RequestOptions) =>\r\n _globalHttp.patch<T>(url, body, options),\r\n\r\n delete: <T>(url: string, options?: RequestOptions) =>\r\n _globalHttp.delete<T>(url, options),\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — abortable()\r\n// Annule automatiquement la requête précédente\r\n// Remplace switchMap de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface AbortableOptions {\r\n signal: AbortSignal\r\n}\r\n\r\nexport function abortable<S, A extends unknown[]>(\r\n fn: (state: S, ...args: [...A, AbortableOptions]) => Promise<void>\r\n) {\r\n let controller: AbortController | null = null\r\n\r\n return async (state: S, ...args: A): Promise<void> => {\r\n // Annuler la requête précédente si elle tourne encore\r\n if (controller) {\r\n controller.abort()\r\n }\r\n\r\n // Créer un nouveau controller pour cette requête\r\n controller = new AbortController()\r\n const signal = controller.signal\r\n\r\n try {\r\n await fn(state, ...args, { signal } as any)\r\n } catch (error: any) {\r\n // Ignorer silencieusement les erreurs d'annulation\r\n if (error?.name === 'AbortError') return\r\n throw error\r\n } finally {\r\n controller = null\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — debounced()\r\n// Attend que l'utilisateur arrête de taper\r\n// Remplace debounceTime de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function debounced<S, A extends unknown[]>(\r\n fn: (state: S, ...args: A) => void | Promise<void>,\r\n ms: number = 300\r\n) {\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n\r\n return (state: S, ...args: A): Promise<void> => {\r\n // Annuler le timer précédent\r\n if (timer) clearTimeout(timer)\r\n\r\n // Retourner une Promise qui se résout après le délai\r\n return new Promise((resolve, reject) => {\r\n timer = setTimeout(async () => {\r\n try {\r\n await fn(state, ...args)\r\n resolve()\r\n } catch (error) {\r\n reject(error)\r\n } finally {\r\n timer = null\r\n }\r\n }, ms)\r\n })\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — throttled()\r\n// Limite la fréquence d'exécution d'une action\r\n// Remplace throttleTime de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function throttled<S, A extends unknown[]>(\r\n fn: (state: S, ...args: A) => void | Promise<void>,\r\n ms: number = 300\r\n) {\r\n let lastCall = 0\r\n let timer: ReturnType<typeof setTimeout> | null = null\r\n\r\n return async (state: S, ...args: A): Promise<void> => {\r\n const now = Date.now()\r\n const remaining = ms - (now - lastCall)\r\n\r\n if (remaining <= 0) {\r\n // Assez de temps passé — on exécute immédiatement\r\n lastCall = now\r\n if (timer) {\r\n clearTimeout(timer)\r\n timer = null\r\n }\r\n await fn(state, ...args)\r\n } else {\r\n // Trop tôt — on planifie pour la fin du délai\r\n if (timer) clearTimeout(timer)\r\n return new Promise((resolve, reject) => {\r\n timer = setTimeout(async () => {\r\n lastCall = Date.now()\r\n timer = null\r\n try {\r\n await fn(state, ...args)\r\n resolve()\r\n } catch (error) {\r\n reject(error)\r\n }\r\n }, remaining)\r\n })\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — retryable()\r\n// Réessaie automatiquement en cas d'échec\r\n// Remplace retryWhen de RxJS — sans RxJS\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface RetryOptions {\r\n attempts: number // nombre de tentatives\r\n backoff: 'fixed' | 'exponential' // stratégie de délai\r\n delay?: number // délai de base en ms (défaut 1000)\r\n onRetry?: (attempt: number, error: Error) => void // callback optionnel\r\n}\r\n\r\nexport function retryable<S, A extends unknown[]>(\r\n fn: (state: S, ...args: A) => Promise<void>,\r\n options: RetryOptions = {\r\n attempts: 3,\r\n backoff: 'exponential',\r\n delay: 1000\r\n }\r\n) {\r\n return async (state: S, ...args: A): Promise<void> => {\r\n const { attempts, backoff, delay = 1000, onRetry } = options\r\n\r\n for (let i = 0; i < attempts; i++) {\r\n try {\r\n await fn(state, ...args)\r\n return // succès — on sort immédiatement\r\n\r\n } catch (error) {\r\n const isLastAttempt = i === attempts - 1\r\n\r\n // Dernière tentative — on remonte l'erreur\r\n if (isLastAttempt) throw error\r\n\r\n // Calculer le délai avant la prochaine tentative\r\n const waitMs = backoff === 'exponential'\r\n ? delay * Math.pow(2, i) // 1s, 2s, 4s, 8s...\r\n : delay // fixe : toujours 1s\r\n\r\n // Callback optionnel — pour logger ou afficher un message\r\n onRetry?.(i + 1, error as Error)\r\n\r\n // Attendre avant de réessayer\r\n await new Promise(resolve => setTimeout(resolve, waitMs))\r\n }\r\n }\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — fromStream()\r\n// Pont entre un flux Observable/callback et le state\r\n// Pour : Firebase, Supabase, WebSocket, SSE\r\n// RxJS optionnel — pas obligatoire\r\n// ─────────────────────────────────────────────────────\r\n\r\n// Interface minimale d'un Observable\r\n// Compatible RxJS sans l'importer\r\nexport interface StatoObservable<T> {\r\n subscribe(observer: {\r\n next?: (value: T) => void\r\n error?: (error: unknown) => void\r\n complete?: () => void\r\n }): { unsubscribe(): void }\r\n}\r\n\r\nexport interface StreamOptions {\r\n // Appelé quand le stream se termine normalement\r\n onComplete?: () => void\r\n // Appelé quand le stream rencontre une erreur\r\n onError?: (error: unknown) => void\r\n}\r\n\r\nexport function fromStream<S, T>(\r\n // setupFn — retourne l'Observable ou le flux\r\n setupFn: (state: S) => StatoObservable<T>,\r\n // updateFn — appelé à chaque valeur émise\r\n updateFn: (state: S, value: T) => void,\r\n options?: StreamOptions\r\n) {\r\n return (state: S): (() => void) => {\r\n // Démarrer le flux\r\n const stream$ = setupFn(state)\r\n const subscription = stream$.subscribe({\r\n\r\n next: (value: T) => {\r\n // Mettre à jour le state à chaque émission\r\n updateFn(state, value)\r\n },\r\n\r\n error: (error: unknown) => {\r\n options?.onError?.(error)\r\n },\r\n\r\n complete: () => {\r\n options?.onComplete?.()\r\n }\r\n })\r\n\r\n // Retourner la fonction de cleanup\r\n // appelée automatiquement à la destruction du store\r\n return () => subscription.unsubscribe()\r\n }\r\n}","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — optimistic()\r\n// Mise à jour optimiste avec rollback automatique\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function optimistic<S, A extends unknown[]>(\r\n // Action immédiate — modifie le state sans attendre\r\n immediate: (state: S, ...args: A) => void,\r\n // Confirmation API — si elle échoue → rollback\r\n confirm: (state: S, ...args: A) => Promise<void>\r\n) {\r\n return async (state: S, ...args: A): Promise<void> => {\r\n // 1. Snapshot du state AVANT la modification\r\n const snapshot = { ...(state as object) } as S\r\n\r\n // 2. Appliquer la modification immédiatement\r\n immediate(state, ...args)\r\n\r\n try {\r\n // 3. Confirmer avec l'API\r\n await confirm(state, ...args)\r\n // Succès — le state optimiste est correct, rien à faire\r\n\r\n } catch (error) {\r\n // 4. Échec — restaurer le state d'avant\r\n Object.assign(state as object, snapshot)\r\n throw error\r\n }\r\n }\r\n}","import type { StateSlice, StatoStoreConfig, StatoHooks } from '../types'\n\nexport interface PersistStorage {\n getItem(key: string): string | null\n setItem(key: string, value: string): void\n removeItem(key: string): void\n}\n\nexport interface PersistEnvelope<T> {\n v: number\n data: Partial<T>\n}\n\nexport interface PersistOptions<S extends object> {\n key: string\n version?: number\n storage?: PersistStorage\n pick?: (keyof S)[]\n migrate?: (data: unknown, fromVersion: number) => Partial<S>\n onError?: (error: Error) => void\n}\n\nfunction resolveStorage(custom?: PersistStorage): PersistStorage | null {\n if (custom) return custom\n if (typeof window === 'undefined') return null\n try {\n return window.localStorage\n } catch {\n return null\n }\n}\n\nfunction pickState<S extends object>(state: Partial<S>, keys?: (keyof S)[]) {\n if (!keys?.length) return state\n const picked: Partial<S> = {}\n for (const key of keys) {\n picked[key] = state[key]\n }\n return picked\n}\n\nexport function withPersist<S extends object>(\n config: S & StatoStoreConfig<S>,\n options: PersistOptions<StateSlice<S>>\n): S & StatoStoreConfig<S> {\n const {\n key,\n version = 1,\n storage: customStorage,\n pick,\n migrate,\n onError\n } = options\n\n const storage = resolveStorage(customStorage)\n const userHooks = config.hooks ?? {}\n\n const mergedHooks: StatoHooks<any> = {\n ...userHooks,\n onInit(store: any) {\n try {\n if (!storage) return userHooks.onInit?.(store)\n const raw = storage.getItem(key)\n if (!raw) return userHooks.onInit?.(store)\n\n const parsed = JSON.parse(raw) as PersistEnvelope<StateSlice<S>>\n const data =\n parsed.v === version\n ? parsed.data\n : migrate\n ? migrate(parsed.data, parsed.v)\n : parsed.data\n\n if (data && typeof data === 'object') {\n store.__store__?.hydrate?.(data)\n }\n } catch (error) {\n onError?.(error as Error)\n }\n return userHooks.onInit?.(store)\n },\n\n onStateChange(prev: any, next: any) {\n try {\n if (storage) {\n const payload: PersistEnvelope<StateSlice<S>> = {\n v: version,\n data: pickState(next, pick as (keyof StateSlice<S>)[] | undefined)\n }\n storage.setItem(key, JSON.stringify(payload))\n }\n } catch (error) {\n onError?.(error as Error)\n }\n userHooks.onStateChange?.(prev, next)\n },\n\n onDestroy(store: any) {\n return userHooks.onDestroy?.(store)\n },\n onAction(name: string, args: unknown[]) {\n return userHooks.onAction?.(name, args)\n },\n onActionDone(name: string, duration: number) {\n return userHooks.onActionDone?.(name, duration)\n },\n onError(error: Error, actionName: string) {\n return userHooks.onError?.(error, actionName)\n }\n }\n\n return {\n ...config,\n hooks: mergedHooks\n }\n}\n\n","// ─────────────────────────────────────────────────────\r\n// @ngstato/core — DevTools\r\n// Logique pure — pas de dépendance Angular\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport interface ActionLog {\r\n id: number\r\n name: string\r\n args: unknown[]\r\n duration: number\r\n status: 'success' | 'error'\r\n error?: string\r\n prevState: unknown\r\n nextState: unknown\r\n at: string\r\n}\r\n\r\nexport interface DevToolsState {\r\n logs: ActionLog[]\r\n isOpen: boolean\r\n maxLogs: number\r\n}\r\n\r\nexport interface DevToolsInstance {\r\n state: DevToolsState\r\n logAction: (log: Omit<ActionLog, 'id' | 'at'>) => void\r\n clear: () => void\r\n open: () => void\r\n close: () => void\r\n toggle: () => void\r\n subscribe: (cb: (state: DevToolsState) => void) => () => void\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// FACTORY\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function createDevTools(maxLogs = 50): DevToolsInstance {\r\n let counter = 0\r\n\r\n const state: DevToolsState = {\r\n logs: [],\r\n isOpen: false,\r\n maxLogs\r\n }\r\n\r\n const listeners = new Set<(state: DevToolsState) => void>()\r\n\r\n function notify() {\r\n listeners.forEach(cb => cb({ ...state, logs: [...state.logs] }))\r\n }\r\n\r\n return {\r\n state,\r\n\r\n logAction(log) {\r\n const entry: ActionLog = {\r\n ...log,\r\n id: ++counter,\r\n at: new Date().toISOString()\r\n }\r\n\r\n state.logs = [entry, ...state.logs].slice(0, maxLogs)\r\n notify()\r\n },\r\n\r\n clear() {\r\n state.logs = []\r\n notify()\r\n },\r\n\r\n open() {\r\n state.isOpen = true\r\n notify()\r\n },\r\n\r\n close() {\r\n state.isOpen = false\r\n notify()\r\n },\r\n\r\n toggle() {\r\n state.isOpen = !state.isOpen\r\n notify()\r\n },\r\n\r\n subscribe(cb) {\r\n listeners.add(cb)\r\n return () => listeners.delete(cb)\r\n }\r\n }\r\n}\r\n\r\n// ─────────────────────────────────────────────────────\r\n// INSTANCE GLOBALE — singleton partagé entre tous les stores\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport const devTools = createDevTools()\r\n\r\n// ─────────────────────────────────────────────────────\r\n// PLUGIN — connecte un store aux DevTools\r\n// ─────────────────────────────────────────────────────\r\n\r\nexport function connectDevTools(store: any, storeName: string) {\r\n if (!devTools) return\r\n\r\n let prevState: any = {}\r\n\r\n // Accès aux hooks via __store__\r\n const internalStore = store.__store__\r\n\r\n if (!internalStore) return\r\n\r\n // Sauvegarder les hooks existants\r\n const existingHooks = { ...internalStore['_hooks'] }\r\n\r\n // Remplacer les hooks\r\n internalStore['_hooks'] = {\r\n ...existingHooks,\r\n\r\n onAction(name: string, args: unknown[]) {\r\n prevState = store.getState()\r\n existingHooks.onAction?.(name, args)\r\n },\r\n\r\n onActionDone(name: string, duration: number) {\r\n const nextState = store.getState()\r\n devTools.logAction({\r\n name: `[${storeName}] ${name}`,\r\n args: [],\r\n duration,\r\n status: 'success',\r\n prevState: { ...prevState },\r\n nextState: { ...nextState }\r\n })\r\n existingHooks.onActionDone?.(name, duration)\r\n },\r\n\r\n onError(error: Error, actionName: string) {\r\n devTools.logAction({\r\n name: `[${storeName}] ${actionName}`,\r\n args: [],\r\n duration: 0,\r\n status: 'error',\r\n error: error.message,\r\n prevState: { ...prevState },\r\n nextState: { ...prevState }\r\n })\r\n existingHooks.onError?.(error, actionName)\r\n },\r\n\r\n onStateChange: existingHooks.onStateChange\r\n }\r\n}"]}
@@ -1,5 +1,3 @@
1
- 'use strict';
2
-
3
1
  // src/store.ts
4
2
  var StatoStore = class {
5
3
  // Le state interne — jamais accessible directement
@@ -10,12 +8,44 @@ var StatoStore = class {
10
8
  _actions = {};
11
9
  // Les computed enregistrés
12
10
  _computed = {};
11
+ _selectors = {};
13
12
  // Les cleanups à appeler à la destruction
14
13
  _cleanups = [];
15
14
  // Les hooks lifecycle
16
15
  _hooks;
16
+ _publicStore = null;
17
+ _effects = [];
18
+ _createMemoizedSelector(fn) {
19
+ let initialized = false;
20
+ let cachedResult;
21
+ let trackedKeys = [];
22
+ let trackedValues = [];
23
+ return () => {
24
+ if (initialized && trackedKeys.length) {
25
+ const unchanged = trackedKeys.every(
26
+ (key, index) => Object.is(this._state[key], trackedValues[index])
27
+ );
28
+ if (unchanged) return cachedResult;
29
+ }
30
+ const reads = /* @__PURE__ */ new Set();
31
+ const trackingState = new Proxy(this._state, {
32
+ get: (target, prop, receiver) => {
33
+ if (typeof prop === "string" && prop in target) {
34
+ reads.add(prop);
35
+ }
36
+ return Reflect.get(target, prop, receiver);
37
+ }
38
+ });
39
+ const result = fn(trackingState);
40
+ trackedKeys = Array.from(reads);
41
+ trackedValues = trackedKeys.map((key) => this._state[key]);
42
+ cachedResult = result;
43
+ initialized = true;
44
+ return result;
45
+ };
46
+ }
17
47
  constructor(config) {
18
- const { actions, computed, hooks, ...initialState } = config;
48
+ const { actions, computed, selectors, effects, hooks, ...initialState } = config;
19
49
  this._state = initialState;
20
50
  this._hooks = hooks ?? {};
21
51
  if (actions) {
@@ -30,6 +60,27 @@ var StatoStore = class {
30
60
  }
31
61
  }
32
62
  }
63
+ if (selectors) {
64
+ for (const [name, fn] of Object.entries(selectors)) {
65
+ if (typeof fn === "function") {
66
+ this._selectors[name] = this._createMemoizedSelector(fn);
67
+ }
68
+ }
69
+ }
70
+ if (effects) {
71
+ for (const entry of effects) {
72
+ const [deps, run] = entry;
73
+ if (typeof deps === "function" && typeof run === "function") {
74
+ this._effects.push({
75
+ deps,
76
+ run,
77
+ hasRun: false,
78
+ running: false,
79
+ rerunRequested: false
80
+ });
81
+ }
82
+ }
83
+ }
33
84
  }
34
85
  // ── Lire le state ──────────────────────────────────
35
86
  getState() {
@@ -38,8 +89,56 @@ var StatoStore = class {
38
89
  // ── Modifier le state — usage interne uniquement ───
39
90
  _setState(partial) {
40
91
  this._state = { ...this._state, ...partial };
92
+ this._runEffects();
41
93
  this._notify();
42
94
  }
95
+ _normalizeDeps(value) {
96
+ return Array.isArray(value) ? value : [value];
97
+ }
98
+ _depsChanged(prev, next) {
99
+ if (!prev) return true;
100
+ if (prev.length !== next.length) return true;
101
+ for (let i = 0; i < next.length; i++) {
102
+ if (!Object.is(prev[i], next[i])) return true;
103
+ }
104
+ return false;
105
+ }
106
+ _runEffects(force = false) {
107
+ for (const effect of this._effects) {
108
+ const depsValue = effect.deps(this._state);
109
+ const depsArray = this._normalizeDeps(depsValue);
110
+ const shouldRun = force || this._depsChanged(effect.prevDeps, depsArray);
111
+ if (!shouldRun) continue;
112
+ const execute = async () => {
113
+ if (effect.running) {
114
+ effect.rerunRequested = true;
115
+ return;
116
+ }
117
+ effect.running = true;
118
+ effect.rerunRequested = false;
119
+ const prevDepsValue = effect.prevDeps;
120
+ effect.prevDeps = depsArray;
121
+ try {
122
+ effect.cleanup?.();
123
+ const maybeCleanup = await effect.run(depsValue, {
124
+ state: { ...this._state },
125
+ store: this._publicStore,
126
+ prevDepsValue
127
+ });
128
+ effect.cleanup = typeof maybeCleanup === "function" ? maybeCleanup : void 0;
129
+ effect.hasRun = true;
130
+ } catch (error) {
131
+ this._hooks.onError?.(error, "effect");
132
+ } finally {
133
+ effect.running = false;
134
+ if (effect.rerunRequested) {
135
+ this._runEffects();
136
+ }
137
+ }
138
+ };
139
+ void execute();
140
+ }
141
+ }
43
142
  // ── Notifier tous les abonnés ──────────────────────
44
143
  _notify() {
45
144
  for (const subscriber of this._subscribers) {
@@ -82,16 +181,34 @@ var StatoStore = class {
82
181
  if (!fn) throw new Error(`[Stato] Computed "${name}" introuvable`);
83
182
  return fn();
84
183
  }
184
+ getSelector(name) {
185
+ const fn = this._selectors[name];
186
+ if (!fn) throw new Error(`[Stato] Selector "${name}" introuvable`);
187
+ return fn();
188
+ }
85
189
  // ── Enregistrer un cleanup (pour fromStream) ───────
86
190
  registerCleanup(fn) {
87
191
  this._cleanups.push(fn);
88
192
  }
193
+ hydrate(partial) {
194
+ this._setState(partial);
195
+ }
196
+ setPublicStore(publicStore) {
197
+ this._publicStore = publicStore;
198
+ this._runEffects(true);
199
+ }
89
200
  // ── Lifecycle — appelé par l'adaptateur Angular ────
90
201
  init(publicStore) {
202
+ this._publicStore = publicStore;
91
203
  this._hooks.onInit?.(publicStore);
204
+ this._runEffects(true);
92
205
  }
93
206
  destroy(publicStore) {
94
207
  this._hooks.onDestroy?.(publicStore);
208
+ for (const effect of this._effects) {
209
+ effect.cleanup?.();
210
+ effect.cleanup = void 0;
211
+ }
95
212
  for (const cleanup of this._cleanups) {
96
213
  cleanup();
97
214
  }
@@ -119,7 +236,7 @@ function createStore(config) {
119
236
  configurable: true
120
237
  });
121
238
  }
122
- const { actions, computed } = config;
239
+ const { actions, computed, selectors } = config;
123
240
  if (actions) {
124
241
  for (const name of Object.keys(actions)) {
125
242
  publicStore[name] = (...args) => store.dispatch(name, ...args);
@@ -134,6 +251,16 @@ function createStore(config) {
134
251
  });
135
252
  }
136
253
  }
254
+ if (selectors) {
255
+ for (const name of Object.keys(selectors)) {
256
+ Object.defineProperty(publicStore, name, {
257
+ get: () => store.getSelector(name),
258
+ enumerable: true,
259
+ configurable: true
260
+ });
261
+ }
262
+ }
263
+ store.setPublicStore(publicStore);
137
264
  return publicStore;
138
265
  }
139
266
 
@@ -366,6 +493,85 @@ function optimistic(immediate, confirm) {
366
493
  };
367
494
  }
368
495
 
496
+ // src/helpers/with-persist.ts
497
+ function resolveStorage(custom) {
498
+ if (custom) return custom;
499
+ if (typeof window === "undefined") return null;
500
+ try {
501
+ return window.localStorage;
502
+ } catch {
503
+ return null;
504
+ }
505
+ }
506
+ function pickState(state, keys) {
507
+ if (!keys?.length) return state;
508
+ const picked = {};
509
+ for (const key of keys) {
510
+ picked[key] = state[key];
511
+ }
512
+ return picked;
513
+ }
514
+ function withPersist(config, options) {
515
+ const {
516
+ key,
517
+ version = 1,
518
+ storage: customStorage,
519
+ pick,
520
+ migrate,
521
+ onError
522
+ } = options;
523
+ const storage = resolveStorage(customStorage);
524
+ const userHooks = config.hooks ?? {};
525
+ const mergedHooks = {
526
+ ...userHooks,
527
+ onInit(store) {
528
+ try {
529
+ if (!storage) return userHooks.onInit?.(store);
530
+ const raw = storage.getItem(key);
531
+ if (!raw) return userHooks.onInit?.(store);
532
+ const parsed = JSON.parse(raw);
533
+ const data = parsed.v === version ? parsed.data : migrate ? migrate(parsed.data, parsed.v) : parsed.data;
534
+ if (data && typeof data === "object") {
535
+ store.__store__?.hydrate?.(data);
536
+ }
537
+ } catch (error) {
538
+ onError?.(error);
539
+ }
540
+ return userHooks.onInit?.(store);
541
+ },
542
+ onStateChange(prev, next) {
543
+ try {
544
+ if (storage) {
545
+ const payload = {
546
+ v: version,
547
+ data: pickState(next, pick)
548
+ };
549
+ storage.setItem(key, JSON.stringify(payload));
550
+ }
551
+ } catch (error) {
552
+ onError?.(error);
553
+ }
554
+ userHooks.onStateChange?.(prev, next);
555
+ },
556
+ onDestroy(store) {
557
+ return userHooks.onDestroy?.(store);
558
+ },
559
+ onAction(name, args) {
560
+ return userHooks.onAction?.(name, args);
561
+ },
562
+ onActionDone(name, duration) {
563
+ return userHooks.onActionDone?.(name, duration);
564
+ },
565
+ onError(error, actionName) {
566
+ return userHooks.onError?.(error, actionName);
567
+ }
568
+ };
569
+ return {
570
+ ...config,
571
+ hooks: mergedHooks
572
+ };
573
+ }
574
+
369
575
  // src/devtools.ts
370
576
  function createDevTools(maxLogs = 50) {
371
577
  let counter = 0;
@@ -452,20 +658,6 @@ function connectDevTools(store, storeName) {
452
658
  };
453
659
  }
454
660
 
455
- exports.StatoHttp = StatoHttp;
456
- exports.StatoHttpError = StatoHttpError;
457
- exports.abortable = abortable;
458
- exports.configureHttp = configureHttp;
459
- exports.connectDevTools = connectDevTools;
460
- exports.createDevTools = createDevTools;
461
- exports.createHttp = createHttp;
462
- exports.createStore = createStore;
463
- exports.debounced = debounced;
464
- exports.devTools = devTools;
465
- exports.fromStream = fromStream;
466
- exports.http = http;
467
- exports.optimistic = optimistic;
468
- exports.retryable = retryable;
469
- exports.throttled = throttled;
470
- //# sourceMappingURL=index.cjs.map
471
- //# sourceMappingURL=index.cjs.map
661
+ export { StatoHttp, StatoHttpError, abortable, configureHttp, connectDevTools, createDevTools, createHttp, createStore, debounced, devTools, fromStream, http, optimistic, retryable, throttled, withPersist };
662
+ //# sourceMappingURL=index.mjs.map
663
+ //# sourceMappingURL=index.mjs.map