@brickflow/http 0.0.14 → 0.0.15

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (39) hide show
  1. package/README.md +296 -277
  2. package/dist/http.d.ts +61 -0
  3. package/dist/http.d.ts.map +1 -0
  4. package/dist/index.d.ts +3 -0
  5. package/dist/index.d.ts.map +1 -0
  6. package/dist/index.mjs +144 -0
  7. package/dist/index.mjs.map +1 -0
  8. package/dist/nuxt.d.ts +72 -0
  9. package/dist/nuxt.d.ts.map +1 -0
  10. package/dist/nuxt.mjs +222 -0
  11. package/dist/nuxt.mjs.map +1 -0
  12. package/dist/utils-DMSINHi5.js +39 -0
  13. package/dist/utils-DMSINHi5.js.map +1 -0
  14. package/dist/utils.d.ts +5 -0
  15. package/dist/utils.d.ts.map +1 -0
  16. package/package.json +27 -16
  17. package/dist/module.d.mts +0 -73
  18. package/dist/module.json +0 -12
  19. package/dist/module.mjs +0 -59
  20. package/dist/runtime/composables/useHttp.d.ts +0 -27
  21. package/dist/runtime/composables/useHttp.js +0 -197
  22. package/dist/runtime/http/client.d.ts +0 -3
  23. package/dist/runtime/http/client.js +0 -217
  24. package/dist/runtime/plugin.d.ts +0 -7
  25. package/dist/runtime/plugin.js +0 -56
  26. package/dist/runtime/types.d.ts +0 -21
  27. package/dist/runtime/utils/helpers.d.ts +0 -5
  28. package/dist/runtime/utils/helpers.js +0 -14
  29. package/dist/runtime/utils/index.d.ts +0 -6
  30. package/dist/runtime/utils/index.js +0 -5
  31. package/dist/runtime/utils/indexeddb.d.ts +0 -14
  32. package/dist/runtime/utils/indexeddb.js +0 -222
  33. package/dist/runtime/utils/middleware.d.ts +0 -8
  34. package/dist/runtime/utils/middleware.js +0 -20
  35. package/dist/runtime/utils/shared.d.ts +0 -83
  36. package/dist/runtime/utils/shared.js +0 -50
  37. package/dist/runtime/utils/typed.d.ts +0 -46
  38. package/dist/runtime/utils/typed.js +0 -9
  39. package/dist/types.d.mts +0 -11
package/README.md CHANGED
@@ -1,406 +1,425 @@
1
- # `@brickflow/http`
1
+ # @brickflow/http
2
2
 
3
- Nuxt HTTP module and typed client with:
3
+ Minimal HTTP package used in this repo for:
4
4
 
5
- - `NuxtApp.$http`
6
- - `useHttp()` auto-import
7
- - request/response middleware
8
- - retry and timeout support
9
- - optional client cache via IndexedDB
10
- - typed URL literals for `get`, `post`, and `useHttp`
5
+ - low-level HTTP transport via `createHttp`
6
+ - Nuxt async state wrapper via `createUseHttp`
7
+ - reusable endpoint factory via `createGet`
8
+ - project-level typing through `declare module '@brickflow/http'`
11
9
 
12
- ## Install
10
+ This package does not know your API schema by default. The schema and error type are configured in the consumer project through `type.d.ts`.
13
11
 
14
- ```bash
15
- pnpm add @brickflow/http
16
- ```
12
+ ## Exports
13
+
14
+ From `@brickflow/http`:
15
+
16
+ - `createHttp`
17
+ - `createURL`
18
+ - `hashData`
19
+ - HTTP types: `HttpClient`, `HttpError`, `HttpKey`, `HttpParam`, `HttpResponse`, `HttpResponseData`, `HttpSuccessData`
17
20
 
18
- ## Nuxt Setup
21
+ From `@brickflow/http/nuxt`:
22
+
23
+ - `createUseHttp`
24
+ - `createGet`
25
+ - Nuxt types: `UseHttpOptions`, `UseHttpResult`, `UseHttpFn`
26
+
27
+ ## 1. Configure API types in `type.d.ts`
28
+
29
+ In this repo the typing is configured in `types/http.d.ts`.
19
30
 
