@brickflow/http 0.0.24 → 0.0.26
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 +2 -8
- package/dist/create-get.d.ts +3 -2
- package/dist/create-get.d.ts.map +1 -1
- package/dist/index.mjs +1 -2
- package/dist/index.mjs.map +1 -1
- package/dist/{nuxt-CcmCJhA5.js → nuxt-DJ1jOcX4.js} +7 -10
- package/dist/nuxt-DJ1jOcX4.js.map +1 -0
- package/dist/nuxt.d.ts +2 -2
- package/dist/nuxt.d.ts.map +1 -1
- package/dist/nuxt.mjs +1 -1
- package/package.json +1 -1
- package/src/create-get.ts +3 -3
- package/src/nuxt.ts +11 -15
- package/dist/nuxt-CcmCJhA5.js.map +0 -1
package/README.md
CHANGED
|
@@ -206,7 +206,6 @@ export const createGet = defineGet(useHttp)
|
|
|
206
206
|
|
|
207
207
|
- `url`
|
|
208
208
|
- `initParams`
|
|
209
|
-
- `mapParams`
|
|
210
209
|
- `effect`
|
|
211
210
|
- `isError`
|
|
212
211
|
- `lazy`
|
|
@@ -306,11 +305,7 @@ products: createGet<{
|
|
|
306
305
|
1. Базовые настройки endpoint-а при объявлении:
|
|
307
306
|
|
|
308
307
|
```ts
|
|
309
|
-
const products = createGet<{ limit: number }>()('/products'
|
|
310
|
-
mapParams: (params) => ({
|
|
311
|
-
limit: params?.limit ?? 10,
|
|
312
|
-
}),
|
|
313
|
-
})
|
|
308
|
+
const products = createGet<{ limit: number }>()('/products')
|
|
314
309
|
```
|
|
315
310
|
|
|
316
311
|
2. Runtime-опции при вызове:
|
|
@@ -323,11 +318,10 @@ const productsHttp = await products({
|
|
|
323
318
|
})
|
|
324
319
|
```
|
|
325
320
|
|
|
326
|
-
Если `effect
|
|
321
|
+
Если `effect` или `isError` указаны и при объявлении, и при вызове, пакет объединяет их так:
|
|
327
322
|
|
|
328
323
|
- `effect` вызывает оба обработчика
|
|
329
324
|
- `isError` из runtime имеет приоритет
|
|
330
|
-
- `mapParams` из runtime имеет приоритет
|
|
331
325
|
|
|
332
326
|
## createUseCase
|
|
333
327
|
|
package/dist/create-get.d.ts
CHANGED
|
@@ -3,14 +3,14 @@ import type { HttpError, UseHttpFn, UseHttpOptions, UseHttpResult } from './nuxt
|
|
|
3
3
|
export interface CreateGetFactory<P extends HttpParam> {
|
|
4
4
|
<T extends string>(url: T, payload?: CreateGetPayload<T, CreateGetParams<T, P>>): (options?: CreateGetOptions<T, CreateGetParams<T, P>>) => Promise<CreateGetResult<T, CreateGetParams<T, P>>>;
|
|
5
5
|
}
|
|
6
|
-
export type CreateGetOptions<T extends string, P extends HttpParam> = Omit<UseHttpOptions<HttpKey, P>, 'effect' | 'isError' | 'url'> & {
|
|
6
|
+
export type CreateGetOptions<T extends string, P extends HttpParam> = Omit<UseHttpOptions<HttpKey, P>, 'effect' | 'initParams' | 'isError' | 'url'> & {
|
|
7
7
|
effect?: CreateGetEffect<T, P>;
|
|
8
|
+
initParams?: CreateGetInitParams<P>;
|
|
8
9
|
isError?: CreateGetIsError<T>;
|
|
9
10
|
};
|
|
10
11
|
export type CreateGetPayload<T extends string, P extends HttpParam> = {
|
|
11
12
|
effect?: CreateGetEffect<T, P>;
|
|
12
13
|
isError?: CreateGetIsError<T>;
|
|
13
|
-
mapParams?: UseHttpOptions<HttpKey, P>['mapParams'];
|
|
14
14
|
};
|
|
15
15
|
export type CreateGetResult<T extends string, P extends HttpParam> = Omit<UseHttpResult<HttpKey, P>, 'data' | 'error'> & {
|
|
16
16
|
data: Exclude<CreateGetData<T>, HttpError> | null;
|
|
@@ -23,6 +23,7 @@ type CreateGetEffectConfig<P extends HttpParam> = {
|
|
|
23
23
|
params: P;
|
|
24
24
|
};
|
|
25
25
|
type CreateGetEmptyParams = Record<never, never>;
|
|
26
|
+
type CreateGetInitParams<P extends HttpParam> = [keyof P] extends [never] ? never : P;
|
|
26
27
|
type CreateGetIsError<T extends string> = (payload: CreateGetData<T>) => boolean;
|
|
27
28
|
type CreateGetParamKeys<T extends string> = T extends `${string}:${infer Rest}` ? Rest extends `${infer Key}/${infer Tail}` ? CreateGetParamKeys<`/${Tail}`> | Key : Rest : never;
|
|
28
29
|
type CreateGetParams<T extends string, P extends HttpParam> = Omit<CreateGetPathParams<T>, keyof P> & P;
|
package/dist/create-get.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"create-get.d.ts","sourceRoot":"","sources":["../src/create-get.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAC9E,OAAO,KAAK,EAAE,SAAS,EAAE,SAAS,EAAE,cAAc,EAAE,aAAa,EAAE,MAAM,QAAQ,CAAA;AAEjF,MAAM,WAAW,gBAAgB,CAAC,CAAC,SAAS,SAAS;IACnD,CAAC,CAAC,SAAS,MAAM,EACf,GAAG,EAAE,CAAC,EACN,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GACnD,CAAC,OAAO,CAAC,EAAE,gBAAgB,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,OAAO,CAAC,eAAe,CAAC,CAAC,EAAE,eAAe,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAA;CAChH;AACD,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,SAAS,SAAS,IAAI,IAAI,CACxE,cAAc,CAAC,OAAO,EAAE,CAAC,CAAC,EAC1B,QAAQ,GAAG,SAAS,GAAG,KAAK,
|
|
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,4 +1,4 @@
|
|
|
1
|
-
import { n as resolveUrlParams, t as createUseHttp } from "./nuxt-
|
|
1
|
+
import { n as resolveUrlParams, t as createUseHttp } from "./nuxt-DJ1jOcX4.js";
|
|
2
2
|
//#region src/create-get.ts
|
|
3
3
|
function createUseCase() {
|
|
4
4
|
return (callback) => callback;
|
|
@@ -14,7 +14,6 @@ function defineGet(useHttp) {
|
|
|
14
14
|
options?.effect?.(data, config);
|
|
15
15
|
},
|
|
16
16
|
isError: options.isError ?? payload?.isError,
|
|
17
|
-
mapParams: options.mapParams ?? payload?.mapParams,
|
|
18
17
|
url
|
|
19
18
|
});
|
|
20
19
|
};
|
package/dist/index.mjs.map
CHANGED
|
@@ -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' | 'isError' | 'url'\n> & {\n effect?: CreateGetEffect<T, P>\n isError?: CreateGetIsError<T>\n}\nexport type CreateGetPayload<T extends string, P extends HttpParam> = {\n effect?: CreateGetEffect<T, P>\n isError?: CreateGetIsError<T>\n mapParams?: UseHttpOptions<HttpKey, P>['mapParams']\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}\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) => void\ntype CreateGetEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\ntype CreateGetEmptyParams = Record<never, never>\n\ntype CreateGetIsError<T extends string> = (payload: CreateGetData<T>) => boolean\n\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\ntype CreateGetParams<T extends string, P extends HttpParam> = Omit<CreateGetPathParams<T>, keyof P> & P\ntype CreateGetPathParams<T extends string> = [CreateGetParamKeys<T>] extends [never]\n ? CreateGetEmptyParams\n : {\n [K in CreateGetParamKeys<T>]: string\n }\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 mapParams: options.mapParams ?? payload?.mapParams,\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 ?? 80000\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 (err) {\n if (isAbortError(err) || attempt >= retries) {\n throw err\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":"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"}
|
|
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 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}\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) => void\ntype CreateGetEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\ntype CreateGetEmptyParams = Record<never, never>\ntype CreateGetInitParams<P extends HttpParam> = [keyof P] extends [never] ? never : P\n\ntype CreateGetIsError<T extends string> = (payload: CreateGetData<T>) => boolean\n\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\ntype CreateGetParams<T extends string, P extends HttpParam> = Omit<CreateGetPathParams<T>, keyof P> & P\ntype CreateGetPathParams<T extends string> = [CreateGetParamKeys<T>] extends [never]\n ? CreateGetEmptyParams\n : {\n [K in CreateGetParamKeys<T>]: string\n }\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 ?? 80000\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 (err) {\n if (isAbortError(err) || attempt >= retries) {\n throw err\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":"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"}
|
|
@@ -66,14 +66,11 @@ const DEFAULT_TTL = DAY * 7;
|
|
|
66
66
|
function createUseHttp(dependencies) {
|
|
67
67
|
let channel;
|
|
68
68
|
const useHttp = async (options) => {
|
|
69
|
-
const
|
|
70
|
-
if (options.mapParams) return options.mapParams(params);
|
|
71
|
-
return params ?? {};
|
|
72
|
-
};
|
|
69
|
+
const resolveParams = (params) => params ?? {};
|
|
73
70
|
const effect = options.effect;
|
|
74
71
|
const isError = createIsErrorGuard(options.isError, dependencies.isError);
|
|
75
72
|
const buildUrl = createURL;
|
|
76
|
-
const initFullUrl = buildUrl(options.url,
|
|
73
|
+
const initFullUrl = buildUrl(options.url, resolveParams(options.initParams));
|
|
77
74
|
const httpClient = dependencies.getHttpClient();
|
|
78
75
|
const cache = import.meta.client ? dependencies.getCache?.() ?? null : null;
|
|
79
76
|
let hasDataFromServer = false;
|
|
@@ -109,12 +106,12 @@ function createUseHttp(dependencies) {
|
|
|
109
106
|
const controller = new AbortController();
|
|
110
107
|
const serverData = useState(`http-${initFullUrl}`, () => null);
|
|
111
108
|
if (options.server && import.meta.server) {
|
|
112
|
-
const paramsReactive = shallowRef(
|
|
109
|
+
const paramsReactive = shallowRef(resolveParams(options.initParams));
|
|
113
110
|
const ssr = await useLazyAsyncData(initFullUrl, async () => {
|
|
114
111
|
return await httpClient.get(options.url, { params: paramsReactive.value });
|
|
115
112
|
});
|
|
116
113
|
result.fetch = async (params) => {
|
|
117
|
-
paramsReactive.value =
|
|
114
|
+
paramsReactive.value = resolveParams(params);
|
|
118
115
|
await ssr.refresh();
|
|
119
116
|
};
|
|
120
117
|
serverData.value = ssr.data.value?.data ?? null;
|
|
@@ -126,7 +123,7 @@ function createUseHttp(dependencies) {
|
|
|
126
123
|
result.hasFreshData = true;
|
|
127
124
|
if (serverData.value) effect?.(serverData.value, {
|
|
128
125
|
cached: false,
|
|
129
|
-
params:
|
|
126
|
+
params: resolveParams(options.initParams)
|
|
130
127
|
});
|
|
131
128
|
if (result.data) hasDataFromServer = true;
|
|
132
129
|
}
|
|
@@ -157,7 +154,7 @@ function createUseHttp(dependencies) {
|
|
|
157
154
|
const raceCondition = {};
|
|
158
155
|
const ttl = dependencies.ttl ?? DEFAULT_TTL;
|
|
159
156
|
const runFetch = async (params, fetchOpt) => {
|
|
160
|
-
const mappedParams =
|
|
157
|
+
const mappedParams = resolveParams(params);
|
|
161
158
|
const fullUrl = buildUrl(options.url, mappedParams);
|
|
162
159
|
const fetchId = Date.now() + getRandom(0, 300);
|
|
163
160
|
if (raceCondition[fullUrl]) {
|
|
@@ -253,4 +250,4 @@ function normalizeBroadcastValue(payload) {
|
|
|
253
250
|
//#endregion
|
|
254
251
|
export { resolveUrlParams as n, createUseHttp as t };
|
|
255
252
|
|
|
256
|
-
//# sourceMappingURL=nuxt-
|
|
253
|
+
//# sourceMappingURL=nuxt-DJ1jOcX4.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nuxt-DJ1jOcX4.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 { useLazyAsyncData, useState } from 'nuxt/app'\nimport { onScopeDispose, shallowReactive, shallowRef } 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) => void\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 let hasDataFromServer = false\n\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 paramsReactive = shallowRef(resolveParams(options.initParams))\n const ssr = await useLazyAsyncData(initFullUrl, async () => {\n return await httpClient.get<T>(options.url, {\n params: paramsReactive.value,\n } as GetConfig<T>)\n })\n\n result.fetch = async (params?: P) => {\n paramsReactive.value = resolveParams(params)\n await ssr.refresh()\n }\n\n serverData.value = ssr.data.value?.data ?? null\n const serverPayload = serverData.value as HttpResponseData<T>\n syncResult(serverPayload)\n\n result.pending = false\n result.pendingCache = false\n result.hasFirstData = true\n result.hasFreshData = true\n\n if (serverData.value) {\n effect?.(serverData.value as HttpResponseData<T>, {\n cached: false,\n params: resolveParams(options.initParams),\n })\n }\n\n if (result.data) {\n hasDataFromServer = true\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 (!hasDataFromServer && 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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"}
|
package/dist/nuxt.d.ts
CHANGED
|
@@ -28,7 +28,6 @@ export interface UseHttpOptions<T extends HttpKey, P extends HttpParam> {
|
|
|
28
28
|
initParams?: P;
|
|
29
29
|
isError?: (payload: HttpResponseData<T>) => boolean;
|
|
30
30
|
lazy?: true;
|
|
31
|
-
mapParams?: (params?: P) => P;
|
|
32
31
|
server?: boolean;
|
|
33
32
|
url: T;
|
|
34
33
|
}
|
|
@@ -47,9 +46,10 @@ type UseHttpEffectConfig<P extends HttpParam> = {
|
|
|
47
46
|
params: P;
|
|
48
47
|
};
|
|
49
48
|
type UseHttpError<T extends HttpKey> = Extract<HttpResponseData<T>, HttpError>;
|
|
50
|
-
type UseHttpFetch<P extends HttpParam> = (params?: P
|
|
49
|
+
type UseHttpFetch<P extends HttpParam> = (params?: UseHttpFetchParams<P>, opt?: {
|
|
51
50
|
signal: AbortSignal;
|
|
52
51
|
}) => Promise<void>;
|
|
52
|
+
type UseHttpFetchParams<P extends HttpParam> = [keyof P] extends [never] ? never : P;
|
|
53
53
|
export declare function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpFn;
|
|
54
54
|
export {};
|
|
55
55
|
//# sourceMappingURL=nuxt.d.ts.map
|
package/dist/nuxt.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt.d.ts","sourceRoot":"","sources":["../src/nuxt.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAa,UAAU,EAAE,cAAc,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAA;AAOzG,MAAM,WAAW,yBAAyB;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,QAAQ,EAAE,MAAM,IAAI,GAAG,YAAY,CAAA;IACnC,aAAa,EAAE,MAAM,UAAU,CAAA;IAC/B,KAAK,CAAC,EAAE,MAAM,OAAO,CAAA;IACrB,OAAO,CAAC,EAAE,cAAc,CAAC,OAAO,CAAC,CAAA;IACjC,GAAG,CAAC,EAAE,MAAM,CAAA;CACb;AAED,MAAM,MAAM,SAAS,GAAG,YAAY,CAAC,MAAM,YAAY,CAAC,CAAA;AACxD,MAAM,WAAW,YAAY;CAAG;AAChC,MAAM,MAAM,eAAe,CAAC,IAAI,SAAS,OAAO,GAAG,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,SAAS,CAAC,CAAA;AAExG,MAAM,WAAW,YAAY;IAC3B,kBAAkB,EAAE,CAAC,IAAI,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACnD,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,GAAG,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAA;IAC7D,GAAG,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC,EAAE,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;CAC9D;AAED,MAAM,WAAW,iBAAiB,CAAC,CAAC;IAClC,IAAI,EAAE,MAAM,CAAA;IACZ,KAAK,EAAE,CAAC,CAAA;CACT;AAED,MAAM,WAAW,SAAS;IACxB,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC,EAAE,CAAC,CAAC,GAAG,OAAO,CAAC,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,CAAA;CACtG;AAED,MAAM,WAAW,cAAc,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS;IACpE,MAAM,CAAC,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IAC5B,UAAU,CAAC,EAAE,CAAC,CAAA;IACd,OAAO,CAAC,EAAE,CAAC,OAAO,EAAE,gBAAgB,CAAC,CAAC,CAAC,KAAK,OAAO,CAAA;IACnD,IAAI,CAAC,EAAE,IAAI,CAAA;IACX,
|
|
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,2 @@
|
|
|
1
|
-
import { t as createUseHttp } from "./nuxt-
|
|
1
|
+
import { t as createUseHttp } from "./nuxt-DJ1jOcX4.js";
|
|
2
2
|
export { createUseHttp };
|
package/package.json
CHANGED
package/src/create-get.ts
CHANGED
|
@@ -9,15 +9,15 @@ export interface CreateGetFactory<P extends HttpParam> {
|
|
|
9
9
|
}
|
|
10
10
|
export type CreateGetOptions<T extends string, P extends HttpParam> = Omit<
|
|
11
11
|
UseHttpOptions<HttpKey, P>,
|
|
12
|
-
'effect' | 'isError' | 'url'
|
|
12
|
+
'effect' | 'initParams' | 'isError' | 'url'
|
|
13
13
|
> & {
|
|
14
14
|
effect?: CreateGetEffect<T, P>
|
|
15
|
+
initParams?: CreateGetInitParams<P>
|
|
15
16
|
isError?: CreateGetIsError<T>
|
|
16
17
|
}
|
|
17
18
|
export type CreateGetPayload<T extends string, P extends HttpParam> = {
|
|
18
19
|
effect?: CreateGetEffect<T, P>
|
|
19
20
|
isError?: CreateGetIsError<T>
|
|
20
|
-
mapParams?: UseHttpOptions<HttpKey, P>['mapParams']
|
|
21
21
|
}
|
|
22
22
|
export type CreateGetResult<T extends string, P extends HttpParam> = Omit<
|
|
23
23
|
UseHttpResult<HttpKey, P>,
|
|
@@ -37,6 +37,7 @@ type CreateGetEffectConfig<P extends HttpParam> = {
|
|
|
37
37
|
params: P
|
|
38
38
|
}
|
|
39
39
|
type CreateGetEmptyParams = Record<never, never>
|
|
40
|
+
type CreateGetInitParams<P extends HttpParam> = [keyof P] extends [never] ? never : P
|
|
40
41
|
|
|
41
42
|
type CreateGetIsError<T extends string> = (payload: CreateGetData<T>) => boolean
|
|
42
43
|
|
|
@@ -76,7 +77,6 @@ export function defineGet(useHttp: UseHttpFn) {
|
|
|
76
77
|
options?.effect?.(data as CreateGetData<T>, config)
|
|
77
78
|
},
|
|
78
79
|
isError: options.isError ?? payload?.isError,
|
|
79
|
-
mapParams: options.mapParams ?? payload?.mapParams,
|
|
80
80
|
url,
|
|
81
81
|
} as UseHttpOptions<HttpKey, CreateGetParams<T, P>>)
|
|
82
82
|
|
package/src/nuxt.ts
CHANGED
|
@@ -41,7 +41,6 @@ export interface UseHttpOptions<T extends HttpKey, P extends HttpParam> {
|
|
|
41
41
|
initParams?: P
|
|
42
42
|
isError?: (payload: HttpResponseData<T>) => boolean
|
|
43
43
|
lazy?: true
|
|
44
|
-
mapParams?: (params?: P) => P
|
|
45
44
|
server?: boolean
|
|
46
45
|
url: T
|
|
47
46
|
}
|
|
@@ -72,8 +71,11 @@ type UseHttpEffectConfig<P extends HttpParam> = {
|
|
|
72
71
|
params: P
|
|
73
72
|
}
|
|
74
73
|
type UseHttpError<T extends HttpKey> = Extract<HttpResponseData<T>, HttpError>
|
|
75
|
-
|
|
76
|
-
|
|
74
|
+
type UseHttpFetch<P extends HttpParam> = (
|
|
75
|
+
params?: UseHttpFetchParams<P>,
|
|
76
|
+
opt?: { signal: AbortSignal },
|
|
77
|
+
) => Promise<void>
|
|
78
|
+
type UseHttpFetchParams<P extends HttpParam> = [keyof P] extends [never] ? never : P
|
|
77
79
|
|
|
78
80
|
export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpFn {
|
|
79
81
|
let channel: BroadcastChannel | null
|
|
@@ -81,18 +83,12 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
81
83
|
const useHttp: UseHttpFn = async <T extends HttpKey, P extends HttpParam>(
|
|
82
84
|
options: UseHttpOptions<T, P>,
|
|
83
85
|
): Promise<UseHttpResult<T, P>> => {
|
|
84
|
-
const
|
|
85
|
-
if (options.mapParams) {
|
|
86
|
-
return options.mapParams(params)
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
return params ?? ({} as P)
|
|
90
|
-
}
|
|
86
|
+
const resolveParams = (params?: P): P => params ?? ({} as P)
|
|
91
87
|
const effect = options.effect
|
|
92
88
|
const isError = createIsErrorGuard(options.isError, dependencies.isError)
|
|
93
89
|
|
|
94
90
|
const buildUrl = createURL
|
|
95
|
-
const initFullUrl = buildUrl(options.url,
|
|
91
|
+
const initFullUrl = buildUrl(options.url, resolveParams(options.initParams))
|
|
96
92
|
const httpClient = dependencies.getHttpClient()
|
|
97
93
|
const cache = import.meta.client ? (dependencies.getCache?.() ?? null) : null
|
|
98
94
|
let hasDataFromServer = false
|
|
@@ -133,7 +129,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
133
129
|
const serverData = useState<null | unknown>(`http-${initFullUrl}`, () => null)
|
|
134
130
|
|
|
135
131
|
if (options.server && import.meta.server) {
|
|
136
|
-
const paramsReactive = shallowRef(
|
|
132
|
+
const paramsReactive = shallowRef(resolveParams(options.initParams))
|
|
137
133
|
const ssr = await useLazyAsyncData(initFullUrl, async () => {
|
|
138
134
|
return await httpClient.get<T>(options.url, {
|
|
139
135
|
params: paramsReactive.value,
|
|
@@ -141,7 +137,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
141
137
|
})
|
|
142
138
|
|
|
143
139
|
result.fetch = async (params?: P) => {
|
|
144
|
-
paramsReactive.value =
|
|
140
|
+
paramsReactive.value = resolveParams(params)
|
|
145
141
|
await ssr.refresh()
|
|
146
142
|
}
|
|
147
143
|
|
|
@@ -157,7 +153,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
157
153
|
if (serverData.value) {
|
|
158
154
|
effect?.(serverData.value as HttpResponseData<T>, {
|
|
159
155
|
cached: false,
|
|
160
|
-
params:
|
|
156
|
+
params: resolveParams(options.initParams),
|
|
161
157
|
})
|
|
162
158
|
}
|
|
163
159
|
|
|
@@ -203,7 +199,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
203
199
|
const ttl = dependencies.ttl ?? DEFAULT_TTL
|
|
204
200
|
|
|
205
201
|
const runFetch = async (params?: P, fetchOpt?: { signal?: AbortSignal }): Promise<void> => {
|
|
206
|
-
const mappedParams =
|
|
202
|
+
const mappedParams = resolveParams(params)
|
|
207
203
|
const fullUrl = buildUrl(options.url, mappedParams)
|
|
208
204
|
const fetchId = Date.now() + getRandom(0, 300)
|
|
209
205
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt-CcmCJhA5.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 { useLazyAsyncData, useState } from 'nuxt/app'\nimport { onScopeDispose, shallowReactive, shallowRef } 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 mapParams?: (params?: P) => P\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) => void\ntype UseHttpEffectConfig<P extends HttpParam> = {\n cached: boolean\n params: P\n}\ntype UseHttpError<T extends HttpKey> = Extract<HttpResponseData<T>, HttpError>\n\ntype UseHttpFetch<P extends HttpParam> = (params?: P, opt?: { signal: AbortSignal }) => Promise<void>\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 mapParams = (params?: P): P => {\n if (options.mapParams) {\n return options.mapParams(params)\n }\n\n return params ?? ({} as P)\n }\n const effect = options.effect\n const isError = createIsErrorGuard(options.isError, dependencies.isError)\n\n const buildUrl = createURL\n const initFullUrl = buildUrl(options.url, mapParams(options.initParams))\n const httpClient = dependencies.getHttpClient()\n const cache = import.meta.client ? (dependencies.getCache?.() ?? null) : null\n let hasDataFromServer = false\n\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 paramsReactive = shallowRef(mapParams(options.initParams))\n const ssr = await useLazyAsyncData(initFullUrl, async () => {\n return await httpClient.get<T>(options.url, {\n params: paramsReactive.value,\n } as GetConfig<T>)\n })\n\n result.fetch = async (params?: P) => {\n paramsReactive.value = mapParams(params)\n await ssr.refresh()\n }\n\n serverData.value = ssr.data.value?.data ?? null\n const serverPayload = serverData.value as HttpResponseData<T>\n syncResult(serverPayload)\n\n result.pending = false\n result.pendingCache = false\n result.hasFirstData = true\n result.hasFreshData = true\n\n if (serverData.value) {\n effect?.(serverData.value as HttpResponseData<T>, {\n cached: false,\n params: mapParams(options.initParams),\n })\n }\n\n if (result.data) {\n hasDataFromServer = true\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 = mapParams(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 (!hasDataFromServer && 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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"}
|