@spoosh/core 0.12.0 → 0.13.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/README.md +1 -1
- package/dist/index.d.mts +369 -58
- package/dist/index.d.ts +369 -58
- package/dist/index.js +145 -120
- package/dist/index.mjs +145 -120
- package/package.json +1 -1
package/dist/index.d.ts
CHANGED
|
@@ -82,10 +82,6 @@ interface TransportOptionsMap {
|
|
|
82
82
|
fetch: never;
|
|
83
83
|
}
|
|
84
84
|
|
|
85
|
-
type RetryConfig = {
|
|
86
|
-
retries?: number | false;
|
|
87
|
-
retryDelay?: number;
|
|
88
|
-
};
|
|
89
85
|
type HeadersInitOrGetter = HeadersInit | (() => HeadersInit | Promise<HeadersInit>);
|
|
90
86
|
type SpooshOptions = Omit<RequestInit, "method" | "body" | "headers"> & {
|
|
91
87
|
headers?: HeadersInitOrGetter;
|
|
@@ -134,7 +130,7 @@ type AnyRequestOptions = BaseRequestOptions$1 & {
|
|
|
134
130
|
transport?: TransportOption;
|
|
135
131
|
/** Transport-specific options passed through to the transport function. */
|
|
136
132
|
transportOptions?: unknown;
|
|
137
|
-
}
|
|
133
|
+
};
|
|
138
134
|
type DynamicParamsOption = {
|
|
139
135
|
params?: Record<string, string | number>;
|
|
140
136
|
};
|
|
@@ -176,11 +172,6 @@ interface BuiltInEvents {
|
|
|
176
172
|
invalidate: string[];
|
|
177
173
|
refetchAll: void;
|
|
178
174
|
}
|
|
179
|
-
/**
|
|
180
|
-
* Resolves event payload type. Built-in events get their specific type,
|
|
181
|
-
* custom events get `unknown` (or explicit type parameter).
|
|
182
|
-
*/
|
|
183
|
-
type EventPayload<E extends string> = E extends keyof BuiltInEvents ? BuiltInEvents[E] : unknown;
|
|
184
175
|
type EventEmitter = {
|
|
185
176
|
/**
|
|
186
177
|
* Subscribe to an event. Built-in events have type-safe payloads.
|
|
@@ -196,7 +187,8 @@ type EventEmitter = {
|
|
|
196
187
|
* eventEmitter.on<MyPayload>("my-event", (payload) => { ... });
|
|
197
188
|
* ```
|
|
198
189
|
*/
|
|
199
|
-
on<E extends
|
|
190
|
+
on<E extends keyof BuiltInEvents>(event: E, callback: EventCallback<BuiltInEvents[E]>): () => void;
|
|
191
|
+
on<T = unknown>(event: string, callback: EventCallback<T>): () => void;
|
|
200
192
|
/**
|
|
201
193
|
* Emit an event. Built-in events have type-safe payloads.
|
|
202
194
|
*
|
|
@@ -209,7 +201,8 @@ type EventEmitter = {
|
|
|
209
201
|
* eventEmitter.emit("my-event", myPayload);
|
|
210
202
|
* ```
|
|
211
203
|
*/
|
|
212
|
-
emit<E extends
|
|
204
|
+
emit<E extends keyof BuiltInEvents>(event: E, payload: BuiltInEvents[E]): void;
|
|
205
|
+
emit<T = unknown>(event: string, payload: T): void;
|
|
213
206
|
off: (event: string, callback: EventCallback) => void;
|
|
214
207
|
clear: () => void;
|
|
215
208
|
};
|
|
@@ -251,6 +244,190 @@ type StateManager = {
|
|
|
251
244
|
};
|
|
252
245
|
declare function createStateManager(): StateManager;
|
|
253
246
|
|
|
247
|
+
/**
|
|
248
|
+
* Devtool-related types for tracing and debugging.
|
|
249
|
+
* These types are used by the devtool plugin and plugins that emit trace events.
|
|
250
|
+
*/
|
|
251
|
+
|
|
252
|
+
/**
|
|
253
|
+
* Stage of plugin execution for tracing.
|
|
254
|
+
*/
|
|
255
|
+
type TraceStage = "return" | "log" | "skip" | "fetch";
|
|
256
|
+
/**
|
|
257
|
+
* Color hint for devtools visualization.
|
|
258
|
+
*/
|
|
259
|
+
type TraceColor = "success" | "warning" | "error" | "info" | "muted";
|
|
260
|
+
/**
|
|
261
|
+
* Structured trace event emitted by plugins.
|
|
262
|
+
* Plugins self-report what they did and why.
|
|
263
|
+
*/
|
|
264
|
+
type TraceEvent = {
|
|
265
|
+
/** Plugin name */
|
|
266
|
+
plugin: string;
|
|
267
|
+
/** Execution stage */
|
|
268
|
+
stage: TraceStage;
|
|
269
|
+
/** Human-readable explanation of what happened */
|
|
270
|
+
reason?: string;
|
|
271
|
+
/** Color hint for devtools (success=green, warning=yellow, error=red, info=blue) */
|
|
272
|
+
color?: TraceColor;
|
|
273
|
+
/** Before/after diff with optional label */
|
|
274
|
+
diff?: {
|
|
275
|
+
before: unknown;
|
|
276
|
+
after: unknown;
|
|
277
|
+
label?: string;
|
|
278
|
+
};
|
|
279
|
+
/** Structured information to display (e.g., invalidated tags, cache keys) */
|
|
280
|
+
info?: Array<{
|
|
281
|
+
label?: string;
|
|
282
|
+
value: unknown;
|
|
283
|
+
}>;
|
|
284
|
+
};
|
|
285
|
+
/**
|
|
286
|
+
* Trace API available to plugins via ctx.trace.
|
|
287
|
+
* Plugins emit structured events; devtools renders them.
|
|
288
|
+
*
|
|
289
|
+
* @example
|
|
290
|
+
* ```ts
|
|
291
|
+
* middleware: async (ctx, next) => {
|
|
292
|
+
* const cached = getCache(ctx.queryKey);
|
|
293
|
+
* if (cached) {
|
|
294
|
+
* ctx.trace?.step({
|
|
295
|
+
* plugin: "cache",
|
|
296
|
+
* stage: "skip",
|
|
297
|
+
* meta: { reason: "Cache hit (TTL valid)" }
|
|
298
|
+
* });
|
|
299
|
+
* return cached;
|
|
300
|
+
* }
|
|
301
|
+
*
|
|
302
|
+
* ctx.trace?.step({
|
|
303
|
+
* plugin: "cache",
|
|
304
|
+
* stage: "before",
|
|
305
|
+
* intent: "read",
|
|
306
|
+
* });
|
|
307
|
+
*
|
|
308
|
+
* const result = await next();
|
|
309
|
+
*
|
|
310
|
+
* ctx.trace?.step({
|
|
311
|
+
* plugin: "cache",
|
|
312
|
+
* stage: "after",
|
|
313
|
+
* meta: {
|
|
314
|
+
* reason: "Stored in cache",
|
|
315
|
+
* diff: { before: null, after: result.data }
|
|
316
|
+
* }
|
|
317
|
+
* });
|
|
318
|
+
*
|
|
319
|
+
* return result;
|
|
320
|
+
* }
|
|
321
|
+
* ```
|
|
322
|
+
*/
|
|
323
|
+
type Trace = {
|
|
324
|
+
/**
|
|
325
|
+
* Emit a trace event. Lazy evaluation - only computed when devtools is active.
|
|
326
|
+
*
|
|
327
|
+
* @param event - Trace event or function that returns trace event (for lazy evaluation)
|
|
328
|
+
*/
|
|
329
|
+
step: (event: TraceEvent | (() => TraceEvent)) => void;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Listener for trace events emitted by plugins.
|
|
333
|
+
*/
|
|
334
|
+
type TraceListener = (event: TraceEvent & {
|
|
335
|
+
queryKey: string;
|
|
336
|
+
timestamp: number;
|
|
337
|
+
}) => void;
|
|
338
|
+
/**
|
|
339
|
+
* Standalone event not tied to a request lifecycle.
|
|
340
|
+
* Used for polling, debounce, gc, and other background activities.
|
|
341
|
+
*/
|
|
342
|
+
type StandaloneEvent = {
|
|
343
|
+
/** Plugin name */
|
|
344
|
+
plugin: string;
|
|
345
|
+
/** Human-readable message */
|
|
346
|
+
message: string;
|
|
347
|
+
/** Color hint for devtools */
|
|
348
|
+
color?: TraceColor;
|
|
349
|
+
/** Related query key (for filtering) */
|
|
350
|
+
queryKey?: string;
|
|
351
|
+
/** Additional metadata */
|
|
352
|
+
meta?: Record<string, unknown>;
|
|
353
|
+
/** Timestamp when event occurred */
|
|
354
|
+
timestamp: number;
|
|
355
|
+
};
|
|
356
|
+
type EventListener = (event: StandaloneEvent) => void;
|
|
357
|
+
type TraceInfo = {
|
|
358
|
+
label?: string;
|
|
359
|
+
value: unknown;
|
|
360
|
+
};
|
|
361
|
+
type TraceOptions = {
|
|
362
|
+
color?: TraceColor;
|
|
363
|
+
diff?: {
|
|
364
|
+
before: unknown;
|
|
365
|
+
after: unknown;
|
|
366
|
+
label?: string;
|
|
367
|
+
};
|
|
368
|
+
info?: TraceInfo[];
|
|
369
|
+
};
|
|
370
|
+
type EventOptions = {
|
|
371
|
+
color?: TraceColor;
|
|
372
|
+
/** Query key this event relates to (for filtering) */
|
|
373
|
+
queryKey?: string;
|
|
374
|
+
/** Additional metadata to display */
|
|
375
|
+
meta?: Record<string, unknown>;
|
|
376
|
+
};
|
|
377
|
+
/**
|
|
378
|
+
* Request-bound tracer API for plugins.
|
|
379
|
+
* Created via `context.tracer?.(pluginName)`.
|
|
380
|
+
* Automatically bound to the request's queryKey for accurate devtool tracing.
|
|
381
|
+
*
|
|
382
|
+
* @example
|
|
383
|
+
* ```ts
|
|
384
|
+
* const t = context.tracer?.("my-plugin");
|
|
385
|
+
* t?.return("Cache hit", { color: "success" });
|
|
386
|
+
* t?.log("Transformed", { color: "info", diff: { before, after } });
|
|
387
|
+
* t?.skip("Nothing to do", { color: "muted" });
|
|
388
|
+
* ```
|
|
389
|
+
*/
|
|
390
|
+
interface RequestTracer {
|
|
391
|
+
/** Returned early without calling next() */
|
|
392
|
+
return(msg: string, options?: TraceOptions): void;
|
|
393
|
+
/** Did something (any activity worth noting) */
|
|
394
|
+
log(msg: string, options?: TraceOptions): void;
|
|
395
|
+
/** Nothing to do, passed through */
|
|
396
|
+
skip(msg: string, options?: TraceOptions): void;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Event emitted after all afterResponse hooks complete.
|
|
400
|
+
* Used by devtools to capture meta snapshots.
|
|
401
|
+
*/
|
|
402
|
+
interface RequestCompleteEvent {
|
|
403
|
+
context: PluginContext;
|
|
404
|
+
queryKey: string;
|
|
405
|
+
}
|
|
406
|
+
/**
|
|
407
|
+
* Internal events used by core and devtools. Not for public use.
|
|
408
|
+
* @internal
|
|
409
|
+
*/
|
|
410
|
+
interface DevtoolEvents {
|
|
411
|
+
"spoosh:devtool-event": StandaloneEvent;
|
|
412
|
+
"spoosh:request-complete": RequestCompleteEvent;
|
|
413
|
+
}
|
|
414
|
+
/**
|
|
415
|
+
* Event tracer API for standalone events not tied to a request lifecycle.
|
|
416
|
+
* Created via `context.eventTracer?.(pluginName)`.
|
|
417
|
+
* Use for async callbacks like polling, debounce completion, gc, etc.
|
|
418
|
+
*
|
|
419
|
+
* @example
|
|
420
|
+
* ```ts
|
|
421
|
+
* const et = context.eventTracer?.("my-plugin");
|
|
422
|
+
* et?.emit("Poll triggered", { queryKey, color: "success" });
|
|
423
|
+
* et?.emit("GC cleaned 5 entries", { color: "info", meta: { count: 5 } });
|
|
424
|
+
* ```
|
|
425
|
+
*/
|
|
426
|
+
interface EventTracer {
|
|
427
|
+
/** Emit a standalone event not tied to a request */
|
|
428
|
+
emit(msg: string, options?: EventOptions): void;
|
|
429
|
+
}
|
|
430
|
+
|
|
254
431
|
type OperationType = "read" | "write" | "infiniteRead";
|
|
255
432
|
type LifecyclePhase = "onMount" | "onUnmount" | "onUpdate";
|
|
256
433
|
type OperationState<TData = unknown, TError = unknown> = {
|
|
@@ -270,10 +447,26 @@ type CacheEntry<TData = unknown, TError = unknown> = {
|
|
|
270
447
|
stale?: boolean;
|
|
271
448
|
};
|
|
272
449
|
/** RequestOptions in plugin context have headers already resolved to Record */
|
|
273
|
-
type PluginRequestOptions = Omit<AnyRequestOptions, "headers"> & {
|
|
450
|
+
type PluginRequestOptions = Omit<AnyRequestOptions, "headers" | "cache"> & {
|
|
274
451
|
headers: Record<string, string>;
|
|
275
452
|
};
|
|
276
|
-
|
|
453
|
+
/**
|
|
454
|
+
* Registry for extending PluginContext with custom properties.
|
|
455
|
+
* Third-party plugins can extend this interface via declaration merging.
|
|
456
|
+
*
|
|
457
|
+
* @example
|
|
458
|
+
* ```ts
|
|
459
|
+
* // In your plugin's types file:
|
|
460
|
+
* declare module '@spoosh/core' {
|
|
461
|
+
* interface PluginContextExtensions {
|
|
462
|
+
* myCustomProperty?: MyCustomType;
|
|
463
|
+
* }
|
|
464
|
+
* }
|
|
465
|
+
* ```
|
|
466
|
+
*/
|
|
467
|
+
interface PluginContextExtensions {
|
|
468
|
+
}
|
|
469
|
+
type PluginContextBase = {
|
|
277
470
|
readonly operationType: OperationType;
|
|
278
471
|
readonly path: string;
|
|
279
472
|
readonly method: HttpMethod;
|
|
@@ -296,9 +489,40 @@ type PluginContext = {
|
|
|
296
489
|
pluginOptions?: unknown;
|
|
297
490
|
/** Force a network request even if cached data exists. Used by plugins to communicate intent. */
|
|
298
491
|
forceRefetch?: boolean;
|
|
492
|
+
/**
|
|
493
|
+
* Creates a request-bound tracer for devtools debugging.
|
|
494
|
+
* Automatically bound to this request's queryKey.
|
|
495
|
+
* Only available when devtools plugin is active.
|
|
496
|
+
*
|
|
497
|
+
* @example
|
|
498
|
+
* ```ts
|
|
499
|
+
* const t = ctx.tracer?.("my-plugin");
|
|
500
|
+
* t?.return("Cache hit", { color: "success" });
|
|
501
|
+
* t?.log("Processing", { color: "info" });
|
|
502
|
+
* t?.skip("Nothing to do", { color: "muted" });
|
|
503
|
+
* ```
|
|
504
|
+
*/
|
|
505
|
+
tracer?: (plugin: string) => RequestTracer;
|
|
506
|
+
/**
|
|
507
|
+
* Creates an event tracer for standalone events not tied to a request lifecycle.
|
|
508
|
+
* Use for async callbacks like polling, debounce completion, gc, etc.
|
|
509
|
+
* Only available when devtools plugin is active.
|
|
510
|
+
*
|
|
511
|
+
* @example
|
|
512
|
+
* ```ts
|
|
513
|
+
* const et = ctx.eventTracer?.("my-plugin");
|
|
514
|
+
* et?.emit("Poll triggered", { queryKey, color: "success" });
|
|
515
|
+
* ```
|
|
516
|
+
*/
|
|
517
|
+
eventTracer?: (plugin: string) => EventTracer;
|
|
299
518
|
};
|
|
519
|
+
/**
|
|
520
|
+
* Plugin context with extensions from third-party plugins.
|
|
521
|
+
* Plugins can extend this via PluginContextExtensions declaration merging.
|
|
522
|
+
*/
|
|
523
|
+
type PluginContext = PluginContextBase & PluginContextExtensions;
|
|
300
524
|
/** Input type for creating PluginContext (without injected properties) */
|
|
301
|
-
type PluginContextInput = Omit<PluginContext, "plugins">;
|
|
525
|
+
type PluginContextInput = Omit<PluginContext, "plugins" | "tracer" | "eventTracer">;
|
|
302
526
|
/**
|
|
303
527
|
* Middleware function that wraps the fetch flow.
|
|
304
528
|
* Plugins use this for full control over request/response handling.
|
|
@@ -318,12 +542,9 @@ type PluginContextInput = Omit<PluginContext, "plugins">;
|
|
|
318
542
|
* return next();
|
|
319
543
|
* }
|
|
320
544
|
*
|
|
321
|
-
* //
|
|
545
|
+
* // Auth middleware - add authentication headers
|
|
322
546
|
* middleware: async (context, next) => {
|
|
323
|
-
*
|
|
324
|
-
* const result = await next();
|
|
325
|
-
* if (!result.error) return result;
|
|
326
|
-
* }
|
|
547
|
+
* context.request.headers['Authorization'] = `Bearer ${getToken()}`;
|
|
327
548
|
* return next();
|
|
328
549
|
* }
|
|
329
550
|
* ```
|
|
@@ -379,7 +600,7 @@ type PluginTypeConfig = {
|
|
|
379
600
|
* Base interface for Spoosh plugins.
|
|
380
601
|
*
|
|
381
602
|
* Plugins can implement:
|
|
382
|
-
* - `middleware`: Wraps the fetch flow for full control (intercept,
|
|
603
|
+
* - `middleware`: Wraps the fetch flow for full control (intercept, transform, modify)
|
|
383
604
|
* - `afterResponse`: Called after every response, regardless of early returns
|
|
384
605
|
* - `lifecycle`: Component lifecycle hooks (onMount, onUpdate, onUnmount)
|
|
385
606
|
* - `exports`: Functions/variables accessible to other plugins
|
|
@@ -427,8 +648,35 @@ interface SpooshPlugin<T extends PluginTypeConfig = PluginTypeConfig> {
|
|
|
427
648
|
/** Expose functions/variables for other plugins to access via `context.plugins.get(name)` */
|
|
428
649
|
exports?: (context: PluginContext) => object;
|
|
429
650
|
/**
|
|
430
|
-
*
|
|
651
|
+
* One-time initialization when the Spoosh instance is created.
|
|
652
|
+
* Use for setting up timers, event listeners, or other side effects.
|
|
653
|
+
* Runs before instanceApi is called.
|
|
654
|
+
*
|
|
655
|
+
* @example
|
|
656
|
+
* ```ts
|
|
657
|
+
* setup: ({ stateManager, eventEmitter, pluginExecutor }) => {
|
|
658
|
+
* // Set up interval timer
|
|
659
|
+
* const intervalId = setInterval(() => {
|
|
660
|
+
* // periodic cleanup
|
|
661
|
+
* }, 60000);
|
|
662
|
+
*
|
|
663
|
+
* // Register context enhancer
|
|
664
|
+
* pluginExecutor.registerContextEnhancer((context) => {
|
|
665
|
+
* context.myProperty = myValue;
|
|
666
|
+
* });
|
|
667
|
+
*
|
|
668
|
+
* // Set up event listener
|
|
669
|
+
* eventEmitter.on("invalidate", (tags) => {
|
|
670
|
+
* // handle invalidation
|
|
671
|
+
* });
|
|
672
|
+
* }
|
|
673
|
+
* ```
|
|
674
|
+
*/
|
|
675
|
+
setup?: (context: SetupContext) => void;
|
|
676
|
+
/**
|
|
677
|
+
* Expose functions/properties on the framework adapter return value (e.g., create).
|
|
431
678
|
* Unlike `exports`, these are accessible directly from the instance, not just within plugin context.
|
|
679
|
+
* Should be pure - use `setup` for side effects like timers or event listeners.
|
|
432
680
|
*
|
|
433
681
|
* @example
|
|
434
682
|
* ```ts
|
|
@@ -441,7 +689,37 @@ interface SpooshPlugin<T extends PluginTypeConfig = PluginTypeConfig> {
|
|
|
441
689
|
instanceApi?: (context: InstanceApiContext) => T extends {
|
|
442
690
|
instanceApi: infer A;
|
|
443
691
|
} ? A : object;
|
|
444
|
-
/**
|
|
692
|
+
/**
|
|
693
|
+
* Plugin execution priority. Lower numbers run first, higher numbers run last.
|
|
694
|
+
* Default: 0
|
|
695
|
+
*
|
|
696
|
+
* @example
|
|
697
|
+
* ```ts
|
|
698
|
+
* // Cache plugin runs early (checks cache before other plugins)
|
|
699
|
+
* { name: "cache", priority: -10, ... }
|
|
700
|
+
*
|
|
701
|
+
* // Throttle plugin runs last (blocks all requests including force fetches)
|
|
702
|
+
* { name: "throttle", priority: 100, ... }
|
|
703
|
+
*
|
|
704
|
+
* // Most plugins use default priority
|
|
705
|
+
* { name: "retry", priority: 0, ... } // or omit priority
|
|
706
|
+
* ```
|
|
707
|
+
*/
|
|
708
|
+
priority?: number;
|
|
709
|
+
/**
|
|
710
|
+
* List of plugin names that this plugin depends on.
|
|
711
|
+
* Used to validate that required plugins are registered.
|
|
712
|
+
* Does not affect execution order - use `priority` for that.
|
|
713
|
+
*
|
|
714
|
+
* @example
|
|
715
|
+
* ```ts
|
|
716
|
+
* {
|
|
717
|
+
* name: "spoosh:optimistic",
|
|
718
|
+
* dependencies: ["spoosh:invalidation"],
|
|
719
|
+
* // ...
|
|
720
|
+
* }
|
|
721
|
+
* ```
|
|
722
|
+
*/
|
|
445
723
|
dependencies?: string[];
|
|
446
724
|
/** @internal Type carrier for inference - do not use directly */
|
|
447
725
|
readonly _types?: T;
|
|
@@ -602,6 +880,12 @@ type RefetchEvent = {
|
|
|
602
880
|
type InstancePluginExecutor = {
|
|
603
881
|
executeMiddleware: <TData, TError>(operationType: OperationType, context: PluginContext, coreFetch: () => Promise<SpooshResponse<any, any>>) => Promise<SpooshResponse<TData, TError>>;
|
|
604
882
|
createContext: (input: PluginContextInput) => PluginContext;
|
|
883
|
+
getPlugins: () => readonly SpooshPlugin[];
|
|
884
|
+
/**
|
|
885
|
+
* Register a function to enhance every PluginContext during creation.
|
|
886
|
+
* Call this during plugin setup to inject properties into all request contexts.
|
|
887
|
+
*/
|
|
888
|
+
registerContextEnhancer: (enhancer: (context: PluginContext) => void) => void;
|
|
605
889
|
};
|
|
606
890
|
/**
|
|
607
891
|
* Context provided to plugin's instanceApi function.
|
|
@@ -612,6 +896,25 @@ type InstanceApiContext<TApi = unknown> = {
|
|
|
612
896
|
stateManager: StateManager;
|
|
613
897
|
eventEmitter: EventEmitter;
|
|
614
898
|
pluginExecutor: InstancePluginExecutor;
|
|
899
|
+
/**
|
|
900
|
+
* Creates an event tracer for standalone events.
|
|
901
|
+
* Only available when devtools plugin is active.
|
|
902
|
+
*/
|
|
903
|
+
eventTracer?: (plugin: string) => EventTracer;
|
|
904
|
+
};
|
|
905
|
+
/**
|
|
906
|
+
* Context provided to plugin's setup function.
|
|
907
|
+
* Used for one-time initialization when the Spoosh instance is created.
|
|
908
|
+
*/
|
|
909
|
+
type SetupContext = {
|
|
910
|
+
stateManager: StateManager;
|
|
911
|
+
eventEmitter: EventEmitter;
|
|
912
|
+
pluginExecutor: InstancePluginExecutor;
|
|
913
|
+
/**
|
|
914
|
+
* Creates an event tracer for standalone events.
|
|
915
|
+
* Only available when devtools plugin is active.
|
|
916
|
+
*/
|
|
917
|
+
eventTracer?: (plugin: string) => EventTracer;
|
|
615
918
|
};
|
|
616
919
|
|
|
617
920
|
type PluginExecutor = {
|
|
@@ -621,8 +924,13 @@ type PluginExecutor = {
|
|
|
621
924
|
executeUpdateLifecycle: (operationType: OperationType, context: PluginContext, previousContext: PluginContext) => Promise<void>;
|
|
622
925
|
executeMiddleware: (operationType: OperationType, context: PluginContext, coreFetch: () => Promise<SpooshResponse<any, any>>) => Promise<SpooshResponse<any, any>>;
|
|
623
926
|
getPlugins: () => readonly SpooshPlugin[];
|
|
624
|
-
/** Creates a full PluginContext with plugins accessor
|
|
927
|
+
/** Creates a full PluginContext with plugins accessor */
|
|
625
928
|
createContext: (input: PluginContextInput) => PluginContext;
|
|
929
|
+
/**
|
|
930
|
+
* Register a function to enhance every PluginContext during creation.
|
|
931
|
+
* Call this during plugin setup to inject properties into all request contexts.
|
|
932
|
+
*/
|
|
933
|
+
registerContextEnhancer: (enhancer: (context: PluginContext) => void) => void;
|
|
626
934
|
};
|
|
627
935
|
declare function createPluginExecutor(initialPlugins?: SpooshPlugin[]): PluginExecutor;
|
|
628
936
|
|
|
@@ -1132,8 +1440,8 @@ type SpooshInstance<TSchema = unknown, TDefaultError = unknown, TPlugins extends
|
|
|
1132
1440
|
*
|
|
1133
1441
|
* @example Basic usage
|
|
1134
1442
|
* ```ts
|
|
1135
|
-
* const
|
|
1136
|
-
* .use([cachePlugin(),
|
|
1443
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api')
|
|
1444
|
+
* .use([cachePlugin(), devtool()]);
|
|
1137
1445
|
*
|
|
1138
1446
|
* const { api } = client;
|
|
1139
1447
|
* const response = await api("posts").GET();
|
|
@@ -1141,19 +1449,19 @@ type SpooshInstance<TSchema = unknown, TDefaultError = unknown, TPlugins extends
|
|
|
1141
1449
|
*
|
|
1142
1450
|
* @example With default options
|
|
1143
1451
|
* ```ts
|
|
1144
|
-
* const
|
|
1452
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api', {
|
|
1145
1453
|
* headers: { 'Authorization': 'Bearer token' }
|
|
1146
1454
|
* }).use([cachePlugin()]);
|
|
1147
1455
|
* ```
|
|
1148
1456
|
*
|
|
1149
1457
|
* @example With React hooks
|
|
1150
1458
|
* ```ts
|
|
1151
|
-
* import {
|
|
1459
|
+
* import { create } from '@spoosh/react';
|
|
1152
1460
|
*
|
|
1153
|
-
* const
|
|
1154
|
-
* .use([cachePlugin(),
|
|
1461
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api')
|
|
1462
|
+
* .use([cachePlugin(), prefetchPlugin()]);
|
|
1155
1463
|
*
|
|
1156
|
-
* const { useRead, useWrite } =
|
|
1464
|
+
* const { useRead, useWrite } = create(client);
|
|
1157
1465
|
*
|
|
1158
1466
|
* // In component
|
|
1159
1467
|
* const { data } = useRead((api) => api("posts").GET());
|
|
@@ -1176,15 +1484,15 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
|
|
|
1176
1484
|
* @example
|
|
1177
1485
|
* ```ts
|
|
1178
1486
|
* // Simple usage
|
|
1179
|
-
* const
|
|
1487
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api');
|
|
1180
1488
|
*
|
|
1181
1489
|
* // With default headers
|
|
1182
|
-
* const
|
|
1490
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api', {
|
|
1183
1491
|
* headers: { 'X-API-Key': 'secret' }
|
|
1184
1492
|
* });
|
|
1185
1493
|
*
|
|
1186
1494
|
* // With XHR transport (narrows available options to XHR-compatible fields)
|
|
1187
|
-
* const
|
|
1495
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api', {
|
|
1188
1496
|
* transport: 'xhr',
|
|
1189
1497
|
* credentials: 'include',
|
|
1190
1498
|
* });
|
|
@@ -1194,38 +1502,22 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
|
|
|
1194
1502
|
/**
|
|
1195
1503
|
* Adds plugins to the Spoosh instance.
|
|
1196
1504
|
*
|
|
1197
|
-
* Returns a
|
|
1198
|
-
*
|
|
1505
|
+
* Returns a configured Spoosh instance with the specified plugins.
|
|
1506
|
+
* Can only be called once - the returned instance does not have `.use()`.
|
|
1199
1507
|
*
|
|
1200
1508
|
* @template TNewPlugins - The const tuple type of the new plugins array
|
|
1201
1509
|
* @param plugins - Array of plugin instances to use
|
|
1202
|
-
* @returns A
|
|
1510
|
+
* @returns A configured Spoosh instance (without `.use()` method)
|
|
1203
1511
|
*
|
|
1204
|
-
* @example Single use() call
|
|
1205
1512
|
* ```ts
|
|
1206
|
-
* const
|
|
1207
|
-
* .use([cachePlugin(), retryPlugin(), debouncePlugin()]);
|
|
1208
|
-
* ```
|
|
1209
|
-
*
|
|
1210
|
-
* @example Chaining use() calls (replaces plugins)
|
|
1211
|
-
* ```ts
|
|
1212
|
-
* const client1 = new Spoosh<Schema, Error>('/api')
|
|
1213
|
-
* .use([cachePlugin()]);
|
|
1214
|
-
*
|
|
1215
|
-
* // This replaces cachePlugin with retryPlugin
|
|
1216
|
-
* const client2 = client1.use([retryPlugin()]);
|
|
1217
|
-
* ```
|
|
1218
|
-
*
|
|
1219
|
-
* @example With plugin configuration
|
|
1220
|
-
* ```ts
|
|
1221
|
-
* const client = new Spoosh<Schema, Error>('/api').use([
|
|
1513
|
+
* const spoosh = new Spoosh<Schema, Error>('/api').use([
|
|
1222
1514
|
* cachePlugin({ staleTime: 5000 }),
|
|
1223
|
-
*
|
|
1515
|
+
* invalidationPlugin(),
|
|
1224
1516
|
* prefetchPlugin(),
|
|
1225
1517
|
* ]);
|
|
1226
1518
|
* ```
|
|
1227
1519
|
*/
|
|
1228
|
-
use<const TNewPlugins extends PluginArray>(plugins: TNewPlugins): Spoosh<TSchema, TError, TNewPlugins>;
|
|
1520
|
+
use<const TNewPlugins extends PluginArray>(plugins: TNewPlugins): Omit<Spoosh<TSchema, TError, TNewPlugins>, "use">;
|
|
1229
1521
|
/**
|
|
1230
1522
|
* Cached instance of the underlying SpooshInstance.
|
|
1231
1523
|
* Created lazily on first property access.
|
|
@@ -1245,7 +1537,7 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
|
|
|
1245
1537
|
*
|
|
1246
1538
|
* @example
|
|
1247
1539
|
* ```ts
|
|
1248
|
-
* const
|
|
1540
|
+
* const spoosh = new Spoosh<ApiSchema, Error>('/api').use([...]);
|
|
1249
1541
|
* const { api } = client;
|
|
1250
1542
|
*
|
|
1251
1543
|
* // GET request
|
|
@@ -1436,6 +1728,25 @@ type TagOptions = {
|
|
|
1436
1728
|
declare function resolveTags(options: TagOptions | undefined, resolvedPath: string[]): string[];
|
|
1437
1729
|
declare function resolvePath(path: string[], params: Record<string, string | number> | undefined): string[];
|
|
1438
1730
|
|
|
1731
|
+
declare const isNetworkError: (err: unknown) => boolean;
|
|
1732
|
+
declare const isAbortError: (err: unknown) => boolean;
|
|
1733
|
+
|
|
1734
|
+
declare function clone<T>(value: T, seen?: WeakMap<WeakKey, any>): T;
|
|
1735
|
+
|
|
1736
|
+
/**
|
|
1737
|
+
* Creates a request-bound tracer for a plugin.
|
|
1738
|
+
* Use for middleware, afterResponse, and lifecycle hooks.
|
|
1739
|
+
*
|
|
1740
|
+
* @example
|
|
1741
|
+
* ```ts
|
|
1742
|
+
* const t = createTracer("spoosh:cache", context.trace);
|
|
1743
|
+
* t.return("Cache hit", { color: "success" });
|
|
1744
|
+
* t.log("Cached response", { color: "info", diff: { before, after } });
|
|
1745
|
+
* t.skip("No query params", { color: "muted" });
|
|
1746
|
+
* ```
|
|
1747
|
+
*/
|
|
1748
|
+
declare function createTracer(plugin: string, trace: Trace | undefined): RequestTracer;
|
|
1749
|
+
|
|
1439
1750
|
type ProxyHandlerConfig<TOptions = SpooshOptions> = {
|
|
1440
1751
|
baseUrl: string;
|
|
1441
1752
|
defaultOptions: TOptions;
|
|
@@ -1670,4 +1981,4 @@ type CreateInfiniteReadOptions<TData, TItem, TError, TRequest> = {
|
|
|
1670
1981
|
};
|
|
1671
1982
|
declare function createInfiniteReadController<TData, TItem, TError, TRequest extends InfiniteRequestOptions = InfiniteRequestOptions>(options: CreateInfiniteReadOptions<TData, TItem, TError, TRequest>): InfiniteReadController<TData, TItem, TError>;
|
|
1672
1983
|
|
|
1673
|
-
export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type EventEmitter, type ExtractBody$1 as ExtractBody, type ExtractData, type ExtractError, type ExtractMethodOptions, type ExtractParamNames, type ExtractQuery$1 as ExtractQuery, type FetchDirection, type FetchExecutor, type FindMatchingKey, HTTP_METHODS, type HasParams, type HasReadMethod, type HasWriteMethod, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodOptionsMap, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextInput, type PluginExecutor, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginRequestOptions, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type ReadClient, type ReadPaths, type ReadSchemaHelper, type RefetchEvent, type RequestOptions$1 as RequestOptions, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type
|
|
1984
|
+
export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type ComputeRequestOptions, type CoreRequestOptionsBase, type CreateInfiniteReadOptions, type CreateOperationOptions, type DataAwareCallback, type DataAwareTransform, type DevtoolEvents, type EventEmitter, type EventListener, type EventOptions, type EventTracer, type ExtractBody$1 as ExtractBody, type ExtractData, type ExtractError, type ExtractMethodOptions, type ExtractParamNames, type ExtractQuery$1 as ExtractQuery, type FetchDirection, type FetchExecutor, type FindMatchingKey, HTTP_METHODS, type HasParams, type HasReadMethod, type HasWriteMethod, type HeadersInitOrGetter, type HttpMethod, type HttpMethodKey, type InfiniteReadController, type InfiniteReadState, type InfiniteRequestOptions, type InstanceApiContext, type InstanceApiResolvers, type InstancePluginExecutor, type LifecyclePhase, type MergePluginInstanceApi, type MergePluginOptions, type MergePluginResults, type MethodOptionsMap, type OperationController, type OperationState, type OperationType, type PageContext, type PluginAccessor, type PluginArray, type PluginContext, type PluginContextBase, type PluginContextExtensions, type PluginContextInput, type PluginExecutor, type PluginExportsRegistry, type PluginFactory, type PluginHandler, type PluginLifecycle, type PluginMiddleware, type PluginRegistry, type PluginRequestOptions, type PluginResolvers, type PluginResponseHandler, type PluginResultResolvers, type PluginTypeConfig, type PluginUpdateHandler, type ReadClient, type ReadPaths, type ReadSchemaHelper, type RefetchEvent, type RequestCompleteEvent, type RequestOptions$1 as RequestOptions, type RequestTracer, type ResolveInstanceApi, type ResolveResultTypes, type ResolveSchemaTypes, type ResolveTypes, type ResolverContext, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type SetupContext, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshOptions, type SpooshOptionsInput, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StandaloneEvent, type StateManager, type StripPrefix, type TagMode, type TagOptions, type Trace, type TraceColor, type TraceEvent, type TraceInfo, type TraceListener, type TraceOptions, type TraceStage, type Transport, type TransportOption, type TransportOptionsMap, type TransportResponse, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, buildUrl, clone, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, createTracer, executeFetch, extractMethodFromSelector, extractPathFromSelector, fetchTransport, form, generateTags, getContentType, isAbortError, isJsonBody, isNetworkError, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveTags, setHeaders, sortObjectKeys, urlencoded, xhrTransport };
|