20
31
  ```ts
21
- export default defineNuxtConfig({
22
- modules: ['@brickflow/http'],
23
- })
32
+ import type { Convention, ConventionKeys } from 'convention'
33
+
34
+ type BrickHttpError = Exclude<Convention<ConventionKeys>, { status: 'success' }>
35
+ type BrickHttpSchema = {
36
+ [TKey in ConventionKeys]: Convention<TKey>
37
+ }
38
+
39
+ declare module '@brickflow/http' {
40
+ interface HttpTypeConfig {
41
+ endpoints: BrickHttpSchema
42
+ error: BrickHttpError
43
+ }
44
+ }
24
45
  ```
25
46
 
26
- With options:
47
+ What this gives:
48
+
49
+ - `HttpKey` becomes your endpoint union
50
+ - `HttpResponseData<'some/endpoint'>` becomes the response type for that endpoint
51
+ - `HttpSuccessData<'some/endpoint'>` becomes response without the configured error branch
52
+ - `UseHttpResult<T, P>['error']` is inferred from `HttpTypeConfig['error']`
53
+
54
+ This is the main place where project typing should live.
55
+
56
+ ## 2. Create low-level HTTP client
57
+
58
+ Real usage from `plugins/01.di.ts`:
27
59
 
28
60
  ```ts
29
- export default defineNuxtConfig({
30
- modules: ['@brickflow/http'],
31
- brickflowHttp: {
32
- baseURL: 'https://api.example.com',
33
- cache: true,
34
- cacheDbName: 'smart-cache-v2',
35
- cacheStoreName: 'data',
36
- cacheTtlMs: 1000 * 60 * 60 * 24 * 7,
37
- clientEnvHeader: true,
38
- defaultHeaders: {
39
- 'X-App-Version': '1.0.0',
40
- },
41
- disableCacheInDev: true,
42
- requestTimeoutMs: 80000,
43
- retry: {
44
- delay: 300,
45
- retries: 3,
46
- },
47
- },
61
+ import { createHttp } from '@brickflow/http'
62
+
63
+ const httpClient = createHttp({
64
+ baseURL: apiUrl,
65
+ headers: () => ({
66
+ 'Client-Env': config.public.isDev ? 'development' : undefined,
67
+ 'Client-Lang': String(locale.value ?? 'en'),
68
+ 'Client-Socket-Id': socketClient?.io.id || '',
69
+ 'X-Requested-With': 'XMLHttpRequest',
70
+ }),
71
+ onResponseError: responseInterceptor,
48
72
  })
49
73
  ```
50
74
 
51
- ## Defaults
75
+ Available options:
52
76
 
53
- `brickflowHttp` defaults:
77
+ - `baseURL`
78
+ - `fetch`
79
+ - `headers`
80
+ - `onResponseError`
81
+ - `requestInit`
82
+ - `timeout`
54
83
 
55
- | Option | Default |
56
- | ------------------- | ------------------ |
57
- | `baseURL` | `''` |
58
- | `cache` | `true` |
59
- | `cacheDbName` | `'smart-cache-v2'` |
60
- | `cacheStoreName` | `'data'` |
61
- | `cacheTtlMs` | `604800000` |
62
- | `clientEnvHeader` | `true` |
63
- | `defaultHeaders` | `{}` |
64
- | `disableCacheInDev` | `true` |
65
- | `requestTimeoutMs` | `80000` |
66
- | `retry.delay` | `300` |
67
- | `retry.retries` | `3` |
84
+ `createHttp` returns:
68
85
 
69
- Runtime behavior:
86
+ ```ts
87
+ interface HttpClient {
88
+ get(url, config?)
89
+ post(url, data?, config?)
90
+ }
91
+ ```
70
92
 
71
- - `X-Requested-With: XMLHttpRequest` is added automatically
72
- - in dev, `Client-Env: development` is added when `clientEnvHeader` is enabled
73
- - `5xx` and `451` responses with `{ status: 'error' }` trigger Nuxt `showError()`
93
+ ## 3. Use `HttpClient` directly
74
94
 
75
- ## Basic Usage
95
+ Used in domain methods that do not need cached async state.
76
96
 
77
- Use `$http` in components, composables, or plugins:
97
+ Example from `domains/content/use-case.ts`:
78
98
 
79
99
  ```ts
80
- const { $http } = useNuxtApp()
81
-
82
- const response = await $http.get<{ id: string; name: string }>('/user', {
83
- params: {
84
- id: '42',
85
- },
86
- })
100
+ async create(title: string, type: string, description?: string) {
101
+ const { data } = await httpClient.post('content/create', {
102
+ description,
103
+ title,
104
+ type,
105
+ })
87
106
 
88
- if ('status' in response.data && response.data.status === 'error') {
89
- console.error(response.data.message)
90
- } else {
91
- console.log(response.data.name)
107
+ return data
92
108
  }
93
109
  ```
