@spoosh/core 0.10.0 → 0.11.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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # @spoosh/core
2
2
 
3
- Core client and plugin system for Spoosh - a type-safe API client framework.
3
+ Core client and plugin system for Spoosh - a type-safe API toolkit.
4
4
 
5
5
  **[Documentation](https://spoosh.dev/docs/react)** · **Requirements:** TypeScript >= 5.0
6
6
 
@@ -47,8 +47,11 @@ type ApiSchema = {
47
47
  ```typescript
48
48
  import { createClient } from "@spoosh/core";
49
49
 
50
- const api = createClient<ApiSchema>({
51
- baseUrl: "/api",
50
+ const api = createClient<ApiSchema>("/api");
51
+
52
+ // With custom options
53
+ const apiWithAuth = createClient<ApiSchema>("/api", {
54
+ headers: { Authorization: "Bearer token" },
52
55
  });
53
56
 
54
57
  // Import body wrappers for explicit serialization
@@ -115,7 +118,7 @@ When using `createClient`, Next.js cache tags are automatically generated from t
115
118
  // Server component
116
119
  import { createClient } from "@spoosh/core";
117
120
 
118
- const api = createClient<ApiSchema>({ baseUrl: process.env.API_URL! });
121
+ const api = createClient<ApiSchema>(process.env.API_URL!);
119
122
 
120
123
  // Auto-generates next: { tags: ['posts'] }
121
124
  const { data: posts } = await api("posts").GET();
@@ -128,51 +131,6 @@ const { data: userPosts } = await api("users/:id/posts").GET({
128
131
 
129
132
  This enables automatic cache invalidation with `revalidateTag()` in Next.js.
130
133
 
131
- ### With Middlewares
132
-
133
- ```typescript
134
- import { createClient, createMiddleware } from "@spoosh/core";
135
-
136
- const authMiddleware = createMiddleware("auth", "before", async (ctx) => {
137
- ctx.requestOptions = {
138
- ...ctx.requestOptions,
139
- headers: { Authorization: `Bearer ${token}` },
140
- };
141
- return ctx;
142
- });
143
-
144
- const api = createClient<ApiSchema>({
145
- baseUrl: "/api",
146
- middlewares: [authMiddleware],
147
- });
148
- ```
149
-
150
- ### Middleware Utilities
151
-
152
- ```typescript
153
- import {
154
- createMiddleware,
155
- applyMiddlewares,
156
- composeMiddlewares,
157
- } from "@spoosh/core";
158
-
159
- // createMiddleware(name, phase, handler) - Create a named middleware
160
- const logMiddleware = createMiddleware("logger", "after", async (ctx) => {
161
- console.log(ctx.response?.status);
162
- return ctx;
163
- });
164
-
165
- // composeMiddlewares(...lists) - Combine multiple middleware arrays
166
- const allMiddlewares = composeMiddlewares(
167
- [authMiddleware],
168
- [logMiddleware],
169
- conditionalMiddlewares
170
- );
171
-
172
- // applyMiddlewares(context, middlewares, phase) - Run middlewares for a phase
173
- const updatedContext = await applyMiddlewares(context, middlewares, "before");
174
- ```
175
-
176
134
  ## Schema Types
177
135
 
178
136
  | Field | Description | Example |
@@ -186,15 +144,16 @@ Path parameters are defined using `:param` syntax in the path key (e.g., `"users
186
144
 
187
145
  ## API Reference
188
146
 
189
- ### createClient(config)
147
+ ### createClient(baseUrl, defaultOptions?)
148
+
149
+ Creates a lightweight type-safe API instance.
190
150
 
191
- Creates a lightweight type-safe API client.
151
+ **Parameters:**
192
152
 
193
- | Option | Type | Description |
194
- | ---------------- | -------------------- | -------------------------------------------------- |
195
- | `baseUrl` | `string` | Base URL for all API requests |
196
- | `defaultOptions` | `RequestInit` | Default fetch options (headers, credentials, etc.) |
197
- | `middlewares` | `SpooshMiddleware[]` | Request/response middlewares |
153
+ | Parameter | Type | Description |
154
+ | ---------------- | ------------- | ------------------------------------------------------------- |
155
+ | `baseUrl` | `string` | Base URL for all API requests |
156
+ | `defaultOptions` | `RequestInit` | (Optional) Default fetch options (headers, credentials, etc.) |
198
157
 
199
158
  ### Spoosh (class)
200
159
 
@@ -228,12 +187,12 @@ const { data } = await api("users").GET();
228
187
 
229
188
  **Properties:**
230
189
 
231
- | Property | Description |
232
- | ----------------- | ---------------------------------------- |
233
- | `.api` | Type-safe API client for making requests |
234
- | `.stateManager` | Cache and state management |
235
- | `.eventEmitter` | Event system for refetch/invalidation |
236
- | `.pluginExecutor` | Plugin lifecycle management |
190
+ | Property | Description |
191
+ | ----------------- | ------------------------------------------- |
192
+ | `.api` | Type-safe API interface for making requests |
193
+ | `.stateManager` | Cache and state management |
194
+ | `.eventEmitter` | Event system for refetch/invalidation |
195
+ | `.pluginExecutor` | Plugin lifecycle management |
237
196
 
238
197
  ## Creating Plugins
239
198
 
package/dist/index.d.mts CHANGED
@@ -4,24 +4,6 @@ type Simplify<T> = {
4
4
  [K in keyof T]: T[K];
5
5
  } & {};
6
6
 
7
- type MiddlewarePhase = "before" | "after";
8
- type MiddlewareContext<TData = unknown, TError = unknown> = {
9
- baseUrl: string;
10
- path: string[];
11
- method: HttpMethod;
12
- defaultOptions: SpooshOptions & SpooshOptionsExtra;
13
- requestOptions?: AnyRequestOptions;
14
- fetchInit?: RequestInit;
15
- response?: SpooshResponse<TData, TError>;
16
- metadata: Record<string, unknown>;
17
- };
18
- type MiddlewareHandler<TData = unknown, TError = unknown> = (context: MiddlewareContext<TData, TError>) => MiddlewareContext<TData, TError> | Promise<MiddlewareContext<TData, TError>>;
19
- type SpooshMiddleware<TData = unknown, TError = unknown> = {
20
- name: string;
21
- phase: MiddlewarePhase;
22
- handler: MiddlewareHandler<TData, TError>;
23
- };
24
-
25
7
  type QueryField<TQuery> = [TQuery] extends [never] ? object : {
26
8
  query: TQuery;
27
9
  };
@@ -54,15 +36,25 @@ type SpooshResponse<TData, TError, TRequestOptions = unknown, TQuery = never, TB
54
36
  aborted?: boolean;
55
37
  readonly __requestOptions?: TRequestOptions;
56
38
  } & InputFieldWrapper<TQuery, TBody, TParamNames>);
