@brickflow/http 0.0.56 → 0.0.58

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
@@ -206,6 +206,7 @@ export const createGet = defineGet(useHttp)
206
206
 
207
207
  - `url`
208
208
  - `initParams`
209
+ - `config` — расширенный `HttpConfig` (например, `ignore`) и `retry`, уходит в `httpClient.get`
209
210
  - `effect`
210
211
  - `isError`
211
212
  - `lazy`
@@ -320,10 +321,23 @@ const productsHttp = await products({
320
321
  })
321
322
  ```
322
323
 
323
- Если `effect` или `isError` указаны и при объявлении, и при вызове, пакет объединяет их так:
324
+ Если `effect`, `isError` или `config` указаны и при объявлении, и при вызове, пакет объединяет их так:
324
325
 
325
326
  - `effect` вызывает оба обработчика
326
327
  - `isError` из runtime имеет приоритет
328
+ - `config` мерджится, поля из runtime имеют приоритет
329
+
330
+ `config` пробрасывает поля расширенного `HttpConfig` в `httpClient.get`, поэтому они доступны в `onResponse` через `response.config`:
331
+
332
+ ```ts
333
+ const products = createGet<{ limit: number }>()('/products', {
334
+ config: { ignore: ['not_found'] },
335
+ })
336
+
337
+ await products({ config: { ignore: ['not_found', 'expired'] } })
338
+ ```
339
+
340
+ `params` и `signal` через `config` не передаются — ими управляет `useHttp`.
327
341
 
328
342
  ## createUseCase
329
343
 
@@ -1,7 +1,7 @@
1
1
  import type { HttpClient, HttpKey, HttpParam, HttpResponseData } from './http';
2
- import type { HttpError, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt';
2
+ import type { HttpError, UseHttpConfig, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt';
3
3
  export interface CreateGetFactory<P extends HttpParam> {
4
- <T extends string>(url: T, payload?: CreateGetPayload<T, CreateGetParams<T, P>>): (options?: CreateGetOptions<T, CreateGetParams<T, P>>) => Promise<CreateGetResult<T, CreateGetParams<T, P>>>;
4
+ <T extends HttpKey>(url: T, payload?: CreateGetPayload<T, CreateGetParams<T, P>>): (options?: CreateGetOptions<T, CreateGetParams<T, P>>) => Promise<CreateGetResult<T, CreateGetParams<T, P>>>;
5
5
  }
6
6
  export type CreateGetOptions<T extends string, P extends HttpParam> = Omit<UseHttpOptions<HttpKey, P>, 'effect' | 'initParams' | 'isError' | 'url'> & {
7
7
  effect?: CreateGetEffect<T, P>;
@@ -13,6 +13,7 @@ export type CreateGetPathParams<T extends string> = [CreateGetParamKeys<T>] exte
13
13
  [K in CreateGetParamKeys<T>]: string;
14
14
  };
15
15
  export type CreateGetPayload<T extends string, P extends HttpParam> = {
16
+ config?: UseHttpConfig<HttpKey & T>;
16
17
  effect?: CreateGetEffect<T, P>;
17
18
  isError?: CreateGetIsError<T>;
18
19
  };
@@ -1 +1 @@
1
- {"version":3,"file":"create-get.d.ts","sourceRoot":"","sources":["../src/create-get.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"create-get.d.ts","sourceRoot":"","sources":["../src/create-get.ts"],"names":[],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -1,5 +1,5 @@
1
- import { n as resolveUrlParams, t as createUseHttp } from "./nuxt-Kmqi3b7w.js";
2
- //#region src/create-get.ts
1
+ import { n as resolveUrlParams, t as createUseHttp } from "./nuxt-C-ATpBQS.js";
2
+ // src/create-get.ts
3
3
  function createUseCase() {
4
4
  return (callback) => callback;
5
5
  }
@@ -9,6 +9,10 @@ function defineGet(useHttp) {
9
9
  return async function request(options = {}) {
10
10
  return await useHttp({
11
11
  ...options,
12
+ config: {
13
+ ...payload?.config,
14
+ ...options.config
15
+ },
12
16
  effect: (data, config) => {
13
17
  payload?.effect?.(data, config);
14
18
  options?.effect?.(data, config);
@@ -21,8 +25,7 @@ function defineGet(useHttp) {
21
25
  return withUrl;
22
26
  };
23
27
  }
24
- //#endregion
25
- //#region src/http.ts
28
+ // src/http.ts
26
29
  function createHttp(options) {
27
30
  const arrayMode = options.arrayMode ?? "json";
28
31
  const clientFetch = options.fetch ?? fetch;
@@ -173,7 +176,6 @@ function toQueryString(params, arrayMode = "json") {
173
176
  function wait(ms) {
174
177
  return new Promise((resolve) => setTimeout(resolve, ms));
175
178
  }
176
- //#endregion
177
179
  export { createHttp, createUseCase, createUseHttp, defineGet };
178
180
 
179
181
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":[],"sources":["../src/create-get.ts","../src/http.ts"],"sourcesContent":["import type { HttpClient, HttpKey, HttpParam, HttpResponseData } from './http'\nimport type { HttpError, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt'\n\nexport interface CreateGetFactory<P extends HttpParam> {\n <T extends string>(\n url: T,\n payload?: CreateGetPayload<T, CreateGetParams<T, P>>,\n ): (options?: CreateGetOptions<T, CreateGetParams<T, P>>) => Promise<CreateGetResult<T, CreateGetParams<T, P>>>\n}\nexport type CreateGetOptions<T extends string, P extends HttpParam> = Omit<\n UseHttpOptions<HttpKey, P>,\n 'effect' | 'initParams' | 'isError' | 'url'\n> & {\n effect?: CreateGetEffect<T, P>\n initParams?: CreateGetInitParams<P>\n isError?: CreateGetIsError<T>\n}\nexport type CreateGetParams<T extends string, P extends HttpParam> = Omit<CreateGetPathParams<T>, keyof P> & P\nexport type CreateGetPathParams<T extends string> = [CreateGetParamKeys<T>] extends [never]\n ? CreateGetEmptyParams\n : {\n [K in CreateGetParamKeys<T>]: string\n }\n\nexport type CreateGetPayload<T extends string, P extends HttpParam> = {\n effect?: CreateGetEffect<T, P>\n isError?: CreateGetIsError<T>\n}\nexport type CreateGetResult<T extends string, P extends HttpParam> = Omit<\n UseHttpResult<HttpKey, P>,\n 'data' | 'error'\n> & {\n data: Exclude<CreateGetData<T>, HttpError> | null\n error: Extract<CreateGetData<T>, HttpError> | null\n}\ntype CreateGetData<T extends string> = T extends HttpKey ? HttpResponseData<T> : unknown\ntype CreateGetEffect<T extends string, P extends HttpParam> = (\n data: CreateGetData<T>,\n config: CreateGetEffectConfig<P>,\n) => undefined\ntype CreateGetEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\n\ntype CreateGetEmptyParams = Record<never, never>\n\ntype CreateGetInitParams<P extends HttpParam> = [keyof P] extends [never] ? never : P\ntype CreateGetIsError<T extends string> = (payload: CreateGetData<T>) => boolean\ntype CreateGetParamKeys<T extends string> = T extends `${string}:${infer Rest}`\n ? Rest extends `${infer Key}/${infer Tail}`\n ? CreateGetParamKeys<`/${Tail}`> | Key\n : Rest\n : never\n\nexport function createUseCase<D>() {\n return <T>(\n callback: (payload: D & { httpClient: HttpClient }) => T,\n ): ((payload: D & { httpClient: HttpClient }) => T) => callback\n}\n\nexport function defineGet(useHttp: UseHttpFn) {\n return function withParams<P extends HttpParam = CreateGetEmptyParams>(): CreateGetFactory<P> {\n function withUrl<T extends string>(\n url: T,\n payload?: CreateGetPayload<T, CreateGetParams<T, P>>,\n ): (\n options?: CreateGetOptions<T, CreateGetParams<T, P>>,\n ) => Promise<CreateGetResult<T, CreateGetParams<T, P>>> {\n return async function request(\n options: CreateGetOptions<T, CreateGetParams<T, P>> = {},\n ): Promise<CreateGetResult<T, CreateGetParams<T, P>>> {\n const result = await useHttp({\n ...options,\n effect: (data, config) => {\n payload?.effect?.(data as CreateGetData<T>, config)\n options?.effect?.(data as CreateGetData<T>, config)\n },\n isError: options.isError ?? payload?.isError,\n url,\n } as UseHttpOptions<HttpKey, CreateGetParams<T, P>>)\n\n return result as CreateGetResult<T, CreateGetParams<T, P>>\n }\n }\n\n return withUrl as CreateGetFactory<P>\n }\n}\n","import { resolveUrlParams } from './utils'\n\nexport interface CreateHttpOptions {\n arrayMode?: HttpArrayMode\n baseURL: string\n fetch?: typeof fetch\n headers?: (() => HttpHeaders) | HttpHeaders\n onResponse?: (response: HttpAnyResponse) => Promise<void> | void\n timeout?: number\n}\n\nexport type GetConfig<TKey extends HttpKey = HttpKey> = HttpConfigFull<TKey> & {\n retry?: {\n delay?: number\n retries?: number\n }\n}\n\nexport type HttpAnyResponse = HttpResponse<HttpResponseData<HttpKey>, HttpKey, HttpConfigFull<HttpKey>>\n\nexport type HttpArrayMode = 'json' | 'repeat'\nexport type HttpClient = {\n get: <T extends HttpKey, TConfig extends GetConfig<T> = GetConfig<T>>(\n url: T,\n config?: TConfig,\n ) => Promise<HttpResponse<HttpResponseData<T>, T, TConfig>>\n post: <\n T extends HttpKey,\n TData extends Record<string, unknown> = Record<string, unknown>,\n TConfig extends PostConfig<T> = PostConfig<T>,\n >(\n url: T,\n data?: HttpPostData<TData>,\n config?: TConfig,\n ) => Promise<HttpResponse<HttpResponseData<T>, T, TConfig>>\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport interface HttpConfig<TKey extends HttpKey = HttpKey> {}\n\nexport interface HttpEndpoint {}\nexport type HttpErrorGuard<TData = unknown, TError extends TData = TData> = (payload: TData) => payload is TError\nexport type HttpKey = Extract<keyof HttpSchema, string>\n\nexport type HttpParam = Record<string, boolean | number | string | string[] | undefined>\nexport type HttpPostData<TData extends Record<string, unknown> = Record<string, unknown>> = FormData | TData\n\nexport interface HttpResponse<\n T = unknown,\n TKey extends HttpKey = HttpKey,\n TConfig extends HttpConfigFull<TKey> = HttpConfigFull<TKey>,\n> {\n config: HttpResponseConfig<TKey, TConfig>\n data: T\n status: number\n}\nexport type HttpResponseConfig<\n TKey extends HttpKey = HttpKey,\n TConfig extends HttpConfig<TKey> = HttpConfig<TKey>,\n> = Omit<TConfig, 'signal'> & { url: string }\n\nexport type HttpResponseData<TKey extends HttpKey = HttpKey> = HttpSchema[TKey]\n\nexport type PostConfig<TKey extends HttpKey = HttpKey> = HttpConfigFull<TKey>\n\ntype HttpConfigFull<TKey extends HttpKey = HttpKey> = HttpConfig<TKey> & {\n params?: HttpParam\n signal?: AbortSignal | AbortSignal[]\n}\n\ntype HttpHeaders = Record<string, string | undefined>\n\ntype HttpSchema = keyof HttpEndpoint extends never ? Record<string, unknown> : HttpEndpoint\n\nexport function createHttp(options: CreateHttpOptions): HttpClient {\n const arrayMode = options.arrayMode ?? 'json'\n const clientFetch = options.fetch ?? fetch\n const timeout = options.timeout ?? 80_000\n\n return {\n get<T extends HttpKey, TConfig extends GetConfig<T> = GetConfig<T>>(url: T, config?: TConfig) {\n const requestConfig = (config ?? {}) as TConfig\n const resolved = resolveUrlParams(url, requestConfig.params)\n const requestUrl = `${joinUrl(options.baseURL, resolved.url)}${toQueryString(resolved.params, arrayMode)}`\n const { delay = 300, retries = 3 } = requestConfig.retry ?? {}\n\n const attemptRequest = async (attempt: number): Promise<HttpResponse<HttpResponseData<T>, T, TConfig>> => {\n try {\n const result = await clientFetch(requestUrl, {\n credentials: 'include',\n headers: resolveHeaders(options.headers),\n method: 'GET',\n signal: createSignal(requestConfig.signal, timeout),\n })\n\n const parsedResult = await result.json()\n const response: HttpResponse<HttpResponseData<T>, T, TConfig> = {\n config: createResponseConfig<T, TConfig>(joinUrl(options.baseURL, resolved.url), {\n ...requestConfig,\n params: resolved.params,\n }),\n data: parsedResult,\n status: result.status,\n }\n\n if (!result.ok && isRetryableStatus(result.status) && attempt < retries) {\n await wait(getRetryDelay(attempt, delay))\n return attemptRequest(attempt + 1)\n }\n\n await options.onResponse?.(response as HttpAnyResponse)\n return response\n } catch (error) {\n if (isAbortError(error) || attempt >= retries) {\n throw error\n }\n\n await wait(getRetryDelay(attempt, delay))\n return attemptRequest(attempt + 1)\n }\n }\n\n return attemptRequest(0)\n },\n async post<\n T extends HttpKey,\n TData extends Record<string, unknown> = Record<string, unknown>,\n TConfig extends PostConfig<T> = PostConfig<T>,\n >(url: T, data?: HttpPostData<TData>, config?: TConfig) {\n const requestConfig = (config ?? {}) as TConfig\n const isForm = isFormData(data)\n const resolved = resolveUrlParams(url, requestConfig.params)\n const requestUrl = `${joinUrl(options.baseURL, resolved.url)}${toQueryString(resolved.params, arrayMode)}`\n const response = await clientFetch(requestUrl, {\n body: isForm || data === undefined ? data : JSON.stringify(data),\n credentials: 'include',\n headers: resolveHeaders(\n options.headers,\n data !== undefined && !isForm ? { 'Content-Type': 'application/json' } : undefined,\n ),\n method: 'POST',\n signal: createSignal(requestConfig.signal, timeout),\n })\n\n let parsedResult: Awaited<ReturnType<typeof response.json>> = {}\n try {\n parsedResult = await response.json()\n } catch {\n parsedResult = {}\n }\n\n const parsedResponse: HttpResponse<HttpResponseData<T>, T, TConfig> = {\n config: createResponseConfig<T, TConfig>(joinUrl(options.baseURL, resolved.url), {\n ...requestConfig,\n params: resolved.params,\n }),\n data: parsedResult,\n status: response.status,\n }\n\n await options.onResponse?.(parsedResponse as HttpAnyResponse)\n return parsedResponse\n },\n }\n}\n\nfunction createAnySignal(signals: AbortSignal[]): AbortSignal {\n if (typeof AbortSignal?.any === 'function') {\n return AbortSignal.any(signals)\n }\n\n const controller = new AbortController()\n\n signals.filter(Boolean).forEach((signal) => {\n signal.addEventListener('abort', () => controller.abort(), { once: true })\n })\n\n return controller.signal\n}\n\nfunction createResponseConfig<TKey extends HttpKey, TConfig extends HttpConfigFull<TKey>>(\n url: string,\n config: TConfig,\n): HttpResponseConfig<TKey, TConfig> {\n const responseConfig = { ...config } as Record<string, unknown>\n delete responseConfig.signal\n\n return {\n ...responseConfig,\n url,\n } as HttpResponseConfig<TKey, TConfig>\n}\n\nfunction createSignal(signal: AbortSignal | AbortSignal[] | undefined, timeout: number): AbortSignal {\n const timeoutSignal = createTimeoutSignal(timeout)\n\n if (Array.isArray(signal)) {\n return createAnySignal([...signal, timeoutSignal])\n }\n\n if (signal) {\n return createAnySignal([signal, timeoutSignal])\n }\n\n return timeoutSignal\n}\n\nfunction createTimeoutSignal(ms: number): AbortSignal {\n if (typeof AbortSignal?.timeout === 'function') {\n return AbortSignal.timeout(ms)\n }\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), ms)\n\n controller.signal.addEventListener('abort', () => clearTimeout(timeoutId), {\n once: true,\n })\n\n return controller.signal\n}\n\nfunction getRetryDelay(attempt: number, delay: number): number {\n return delay * 2 ** attempt\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof DOMException && err.name === 'AbortError'\n}\n\nfunction isFormData(value: unknown): value is FormData {\n return typeof FormData !== 'undefined' && value instanceof FormData\n}\n\nfunction isRetryableStatus(status: number): boolean {\n return status >= 500 || status === 429\n}\n\nfunction joinUrl(baseURL: string, url: string): string {\n const normalizedBase = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL\n const normalizedUrl = url.startsWith('/') ? url.slice(1) : url\n\n return `${normalizedBase}/${normalizedUrl}`\n}\n\nfunction resolveHeaders(\n value: CreateHttpOptions['headers'],\n extraHeaders?: Record<string, string>,\n): Record<string, string> {\n const headers = typeof value === 'function' ? value() : value\n\n return Object.entries({\n ...headers,\n ...extraHeaders,\n }).reduce<Record<string, string>>((acc, [key, headerValue]) => {\n if (typeof headerValue === 'string') {\n acc[key] = headerValue\n }\n\n return acc\n }, {})\n}\n\nfunction serializeQueryValue(\n urlParams: URLSearchParams,\n key: string,\n value: HttpParam[string],\n arrayMode: HttpArrayMode,\n): void {\n if (value === undefined) {\n return\n }\n\n if (Array.isArray(value)) {\n if (arrayMode === 'json') {\n urlParams.append(key, JSON.stringify(value))\n return\n }\n\n value.forEach((item) => {\n urlParams.append(`${key}[]`, item)\n })\n return\n }\n\n urlParams.append(key, String(value))\n}\n\nfunction toQueryString(params?: HttpParam, arrayMode: HttpArrayMode = 'json'): string {\n const urlParams = new URLSearchParams()\n\n Object.entries(params ?? {}).forEach(([key, value]) => {\n serializeQueryValue(urlParams, key, value, arrayMode)\n })\n\n return urlParams.size > 0 ? `?${urlParams}` : ''\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n"],"mappings":";;AAuDA,SAAgB,gBAAmB;CACjC,QACE,aACqD;AACzD;AAEA,SAAgB,UAAU,SAAoB;CAC5C,OAAO,SAAS,aAA8E;EAC5F,SAAS,QACP,KACA,SAGsD;GACtD,OAAO,eAAe,QACpB,UAAsD,CAAC,GACH;IAWpD,OAAO,MAVc,QAAQ;KAC3B,GAAG;KACH,SAAS,MAAM,WAAW;MACxB,SAAS,SAAS,MAA0B,MAAM;MAClD,SAAS,SAAS,MAA0B,MAAM;KACpD;KACA,SAAS,QAAQ,WAAW,SAAS;KACrC;IACF,CAAmD;GAGrD;EACF;EAEA,OAAO;CACT;AACF;;;ACdA,SAAgB,WAAW,SAAwC;CACjE,MAAM,YAAY,QAAQ,aAAa;CACvC,MAAM,cAAc,QAAQ,SAAS;CACrC,MAAM,UAAU,QAAQ,WAAW;CAEnC,OAAO;EACL,IAAoE,KAAQ,QAAkB;GAC5F,MAAM,gBAAiB,UAAU,CAAC;GAClC,MAAM,WAAW,iBAAiB,KAAK,cAAc,MAAM;GAC3D,MAAM,aAAa,GAAG,QAAQ,QAAQ,SAAS,SAAS,GAAG,IAAI,cAAc,SAAS,QAAQ,SAAS;GACvG,MAAM,EAAE,QAAQ,KAAK,UAAU,MAAM,cAAc,SAAS,CAAC;GAE7D,MAAM,iBAAiB,OAAO,YAA4E;IACxG,IAAI;KACF,MAAM,SAAS,MAAM,YAAY,YAAY;MAC3C,aAAa;MACb,SAAS,eAAe,QAAQ,OAAO;MACvC,QAAQ;MACR,QAAQ,aAAa,cAAc,QAAQ,OAAO;KACpD,CAAC;KAED,MAAM,eAAe,MAAM,OAAO,KAAK;KACvC,MAAM,WAA0D;MAC9D,QAAQ,qBAAiC,QAAQ,QAAQ,SAAS,SAAS,GAAG,GAAG;OAC/E,GAAG;OACH,QAAQ,SAAS;MACnB,CAAC;MACD,MAAM;MACN,QAAQ,OAAO;KACjB;KAEA,IAAI,CAAC,OAAO,MAAM,kBAAkB,OAAO,MAAM,KAAK,UAAU,SAAS;MACvE,MAAM,KAAK,cAAc,SAAS,KAAK,CAAC;MACxC,OAAO,eAAe,UAAU,CAAC;KACnC;KAEA,MAAM,QAAQ,aAAa,QAA2B;KACtD,OAAO;IACT,SAAS,OAAO;KACd,IAAI,aAAa,KAAK,KAAK,WAAW,SACpC,MAAM;KAGR,MAAM,KAAK,cAAc,SAAS,KAAK,CAAC;KACxC,OAAO,eAAe,UAAU,CAAC;IACnC;GACF;GAEA,OAAO,eAAe,CAAC;EACzB;EACA,MAAM,KAIJ,KAAQ,MAA4B,QAAkB;GACtD,MAAM,gBAAiB,UAAU,CAAC;GAClC,MAAM,SAAS,WAAW,IAAI;GAC9B,MAAM,WAAW,iBAAiB,KAAK,cAAc,MAAM;GAC3D,MAAM,aAAa,GAAG,QAAQ,QAAQ,SAAS,SAAS,GAAG,IAAI,cAAc,SAAS,QAAQ,SAAS;GACvG,MAAM,WAAW,MAAM,YAAY,YAAY;IAC7C,MAAM,UAAU,SAAS,KAAA,IAAY,OAAO,KAAK,UAAU,IAAI;IAC/D,aAAa;IACb,SAAS,eACP,QAAQ,SACR,SAAS,KAAA,KAAa,CAAC,SAAS,EAAE,gBAAgB,mBAAmB,IAAI,KAAA,CAC3E;IACA,QAAQ;IACR,QAAQ,aAAa,cAAc,QAAQ,OAAO;GACpD,CAAC;GAED,IAAI,eAA0D,CAAC;GAC/D,IAAI;IACF,eAAe,MAAM,SAAS,KAAK;GACrC,QAAQ;IACN,eAAe,CAAC;GAClB;GAEA,MAAM,iBAAgE;IACpE,QAAQ,qBAAiC,QAAQ,QAAQ,SAAS,SAAS,GAAG,GAAG;KAC/E,GAAG;KACH,QAAQ,SAAS;IACnB,CAAC;IACD,MAAM;IACN,QAAQ,SAAS;GACnB;GAEA,MAAM,QAAQ,aAAa,cAAiC;GAC5D,OAAO;EACT;CACF;AACF;AAEA,SAAS,gBAAgB,SAAqC;CAC5D,IAAI,OAAO,aAAa,QAAQ,YAC9B,OAAO,YAAY,IAAI,OAAO;CAGhC,MAAM,aAAa,IAAI,gBAAgB;CAEvC,QAAQ,OAAO,OAAO,CAAC,CAAC,SAAS,WAAW;EAC1C,OAAO,iBAAiB,eAAe,WAAW,MAAM,GAAG,EAAE,MAAM,KAAK,CAAC;CAC3E,CAAC;CAED,OAAO,WAAW;AACpB;AAEA,SAAS,qBACP,KACA,QACmC;CACnC,MAAM,iBAAiB,EAAE,GAAG,OAAO;CACnC,OAAO,eAAe;CAEtB,OAAO;EACL,GAAG;EACH;CACF;AACF;AAEA,SAAS,aAAa,QAAiD,SAA8B;CACnG,MAAM,gBAAgB,oBAAoB,OAAO;CAEjD,IAAI,MAAM,QAAQ,MAAM,GACtB,OAAO,gBAAgB,CAAC,GAAG,QAAQ,aAAa,CAAC;CAGnD,IAAI,QACF,OAAO,gBAAgB,CAAC,QAAQ,aAAa,CAAC;CAGhD,OAAO;AACT;AAEA,SAAS,oBAAoB,IAAyB;CACpD,IAAI,OAAO,aAAa,YAAY,YAClC,OAAO,YAAY,QAAQ,EAAE;CAG/B,MAAM,aAAa,IAAI,gBAAgB;CACvC,MAAM,YAAY,iBAAiB,WAAW,MAAM,GAAG,EAAE;CAEzD,WAAW,OAAO,iBAAiB,eAAe,aAAa,SAAS,GAAG,EACzE,MAAM,KACR,CAAC;CAED,OAAO,WAAW;AACpB;AAEA,SAAS,cAAc,SAAiB,OAAuB;CAC7D,OAAO,QAAQ,KAAK;AACtB;AAEA,SAAS,aAAa,KAAuB;CAC3C,OAAO,eAAe,gBAAgB,IAAI,SAAS;AACrD;AAEA,SAAS,WAAW,OAAmC;CACrD,OAAO,OAAO,aAAa,eAAe,iBAAiB;AAC7D;AAEA,SAAS,kBAAkB,QAAyB;CAClD,OAAO,UAAU,OAAO,WAAW;AACrC;AAEA,SAAS,QAAQ,SAAiB,KAAqB;CAIrD,OAAO,GAHgB,QAAQ,SAAS,GAAG,IAAI,QAAQ,MAAM,GAAG,EAAE,IAAI,QAG7C,GAFH,IAAI,WAAW,GAAG,IAAI,IAAI,MAAM,CAAC,IAAI;AAG7D;AAEA,SAAS,eACP,OACA,cACwB;CACxB,MAAM,UAAU,OAAO,UAAU,aAAa,MAAM,IAAI;CAExD,OAAO,OAAO,QAAQ;EACpB,GAAG;EACH,GAAG;CACL,CAAC,CAAC,CAAC,QAAgC,KAAK,CAAC,KAAK,iBAAiB;EAC7D,IAAI,OAAO,gBAAgB,UACzB,IAAI,OAAO;EAGb,OAAO;CACT,GAAG,CAAC,CAAC;AACP;AAEA,SAAS,oBACP,WACA,KACA,OACA,WACM;CACN,IAAI,UAAU,KAAA,GACZ;CAGF,IAAI,MAAM,QAAQ,KAAK,GAAG;EACxB,IAAI,cAAc,QAAQ;GACxB,UAAU,OAAO,KAAK,KAAK,UAAU,KAAK,CAAC;GAC3C;EACF;EAEA,MAAM,SAAS,SAAS;GACtB,UAAU,OAAO,GAAG,IAAI,KAAK,IAAI;EACnC,CAAC;EACD;CACF;CAEA,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC;AACrC;AAEA,SAAS,cAAc,QAAoB,YAA2B,QAAgB;CACpF,MAAM,YAAY,IAAI,gBAAgB;CAEtC,OAAO,QAAQ,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EACrD,oBAAoB,WAAW,KAAK,OAAO,SAAS;CACtD,CAAC;CAED,OAAO,UAAU,OAAO,IAAI,IAAI,cAAc;AAChD;AAEA,SAAS,KAAK,IAA2B;CACvC,OAAO,IAAI,SAAS,YAAY,WAAW,SAAS,EAAE,CAAC;AACzD"}
1
+ {"version":3,"file":"index.mjs","names":[],"sources":["../src/create-get.ts","../src/http.ts"],"sourcesContent":["import type { HttpClient, HttpKey, HttpParam, HttpResponseData } from './http'\nimport type { HttpError, UseHttpConfig, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt'\n\nexport interface CreateGetFactory<P extends HttpParam> {\n <T extends HttpKey>(\n url: T,\n payload?: CreateGetPayload<T, CreateGetParams<T, P>>,\n ): (options?: CreateGetOptions<T, CreateGetParams<T, P>>) => Promise<CreateGetResult<T, CreateGetParams<T, P>>>\n}\nexport type CreateGetOptions<T extends string, P extends HttpParam> = Omit<\n UseHttpOptions<HttpKey, P>,\n 'effect' | 'initParams' | 'isError' | 'url'\n> & {\n effect?: CreateGetEffect<T, P>\n initParams?: CreateGetInitParams<P>\n isError?: CreateGetIsError<T>\n}\nexport type CreateGetParams<T extends string, P extends HttpParam> = Omit<CreateGetPathParams<T>, keyof P> & P\nexport type CreateGetPathParams<T extends string> = [CreateGetParamKeys<T>] extends [never]\n ? CreateGetEmptyParams\n : {\n [K in CreateGetParamKeys<T>]: string\n }\n\nexport type CreateGetPayload<T extends string, P extends HttpParam> = {\n config?: UseHttpConfig<HttpKey & T>\n effect?: CreateGetEffect<T, P>\n isError?: CreateGetIsError<T>\n}\nexport type CreateGetResult<T extends string, P extends HttpParam> = Omit<\n UseHttpResult<HttpKey, P>,\n 'data' | 'error'\n> & {\n data: Exclude<CreateGetData<T>, HttpError> | null\n error: Extract<CreateGetData<T>, HttpError> | null\n}\ntype CreateGetData<T extends string> = T extends HttpKey ? HttpResponseData<T> : unknown\ntype CreateGetEffect<T extends string, P extends HttpParam> = (\n data: CreateGetData<T>,\n config: CreateGetEffectConfig<P>,\n) => undefined\ntype CreateGetEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\n\ntype CreateGetEmptyParams = Record<never, never>\n\ntype CreateGetInitParams<P extends HttpParam> = [keyof P] extends [never] ? never : P\ntype CreateGetIsError<T extends string> = (payload: CreateGetData<T>) => boolean\ntype CreateGetParamKeys<T extends string> = T extends `${string}:${infer Rest}`\n ? Rest extends `${infer Key}/${infer Tail}`\n ? CreateGetParamKeys<`/${Tail}`> | Key\n : Rest\n : never\n\nexport function createUseCase<D>() {\n return <T>(\n callback: (payload: D & { httpClient: HttpClient }) => T,\n ): ((payload: D & { httpClient: HttpClient }) => T) => callback\n}\n\nexport function defineGet(useHttp: UseHttpFn) {\n return function withParams<P extends HttpParam = CreateGetEmptyParams>(): CreateGetFactory<P> {\n function withUrl<T extends HttpKey>(\n url: T,\n payload?: CreateGetPayload<T, CreateGetParams<T, P>>,\n ): (\n options?: CreateGetOptions<T, CreateGetParams<T, P>>,\n ) => Promise<CreateGetResult<T, CreateGetParams<T, P>>> {\n return async function request(\n options: CreateGetOptions<T, CreateGetParams<T, P>> = {},\n ): Promise<CreateGetResult<T, CreateGetParams<T, P>>> {\n const result = await useHttp({\n ...options,\n config: { ...payload?.config, ...options.config },\n effect: (data, config) => {\n payload?.effect?.(data as CreateGetData<T>, config)\n options?.effect?.(data as CreateGetData<T>, config)\n },\n isError: options.isError ?? payload?.isError,\n url,\n } as UseHttpOptions<HttpKey, CreateGetParams<T, P>>)\n\n return result as CreateGetResult<T, CreateGetParams<T, P>>\n }\n }\n\n return withUrl as CreateGetFactory<P>\n }\n}\n","import { resolveUrlParams } from './utils'\n\nexport interface CreateHttpOptions {\n arrayMode?: HttpArrayMode\n baseURL: string\n fetch?: typeof fetch\n headers?: (() => HttpHeaders) | HttpHeaders\n onResponse?: (response: HttpAnyResponse) => Promise<void> | void\n timeout?: number\n}\n\nexport type GetConfig<TKey extends HttpKey = HttpKey> = HttpConfigFull<TKey> & {\n retry?: {\n delay?: number\n retries?: number\n }\n}\n\nexport type HttpAnyResponse = HttpResponse<HttpResponseData<HttpKey>, HttpKey, HttpConfigFull<HttpKey>>\n\nexport type HttpArrayMode = 'json' | 'repeat'\nexport type HttpClient = {\n get: <T extends HttpKey, TConfig extends GetConfig<T> = GetConfig<T>>(\n url: T,\n config?: TConfig,\n ) => Promise<HttpResponse<HttpResponseData<T>, T, TConfig>>\n post: <\n T extends HttpKey,\n TData extends Record<string, unknown> = Record<string, unknown>,\n TConfig extends PostConfig<T> = PostConfig<T>,\n >(\n url: T,\n data?: HttpPostData<TData>,\n config?: TConfig,\n ) => Promise<HttpResponse<HttpResponseData<T>, T, TConfig>>\n}\n\n// eslint-disable-next-line @typescript-eslint/no-unused-vars\nexport interface HttpConfig<TKey extends HttpKey = HttpKey> {}\n\nexport interface HttpEndpoint {}\nexport type HttpErrorGuard<TData = unknown, TError extends TData = TData> = (payload: TData) => payload is TError\nexport type HttpKey = Extract<keyof HttpSchema, string>\n\nexport type HttpParam = Record<string, boolean | number | string | string[] | undefined>\nexport type HttpPostData<TData extends Record<string, unknown> = Record<string, unknown>> = FormData | TData\n\nexport interface HttpResponse<\n T = unknown,\n TKey extends HttpKey = HttpKey,\n TConfig extends HttpConfigFull<TKey> = HttpConfigFull<TKey>,\n> {\n config: HttpResponseConfig<TKey, TConfig>\n data: T\n status: number\n}\nexport type HttpResponseConfig<\n TKey extends HttpKey = HttpKey,\n TConfig extends HttpConfig<TKey> = HttpConfig<TKey>,\n> = Omit<TConfig, 'signal'> & { url: string }\n\nexport type HttpResponseData<TKey extends HttpKey = HttpKey> = HttpSchema[TKey]\n\nexport type PostConfig<TKey extends HttpKey = HttpKey> = HttpConfigFull<TKey>\n\ntype HttpConfigFull<TKey extends HttpKey = HttpKey> = HttpConfig<TKey> & {\n params?: HttpParam\n signal?: AbortSignal | AbortSignal[]\n}\n\ntype HttpHeaders = Record<string, string | undefined>\n\ntype HttpSchema = keyof HttpEndpoint extends never ? Record<string, unknown> : HttpEndpoint\n\nexport function createHttp(options: CreateHttpOptions): HttpClient {\n const arrayMode = options.arrayMode ?? 'json'\n const clientFetch = options.fetch ?? fetch\n const timeout = options.timeout ?? 80_000\n\n return {\n get<T extends HttpKey, TConfig extends GetConfig<T> = GetConfig<T>>(url: T, config?: TConfig) {\n const requestConfig = (config ?? {}) as TConfig\n const resolved = resolveUrlParams(url, requestConfig.params)\n const requestUrl = `${joinUrl(options.baseURL, resolved.url)}${toQueryString(resolved.params, arrayMode)}`\n const { delay = 300, retries = 3 } = requestConfig.retry ?? {}\n\n const attemptRequest = async (attempt: number): Promise<HttpResponse<HttpResponseData<T>, T, TConfig>> => {\n try {\n const result = await clientFetch(requestUrl, {\n credentials: 'include',\n headers: resolveHeaders(options.headers),\n method: 'GET',\n signal: createSignal(requestConfig.signal, timeout),\n })\n\n const parsedResult = await result.json()\n const response: HttpResponse<HttpResponseData<T>, T, TConfig> = {\n config: createResponseConfig<T, TConfig>(joinUrl(options.baseURL, resolved.url), {\n ...requestConfig,\n params: resolved.params,\n }),\n data: parsedResult,\n status: result.status,\n }\n\n if (!result.ok && isRetryableStatus(result.status) && attempt < retries) {\n await wait(getRetryDelay(attempt, delay))\n return attemptRequest(attempt + 1)\n }\n\n await options.onResponse?.(response as unknown as HttpAnyResponse)\n return response\n } catch (error) {\n if (isAbortError(error) || attempt >= retries) {\n throw error\n }\n\n await wait(getRetryDelay(attempt, delay))\n return attemptRequest(attempt + 1)\n }\n }\n\n return attemptRequest(0)\n },\n async post<\n T extends HttpKey,\n TData extends Record<string, unknown> = Record<string, unknown>,\n TConfig extends PostConfig<T> = PostConfig<T>,\n >(url: T, data?: HttpPostData<TData>, config?: TConfig) {\n const requestConfig = (config ?? {}) as TConfig\n const isForm = isFormData(data)\n const resolved = resolveUrlParams(url, requestConfig.params)\n const requestUrl = `${joinUrl(options.baseURL, resolved.url)}${toQueryString(resolved.params, arrayMode)}`\n const response = await clientFetch(requestUrl, {\n body: isForm || data === undefined ? data : JSON.stringify(data),\n credentials: 'include',\n headers: resolveHeaders(\n options.headers,\n data !== undefined && !isForm ? { 'Content-Type': 'application/json' } : undefined,\n ),\n method: 'POST',\n signal: createSignal(requestConfig.signal, timeout),\n })\n\n let parsedResult: Awaited<ReturnType<typeof response.json>> = {}\n try {\n parsedResult = await response.json()\n } catch {\n parsedResult = {}\n }\n\n const parsedResponse: HttpResponse<HttpResponseData<T>, T, TConfig> = {\n config: createResponseConfig<T, TConfig>(joinUrl(options.baseURL, resolved.url), {\n ...requestConfig,\n params: resolved.params,\n }),\n data: parsedResult,\n status: response.status,\n }\n\n await options.onResponse?.(parsedResponse as unknown as HttpAnyResponse)\n return parsedResponse\n },\n }\n}\n\nfunction createAnySignal(signals: AbortSignal[]): AbortSignal {\n if (typeof AbortSignal?.any === 'function') {\n return AbortSignal.any(signals)\n }\n\n const controller = new AbortController()\n\n signals.filter(Boolean).forEach((signal) => {\n signal.addEventListener('abort', () => controller.abort(), { once: true })\n })\n\n return controller.signal\n}\n\nfunction createResponseConfig<TKey extends HttpKey, TConfig extends HttpConfigFull<TKey>>(\n url: string,\n config: TConfig,\n): HttpResponseConfig<TKey, TConfig> {\n const responseConfig = { ...config } as Record<string, unknown>\n delete responseConfig.signal\n\n return {\n ...responseConfig,\n url,\n } as HttpResponseConfig<TKey, TConfig>\n}\n\nfunction createSignal(signal: AbortSignal | AbortSignal[] | undefined, timeout: number): AbortSignal {\n const timeoutSignal = createTimeoutSignal(timeout)\n\n if (Array.isArray(signal)) {\n return createAnySignal([...signal, timeoutSignal])\n }\n\n if (signal) {\n return createAnySignal([signal, timeoutSignal])\n }\n\n return timeoutSignal\n}\n\nfunction createTimeoutSignal(ms: number): AbortSignal {\n if (typeof AbortSignal?.timeout === 'function') {\n return AbortSignal.timeout(ms)\n }\n\n const controller = new AbortController()\n const timeoutId = setTimeout(() => controller.abort(), ms)\n\n controller.signal.addEventListener('abort', () => clearTimeout(timeoutId), {\n once: true,\n })\n\n return controller.signal\n}\n\nfunction getRetryDelay(attempt: number, delay: number): number {\n return delay * 2 ** attempt\n}\n\nfunction isAbortError(err: unknown): boolean {\n return err instanceof DOMException && err.name === 'AbortError'\n}\n\nfunction isFormData(value: unknown): value is FormData {\n return typeof FormData !== 'undefined' && value instanceof FormData\n}\n\nfunction isRetryableStatus(status: number): boolean {\n return status >= 500 || status === 429\n}\n\nfunction joinUrl(baseURL: string, url: string): string {\n const normalizedBase = baseURL.endsWith('/') ? baseURL.slice(0, -1) : baseURL\n const normalizedUrl = url.startsWith('/') ? url.slice(1) : url\n\n return `${normalizedBase}/${normalizedUrl}`\n}\n\nfunction resolveHeaders(\n value: CreateHttpOptions['headers'],\n extraHeaders?: Record<string, string>,\n): Record<string, string> {\n const headers = typeof value === 'function' ? value() : value\n\n return Object.entries({\n ...headers,\n ...extraHeaders,\n }).reduce<Record<string, string>>((acc, [key, headerValue]) => {\n if (typeof headerValue === 'string') {\n acc[key] = headerValue\n }\n\n return acc\n }, {})\n}\n\nfunction serializeQueryValue(\n urlParams: URLSearchParams,\n key: string,\n value: HttpParam[string],\n arrayMode: HttpArrayMode,\n): void {\n if (value === undefined) {\n return\n }\n\n if (Array.isArray(value)) {\n if (arrayMode === 'json') {\n urlParams.append(key, JSON.stringify(value))\n return\n }\n\n value.forEach((item) => {\n urlParams.append(`${key}[]`, item)\n })\n return\n }\n\n urlParams.append(key, String(value))\n}\n\nfunction toQueryString(params?: HttpParam, arrayMode: HttpArrayMode = 'json'): string {\n const urlParams = new URLSearchParams()\n\n Object.entries(params ?? {}).forEach(([key, value]) => {\n serializeQueryValue(urlParams, key, value, arrayMode)\n })\n\n return urlParams.size > 0 ? `?${urlParams}` : ''\n}\n\nfunction wait(ms: number): Promise<void> {\n return new Promise((resolve) => setTimeout(resolve, ms))\n}\n"],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  import { useState } from "nuxt/app";
2
2
  import { onScopeDispose, shallowReactive } from "vue";
3
- //#region src/utils.ts
3
+ // src/utils.ts
4
4
  function createURL(url, params) {
5
5
  const resolved = resolveUrlParams(url, params);
6
6
  const urlParams = new URLSearchParams();
@@ -58,8 +58,7 @@ function resolveUrlParams(url, params) {
58
58
  url: resolvedUrl
59
59
  };
60
60
  }
61
- //#endregion
62
- //#region src/nuxt.ts
61
+ // src/nuxt.ts
63
62
  const DAY = 864e5;
64
63
  const DEFAULT_CHANNEL_NAME = "http-tab-sync";
65
64
  const DEFAULT_TTL = DAY * 7;
@@ -107,7 +106,10 @@ function createUseHttp(dependencies) {
107
106
  if (options.server && import.meta.server) {
108
107
  const mappedParams = resolveParams(options.initParams);
109
108
  try {
110
- const responsePayload = (await httpClient.get(options.url, { params: mappedParams })).data;
109
+ const responsePayload = (await httpClient.get(options.url, {
110
+ ...options.config,
111
+ params: mappedParams
112
+ })).data;
111
113
  serverData.value = responsePayload;
112
114
  effect?.(responsePayload, {
113
115
  cached: false,
@@ -175,6 +177,7 @@ function createUseHttp(dependencies) {
175
177
  if (controller.signal.aborted || fetchOpt?.signal?.aborted) throw new DOMException("Aborted", "AbortError");
176
178
  const signalHttp = fetchOpt?.signal ? [controller.signal, fetchOpt.signal] : controller.signal;
177
179
  const response = await httpClient.get(options.url, {
180
+ ...options.config,
178
181
  params: mappedParams,
179
182
  signal: signalHttp
180
183
  });
@@ -243,7 +246,6 @@ function normalizeBroadcastValue(payload) {
243
246
  return JSON.parse(JSON.stringify(payload));
244
247
  }
245
248
  }
246
- //#endregion
247
249
  export { resolveUrlParams as n, createUseHttp as t };
248
250
 
249
- //# sourceMappingURL=nuxt-Kmqi3b7w.js.map
251
+ //# sourceMappingURL=nuxt-C-ATpBQS.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"nuxt-C-ATpBQS.js","names":[],"sources":["../src/utils.ts","../src/nuxt.ts"],"sourcesContent":["import type { HttpParam } from './http'\n\nexport function createURL(url: string, params?: HttpParam): string {\n const resolved = resolveUrlParams(url, params)\n const urlParams = new URLSearchParams()\n\n Object.entries(resolved.params ?? {}).forEach(([key, value]) => {\n if (value === undefined) {\n return\n }\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n urlParams.append(`${key}[]`, item)\n })\n return\n }\n\n urlParams.append(key, String(value))\n })\n\n const query = urlParams.size > 0 ? `?${urlParams}` : ''\n return urlParams.size > 0 ? `${resolved.url}${query}` : resolved.url\n}\n\nexport function fastDevHash(data: unknown): string {\n const str = JSON.stringify(data)\n let hash = 0\n\n for (let i = 0; i < str.length; i++) {\n const chr = str.charCodeAt(i)\n hash = (hash << 5) - hash + chr\n hash |= 0\n }\n\n return Math.abs(hash).toString(16)\n}\n\nexport async function hashData(data: unknown): Promise<string> {\n const subtle = globalThis.crypto?.subtle\n\n if (subtle) {\n const encoded = new TextEncoder().encode(JSON.stringify(data))\n const buffer = await subtle.digest('SHA-1', encoded)\n const array = Array.from(new Uint8Array(buffer))\n\n return array.map((value) => value.toString(16).padStart(2, '0')).join('')\n }\n\n return fastDevHash(data)\n}\n\nexport function resolveUrlParams(\n url: string,\n params?: HttpParam,\n): {\n params: HttpParam | undefined\n url: string\n} {\n if (!params) {\n return {\n params,\n url,\n }\n }\n\n const usedKeys: Record<string, true> = {}\n const resolvedUrl = url.replaceAll(/:(\\w+)/g, (segment, key: string) => {\n const value = params[key]\n\n if (value === undefined) {\n return segment\n }\n\n usedKeys[key] = true\n return encodeURIComponent(String(value))\n })\n const queryParams = Object.entries(params).reduce<HttpParam>((acc, [key, value]) => {\n if (usedKeys[key]) {\n return acc\n }\n\n acc[key] = value\n return acc\n }, {})\n\n return {\n params: Object.keys(queryParams).length > 0 ? queryParams : undefined,\n url: resolvedUrl,\n }\n}\n","import { useState } from 'nuxt/app'\nimport { onScopeDispose, shallowReactive } from 'vue'\n\nimport type { GetConfig, HttpClient, HttpErrorGuard, HttpKey, HttpParam, HttpResponseData } from './http'\n\nimport { createURL, hashData } from './utils'\n\nconst DAY = 1000 * 60 * 60 * 24\nconst DEFAULT_CHANNEL_NAME = 'http-tab-sync'\nconst DEFAULT_TTL = DAY * 7\nexport interface CreateUseHttpDependencies {\n channelName?: string\n getCache: () => null | UseHttpCache\n getHttpClient: () => HttpClient\n isDev?: () => boolean\n isError?: HttpErrorGuard<unknown>\n ttl?: number\n}\n\nexport type HttpError = HttpErrorMap[keyof HttpErrorMap]\nexport interface HttpErrorMap {}\nexport type HttpSuccessData<TKey extends HttpKey = HttpKey> = Exclude<HttpResponseData<TKey>, HttpError>\n\nexport interface UseHttpCache {\n deleteKeysWithPart: (part: string) => Promise<void>\n get: <T>(key: string) => Promise<null | UseHttpCacheEntry<T>>\n set: <T>(key: string, value: T, ttl: number) => Promise<void>\n}\n\nexport interface UseHttpCacheEntry<T> {\n hash: string\n value: T\n}\n\nexport type UseHttpConfig<T extends HttpKey = HttpKey> = Omit<GetConfig<T>, 'params' | 'signal'>\n\nexport interface UseHttpFn {\n <T extends HttpKey, P extends HttpParam>(options: UseHttpOptions<T, P>): Promise<UseHttpResult<T, P>>\n}\n\nexport interface UseHttpOptions<T extends HttpKey, P extends HttpParam> {\n config?: UseHttpConfig<T>\n effect?: UseHttpEffect<T, P>\n initParams?: P\n isError?: (payload: HttpResponseData<T>) => boolean\n lazy?: true\n server?: boolean\n url: T\n}\n\nexport interface UseHttpResult<T extends HttpKey, P extends HttpParam> {\n data: HttpSuccessData<T> | null\n error: null | UseHttpError<T>\n fetch: UseHttpFetch<P>\n hasFirstData: boolean\n hasFreshData: boolean\n pending: boolean\n pendingCache: boolean\n}\n\ntype BroadcastMessage = {\n data: unknown\n fullUrl: string\n params: HttpParam\n type: 'STATE_UPDATE'\n}\n\ntype UseHttpEffect<T extends HttpKey, P extends HttpParam> = (\n data: HttpResponseData<T>,\n config: UseHttpEffectConfig<P>,\n) => undefined\ntype UseHttpEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\ntype UseHttpError<T extends HttpKey> = Extract<HttpResponseData<T>, HttpError>\ntype UseHttpFetch<P extends HttpParam> = (\n params?: UseHttpFetchParams<P>,\n opt?: { signal: AbortSignal },\n) => Promise<void>\ntype UseHttpFetchParams<P extends HttpParam> = [keyof P] extends [never] ? never : P\n\nexport function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpFn {\n let channel: BroadcastChannel | null\n\n const useHttp: UseHttpFn = async <T extends HttpKey, P extends HttpParam>(\n options: UseHttpOptions<T, P>,\n ): Promise<UseHttpResult<T, P>> => {\n const resolveParams = (params?: P): P => params ?? ({} as P)\n const effect = options.effect\n const isError = createIsErrorGuard(options.isError, dependencies.isError)\n\n const buildUrl = createURL\n const initFullUrl = buildUrl(options.url, resolveParams(options.initParams))\n const httpClient = dependencies.getHttpClient()\n const cache = import.meta.client ? (dependencies.getCache?.() ?? null) : null\n const result = shallowReactive({\n data: null as null | unknown,\n error: null as null | unknown,\n fetch: async (_params?: P, _opt?: { signal: AbortSignal }): Promise<void> => await undefined,\n hasFirstData: false,\n hasFreshData: false,\n pending: true,\n pendingCache: true,\n })\n const setError = (value: null | unknown): void => {\n result.error = value\n }\n const setData = (value: null | unknown): void => {\n result.data = value\n }\n const syncResult = (payload: HttpResponseData<T> | null | undefined): void => {\n if (payload === null || payload === undefined) {\n setData(null)\n setError(null)\n return\n }\n\n if (isError(payload)) {\n setData(null)\n setError(payload)\n return\n }\n\n setData(payload)\n setError(null)\n }\n\n const controller = new AbortController()\n const serverData = useState<null | unknown>(`http-${initFullUrl}`, () => null)\n\n if (options.server && import.meta.server) {\n const mappedParams = resolveParams(options.initParams)\n\n try {\n const response = await httpClient.get<T>(options.url, {\n ...options.config,\n params: mappedParams,\n } as GetConfig<T>)\n const responsePayload = response.data as HttpResponseData<T>\n\n serverData.value = responsePayload\n\n effect?.(responsePayload, {\n cached: false,\n params: mappedParams,\n })\n syncResult(responsePayload)\n result.hasFirstData = true\n result.hasFreshData = true\n } catch (error) {\n console.error(error)\n } finally {\n result.pending = false\n result.pendingCache = false\n }\n }\n\n if (import.meta.client) {\n channel = getChannel(dependencies.channelName ?? DEFAULT_CHANNEL_NAME, channel)\n const fullUrlHistory: Record<string, true> = {}\n\n function onMessage(event: MessageEvent<Partial<BroadcastMessage>>): void {\n if (event.data.fullUrl && fullUrlHistory[event.data.fullUrl]) {\n const eventPayload = event.data.data as HttpResponseData<T> | undefined\n\n if (eventPayload) {\n effect?.(eventPayload, {\n cached: false,\n params: event.data.params as P,\n })\n }\n\n syncResult(eventPayload)\n\n result.hasFirstData = true\n result.hasFreshData = true\n }\n }\n\n channel?.addEventListener('message', onMessage)\n\n if (serverData.value) {\n const clientServerPayload = serverData.value as HttpResponseData<T>\n syncResult(clientServerPayload)\n result.pending = false\n result.pendingCache = false\n result.hasFirstData = true\n result.hasFreshData = true\n }\n\n const raceCondition: Record<string, number> = {}\n const ttl = dependencies.ttl ?? DEFAULT_TTL\n\n const runFetch = async (params?: P, fetchOpt?: { signal?: AbortSignal }): Promise<void> => {\n const mappedParams = resolveParams(params)\n const fullUrl = buildUrl(options.url, mappedParams)\n const fetchId = Date.now() + getRandom(0, 300)\n\n if (raceCondition[fullUrl]) {\n console.info('Race Condition affect', fullUrl)\n return\n }\n\n raceCondition[fullUrl] = fetchId\n\n try {\n result.pending = true\n result.pendingCache = true\n\n const cachedFetch = cache && !dependencies.isDev?.() ? await cache.get<unknown>(fullUrl) : null\n\n if (cachedFetch) {\n const cachedPayload = cachedFetch.value as HttpResponseData<T>\n\n effect?.(cachedPayload, {\n cached: true,\n params: mappedParams,\n })\n\n syncResult(cachedPayload)\n result.hasFirstData = true\n\n result.pendingCache = false\n }\n\n if (controller.signal.aborted || fetchOpt?.signal?.aborted) {\n throw new DOMException('Aborted', 'AbortError')\n }\n\n const signalHttp = fetchOpt?.signal ? [controller.signal, fetchOpt.signal] : controller.signal\n const response = await httpClient.get<T>(options.url, {\n ...options.config,\n params: mappedParams,\n signal: signalHttp,\n } as GetConfig<T>)\n const responsePayload = response.data as HttpResponseData<T>\n\n effect?.(responsePayload, {\n cached: false,\n params: mappedParams,\n })\n\n if (isError(responsePayload)) {\n syncResult(responsePayload)\n } else {\n syncResult(responsePayload)\n const successData = responsePayload\n\n fullUrlHistory[fullUrl] = true\n channel?.postMessage({\n data: normalizeBroadcastValue(successData),\n fullUrl,\n params: normalizeBroadcastValue(mappedParams),\n type: 'STATE_UPDATE',\n } satisfies BroadcastMessage)\n\n if (cache) {\n if (cachedFetch) {\n const newHash = await hashData(responsePayload)\n if (newHash !== cachedFetch.hash) {\n await cache.deleteKeysWithPart(options.url)\n }\n }\n\n if (response.status === 200) {\n await cache.set(fullUrl, successData, ttl)\n }\n }\n }\n\n result.hasFirstData = true\n result.hasFreshData = true\n } catch (error) {\n console.error(error)\n } finally {\n if (raceCondition[fullUrl] === fetchId) {\n delete raceCondition[fullUrl]\n }\n\n result.pending = false\n result.pendingCache = false\n }\n }\n\n result.fetch = runFetch\n\n if (options.lazy !== true) {\n runFetch(options.initParams)\n }\n\n onScopeDispose(() => {\n channel?.removeEventListener('message', onMessage)\n controller.abort(`Http Abort -> onScopeDispose ${options.url}`)\n\n if (serverData.value) {\n serverData.value = null\n }\n })\n }\n\n return result as UseHttpResult<T, P>\n }\n\n return useHttp\n}\n\nfunction createIsErrorGuard<TData>(\n localGuard?: (payload: TData) => boolean,\n globalGuard?: HttpErrorGuard<unknown>,\n): (payload: TData) => boolean {\n if (localGuard) {\n return localGuard\n }\n\n if (globalGuard) {\n return globalGuard as (payload: TData) => boolean\n }\n\n return (): boolean => false\n}\n\nfunction getChannel(name: string, currentChannel?: BroadcastChannel | null): BroadcastChannel | null {\n if (currentChannel) {\n return currentChannel\n }\n\n if (import.meta.server || typeof BroadcastChannel !== 'function') {\n return null\n }\n\n return new BroadcastChannel(name)\n}\n\nfunction getRandom(min: number, max: number): number {\n return Math.floor(Math.random() * (max - min + 1)) + min\n}\n\nfunction normalizeBroadcastValue<T>(payload: T): T {\n try {\n return structuredClone(payload)\n } catch {\n return JSON.parse(JSON.stringify(payload)) as T\n }\n}\n"],"mappings":";;;AAEA,SAAgB,UAAU,KAAa,QAA4B;CACjE,MAAM,WAAW,iBAAiB,KAAK,MAAM;CAC7C,MAAM,YAAY,IAAI,gBAAgB;CAEtC,OAAO,QAAQ,SAAS,UAAU,CAAC,CAAC,CAAC,CAAC,SAAS,CAAC,KAAK,WAAW;EAC9D,IAAI,UAAU,KAAA,GACZ;EAGF,IAAI,MAAM,QAAQ,KAAK,GAAG;GACxB,MAAM,SAAS,SAAS;IACtB,UAAU,OAAO,GAAG,IAAI,KAAK,IAAI;GACnC,CAAC;GACD;EACF;EAEA,UAAU,OAAO,KAAK,OAAO,KAAK,CAAC;CACrC,CAAC;CAED,MAAM,QAAQ,UAAU,OAAO,IAAI,IAAI,cAAc;CACrD,OAAO,UAAU,OAAO,IAAI,GAAG,SAAS,MAAM,UAAU,SAAS;AACnE;AAEA,SAAgB,YAAY,MAAuB;CACjD,MAAM,MAAM,KAAK,UAAU,IAAI;CAC/B,IAAI,OAAO;CAEX,KAAK,IAAI,IAAI,GAAG,IAAI,IAAI,QAAQ,KAAK;EACnC,MAAM,MAAM,IAAI,WAAW,CAAC;EAC5B,QAAQ,QAAQ,KAAK,OAAO;EAC5B,QAAQ;CACV;CAEA,OAAO,KAAK,IAAI,IAAI,CAAC,CAAC,SAAS,EAAE;AACnC;AAEA,eAAsB,SAAS,MAAgC;CAC7D,MAAM,SAAS,WAAW,QAAQ;CAElC,IAAI,QAAQ;EACV,MAAM,UAAU,IAAI,YAAY,CAAC,CAAC,OAAO,KAAK,UAAU,IAAI,CAAC;EAC7D,MAAM,SAAS,MAAM,OAAO,OAAO,SAAS,OAAO;EAGnD,OAFc,MAAM,KAAK,IAAI,WAAW,MAAM,CAEnC,CAAC,CAAC,KAAK,UAAU,MAAM,SAAS,EAAE,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC,CAAC,KAAK,EAAE;CAC1E;CAEA,OAAO,YAAY,IAAI;AACzB;AAEA,SAAgB,iBACd,KACA,QAIA;CACA,IAAI,CAAC,QACH,OAAO;EACL;EACA;CACF;CAGF,MAAM,WAAiC,CAAC;CACxC,MAAM,cAAc,IAAI,WAAW,YAAY,SAAS,QAAgB;EACtE,MAAM,QAAQ,OAAO;EAErB,IAAI,UAAU,KAAA,GACZ,OAAO;EAGT,SAAS,OAAO;EAChB,OAAO,mBAAmB,OAAO,KAAK,CAAC;CACzC,CAAC;CACD,MAAM,cAAc,OAAO,QAAQ,MAAM,CAAC,CAAC,QAAmB,KAAK,CAAC,KAAK,WAAW;EAClF,IAAI,SAAS,MACX,OAAO;EAGT,IAAI,OAAO;EACX,OAAO;CACT,GAAG,CAAC,CAAC;CAEL,OAAO;EACL,QAAQ,OAAO,KAAK,WAAW,CAAC,CAAC,SAAS,IAAI,cAAc,KAAA;EAC5D,KAAK;CACP;AACF;;ACnFA,MAAM,MAAM;AACZ,MAAM,uBAAuB;AAC7B,MAAM,cAAc,MAAM;AAyE1B,SAAgB,cAAc,cAAoD;CAChF,IAAI;CAEJ,MAAM,UAAqB,OACzB,YACiC;EACjC,MAAM,iBAAiB,WAAkB,UAAW,CAAC;EACrD,MAAM,SAAS,QAAQ;EACvB,MAAM,UAAU,mBAAmB,QAAQ,SAAS,aAAa,OAAO;EAExE,MAAM,WAAW;EACjB,MAAM,cAAc,SAAS,QAAQ,KAAK,cAAc,QAAQ,UAAU,CAAC;EAC3E,MAAM,aAAa,aAAa,cAAc;EAC9C,MAAM,QAAQ,YAAY,SAAU,aAAa,WAAW,KAAK,OAAQ;EACzE,MAAM,SAAS,gBAAgB;GAC7B,MAAM;GACN,OAAO;GACP,OAAO,OAAO,SAAa,SAAkD,MAAM,KAAA;GACnF,cAAc;GACd,cAAc;GACd,SAAS;GACT,cAAc;EAChB,CAAC;EACD,MAAM,YAAY,UAAgC;GAChD,OAAO,QAAQ;EACjB;EACA,MAAM,WAAW,UAAgC;GAC/C,OAAO,OAAO;EAChB;EACA,MAAM,cAAc,YAA0D;GAC5E,IAAI,YAAY,QAAQ,YAAY,KAAA,GAAW;IAC7C,QAAQ,IAAI;IACZ,SAAS,IAAI;IACb;GACF;GAEA,IAAI,QAAQ,OAAO,GAAG;IACpB,QAAQ,IAAI;IACZ,SAAS,OAAO;IAChB;GACF;GAEA,QAAQ,OAAO;GACf,SAAS,IAAI;EACf;EAEA,MAAM,aAAa,IAAI,gBAAgB;EACvC,MAAM,aAAa,SAAyB,QAAQ,qBAAqB,IAAI;EAE7E,IAAI,QAAQ,UAAU,YAAY,QAAQ;GACxC,MAAM,eAAe,cAAc,QAAQ,UAAU;GAErD,IAAI;IAKF,MAAM,mBAAkB,MAJD,WAAW,IAAO,QAAQ,KAAK;KACpD,GAAG,QAAQ;KACX,QAAQ;IACV,CAAiB,EAAA,CACgB;IAEjC,WAAW,QAAQ;IAEnB,SAAS,iBAAiB;KACxB,QAAQ;KACR,QAAQ;IACV,CAAC;IACD,WAAW,eAAe;IAC1B,OAAO,eAAe;IACtB,OAAO,eAAe;GACxB,SAAS,OAAO;IACd,QAAQ,MAAM,KAAK;GACrB,UAAU;IACR,OAAO,UAAU;IACjB,OAAO,eAAe;GACxB;EACF;EAEA,IAAI,YAAY,QAAQ;GACtB,UAAU,WAAW,aAAa,eAAe,sBAAsB,OAAO;GAC9E,MAAM,iBAAuC,CAAC;GAE9C,SAAS,UAAU,OAAsD;IACvE,IAAI,MAAM,KAAK,WAAW,eAAe,MAAM,KAAK,UAAU;KAC5D,MAAM,eAAe,MAAM,KAAK;KAEhC,IAAI,cACF,SAAS,cAAc;MACrB,QAAQ;MACR,QAAQ,MAAM,KAAK;KACrB,CAAC;KAGH,WAAW,YAAY;KAEvB,OAAO,eAAe;KACtB,OAAO,eAAe;IACxB;GACF;GAEA,SAAS,iBAAiB,WAAW,SAAS;GAE9C,IAAI,WAAW,OAAO;IACpB,MAAM,sBAAsB,WAAW;IACvC,WAAW,mBAAmB;IAC9B,OAAO,UAAU;IACjB,OAAO,eAAe;IACtB,OAAO,eAAe;IACtB,OAAO,eAAe;GACxB;GAEA,MAAM,gBAAwC,CAAC;GAC/C,MAAM,MAAM,aAAa,OAAO;GAEhC,MAAM,WAAW,OAAO,QAAY,aAAuD;IACzF,MAAM,eAAe,cAAc,MAAM;IACzC,MAAM,UAAU,SAAS,QAAQ,KAAK,YAAY;IAClD,MAAM,UAAU,KAAK,IAAI,IAAI,UAAU,GAAG,GAAG;IAE7C,IAAI,cAAc,UAAU;KAC1B,QAAQ,KAAK,yBAAyB,OAAO;KAC7C;IACF;IAEA,cAAc,WAAW;IAEzB,IAAI;KACF,OAAO,UAAU;KACjB,OAAO,eAAe;KAEtB,MAAM,cAAc,SAAS,CAAC,aAAa,QAAQ,IAAI,MAAM,MAAM,IAAa,OAAO,IAAI;KAE3F,IAAI,aAAa;MACf,MAAM,gBAAgB,YAAY;MAElC,SAAS,eAAe;OACtB,QAAQ;OACR,QAAQ;MACV,CAAC;MAED,WAAW,aAAa;MACxB,OAAO,eAAe;MAEtB,OAAO,eAAe;KACxB;KAEA,IAAI,WAAW,OAAO,WAAW,UAAU,QAAQ,SACjD,MAAM,IAAI,aAAa,WAAW,YAAY;KAGhD,MAAM,aAAa,UAAU,SAAS,CAAC,WAAW,QAAQ,SAAS,MAAM,IAAI,WAAW;KACxF,MAAM,WAAW,MAAM,WAAW,IAAO,QAAQ,KAAK;MACpD,GAAG,QAAQ;MACX,QAAQ;MACR,QAAQ;KACV,CAAiB;KACjB,MAAM,kBAAkB,SAAS;KAEjC,SAAS,iBAAiB;MACxB,QAAQ;MACR,QAAQ;KACV,CAAC;KAED,IAAI,QAAQ,eAAe,GACzB,WAAW,eAAe;UACrB;MACL,WAAW,eAAe;MAC1B,MAAM,cAAc;MAEpB,eAAe,WAAW;MAC1B,SAAS,YAAY;OACnB,MAAM,wBAAwB,WAAW;OACzC;OACA,QAAQ,wBAAwB,YAAY;OAC5C,MAAM;MACR,CAA4B;MAE5B,IAAI,OAAO;OACT,IAAI,aAEE;YAAA,MADkB,SAAS,eAAe,MAC9B,YAAY,MAC1B,MAAM,MAAM,mBAAmB,QAAQ,GAAG;OAAA;OAI9C,IAAI,SAAS,WAAW,KACtB,MAAM,MAAM,IAAI,SAAS,aAAa,GAAG;MAE7C;KACF;KAEA,OAAO,eAAe;KACtB,OAAO,eAAe;IACxB,SAAS,OAAO;KACd,QAAQ,MAAM,KAAK;IACrB,UAAU;KACR,IAAI,cAAc,aAAa,SAC7B,OAAO,cAAc;KAGvB,OAAO,UAAU;KACjB,OAAO,eAAe;IACxB;GACF;GAEA,OAAO,QAAQ;GAEf,IAAI,QAAQ,SAAS,MACnB,SAAS,QAAQ,UAAU;GAG7B,qBAAqB;IACnB,SAAS,oBAAoB,WAAW,SAAS;IACjD,WAAW,MAAM,gCAAgC,QAAQ,KAAK;IAE9D,IAAI,WAAW,OACb,WAAW,QAAQ;GAEvB,CAAC;EACH;EAEA,OAAO;CACT;CAEA,OAAO;AACT;AAEA,SAAS,mBACP,YACA,aAC6B;CAC7B,IAAI,YACF,OAAO;CAGT,IAAI,aACF,OAAO;CAGT,aAAsB;AACxB;AAEA,SAAS,WAAW,MAAc,gBAAmE;CACnG,IAAI,gBACF,OAAO;CAGT,IAAI,YAAY,UAAU,OAAO,qBAAqB,YACpD,OAAO;CAGT,OAAO,IAAI,iBAAiB,IAAI;AAClC;AAEA,SAAS,UAAU,KAAa,KAAqB;CACnD,OAAO,KAAK,MAAM,KAAK,OAAO,KAAK,MAAM,MAAM,EAAE,IAAI;AACvD;AAEA,SAAS,wBAA2B,SAAe;CACjD,IAAI;EACF,OAAO,gBAAgB,OAAO;CAChC,QAAQ;EACN,OAAO,KAAK,MAAM,KAAK,UAAU,OAAO,CAAC;CAC3C;AACF"}
package/dist/nuxt.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { HttpClient, HttpErrorGuard, HttpKey, HttpParam, HttpResponseData } from './http';
1
+ import type { GetConfig, HttpClient, HttpErrorGuard, HttpKey, HttpParam, HttpResponseData } from './http';
2
2
  export interface CreateUseHttpDependencies {
3
3
  channelName?: string;
4
4
  getCache: () => null | UseHttpCache;
@@ -20,10 +20,12 @@ export interface UseHttpCacheEntry<T> {
20
20
  hash: string;
21
21
  value: T;
22
22
  }
23
+ export type UseHttpConfig<T extends HttpKey = HttpKey> = Omit<GetConfig<T>, 'params' | 'signal'>;
23
24
  export interface UseHttpFn {
24
25
  <T extends HttpKey, P extends HttpParam>(options: UseHttpOptions<T, P>): Promise<UseHttpResult<T, P>>;
25
26
  }
26
27
  export interface UseHttpOptions<T extends HttpKey, P extends HttpParam> {
28
+ config?: UseHttpConfig<T>;
27
29
  effect?: UseHttpEffect<T, P>;
28
30
  initParams?: P;
29
31
  isError?: (payload: HttpResponseData<T>) => boolean;
@@ -1 +1 @@
1
- {"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"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"}
package/dist/nuxt.mjs CHANGED
@@ -1,2 +1 @@
1
- import { t as createUseHttp } from "./nuxt-Kmqi3b7w.js";
2
- export { createUseHttp };
1
+ export { t as createUseHttp } from "./nuxt-C-ATpBQS.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@brickflow/http",
3
- "version": "0.0.56",
3
+ "version": "0.0.58",
4
4
  "description": "Minimal HTTP transport and Nuxt state helpers for brickflow.",
5
5
  "sideEffects": false,
6
6
  "files": [
@@ -36,13 +36,13 @@
36
36
  "access": "public"
37
37
  },
38
38
  "dependencies": {
39
- "@nuxt/kit": "4.5.2"
39
+ "@nuxt/kit": "4.6.3"
40
40
  },
41
41
  "devDependencies": {
42
42
  "@brickflow/lint": "workspace:*",
43
43
  "@brickflow/prettier": "workspace:*",
44
- "rolldown": "1.2.7",
45
- "vue-tsc": "3.3.11"
44
+ "rolldown": "1.2.16",
45
+ "vue-tsc": "3.3.14"
46
46
  },
47
47
  "peerDependencies": {
48
48
  "nuxt": ">=3",
package/src/create-get.ts CHANGED
@@ -1,8 +1,8 @@
1
1
  import type { HttpClient, HttpKey, HttpParam, HttpResponseData } from './http'
2
- import type { HttpError, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt'
2
+ import type { HttpError, UseHttpConfig, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt'
3
3
 
4
4
  export interface CreateGetFactory<P extends HttpParam> {
5
- <T extends string>(
5
+ <T extends HttpKey>(
6
6
  url: T,
7
7
  payload?: CreateGetPayload<T, CreateGetParams<T, P>>,
8
8
  ): (options?: CreateGetOptions<T, CreateGetParams<T, P>>) => Promise<CreateGetResult<T, CreateGetParams<T, P>>>
@@ -23,6 +23,7 @@ export type CreateGetPathParams<T extends string> = [CreateGetParamKeys<T>] exte
23
23
  }
24
24
 
25
25
  export type CreateGetPayload<T extends string, P extends HttpParam> = {
26
+ config?: UseHttpConfig<HttpKey & T>
26
27
  effect?: CreateGetEffect<T, P>
27
28
  isError?: CreateGetIsError<T>
28
29
  }
@@ -61,7 +62,7 @@ export function createUseCase<D>() {
61
62
 
62
63
  export function defineGet(useHttp: UseHttpFn) {
63
64
  return function withParams<P extends HttpParam = CreateGetEmptyParams>(): CreateGetFactory<P> {
64
- function withUrl<T extends string>(
65
+ function withUrl<T extends HttpKey>(
65
66
  url: T,
66
67
  payload?: CreateGetPayload<T, CreateGetParams<T, P>>,
67
68
  ): (
@@ -72,6 +73,7 @@ export function defineGet(useHttp: UseHttpFn) {
72
73
  ): Promise<CreateGetResult<T, CreateGetParams<T, P>>> {
73
74
  const result = await useHttp({
74
75
  ...options,
76
+ config: { ...payload?.config, ...options.config },
75
77
  effect: (data, config) => {
76
78
  payload?.effect?.(data as CreateGetData<T>, config)
77
79
  options?.effect?.(data as CreateGetData<T>, config)
package/src/http.ts CHANGED
@@ -108,7 +108,7 @@ export function createHttp(options: CreateHttpOptions): HttpClient {
108
108
  return attemptRequest(attempt + 1)
109
109
  }
110
110
 
111
- await options.onResponse?.(response as HttpAnyResponse)
111
+ await options.onResponse?.(response as unknown as HttpAnyResponse)
112
112
  return response
113
113
  } catch (error) {
114
114
  if (isAbortError(error) || attempt >= retries) {
@@ -158,7 +158,7 @@ export function createHttp(options: CreateHttpOptions): HttpClient {
158
158
  status: response.status,
159
159
  }
160
160
 
161
- await options.onResponse?.(parsedResponse as HttpAnyResponse)
161
+ await options.onResponse?.(parsedResponse as unknown as HttpAnyResponse)
162
162
  return parsedResponse
163
163
  },
164
164
  }
package/src/nuxt.ts CHANGED
@@ -32,11 +32,14 @@ export interface UseHttpCacheEntry<T> {
32
32
  value: T
33
33
  }
34
34
 
35
+ export type UseHttpConfig<T extends HttpKey = HttpKey> = Omit<GetConfig<T>, 'params' | 'signal'>
36
+
35
37
  export interface UseHttpFn {
36
38
  <T extends HttpKey, P extends HttpParam>(options: UseHttpOptions<T, P>): Promise<UseHttpResult<T, P>>
37
39
  }
38
40
 
39
41
  export interface UseHttpOptions<T extends HttpKey, P extends HttpParam> {
42
+ config?: UseHttpConfig<T>
40
43
  effect?: UseHttpEffect<T, P>
41
44
  initParams?: P
42
45
  isError?: (payload: HttpResponseData<T>) => boolean
@@ -131,6 +134,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
131
134
 
132
135
  try {
133
136
  const response = await httpClient.get<T>(options.url, {
137
+ ...options.config,
134
138
  params: mappedParams,
135
139
  } as GetConfig<T>)
136
140
  const responsePayload = response.data as HttpResponseData<T>
@@ -226,6 +230,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
226
230
 
227
231
  const signalHttp = fetchOpt?.signal ? [controller.signal, fetchOpt.signal] : controller.signal
228
232
  const response = await httpClient.get<T>(options.url, {
233
+ ...options.config,
229
234
  params: mappedParams,
230
235
  signal: signalHttp,
231
236
  } as GetConfig<T>)
@@ -1 +0,0 @@
1
- {"version":3,"file":"nuxt-Kmqi3b7w.js","names":[],"sources":["../src/utils.ts","../src/nuxt.ts"],"sourcesContent":["import type { HttpParam } from './http'\n\nexport function createURL(url: string, params?: HttpParam): string {\n const resolved = resolveUrlParams(url, params)\n const urlParams = new URLSearchParams()\n\n Object.entries(resolved.params ?? {}).forEach(([key, value]) => {\n if (value === undefined) {\n return\n }\n\n if (Array.isArray(value)) {\n value.forEach((item) => {\n urlParams.append(`${key}[]`, item)\n })\n return\n }\n\n urlParams.append(key, String(value))\n })\n\n const query = urlParams.size > 0 ? `?${urlParams}` : ''\n return urlParams.size > 0 ? `${resolved.url}${query}` : resolved.url\n}\n\nexport function fastDevHash(data: unknown): string {\n const str = JSON.stringify(data)\n let hash = 0\n\n for (let i = 0; i < str.length; i++) {\n const chr = str.charCodeAt(i)\n hash = (hash << 5) - hash + chr\n hash |= 0\n }\n\n return Math.abs(hash).toString(16)\n}\n\nexport async function hashData(data: unknown): Promise<string> {\n const subtle = globalThis.crypto?.subtle\n\n if (subtle) {\n const encoded = new TextEncoder().encode(JSON.stringify(data))\n const buffer = await subtle.digest('SHA-1', encoded)\n const array = Array.from(new Uint8Array(buffer))\n\n return array.map((value) => value.toString(16).padStart(2, '0')).join('')\n }\n\n return fastDevHash(data)\n}\n\nexport function resolveUrlParams(\n url: string,\n params?: HttpParam,\n): {\n params: HttpParam | undefined\n url: string\n} {\n if (!params) {\n return {\n params,\n url,\n }\n }\n\n const usedKeys: Record<string, true> = {}\n const resolvedUrl = url.replaceAll(/:(\\w+)/g, (segment, key: string) => {\n const value = params[key]\n\n if (value === undefined) {\n return segment\n }\n\n usedKeys[key] = true\n return encodeURIComponent(String(value))\n })\n const queryParams = Object.entries(params).reduce<HttpParam>((acc, [key, value]) => {\n if (usedKeys[key]) {\n return acc\n }\n\n acc[key] = value\n return acc\n }, {})\n\n return {\n params: Object.keys(queryParams).length > 0 ? queryParams : undefined,\n url: resolvedUrl,\n }\n}\n","import { useState } from 'nuxt/app'\nimport { onScopeDispose, shallowReactive } from 'vue'\n\nimport type { GetConfig, HttpClient, HttpErrorGuard, HttpKey, HttpParam, HttpResponseData } from './http'\n\nimport { createURL, hashData } from './utils'\n\nconst DAY = 1000 * 60 * 60 * 24\nconst DEFAULT_CHANNEL_NAME = 'http-tab-sync'\nconst DEFAULT_TTL = DAY * 7\nexport interface CreateUseHttpDependencies {\n channelName?: string\n getCache: () => null | UseHttpCache\n getHttpClient: () => HttpClient\n isDev?: () => boolean\n isError?: HttpErrorGuard<unknown>\n ttl?: number\n}\n\nexport type HttpError = HttpErrorMap[keyof HttpErrorMap]\nexport interface HttpErrorMap {}\nexport type HttpSuccessData<TKey extends HttpKey = HttpKey> = Exclude<HttpResponseData<TKey>, HttpError>\n\nexport interface UseHttpCache {\n deleteKeysWithPart: (part: string) => Promise<void>\n get: <T>(key: string) => Promise<null | UseHttpCacheEntry<T>>\n set: <T>(key: string, value: T, ttl: number) => Promise<void>\n}\n\nexport interface UseHttpCacheEntry<T> {\n hash: string\n value: T\n}\n\nexport interface UseHttpFn {\n <T extends HttpKey, P extends HttpParam>(options: UseHttpOptions<T, P>): Promise<UseHttpResult<T, P>>\n}\n\nexport interface UseHttpOptions<T extends HttpKey, P extends HttpParam> {\n effect?: UseHttpEffect<T, P>\n initParams?: P\n isError?: (payload: HttpResponseData<T>) => boolean\n lazy?: true\n server?: boolean\n url: T\n}\n\nexport interface UseHttpResult<T extends HttpKey, P extends HttpParam> {\n data: HttpSuccessData<T> | null\n error: null | UseHttpError<T>\n fetch: UseHttpFetch<P>\n hasFirstData: boolean\n hasFreshData: boolean\n pending: boolean\n pendingCache: boolean\n}\n\ntype BroadcastMessage = {\n data: unknown\n fullUrl: string\n params: HttpParam\n type: 'STATE_UPDATE'\n}\n\ntype UseHttpEffect<T extends HttpKey, P extends HttpParam> = (\n data: HttpResponseData<T>,\n config: UseHttpEffectConfig<P>,\n) => undefined\ntype UseHttpEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\ntype UseHttpError<T extends HttpKey> = Extract<HttpResponseData<T>, HttpError>\ntype UseHttpFetch<P extends HttpParam> = (\n params?: UseHttpFetchParams<P>,\n opt?: { signal: AbortSignal },\n) => Promise<void>\ntype UseHttpFetchParams<P extends HttpParam> = [keyof P] extends [never] ? never : P\n\nexport function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpFn {\n let channel: BroadcastChannel | null\n\n const useHttp: UseHttpFn = async <T extends HttpKey, P extends HttpParam>(\n options: UseHttpOptions<T, P>,\n ): Promise<UseHttpResult<T, P>> => {\n const resolveParams = (params?: P): P => params ?? ({} as P)\n const effect = options.effect\n const isError = createIsErrorGuard(options.isError, dependencies.isError)\n\n const buildUrl = createURL\n const initFullUrl = buildUrl(options.url, resolveParams(options.initParams))\n const httpClient = dependencies.getHttpClient()\n const cache = import.meta.client ? (dependencies.getCache?.() ?? null) : null\n const result = shallowReactive({\n data: null as null | unknown,\n error: null as null | unknown,\n fetch: async (_params?: P, _opt?: { signal: AbortSignal }): Promise<void> => await undefined,\n hasFirstData: false,\n hasFreshData: false,\n pending: true,\n pendingCache: true,\n })\n const setError = (value: null | unknown): void => {\n result.error = value\n }\n const setData = (value: null | unknown): void => {\n result.data = value\n }\n const syncResult = (payload: HttpResponseData<T> | null | undefined): void => {\n if (payload === null || payload === undefined) {\n setData(null)\n setError(null)\n return\n }\n\n if (isError(payload)) {\n setData(null)\n setError(payload)\n return\n }\n\n setData(payload)\n setError(null)\n }\n\n const controller = new AbortController()\n const serverData = useState<null | unknown>(`http-${initFullUrl}`, () => null)\n\n if (options.server && import.meta.server) {\n const mappedParams = resolveParams(options.initParams)\n\n try {\n const response = await httpClient.get<T>(options.url, {\n params: mappedParams,\n } as GetConfig<T>)\n const responsePayload = response.data as HttpResponseData<T>\n\n serverData.value = responsePayload\n\n effect?.(responsePayload, {\n cached: false,\n params: mappedParams,\n })\n syncResult(responsePayload)\n result.hasFirstData = true\n result.hasFreshData = true\n } catch (error) {\n console.error(error)\n } finally {\n result.pending = false\n result.pendingCache = false\n }\n }\n\n if (import.meta.client) {\n channel = getChannel(dependencies.channelName ?? DEFAULT_CHANNEL_NAME, channel)\n const fullUrlHistory: Record<string, true> = {}\n\n function onMessage(event: MessageEvent<Partial<BroadcastMessage>>): void {\n if (event.data.fullUrl && fullUrlHistory[event.data.fullUrl]) {\n const eventPayload = event.data.data as HttpResponseData<T> | undefined\n\n if (eventPayload) {\n effect?.(eventPayload, {\n cached: false,\n params: event.data.params as P,\n })\n }\n\n syncResult(eventPayload)\n\n result.hasFirstData = true\n result.hasFreshData = true\n }\n }\n\n channel?.addEventListener('message', onMessage)\n\n if (serverData.value) {\n const clientServerPayload = serverData.value as HttpResponseData<T>\n syncResult(clientServerPayload)\n result.pending = false\n result.pendingCache = false\n result.hasFirstData = true\n result.hasFreshData = true\n }\n\n const raceCondition: Record<string, number> = {}\n const ttl = dependencies.ttl ?? DEFAULT_TTL\n\n const runFetch = async (params?: P, fetchOpt?: { signal?: AbortSignal }): Promise<void> => {\n const mappedParams = resolveParams(params)\n const fullUrl = buildUrl(options.url, mappedParams)\n const fetchId = Date.now() + getRandom(0, 300)\n\n if (raceCondition[fullUrl]) {\n console.info('Race Condition affect', fullUrl)\n return\n }\n\n raceCondition[fullUrl] = fetchId\n\n try {\n result.pending = true\n result.pendingCache = true\n\n const cachedFetch = cache && !dependencies.isDev?.() ? await cache.get<unknown>(fullUrl) : null\n\n if (cachedFetch) {\n const cachedPayload = cachedFetch.value as HttpResponseData<T>\n\n effect?.(cachedPayload, {\n cached: true,\n params: mappedParams,\n })\n\n syncResult(cachedPayload)\n result.hasFirstData = true\n\n result.pendingCache = false\n }\n\n if (controller.signal.aborted || fetchOpt?.signal?.aborted) {\n throw new DOMException('Aborted', 'AbortError')\n }\n\n const signalHttp = fetchOpt?.signal ? [controller.signal, fetchOpt.signal] : controller.signal\n const response = await httpClient.get<T>(options.url, {\n params: mappedParams,\n signal: signalHttp,\n } as GetConfig<T>)\n const responsePayload = response.data as HttpResponseData<T>\n\n effect?.(responsePayload, {\n cached: false,\n params: mappedParams,\n })\n\n if (isError(responsePayload)) {\n syncResult(responsePayload)\n } else {\n syncResult(responsePayload)\n const successData = responsePayload\n\n fullUrlHistory[fullUrl] = true\n channel?.postMessage({\n data: normalizeBroadcastValue(successData),\n fullUrl,\n params: normalizeBroadcastValue(mappedParams),\n type: 'STATE_UPDATE',\n } satisfies BroadcastMessage)\n\n if (cache) {\n if (cachedFetch) {\n const newHash = await hashData(responsePayload)\n if (newHash !== cachedFetch.hash) {\n await cache.deleteKeysWithPart(options.url)\n }\n }\n\n if (response.status === 200) {\n await cache.set(fullUrl, successData, ttl)\n }\n }\n }\n\n result.hasFirstData = true\n result.hasFreshData = true\n } catch (error) {\n console.error(error)\n } finally {\n if (raceCondition[fullUrl] === fetchId) {\n delete raceCondition[fullUrl]\n }\n\n result.pending = false\n result.pendingCache = false\n }\n }\n\n result.fetch = runFetch\n\n if (options.lazy !== true) {\n runFetch(options.initParams)\n }\n\n onScopeDispose(() => {\n channel?.removeEventListener('message', onMessage)\n controller.abort(`Http Abort -> onScopeDispose ${options.url}`)\n\n if (serverData.value) {\n serverData.value = null\n }\n })\n }\n\n return result as UseHttpResult<T, P>\n }\n\n return useHttp\n}\n\nfunction createIsErrorGuard<TData>(\n localGuard?: (payload: TData) => boolean,\n globalGuard?: HttpErrorGuard<unknown>,\n): (payload: TData) => boolean {\n if (localGuard) {\n return localGuard\n }\n\n if (globalGuard) {\n return globalGuard as (payload: TData) => boolean\n }\n\n return (): boolean => false\n}\n\nfunction getChannel(name: string, currentChannel?: BroadcastChannel | null): BroadcastChannel | null {\n if (currentChannel) {\n return currentChannel\n }\n\n if (import.meta.server || typeof BroadcastChannel !== 'function') {\n return null\n }\n\n return new BroadcastChannel(name)\n}\n\nfunction getRandom(min: number, max: number): number {\n return Math.floor(Math.random() * (max - min + 1)) + min\n}\n\nfunction normalizeBroadcastValue<T>(payload: T): T {\n try {\n return structuredClone(payload)\n } catch {\n return JSON.parse(JSON.stringify(payload)) as T\n }\n}\n"],"mappings":"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"}