94
110
 
95
- POST:
111
+ Another example:
96
112
 
97
113
  ```ts
98
- const { $http } = useNuxtApp()
114
+ async updateType(itemId: string, type: string) {
115
+ const { data } = await httpClient.post('content/update-type', {
116
+ itemId,
117
+ type,
118
+ })
99
119
 
100
- const response = await $http.post<{ ok: true }>(
101
- '/posts',
102
- {
103
- title: 'Hello',
104
- },
105
- {
106
- params: {
107
- draft: true,
108
- },
109
- },
110
- )
120
+ return data
121
+ }
111
122
  ```
112
123
 
113
- ## `useHttp()`
124
+ Use this style when:
114
125
 
115
- `useHttp()` is auto-imported and returns:
126
+ - request is one-shot
127
+ - you do not need `pending`, `hasFirstData`, cache, SSR sync, or `fetch()`
116
128
 
117
- - `data`
118
- - `error`
119
- - `pending`
120
- - `pendingCache`
121
- - `hasFirstData`
122
- - `hasFreshData`
123
- - `fetch()`
129
+ ## 4. Create Nuxt `useHttp`
124
130
 
125
- Basic example:
131
+ In this repo the app-level `useHttp` is created once in `core/util.ts`:
126
132
 
127
133
  ```ts
128
- const users = await useHttp<Array<{ id: string; name: string }>>({
129
- server: true,
130
- url: '/users',
134
+ import { createUseHttp } from '@brickflow/http/nuxt'
135
+
136
+ const useHttp = createUseHttp({
137
+ getCache: () => ({
138
+ deleteKeysWithPart: async (part) => await dbDeleteKeysWithPart(part, 'smart-cache-v2', STORE_NAME),
139
+ get: async (key) => await dbGet(key, 'smart-cache-v2', STORE_NAME),
140
+ set: async (key, value, ttl) => await dbSafeSet(key, value, 'smart-cache-v2', STORE_NAME, ttl),
141
+ }),
142
+ getHttpClient: () => useNuxtApp().$http,
143
+ isDev: () => useRuntimeConfig().public.isDev,
131
144
  })
132
145
  ```
133
146
 
134
- With params:
147
+ Dependencies:
135
148
 
136
- ```ts
137
- const users = await useHttp<Array<{ id: string; name: string }>, { page: number }>({
138
- initParams: {
139
- page: 1,
140
- },
141
- url: '/users',
142
- })
149
+ - `getHttpClient`
150
+ - `getCache`
151
+ - `isError`
152
+ - `isDev`
153
+ - `ttl`
154
+ - `channelName`
143
155
 
144
- await users.fetch({
145
- page: 2,
146
- })
147
- ```
156
+ `isError` can be set globally here if your project needs a custom runtime error predicate.
157
+
158
+ ## 5. Bind `createGet` once
148
159
 
149
- With side effects:
160
+ The package exports `createGet(useHttp)`, which builds typed endpoint helpers on top of your local `useHttp`.
161
+
162
+ Real usage from `core/util.ts`:
150
163
 
151
164
  ```ts
152
- const profile = await useHttp<{ id: string; name: string }>({
153
- effect(payload, { cached }) {
154
- if (!cached) {
155
- console.log('fresh profile payload', payload)
156
- }
157
- },
158
- url: '/profile',
159
- })
165
+ import { createGet as createHttpGet, createUseHttp } from '@brickflow/http/nuxt'
166
+
167
+ const useHttp = createUseHttp({ ... })
168
+
169
+ export const createGet = createHttpGet(useHttp)
160
170
  ```
161
171
 
162
- ## Typed Routes
172
+ After that you can reuse `createGet` in domain files.
173
+
174
+ ## 6. Create typed GET endpoints
163
175
 
164
- If you want `'/users'` and other URL literals to infer `params`, `data`, `error`, and `body` automatically, extend the global `BrickflowHttpRouteMap`.
176
+ ### Without params
165
177
 
166
- Create a declaration file, for example `types/brickflow-http.d.ts`:
178
+ Example from `domains/storage/use-case.ts`:
167
179
 