57
- type SpooshOptionsExtra<TData = unknown, TError = unknown> = {
58
- middlewares?: SpooshMiddleware<TData, TError>[];
59
- };
60
39
 
61
- type SpooshBody<T = unknown> = {
62
- readonly __spooshBody: true;
63
- readonly kind: "form" | "json" | "urlencoded";
64
- readonly value: T;
65
- };
40
+ /**
41
+ * Opaque type representing a transformed body. Create using `form()`, `json()`, or `urlencoded()` helpers.
42
+ * Do not create this type manually - use the helper functions instead.
43
+ *
44
+ * @example
45
+ * ```ts
46
+ * import { form, json, urlencoded } from "@spoosh/core";
47
+ *
48
+ * // Use helpers to create SpooshBody
49
+ * trigger({ body: form({ file: myFile }) });
50
+ * trigger({ body: json({ data: "value" }) });
51
+ * trigger({ body: urlencoded({ key: "value" }) });
52
+ * ```
53
+ */
54
+ declare class SpooshBodyClass<T> {
55
+ private __brand;
56
+ }
57
+ type SpooshBody<T = unknown> = SpooshBodyClass<T>;
66
58
  declare function isSpooshBody(value: unknown): value is SpooshBody;
67
59
  declare function form<T>(value: T): SpooshBody<T>;
68
60
  declare function json<T>(value: T): SpooshBody<T>;
