@braine/quantum-query 1.2.5 → 1.2.6

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.d.cts CHANGED
@@ -1,7 +1,7 @@
1
1
  import * as react_jsx_runtime from 'react/jsx-runtime';
2
- import { ReactNode } from 'react';
2
+ import React, { ReactNode } from 'react';
3
3
 
4
- declare function subscribe(store: object, callback: (target: any, prop: any, value: any) => void): () => boolean;
4
+ declare function subscribe(store: object, callback: (target: object, prop: string | symbol, value: unknown) => void): () => boolean;
5
5
  declare function createState<T extends object>(initialState: T): T;
6
6
 
7
7
  interface StorageAdapter {
@@ -93,141 +93,156 @@ declare function getPromiseState(promise: Promise<any>): {
93
93
  error: any;
94
94
  };
95
95
 
96
- /**
97
- * Generic Schema Interface
98
- * Compatible with Zod, Valibot, ArkType, etc.
99
- */
100
- interface Schema<T> {
101
- parse: (data: unknown) => T;
102
- }
103
- interface QueryClientConfig {
104
- defaultStaleTime?: number;
105
- defaultCacheTime?: number;
106
- }
107
96
  /**
108
97
  * Middleware Plugin Interface
109
98
  */
110
99
  interface QueryPlugin {
111
100
  name: string;
112
- onFetchStart?: (queryKey: any[]) => void;
113
- onFetchSuccess?: (queryKey: any[], data: any) => void;
114
- onFetchError?: (queryKey: any[], error: Error) => void;
115
- onInvalidate?: (queryKey: any[]) => void;
116
- onQueryUpdated?: (queryKey: any[], data: any) => void;
101
+ onFetchStart?: (queryKey: unknown[]) => void;
102
+ onFetchSuccess?: (queryKey: unknown[], data: unknown) => void;
103
+ onFetchError?: (queryKey: unknown[], error: Error) => void;
104
+ onInvalidate?: (queryKey: unknown[]) => void;
105
+ onQueryUpdated?: (queryKey: unknown[], data: unknown) => void;
106
+ }
107
+ interface InfiniteData<T> {
108
+ pages: T[];
109
+ pageParams: unknown[];
117
110
  }
118
111
 
119
112
  /**
120
- * Micro-Signals with Batching (Zero Dependency Reactivity)
113
+ * Micro-Signals (Powered by @preact/signals-core)
121
114
  *
122
- * A minimal implementation of the Signals pattern with micro-batching for O(1) state updates.
123
- * Uses queueMicrotask to coalesce multiple updates into a single notification cycle.
115
+ * Industry-standard ultra-fast fine-grained reactivity.
116
+ * API adapted to match original interface for backward compatibility.
124
117
  */
118
+
125
119
  interface Signal<T> {
126
120
  get: () => T;
127
121
  set: (value: T) => void;
128
122
  subscribe: (fn: (value: T) => void) => () => void;
129
123
  }
130
124
 
131
- interface CacheEntry<T = any> {
132
- data: T;
125
+ type QueryStatus$1 = 'pending' | 'success' | 'error';
126
+ type FetchDirection$1 = 'initial' | 'next' | 'previous' | 'idle';
127
+ interface QueryKey {
128
+ key: readonly unknown[];
129
+ params?: Record<string, unknown>;
130
+ }
131
+ type QueryKeyInput = readonly unknown[] | QueryKey;
132
+ interface CacheEntry<T = unknown> {
133
+ data: T | undefined;
134
+ status: QueryStatus$1;
135
+ error: Error | null;
136
+ isFetching: boolean;
137
+ fetchDirection: FetchDirection$1;
133
138
  timestamp: number;
134
139
  staleTime: number;
135
140
  cacheTime: number;
136
- key: any[];
141
+ key: QueryKeyInput;
142
+ tags?: string[];
143
+ isInvalidated?: boolean;
137
144
  }
138
- interface QueryKey {
139
- key: any[];
140
- params?: Record<string, any>;
145
+
146
+ type MutationStatus = 'idle' | 'pending' | 'success' | 'error';
147
+ interface MutationState<TData = unknown, TVariables = unknown, TContext = unknown> {
148
+ data: TData | undefined;
149
+ error: Error | null;
150
+ variables: TVariables | undefined;
151
+ context: TContext | undefined;
152
+ status: MutationStatus;
153
+ submittedAt: number;
141
154
  }
142
- type QueryKeyInput = any[] | QueryKey;
155
+ declare class MutationCache {
156
+ private mutations;
157
+ private mutationKeys;
158
+ /**
159
+ * Get or Create a Signal for a specific mutation instance (ID)
160
+ */
161
+ getSignal: <TData, TVariables, TContext>(id: string) => Signal<MutationState<TData, TVariables, TContext>>;
162
+ /**
163
+ * Register a mutation ID with a Key (for tracking shared keys)
164
+ */
165
+ register: (id: string, key?: unknown[]) => void;
166
+ /**
167
+ * Unregister cleanup
168
+ */
169
+ unregister: (id: string, key?: unknown[]) => void;
170
+ notify: <TData, TVariables, TContext>(id: string, state: Partial<MutationState<TData, TVariables, TContext>>) => void;
171
+ /**
172
+ * Get number of mutations currently pending
173
+ */
174
+ isMutating: (filters?: {
175
+ mutationKey?: unknown[];
176
+ }) => number;
177
+ }
178
+
143
179
  declare class QueryCache {
144
- private signals;
145
- private gcInterval;
180
+ private storage;
181
+ private remotes;
182
+ mutationCache: MutationCache;
183
+ private pluginManager;
146
184
  private readonly defaultStaleTime;
147
185
  private readonly defaultCacheTime;
148
186
  constructor(config?: {
149
- enableGC?: boolean;
187
+ defaultStaleTime?: number;
188
+ defaultCacheTime?: number;
150
189
  });
151
190
  /**
152
- * Generate cache key from query key array
153
- */
154
- private generateKey;
155
- /**
156
- * Get data (wrapper around signal.get)
191
+ * Get data from storage
157
192
  */
158
193
  get: <T>(queryKey: QueryKeyInput) => T | undefined;
159
194
  /**
160
- * Get Signal for a key (Low level API for hooks)
161
- * Automatically creates a signal if one doesn't exist
195
+ * Get Signal for reactivity (used by hooks)
162
196
  */
163
197
  getSignal: <T>(queryKey: QueryKeyInput) => Signal<CacheEntry<T> | undefined>;
164
198
  /**
165
- * Check if data is stale
166
- */
167
- isStale: (queryKey: QueryKeyInput) => boolean;
168
- /**
169
- * Set cached data (updates signal)
199
+ * Set data manually (Optimistic updates / Prefetch)
170
200
  */
171
201
  set: <T>(queryKey: QueryKeyInput, data: T, options?: {
172
202
  staleTime?: number;
173
203
  cacheTime?: number;
204
+ fetchDirection?: FetchDirection$1;
205
+ tags?: string[];
174
206
  }) => void;
175
- private deduplicationCache;
176
- private plugins;
177
- /**
178
- * Register a middleware plugin
179
- */
180
- use: (plugin: QueryPlugin) => this;
181
- /**
182
- * Fetch data with deduplication.
183
- * If a request for the same key is already in flight, returns the existing promise.
184
- */
185
- fetch: <T>(queryKey: QueryKeyInput, fn: () => Promise<T>) => Promise<T>;
186
207
  /**
187
- * Invalidate all queries
208
+ * Restore cache entry (Hydration)
188
209
  */
189
- invalidateAll: () => void;
210
+ restore: (queryKey: QueryKeyInput, entry: CacheEntry<any>) => void;
190
211
  /**
191
- * Remove a specific query from cache
212
+ * Fetch data (Orchestration)
192
213
  */
193
- remove: (queryKey: QueryKeyInput) => void;
214
+ fetch: <T>(queryKey: QueryKeyInput, fn: (context: {
215
+ signal?: AbortSignal;
216
+ }) => Promise<T>, options?: {
217
+ fetchDirection?: FetchDirection$1;
218
+ signal?: AbortSignal;
219
+ retry?: number | boolean;
220
+ retryDelay?: number | ((attemptIndex: number) => number);
221
+ }) => Promise<T>;
194
222
  /**
195
- * Invalidate queries matching the key prefix
196
- * Marks them as undefined to trigger refetches without breaking subscriptions
223
+ * Invalidate queries
197
224
  */
198
225
  invalidate: (queryKey: QueryKeyInput) => void;
199
- /**
200
- * Remove all cache entries
201
- */
226
+ invalidateTags: (tags: string[]) => void;
227
+ use: (plugin: QueryPlugin) => this;
228
+ isStale: (queryKey: QueryKeyInput) => boolean;
229
+ getAll: () => Map<string, CacheEntry<unknown>>;
230
+ snapshot: () => Map<string, Signal<CacheEntry<unknown> | undefined>>;
202
231
  clear: () => void;
203
- /**
204
- * Prefetch data (same as set but explicit intent)
205
- */
232
+ remove: (key: QueryKeyInput) => void;
206
233
  prefetch: <T>(queryKey: QueryKeyInput, data: T, options?: {
207
234
  staleTime?: number;
208
235
  cacheTime?: number;
209
236
  }) => void;
210
- /**
211
- * Garbage collection - remove expired entries
212
- */
213
- private startGarbageCollection;
214
- /**
215
- * Stop garbage collection
216
- */
217
237
  destroy: () => void;
218
- /**
219
- * Get cache stats (for debugging)
220
- */
221
238
  getStats: () => {
222
239
  size: number;
223
240
  keys: string[];
224
241
  };
225
- /**
226
- * Get all entries (wrapper for DevTools)
227
- */
228
- getAll: () => Map<string, CacheEntry>;
242
+ getSnapshot: () => Map<string, Signal<CacheEntry<unknown> | undefined>>;
243
+ invalidateAll: () => void;
244
+ private normalizeKey;
229
245
  }
230
- declare const queryCache: QueryCache;
231
246
 
232
247
  /**
233
248
  * Pagination Hook
@@ -240,6 +255,7 @@ interface UsePaginatedQueryOptions<T> {
240
255
  staleTime?: number;
241
256
  cacheTime?: number;
242
257
  enabled?: boolean;
258
+ retry?: number | boolean;
243
259
  }
244
260
  interface PaginatedQueryResult<T> {
245
261
  data: T | undefined;
@@ -254,75 +270,70 @@ interface PaginatedQueryResult<T> {
254
270
  hasPrevious: boolean;
255
271
  refetch: () => Promise<void>;
256
272
  }
257
- declare function usePaginatedQuery<T>({ queryKey, queryFn, pageSize, staleTime, cacheTime, enabled }: UsePaginatedQueryOptions<T>): PaginatedQueryResult<T>;
273
+ declare function usePaginatedQuery<T>({ queryKey, queryFn, pageSize, staleTime, cacheTime, enabled, retry }: UsePaginatedQueryOptions<T>): PaginatedQueryResult<T>;
258
274
 
259
275
  /**
260
276
  * useQuery Hook
261
277
  * Base query hook with stale-while-revalidate and background refetching
278
+ *
279
+ * Refactored to use QueryObserver (Clean Architecture)
262
280
  */
263
281
 
264
- interface UseQueryOptions<T> {
265
- queryKey: any[];
266
- queryFn: () => Promise<unknown>;
267
- schema?: Schema<T>;
282
+ interface UseQueryOptions<T, TData = T> {
283
+ queryKey: unknown[];
284
+ queryFn: (context?: {
285
+ signal?: AbortSignal;
286
+ }) => Promise<T>;
268
287
  staleTime?: number;
269
288
  cacheTime?: number;
270
289
  enabled?: boolean;
271
290
  refetchOnWindowFocus?: boolean;
272
- refetchOnReconnect?: boolean;
273
- refetchInterval?: number;
291
+ retry?: number | boolean;
292
+ select?: (data: T) => TData;
293
+ tags?: string[];
274
294
  }
275
- interface QueryResult<T> {
276
- data: T | undefined;
277
- isLoading: boolean;
295
+ type QueryStatus = 'pending' | 'error' | 'success';
296
+ type FetchDirection = 'idle' | 'fetching';
297
+ interface UseQueryResult<TData, TError = Error> {
298
+ data: TData | undefined;
299
+ status: QueryStatus;
300
+ fetchStatus: FetchDirection;
301
+ isPending: boolean;
302
+ isSuccess: boolean;
278
303
  isError: boolean;
279
304
  isFetching: boolean;
280
- isStale: boolean;
281
- error: Error | null;
282
- refetch: () => Promise<void>;
305
+ error: TError | null;
306
+ refetch: () => void;
307
+ signal: Signal<CacheEntry<any> | undefined>;
283
308
  }
284
- declare function useQuery<T>({ queryKey, queryFn, schema, staleTime, cacheTime, enabled, refetchOnWindowFocus, refetchOnReconnect, refetchInterval }: UseQueryOptions<T>): QueryResult<T>;
309
+ declare function useQuery<T, TData = T, TError = Error>(options: UseQueryOptions<T, TData>): UseQueryResult<TData, TError>;
285
310
 
286
- /**
287
- * useMutation Hook
288
- * Handles mutations with optimistic updates and rollback
289
- */
290
- interface UseMutationOptions<TData, TVariables, TContext = any> {
311
+ interface UseMutationOptions<TData, TVariables, TContext = unknown> {
291
312
  mutationFn: (variables: TVariables) => Promise<TData>;
313
+ mutationKey?: unknown[];
292
314
  onMutate?: (variables: TVariables) => Promise<TContext> | TContext;
293
315
  onSuccess?: (data: TData, variables: TVariables, context: TContext | undefined) => void;
294
316
  onError?: (error: Error, variables: TVariables, context: TContext | undefined) => void;
295
317
  onSettled?: (data: TData | undefined, error: Error | null, variables: TVariables, context: TContext | undefined) => void;
318
+ invalidatesTags?: string[];
319
+ optimistic?: {
320
+ queryKey: unknown[];
321
+ update: (variables: TVariables, oldData: unknown) => unknown;
322
+ };
296
323
  }
297
324
  interface MutationResult<TData, TVariables> {
298
- mutate: (variables: TVariables) => Promise<void>;
325
+ mutate: (variables: TVariables) => void;
299
326
  mutateAsync: (variables: TVariables) => Promise<TData>;
300
327
  data: TData | undefined;
301
328
  error: Error | null;
302
329
  isLoading: boolean;
303
330
  isError: boolean;
304
331
  isSuccess: boolean;
332
+ isIdle: boolean;
333
+ status: 'idle' | 'pending' | 'success' | 'error';
305
334
  reset: () => void;
306
335
  }
307
- declare function useMutation<TData = unknown, TVariables = void, TContext = any>({ mutationFn, onMutate, onSuccess, onError, onSettled }: UseMutationOptions<TData, TVariables, TContext>): MutationResult<TData, TVariables>;
308
- declare const optimisticHelpers: {
309
- /**
310
- * Cancel ongoing queries for a key
311
- */
312
- cancelQueries(queryKey: any[]): Promise<void>;
313
- /**
314
- * Get current query data
315
- */
316
- getQueryData<T>(queryKey: any[]): T | undefined;
317
- /**
318
- * Set query data (for optimistic updates)
319
- */
320
- setQueryData<T>(queryKey: any[], updater: T | ((old: T | undefined) => T)): T | undefined;
321
- /**
322
- * Invalidate queries (trigger refetch)
323
- */
324
- invalidateQueries(queryKey: any[]): void;
325
- };
336
+ declare function useMutation<TData = unknown, TVariables = void, TContext = unknown>(options: UseMutationOptions<TData, TVariables, TContext>): MutationResult<TData, TVariables>;
326
337
 
327
338
  type QueryClient = QueryCache;
328
339
  declare const QueryClientProvider: ({ client, children }: {
@@ -334,9 +345,15 @@ declare const useQueryClient: () => QueryClient;
334
345
  /**
335
346
  * Infinite Query Hook (Reactive)
336
347
  * Provides infinite scroll with Signal-based reactivity
348
+ *
349
+ * Refactored to "Senior Standards":
350
+ * - No local state (useReducer removed)
351
+ * - All state derived from Global QueryCache Signal
352
+ * - Manual signal updates for aggregate key to track fetching state of pages
337
353
  */
354
+
338
355
  interface UseInfiniteQueryOptions<T, TPageParam = any> {
339
- queryKey: any[];
356
+ queryKey: unknown[];
340
357
  queryFn: (context: {
341
358
  pageParam: TPageParam;
342
359
  }) => Promise<T>;
@@ -346,10 +363,7 @@ interface UseInfiniteQueryOptions<T, TPageParam = any> {
346
363
  staleTime?: number;
347
364
  cacheTime?: number;
348
365
  enabled?: boolean;
349
- }
350
- interface InfiniteData<T> {
351
- pages: T[];
352
- pageParams: any[];
366
+ retry?: number | boolean;
353
367
  }
354
368
  interface InfiniteQueryResult<T> {
355
369
  data: InfiniteData<T> | undefined;
@@ -365,10 +379,53 @@ interface InfiniteQueryResult<T> {
365
379
  error: Error | null;
366
380
  refetch: () => Promise<void>;
367
381
  }
368
- declare function useInfiniteQuery<T, TPageParam = any>({ queryKey, queryFn, getNextPageParam, getPreviousPageParam, initialPageParam, staleTime, cacheTime, enabled }: UseInfiniteQueryOptions<T, TPageParam>): InfiniteQueryResult<T>;
382
+ declare function useInfiniteQuery<T, TPageParam = any>({ queryKey, queryFn, getNextPageParam, getPreviousPageParam, initialPageParam, staleTime, cacheTime, enabled, retry }: UseInfiniteQueryOptions<T, TPageParam>): InfiniteQueryResult<T>;
383
+
384
+ interface DehydratedState {
385
+ queries: Array<{
386
+ queryKey: unknown[];
387
+ queryHash: string;
388
+ state: CacheEntry<unknown>;
389
+ }>;
390
+ }
391
+ /**
392
+ * Serialize the query cache for transport.
393
+ */
394
+ declare function dehydrate(client: QueryCache): DehydratedState;
395
+ /**
396
+ * Hydrate the query cache from serialized state.
397
+ */
398
+ declare function hydrate(client: QueryCache, state: DehydratedState): void;
399
+
400
+ interface HydrationBoundaryProps {
401
+ state?: DehydratedState;
402
+ children: React.ReactNode;
403
+ }
404
+ declare function HydrationBoundary({ state, children }: HydrationBoundaryProps): react_jsx_runtime.JSX.Element;
369
405
 
370
- declare function QuantumDevTools(): react_jsx_runtime.JSX.Element;
406
+ interface UseSuspenseQueryOptions<T> extends UseQueryOptions<T> {
407
+ }
408
+ type SuspenseQueryResult<T> = Omit<UseQueryResult<T>, 'data' | 'isLoading' | 'isError' | 'error'> & {
409
+ data: T;
410
+ };
411
+ declare function useSuspenseQuery<T>(options: UseSuspenseQueryOptions<T>): SuspenseQueryResult<T>;
371
412
 
372
- declare function useQueryCache(): Map<string, CacheEntry<any>>;
413
+ /**
414
+ * Bridge: Signal -> Proxy (Readonly)
415
+ *
416
+ * Creates a reactive proxy object that mirrors a signal's value.
417
+ * Useful for using Query results inside a Store.
418
+ */
419
+ type ProxyResult<T> = T extends object ? T : {
420
+ value: T;
421
+ };
422
+ declare function fromSignal<T>(signal: Signal<T>): ProxyResult<T>;
423
+ /**
424
+ * Bridge: Proxy -> Signal
425
+ *
426
+ * Creates a Signal that updates whenever the accessed parts of the proxy change.
427
+ * Uses the Proxy's `activeListener` tracking mechanism.
428
+ */
429
+ declare function toSignal<T>(selector: () => T): Signal<T>;
373
430
 
374
- export { type CacheEntry, type HttpClient, type InfiniteData, type InfiniteQueryResult, type MutationResult, type PaginatedQueryResult, QuantumDevTools, QueryCache, type QueryClient, type QueryClientConfig, QueryClientProvider, type QueryKey, type QueryKeyInput, type QueryResult, type Schema, type UseInfiniteQueryOptions, type UseMutationOptions, type UsePaginatedQueryOptions, type UseQueryOptions, computed, createHttpClient, createState, defineModel, enableDevTools, getPromiseState, handlePromise, isPromise, optimisticHelpers, queryCache, scheduleUpdate, subscribe, unwrapPromise, useInfiniteQuery, useMutation, usePaginatedQuery, useQuery, useQueryCache, useQueryClient, useStore };
431
+ export { type CacheEntry, type HttpClient, HydrationBoundary, type MutationResult, type PaginatedQueryResult, QueryCache, QueryClientProvider, type QueryKey, type QueryKeyInput, type QueryPlugin, type QueryStatus$1 as QueryStatus, type Signal, type SuspenseQueryResult, type UseMutationOptions, type UsePaginatedQueryOptions, type UseQueryOptions, type UseQueryResult, type UseSuspenseQueryOptions, computed, createHttpClient, createState, defineModel, dehydrate, enableDevTools, fromSignal, getPromiseState, handlePromise, hydrate, isPromise, scheduleUpdate, subscribe, toSignal, unwrapPromise, useInfiniteQuery, useMutation, usePaginatedQuery, useQuery, useQueryClient, useStore, useSuspenseQuery };