168
180
  ```ts
169
- import type { HttpErrorPayload } from '@brickflow/http'
170
-
171
- declare global {
172
- interface BrickflowHttpRouteMap {
173
- '/api/user': {
174
- data: { id: string; name: string }
175
- error: HttpErrorPayload & { code?: 'NOT_FOUND' }
176
- params: { id: string }
177
- }
178
- '/api/posts': {
179
- data: Array<{ id: string; title: string }>
180
- params: { page?: number }
181
- }
182
- '/api/posts/create': {
183
- body: { title: string }
184
- data: { id: string }
185
- }
186
- }
187
- }
181
+ plans: createGet()('storage/plans')
182
+ ```
183
+
184
+ ### With params
185
+
186
+ Example from `domains/feed/use-case.ts`:
188
187
 
189
- export {}
188
+ ```ts
189
+ home: createGet<{
190
+ category?: 'fresh' | 'popular' | 'recommended' | 'updated'
191
+ limit: number
192
+ offset: number
193
+ }>()('feed/home')
190
194
  ```
191
195
 
192
- After that, `$http` and `useHttp()` infer types from the URL literal automatically.
196
+ ### With `ignore`
193
197
 
194
- Typed `get`:
198
+ Example from `domains/content/use-case.ts`:
195
199
 
196
200
  ```ts
197
- const { $http } = useNuxtApp()
201
+ analytics: createGet<{
202
+ itemId: string
203
+ period: '7d' | '28d' | '90d'
204
+ }>()('content/analytics', {
205
+ ignore(res) {
206
+ if (res.data.kind === 'no_auth') {
207
+ return true
208
+ }
198
209
 
199
- const response = await $http.get('/api/user', {
200
- params: {
201
- id: '42',
210
+ return false
202
211
  },
203
212
  })
204
213
  ```
205
214
 
206
- Typed `post`:
215
+ ### With `effect`
216
+
217
+ Example from `domains/root/use-case.ts`:
207
218
 
208
219
  ```ts
209
- const { $http } = useNuxtApp()
220
+ main: createGet()('root/main', {
221
+ effect(data, config) {
222
+ if (data.status === 'error') {
223
+ return
224
+ }
210
225
 
211
- await $http.post('/api/posts/create', {
212
- title: 'New post',
226
+ if (!config.cached) {
227
+ userStore.setUser(data.user)
228
+ userStore.setRegion(data.region)
229
+ }
230
+ },
213
231
  })
214
232
  ```
215
233
 
216
- Typed `useHttp` without generics:
234
+ ### With `effect` and success handling
235
+
236
+ Example from `domains/storage/use-case.ts`:
217
237
 
218
238
  ```ts
219
- const posts = await useHttp({
220
- initParams: {
221
- page: 1,
239
+ current: createGet()('storage/current', {
240
+ effect(data) {
241
+ if (data.status === 'success') {
242
+ storageStore.setCurrentPlan(data.plan)
243
+ }
222
244
  },
223
- url: '/api/posts',
224
- })
225
-
226
- await posts.fetch({
227
- page: 2,
228
245
  })
229
246
  ```
230
247
 
231
- ## Strict Client
248
+ ## 7. Consume endpoint state in components
232
249
 
233
- `$http` keeps a fallback overload for plain `string`, so unknown URLs are still allowed.
250
+ ### Create request object
234
251
 
235
- If you want to forbid unknown URLs completely:
252
+ Example from `components/Search/index.vue`:
236
253
 
237
254
  ```ts
238
- import { createStrictHttpClient } from '@brickflow/http'
255
+ const searchFastHttp = await app.$di.search.fast({
256
+ lazy: true,
257
+ server: false,
258
+ })
259
+ ```
239
260
 
240
- const { $http } = useNuxtApp()
241
- const strictHttp = createStrictHttpClient($http)
261
+ ### Trigger fetch manually
242
262
 