@@ -231,7 +223,7 @@ type CacheEntryWithKey<TData = unknown, TError = unknown> = {
231
223
  declare function createInitialState<TData, TError>(): OperationState<TData, TError>;
232
224
  type StateManager = {
233
225
  createQueryKey: (params: {
234
- path: string[];
226
+ path: string;
235
227
  method: string;
236
228
  options?: unknown;
237
229
  }) => string;
@@ -249,6 +241,8 @@ type StateManager = {
249
241
  getAllCacheEntries: <TData, TError>() => CacheEntryWithKey<TData, TError>[];
250
242
  /** Get the number of cache entries */
251
243
  getSize: () => number;
244
+ /** Get the number of active subscribers for a cache key */
245
+ getSubscribersCount: (key: string) => number;
252
246
  /** Set a pending promise for a query key (for deduplication) */
253
247
  setPendingPromise: (key: string, promise: Promise<unknown> | undefined) => void;
254
248
  /** Get a pending promise for a query key */
@@ -275,9 +269,13 @@ type CacheEntry<TData = unknown, TError = unknown> = {
275
269
  /** Cache was invalidated while no subscriber was listening. Triggers refetch on next mount. */
276
270
  stale?: boolean;
277
271
  };
278
- type PluginContext<TData = unknown, TError = unknown> = {
272
+ /** RequestOptions in plugin context have headers already resolved to Record */
273
+ type PluginRequestOptions = Omit<AnyRequestOptions, "headers"> & {
274
+ headers: Record<string, string>;
275
+ };
276
+ type PluginContext = {
279
277
  readonly operationType: OperationType;
280
- readonly path: string[];
278
+ readonly path: string;
281
279
  readonly method: HttpMethod;
282
280
  readonly queryKey: string;
283
281
  readonly tags: string[];
@@ -285,17 +283,10 @@ type PluginContext<TData = unknown, TError = unknown> = {
285
283
  readonly requestTimestamp: number;
286
284
  /** Unique identifier for the hook instance. Persists across queryKey changes within the same hook. */
287
285
  readonly hookId?: string;
288
- requestOptions: AnyRequestOptions;
289
- state: OperationState<TData, TError>;
290
- response?: SpooshResponse<TData, TError>;
286
+ request: PluginRequestOptions;
291
287
  metadata: Map<string, unknown>;
292
- abort: () => void;
293
288
  stateManager: StateManager;
294
289
  eventEmitter: EventEmitter;
295
- /** Resolved headers as a plain object. Modify via setHeaders(). */
296
- headers: Record<string, string>;
297
- /** Add/update headers. Merges with existing headers. */
298
- setHeaders: (headers: Record<string, string>) => void;
299
290
  /** Access other plugins' exported APIs */
300
291
  plugins: PluginAccessor;
301
292
  /** Plugin-specific options passed from hooks (useRead/useWrite/useInfiniteRead) */
@@ -304,7 +295,7 @@ type PluginContext<TData = unknown, TError = unknown> = {
304
295
  forceRefetch?: boolean;
305
296
  };
306
297
  /** Input type for creating PluginContext (without injected properties) */
307
- type PluginContextInput<TData = unknown, TError = unknown> = Omit<PluginContext<TData, TError>, "plugins" | "setHeaders" | "headers">;
298
+ type PluginContextInput = Omit<PluginContext, "plugins">;
308
299
  /**
309
300
  * Middleware function that wraps the fetch flow.
310
301
  * Plugins use this for full control over request/response handling.
@@ -334,22 +325,22 @@ type PluginContextInput<TData = unknown, TError = unknown> = Omit<PluginContext<
334
325
  * }
335
326
  * ```
336
327
  */
337
- type PluginMiddleware<TData = unknown, TError = unknown> = (context: PluginContext<TData, TError>, next: () => Promise<SpooshResponse<TData, TError>>) => Promise<SpooshResponse<TData, TError>>;
338
- type PluginHandler<TData = unknown, TError = unknown> = (context: PluginContext<TData, TError>) => void | Promise<void>;
339
- type PluginUpdateHandler<TData = unknown, TError = unknown> = (context: PluginContext<TData, TError>, previousContext: PluginContext<TData, TError>) => void | Promise<void>;
328
+ type PluginMiddleware = (context: PluginContext, next: () => Promise<SpooshResponse<any, any>>) => Promise<SpooshResponse<any, any>>;
329
+ type PluginHandler = (context: PluginContext) => void | Promise<void>;
330
+ type PluginUpdateHandler = (context: PluginContext, previousContext: PluginContext) => void | Promise<void>;
340
331
  /**
341
332
  * Handler called after every response, regardless of early returns from middleware.
342
333
  * Can return a new response to transform it, or void for side effects only.
343
334
  * Returned responses are chained through plugins in order.
344
335
  */
345
- type PluginResponseHandler<TData = unknown, TError = unknown> = (context: PluginContext<TData, TError>, response: SpooshResponse<TData, TError>) => SpooshResponse<TData, TError> | void | Promise<SpooshResponse<TData, TError> | void>;
346
- type PluginLifecycle<TData = unknown, TError = unknown> = {
336
+ type PluginResponseHandler = (context: PluginContext, response: SpooshResponse<any, any>) => SpooshResponse<any, any> | void | Promise<SpooshResponse<any, any> | void>;
337
+ type PluginLifecycle = {
347
338
  /** Called on component mount */
348
- onMount?: PluginHandler<TData, TError>;
339
+ onMount?: PluginHandler;
349
340
  /** Called when options/query changes. Receives both new and previous context. */
350
- onUpdate?: PluginUpdateHandler<TData, TError>;
341
+ onUpdate?: PluginUpdateHandler;
351
342
  /** Called on component unmount */
352
- onUnmount?: PluginHandler<TData, TError>;
343
+ onUnmount?: PluginHandler;
353
344
  };
354
345
  /**
355
346
  * Configuration object for plugin type definitions.
@@ -606,8 +597,8 @@ type RefetchEvent = {
606
597
  * Avoids circular dependency with executor.ts.
607
598
  */
608
599
  type InstancePluginExecutor = {
609
- executeMiddleware: <TData, TError>(operationType: OperationType, context: PluginContext<TData, TError>, coreFetch: () => Promise<SpooshResponse<TData, TError>>) => Promise<SpooshResponse<TData, TError>>;
610
- createContext: <TData, TError>(input: PluginContextInput<TData, TError>) => PluginContext<TData, TError>;
600
+ executeMiddleware: <TData, TError>(operationType: OperationType, context: PluginContext, coreFetch: () => Promise<SpooshResponse<any, any>>) => Promise<SpooshResponse<TData, TError>>;
601
+ createContext: (input: PluginContextInput) => PluginContext;
611
602
  };
612
603
  /**
613
604
  * Context provided to plugin's instanceApi function.
@@ -622,14 +613,13 @@ type InstanceApiContext<TApi = unknown> = {
622
613
 
623
614
  type PluginExecutor = {
624
615
  /** Execute lifecycle hooks for onMount or onUnmount */
625
- executeLifecycle: <TData, TError>(phase: "onMount" | "onUnmount", operationType: OperationType, context: PluginContext<TData, TError>) => Promise<void>;
616
+ executeLifecycle: (phase: "onMount" | "onUnmount", operationType: OperationType, context: PluginContext) => Promise<void>;
626
617
  /** Execute onUpdate lifecycle with previous context */
627
- executeUpdateLifecycle: <TData, TError>(operationType: OperationType, context: PluginContext<TData, TError>, previousContext: PluginContext<TData, TError>) => Promise<void>;
628
- /** Execute middleware chain with a core fetch function, then run afterResponse handlers */
629
- executeMiddleware: <TData, TError>(operationType: OperationType, context: PluginContext<TData, TError>, coreFetch: () => Promise<SpooshResponse<TData, TError>>) => Promise<SpooshResponse<TData, TError>>;
618
+ executeUpdateLifecycle: (operationType: OperationType, context: PluginContext, previousContext: PluginContext) => Promise<void>;
619
+ executeMiddleware: (operationType: OperationType, context: PluginContext, coreFetch: () => Promise<SpooshResponse<any, any>>) => Promise<SpooshResponse<any, any>>;
630
620
  getPlugins: () => readonly SpooshPlugin[];
631
621
  /** Creates a full PluginContext with plugins accessor injected */
632
- createContext: <TData, TError>(input: PluginContextInput<TData, TError>) => PluginContext<TData, TError>;
622
+ createContext: (input: PluginContextInput) => PluginContext;
633
623
  };
634
624
  declare function createPluginExecutor(initialPlugins?: SpooshPlugin[]): PluginExecutor;
635
625
 
@@ -1060,7 +1050,7 @@ type PathMethods<TSchema, TPath extends string, TDefaultError> = FindMatchingKey
1060
1050
  */
1061
1051
  type SchemaPaths<TSchema> = keyof TSchema & string;
1062
1052
  /**
1063
- * An API client that uses path strings instead of chained property access.
1053
+ * An API interface that uses path strings instead of chained property access.
1064
1054
  * Methods use HTTP names directly: GET, POST, PUT, PATCH, DELETE.
1065
1055
  *
1066
1056
  * @example
@@ -1091,7 +1081,7 @@ type ReadPathMethods<TSchema, TPath extends string, TDefaultError> = FindMatchin
1091
1081
  GET: MethodFn<TSchema[TKey]["GET"], TDefaultError, TPath>;
1092
1082
  }> : never : never : never;
1093
1083
  /**
1094
- * A read-only API client that only exposes GET methods.
1084
+ * A read-only API interface that only exposes GET methods.
1095
1085
  * Used by useRead and injectRead hooks.
1096
1086
  */
1097
1087
  type ReadClient<TSchema, TDefaultError = unknown> = <TPath extends ReadPaths<TSchema> | (string & {})>(path: TPath) => HasReadMethod<TSchema, TPath> extends true ? ReadPathMethods<TSchema, TPath, TDefaultError> : never;
@@ -1103,7 +1093,7 @@ type WritePathMethods<TSchema, TPath extends string, TDefaultError> = FindMatchi
1103
1093
  [M in WriteMethod as M extends keyof TSchema[TKey] ? M : never]: M extends keyof TSchema[TKey] ? MethodFn<TSchema[TKey][M], TDefaultError, TPath> : never;
1104
1094
  }> : never : never;
1105
1095
  /**
1106
- * A write-only API client that only exposes mutation methods (POST, PUT, PATCH, DELETE).
1096
+ * A write-only API interface that only exposes mutation methods (POST, PUT, PATCH, DELETE).
1107
1097
  * Used by useWrite and injectWrite hooks.
1108
1098
  */
1109
1099
  type WriteClient<TSchema, TDefaultError = unknown> = <TPath extends WritePaths<TSchema> | (string & {})>(path: TPath) => HasWriteMethod<TSchema, TPath> extends true ? WritePathMethods<TSchema, TPath, TDefaultError> : never;
@@ -1246,7 +1236,7 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1246
1236
  */
1247
1237
  private getInstance;
1248
1238
  /**
1249
- * The type-safe API client for making requests.
1239
+ * The type-safe API interface for making requests.
1250
1240
  *
1251
1241
  * Provides a proxy-based interface for accessing endpoints defined in your schema.
1252
1242
  *
@@ -1346,19 +1336,15 @@ declare class Spoosh<TSchema = unknown, TError = unknown, TPlugins extends Plugi
1346
1336
  };
1347
1337
  }
1348
1338
 
1349
- type SpooshClientConfig = {
1350
- baseUrl: string;
1351
- defaultOptions?: SpooshOptionsInput;
1352
- middlewares?: SpooshMiddleware[];
1353
- };
1354
1339
  /**
1355
- * Creates a lightweight type-safe API client for vanilla JavaScript/TypeScript usage.
1340
+ * Creates a lightweight type-safe API instance for vanilla JavaScript/TypeScript usage.
1356
1341
  *
1357
1342
  * This is a simpler alternative to `Spoosh` for users who don't need
1358
1343
  * the full plugin system, state management, or React integration.
1359
1344
  *
1360
- * @param config - Client configuration
1361
- * @returns Type-safe API client
1345
+ * @param baseUrl - Base URL for all API requests
1346
+ * @param defaultOptions - Default fetch options (headers, credentials, etc.)
1347
+ * @returns Type-safe API instance
1362
1348
  *
1363
1349
  * @example
1364
1350
  * ```ts
@@ -1378,23 +1364,21 @@ type SpooshClientConfig = {
1378
1364
  * message: string;
1379
1365
  * }
1380
1366
  *
1381
- * const api = createClient<ApiSchema, ApiError>({
1382
- * baseUrl: "/api",
1383
- * });
1367
+ * const api = createClient<ApiSchema, ApiError>("/api");
1384
1368
  *
1385
1369
  * // Type-safe API calls with path strings
1386
1370
  * const { data } = await api("posts").GET();
1387
1371
  * const { data: post } = await api("posts/123").GET();
1388
1372
  * await api("posts/:id").GET({ params: { id: 123 } });
1389
1373
  *
1390
- * // With XHR transport
1391
- * const api = createClient<ApiSchema, ApiError>({
1392
- * baseUrl: "/api",
1393
- * defaultOptions: { transport: "xhr" },
1374
+ * // With custom options
1375
+ * const api = createClient<ApiSchema, ApiError>("/api", {
1376
+ * headers: { Authorization: "Bearer token" },
1377
+ * transport: "xhr",
1394
1378
  * });
1395
1379
  * ```
1396
1380
  */
1397
- declare function createClient<TSchema, TDefaultError = unknown>(config: SpooshClientConfig): SpooshClient<TSchema, TDefaultError>;
1381
+ declare function createClient<TSchema, TDefaultError = unknown>(baseUrl: string, defaultOptions?: SpooshOptionsInput): SpooshClient<TSchema, TDefaultError>;
1398
1382
 
1399
1383
  declare function buildUrl(baseUrl: string, path: string[], query?: Record<string, string | number | boolean | undefined>): string;
1400
1384
 
@@ -1456,7 +1440,7 @@ type ProxyHandlerConfig<TOptions = SpooshOptions> = {
1456
1440
  nextTags?: boolean;
1457
1441
  };
1458
1442
  /**
1459
- * Creates an API client proxy that uses path strings instead of chained property access.
1443
+ * Creates an API proxy that uses path strings instead of chained property access.
1460
1444
  * Methods use HTTP names directly: GET, POST, PUT, PATCH, DELETE.
1461
1445
  *
1462
1446
  * @param config - Proxy handler configuration
@@ -1474,7 +1458,7 @@ type ProxyHandlerConfig<TOptions = SpooshOptions> = {
1474
1458
  */
1475
1459
  declare function createProxyHandler<TSchema, TDefaultError = unknown, TOptions = SpooshOptions>(config: ProxyHandlerConfig<TOptions>): SpooshClient<TSchema, TDefaultError>;
1476
1460
 
1477
- /** All supported HTTP method keys used in the API client */
1461
+ /** All supported HTTP method keys used in the API toolkit */
1478
1462
  declare const HTTP_METHODS: readonly ["GET", "POST", "PUT", "PATCH", "DELETE"];
1479
1463
  /** Union type of all HTTP method keys */
1480
1464
  type HttpMethodKey = (typeof HTTP_METHODS)[number];
@@ -1593,11 +1577,7 @@ declare module "./types" {
1593
1577
  }
1594
1578
  declare const xhrTransport: Transport<XhrTransportOptions>;
1595
1579
 
1596
- declare function executeFetch<TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: SpooshOptions & SpooshOptionsExtra, requestOptions?: AnyRequestOptions, nextTags?: boolean): Promise<SpooshResponse<TData, TError>>;
1597
-
1598
- declare function createMiddleware<TData = unknown, TError = unknown>(name: string, phase: MiddlewarePhase, handler: SpooshMiddleware<TData, TError>["handler"]): SpooshMiddleware<TData, TError>;
1599
- declare function applyMiddlewares<TData = unknown, TError = unknown>(context: MiddlewareContext<TData, TError>, middlewares: SpooshMiddleware<TData, TError>[], phase: MiddlewarePhase): Promise<MiddlewareContext<TData, TError>>;
1600
- declare function composeMiddlewares<TData = unknown, TError = unknown>(...middlewareLists: (SpooshMiddleware<TData, TError>[] | undefined)[]): SpooshMiddleware<TData, TError>[];
1580
+ declare function executeFetch<TData, TError>(baseUrl: string, path: string[], method: HttpMethod, defaultOptions: SpooshOptions, requestOptions?: AnyRequestOptions, nextTags?: boolean): Promise<SpooshResponse<TData, TError>>;
1601
1581
 
1602
1582
  type ExecuteOptions = {
1603
1583
  force?: boolean;
@@ -1613,15 +1593,15 @@ type OperationController<TData = unknown, TError = unknown> = {
1613
1593
  /** Called once when hook finally unmounts */
1614
1594
  unmount: () => void;
1615
1595
  /** Called when options/query changes. Pass previous context for cleanup. */
1616
- update: (previousContext: PluginContext<TData, TError>) => void;
1596
+ update: (previousContext: PluginContext) => void;
1617
1597
  /** Get current context (for passing to update as previousContext) */
1618
- getContext: () => PluginContext<TData, TError>;
1598
+ getContext: () => PluginContext;
1619
1599
  setPluginOptions: (options: unknown) => void;
1620
1600
  setMetadata: (key: string, value: unknown) => void;
1621
1601
  };
1622
1602
  type CreateOperationOptions<TData, TError> = {
1623
1603
  operationType: OperationType;
1624
- path: string[];
1604
+ path: string;
1625
1605
  method: HttpMethod;
1626
1606
  tags: string[];
1627
1607
  requestOptions?: AnyRequestOptions;
@@ -1663,12 +1643,12 @@ type InfiniteReadController<TData, TItem, TError> = {
1663
1643
  abort: () => void;
1664
1644
  mount: () => void;
1665
1645
  unmount: () => void;
1666
- update: (previousContext: PluginContext<TData, TError>) => void;
1667
- getContext: () => PluginContext<TData, TError>;
1646
+ update: (previousContext: PluginContext) => void;
1647
+ getContext: () => PluginContext;
1668
1648
  setPluginOptions: (options: unknown) => void;
1669
1649
  };
1670
1650
  type CreateInfiniteReadOptions<TData, TItem, TError, TRequest> = {
1671
- path: string[];
1651
+ path: string;
1672
1652
  method: HttpMethod;
1673
1653
  tags: string[];
1674
1654
  initialRequest: InfiniteRequestOptions;
@@ -1687,4 +1667,4 @@ type CreateInfiniteReadOptions<TData, TItem, TError, TRequest> = {
1687
1667
  };
1688
1668
  declare function createInfiniteReadController<TData, TItem, TError, TRequest extends InfiniteRequestOptions = InfiniteRequestOptions>(options: CreateInfiniteReadOptions<TData, TItem, TError, TRequest>): InfiniteReadController<TData, TItem, TError>;
1689
1669
 
1690
- export { type AnyRequestOptions, type ApiSchema, type BuiltInEvents, type CacheEntry, type CacheEntryWithKey, type CapturedCall, type SpooshClientConfig as ClientConfig, 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 MiddlewareContext, type MiddlewareHandler, type MiddlewarePhase, 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 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 RetryConfig, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshMiddleware, type SpooshOptions, type SpooshOptionsExtra, type SpooshOptionsInput, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StateManager, type StripPrefix, type TagMode, type TagOptions, type Transport, type TransportOption, type TransportOptionsMap, type TransportResponse, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, applyMiddlewares, buildUrl, composeMiddlewares, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createMiddleware, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, fetchTransport, form, generateTags, getContentType, isJsonBody, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveTags, setHeaders, sortObjectKeys, urlencoded, xhrTransport };
1670
+ 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 RetryConfig, type SchemaPaths, type SelectedEndpoint, type SelectorFunction, type SelectorResult, type Simplify, Spoosh, type SpooshBody, type SpooshClient, type SpooshConfig, type SpooshInstance, type SpooshOptions, type SpooshOptionsInput, type SpooshPlugin, type SpooshResponse, type SpooshSchema, type StateManager, type StripPrefix, type TagMode, type TagOptions, type Transport, type TransportOption, type TransportOptionsMap, type TransportResponse, type WriteClient, type WriteMethod, type WritePaths, type WriteSchemaHelper, __DEV__, buildUrl, containsFile, createClient, createEventEmitter, createInfiniteReadController, createInitialState, createOperationController, createPluginExecutor, createPluginRegistry, createProxyHandler, createSelectorProxy, createStateManager, executeFetch, extractMethodFromSelector, extractPathFromSelector, fetchTransport, form, generateTags, getContentType, isJsonBody, isSpooshBody, json, mergeHeaders, objectToFormData, objectToUrlEncoded, resolveHeadersToRecord, resolvePath, resolveRequestBody, resolveTags, setHeaders, sortObjectKeys, urlencoded, xhrTransport };