243
- await strictHttp.get('/api/user', {
244
- params: { id: '42' },
263
+ ```ts
264
+ await searchFastHttp.fetch({
265
+ text: searchQuery.value,
245
266
  })
246
-
247
- // TypeScript error
248
- await strictHttp.get('/api/unknown')
249
267
  ```
250
268
 
251
- If you want typed overloads on a standalone client while keeping the plain `string` fallback:
269
+ ### Read `data`
252
270
 
253
271
  ```ts
254
- import { createHttpClient, createTypedHttpClient } from '@brickflow/http'
272
+ const data = searchFastHttp.data
255
273
 
256
- const http = createTypedHttpClient(
257
- createHttpClient({
258
- baseURL: 'https://api.example.com',
259
- }),
260
- )
274
+ if (data?.status === 'success') {
275
+ items.value = data.items
276
+ users.value = data.users
277
+ }
261
278
  ```
262
279
 
263
- ## Dynamic Base URL
280
+ ### Read loading flags
264
281
 
265
- Standalone client supports a dynamic resolver:
282
+ Example from `components/ProfileMyGrid/index.vue`:
266
283
 
267
- ```ts
268
- const tenantStore = useTenantStore()
284
+ ```vue
285
+ :loading="myContentHttp.pending || myContentHttp.pendingCache"
286
+ ```
269
287
 
270
- const http = createHttpClient({
271
- baseURL: () => tenantStore.apiBaseUrl,
272
- })
288
+ ### Use `hasFirstData`
289
+
290
+ ```vue
291
+ v-if="!myContentHttp.pending && myContentHttp.hasFirstData && items.length === 0"
273
292
  ```
274
293
 
275
- In Nuxt, the better option is request middleware, because it works for both `$http` and `useHttp()`:
294
+ ## 8. `effect` semantics
276
295
 
277
- ```ts
278
- import { addHttpRequestMiddleware } from '@brickflow/http'
296
+ `effect` receives the full response payload.
279
297
 
280
- export default defineNuxtPlugin(() => {
281
- const apiBaseUrl = useState('api-base-url', () => 'https://dummyjson.com')
298
+ That means:
282
299
 
283
- addHttpRequestMiddleware((request) => {
284
- if (request.url.startsWith('/products') || request.url.startsWith('/test')) {
285
- request.baseURL = apiBaseUrl.value
300
+ - it is called for success
301
+ - it is called for error
302
+ - you can branch on `data.status`
303
+ - `config.cached` tells whether the payload came from cache
304
+ - `config.params` contains mapped params used for the request
305
+
306
+ Example from `pages/profile/[username].vue`:
307
+
308
+ ```ts
309
+ const profileHttp = await app.$di.profile.info({
310
+ effect(data) {
311
+ if (data.status === 'error' && data.kind === 'not_found') {
312
+ showError(createError({
313
+ fatal: true,
314
+ statusCode: 404,
315
+ statusMessage: 'Page Not Found',
316
+ }))
286
317
  }
287
- })
318
+ },
319
+ initParams: {
320
+ username: String(profileParam.value),
321
+ },
322
+ server: true,
288
323
  })
289
324
  ```
290
325
 
291
- Then the same request code can stay relative:
326
+ ## 9. `data` and `error`
292
327
 
293
- ```ts
294
- const products = await useHttp({
295
- url: '/products',
296
- })
328
+ `UseHttpResult<T, P>` is split like this:
297
329
 
298
- const { $http } = useNuxtApp()
299
- await $http.get('/test')
300
- ```
330
+ - `data`: success payload only
331
+ - `error`: configured project error payload only
301
332
 
302
- The playground app contains a live example that switches the same typed requests between:
333
+ Internally the split is done by runtime error predicate:
303
334
 
304
- - direct `https://dummyjson.com`
305
- - local proxy `/api/dummyjson`
335
+ - global `isError` from `createUseHttp(...)`
336
+ - or per-request `isError`
337
+ - fallback: `payload.status === 'error'`
306
338
 
307
- See:
339
+ Important:
308
340
 
309
- - [apps/playground/app/pages/index.vue](/Users/andrii/Lab/personal/brickme/apps/playground/app/pages/index.vue:1)
310
- - [apps/playground/app/plugins/http-middleware.ts](/Users/andrii/Lab/personal/brickme/apps/playground/app/plugins/http-middleware.ts:1)
341
+ - runtime error predicate does not reconfigure TypeScript types
342
+ - TypeScript error type comes from `declare module '@brickflow/http'`
311
343
 
312
- ## Global Middleware
344
+ ## 10. Supported request options
313
345
 
314
- Register middleware once and it will run for every request or response:
346
+ For `useHttp` / `createGet`:
315
347
 
316
- ```ts
317
- import { addHttpRequestMiddleware, addHttpResponseMiddleware } from '@brickflow/http'
348
+ - `url`
349
+ - `initParams`
350
+ - `mapParams`
351
+ - `effect`
352
+ - `ignore`
353
+ - `isError`
354
+ - `lazy`
355
+ - `server`
318
356
 
319
- export default defineNuxtPlugin(() => {
320
- addHttpRequestMiddleware((request) => {
321
- request.headers.set('X-App-Version', '1.0.0')
322
- })
357
+ Example with `initParams`:
323
358
 
324
- addHttpResponseMiddleware((response, request) => {
325
- if (response.status >= 500) {
326
- console.error('HTTP error', request.url, response.status)
327
- }
328
- })
359
+ ```ts
360
+ const myContentHttp = await app.$di.content.my({
361
+ initParams: {
362
+ limit: props.limit,
363
+ offset: 0,
364
+ order: selectedOrder.value,
365
+ orderColumn: 'date',
366
+ type: selectedType.value,
367
+ },
329
368
  })
330
369
  ```
331
370
 
332
- Request middleware can mutate:
371
+ Example with `fetch(...)` overriding params:
333
372
 
334
- - `baseURL`
335
- - `url`
336
- - `method`
337
- - `headers`
338
- - `body`
339
- - `params`
340
- - `signal`
341
- - `credentials`
373
+ ```ts
374
+ await myContentHttp.fetch({
375
+ limit: props.limit,
376
+ offset,
377
+ order: selectedOrder.value,
378
+ orderColumn: 'date',
379
+ type: selectedType.value,
380
+ })
381
+ ```
342
382
 
343
- Response middleware receives:
383
+ ## 11. Cache behavior
344
384
 
345
- - `response`
346
- - `request`
385
+ When `getCache` is provided, `createUseHttp`:
347
386
 
348
- You can remove middleware later:
387
+ - tries cached value first
388
+ - calls `effect(..., { cached: true })` for cached payload
389
+ - then performs fresh request
390
+ - stores success response in cache
391
+ - invalidates related keys when response hash changes
349
392
 
350
- ```ts
351
- import { addHttpRequestMiddleware, removeHttpRequestMiddleware } from '@brickflow/http'
393
+ In this repo the cache is backed by IndexedDB in `core/util.ts`.
352
394
 
353
- const middleware = (request: Parameters<typeof addHttpRequestMiddleware>[0]) => {
354
- request.headers.set('X-Debug', '1')
355
- }
395
+ ## 12. URL and hash helpers
396
+
397
+ The package also exports helpers used by the current implementation:
356
398
 
357
- addHttpRequestMiddleware(middleware)
358
- removeHttpRequestMiddleware(middleware)
399
+ ```ts
400
+ import { createURL, hashData } from '@brickflow/http'
359
401
  ```
360
402
 
361
- ## Standalone Client
403
+ `createURL(url, params)` builds query strings.
362
404
 
363
- You can use the client outside Nuxt injection:
405
+ `hashData(data)` computes response hash for cache invalidation.
364
406
 
365
- ```ts
366
- import { createHttpClient } from '@brickflow/http'
367
-
368
- const http = createHttpClient({
369
- baseURL: 'https://api.example.com',
370
- requestTimeoutMs: 10000,
371
- retry: {
372
- delay: 250,
373
- retries: 2,
374
- },
375
- })
407
+ ## 13. Recommended usage in this repo
376
408
 
377
- const response = await http.get<{ ok: true }>('/health')
378
- ```
409
+ Use `createHttp` when:
379
410
 
380
- With custom headers:
411
+ - you need direct `get/post`
412
+ - you are writing mutations or one-shot calls
381
413
 
382
- ```ts
383
- const http = createHttpClient({
384
- baseURL: async () => `https://${tenant.value}.api.example.com`,
385
- createHeaders: async () => {
386
- return {
387
- Authorization: `Bearer ${token}`,
388
- }
389
- },
390
- })
391
- ```
414
+ Use `createUseHttp` + `createGet` when:
392
415
 
393
- ## Exports
416
+ - you need SSR-aware async state
417
+ - you need `pending`, `pendingCache`, `hasFirstData`, `hasFreshData`
418
+ - you need cache integration
419
+ - you want reusable typed endpoint factories in domain modules
420
+
421
+ Use `type.d.ts` when:
394
422
 
395
- Main exports:
396
-
397
- - default Nuxt module
398
- - `createHttpClient`
399
- - `createTypedHttpClient`
400
- - `createStrictHttpClient`
401
- - `defineHttpRoutes`
402
- - `addHttpRequestMiddleware`
403
- - `addHttpResponseMiddleware`
404
- - `removeHttpRequestMiddleware`
405
- - `removeHttpResponseMiddleware`
406
- - public TypeScript types for client, config, middleware, payloads, and typed route maps
423
+ - you want to define endpoint keys
424
+ - you want to define the project-wide error type
425
+ - you want all consumers to infer the same API schema