@brickflow/http 0.0.32 → 0.0.34
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/dist/index.mjs +1 -1
- package/dist/{nuxt-BTEWkpXt.js → nuxt-Kmqi3b7w.js} +21 -25
- package/dist/nuxt-Kmqi3b7w.js.map +1 -0
- package/dist/nuxt.d.ts.map +1 -1
- package/dist/nuxt.mjs +1 -1
- package/package.json +1 -1
- package/src/nuxt.ts +20 -30
- package/dist/nuxt-BTEWkpXt.js.map +0 -1
package/dist/index.mjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { onScopeDispose, shallowReactive
|
|
1
|
+
import { useState } from "nuxt/app";
|
|
2
|
+
import { onScopeDispose, shallowReactive } from "vue";
|
|
3
3
|
//#region src/utils.ts
|
|
4
4
|
function createURL(url, params) {
|
|
5
5
|
const resolved = resolveUrlParams(url, params);
|
|
@@ -73,7 +73,6 @@ function createUseHttp(dependencies) {
|
|
|
73
73
|
const initFullUrl = buildUrl(options.url, resolveParams(options.initParams));
|
|
74
74
|
const httpClient = dependencies.getHttpClient();
|
|
75
75
|
const cache = import.meta.client ? dependencies.getCache?.() ?? null : null;
|
|
76
|
-
let hasDataFromServer = false;
|
|
77
76
|
const result = shallowReactive({
|
|
78
77
|
data: null,
|
|
79
78
|
error: null,
|
|
@@ -106,26 +105,23 @@ function createUseHttp(dependencies) {
|
|
|
106
105
|
const controller = new AbortController();
|
|
107
106
|
const serverData = useState(`http-${initFullUrl}`, () => null);
|
|
108
107
|
if (options.server && import.meta.server) {
|
|
109
|
-
const
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
params: resolveParams(options.initParams)
|
|
127
|
-
});
|
|
128
|
-
if (result.data) hasDataFromServer = true;
|
|
108
|
+
const mappedParams = resolveParams(options.initParams);
|
|
109
|
+
try {
|
|
110
|
+
const responsePayload = (await httpClient.get(options.url, { params: mappedParams })).data;
|
|
111
|
+
serverData.value = responsePayload;
|
|
112
|
+
effect?.(responsePayload, {
|
|
113
|
+
cached: false,
|
|
114
|
+
params: mappedParams
|
|
115
|
+
});
|
|
116
|
+
syncResult(responsePayload);
|
|
117
|
+
result.hasFirstData = true;
|
|
118
|
+
result.hasFreshData = true;
|
|
119
|
+
} catch (error) {
|
|
120
|
+
console.error(error);
|
|
121
|
+
} finally {
|
|
122
|
+
result.pending = false;
|
|
123
|
+
result.pendingCache = false;
|
|
124
|
+
}
|
|
129
125
|
}
|
|
130
126
|
if (import.meta.client) {
|
|
131
127
|
channel = getChannel(dependencies.channelName ?? DEFAULT_CHANNEL_NAME, channel);
|
|
@@ -216,7 +212,7 @@ function createUseHttp(dependencies) {
|
|
|
216
212
|
}
|
|
217
213
|
};
|
|
218
214
|
result.fetch = runFetch;
|
|
219
|
-
if (
|
|
215
|
+
if (options.lazy !== true) runFetch(options.initParams);
|
|
220
216
|
onScopeDispose(() => {
|
|
221
217
|
channel?.removeEventListener("message", onMessage);
|
|
222
218
|
controller.abort(`Http Abort -> onScopeDispose ${options.url}`);
|
|
@@ -250,4 +246,4 @@ function normalizeBroadcastValue(payload) {
|
|
|
250
246
|
//#endregion
|
|
251
247
|
export { resolveUrlParams as n, createUseHttp as t };
|
|
252
248
|
|
|
253
|
-
//# sourceMappingURL=nuxt-
|
|
249
|
+
//# sourceMappingURL=nuxt-Kmqi3b7w.js.map
|
|
@@ -0,0 +1 @@
|
|
|
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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"}
|
package/dist/nuxt.d.ts.map
CHANGED
|
@@ -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":"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,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,GAAG,EAAE,CAAC,CAAA;CACP;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS;IACnE,IAAI,EAAE,eAAe,CAAC,CAAC,CAAC,GAAG,IAAI,CAAA;IAC/B,KAAK,EAAE,IAAI,GAAG,YAAY,CAAC,CAAC,CAAC,CAAA;IAC7B,KAAK,EAAE,YAAY,CAAC,CAAC,CAAC,CAAA;IACtB,YAAY,EAAE,OAAO,CAAA;IACrB,YAAY,EAAE,OAAO,CAAA;IACrB,OAAO,EAAE,OAAO,CAAA;IAChB,YAAY,EAAE,OAAO,CAAA;CACtB;AASD,KAAK,aAAa,CAAC,CAAC,SAAS,OAAO,EAAE,CAAC,SAAS,SAAS,IAAI,CAC3D,IAAI,EAAE,gBAAgB,CAAC,CAAC,CAAC,EACzB,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAC3B,SAAS,CAAA;AACd,KAAK,mBAAmB,CAAC,CAAC,SAAS,SAAS,IAAI;IAC9C,MAAM,EAAE,OAAO,CAAA;IACf,MAAM,EAAE,CAAC,CAAA;CACV,CAAA;AACD,KAAK,YAAY,CAAC,CAAC,SAAS,OAAO,IAAI,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,EAAE,SAAS,CAAC,CAAA;AAC9E,KAAK,YAAY,CAAC,CAAC,SAAS,SAAS,IAAI,CACvC,MAAM,CAAC,EAAE,kBAAkB,CAAC,CAAC,CAAC,EAC9B,GAAG,CAAC,EAAE;IAAE,MAAM,EAAE,WAAW,CAAA;CAAE,KAC1B,OAAO,CAAC,IAAI,CAAC,CAAA;AAClB,KAAK,kBAAkB,CAAC,CAAC,SAAS,SAAS,IAAI,CAAC,MAAM,CAAC,CAAC,SAAS,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,CAAA;AAEpF,wBAAgB,aAAa,CAAC,YAAY,EAAE,yBAAyB,GAAG,SAAS,CA6NhF"}
|
package/dist/nuxt.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { t as createUseHttp } from "./nuxt-
|
|
1
|
+
import { t as createUseHttp } from "./nuxt-Kmqi3b7w.js";
|
|
2
2
|
export { createUseHttp };
|
package/package.json
CHANGED
package/src/nuxt.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { onScopeDispose, shallowReactive
|
|
1
|
+
import { useState } from 'nuxt/app'
|
|
2
|
+
import { onScopeDispose, shallowReactive } from 'vue'
|
|
3
3
|
|
|
4
4
|
import type { GetConfig, HttpClient, HttpErrorGuard, HttpKey, HttpParam, HttpResponseData } from './http'
|
|
5
5
|
|
|
@@ -91,8 +91,6 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
91
91
|
const initFullUrl = buildUrl(options.url, resolveParams(options.initParams))
|
|
92
92
|
const httpClient = dependencies.getHttpClient()
|
|
93
93
|
const cache = import.meta.client ? (dependencies.getCache?.() ?? null) : null
|
|
94
|
-
let hasDataFromServer = false
|
|
95
|
-
|
|
96
94
|
const result = shallowReactive({
|
|
97
95
|
data: null as null | unknown,
|
|
98
96
|
error: null as null | unknown,
|
|
@@ -129,36 +127,28 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
129
127
|
const serverData = useState<null | unknown>(`http-${initFullUrl}`, () => null)
|
|
130
128
|
|
|
131
129
|
if (options.server && import.meta.server) {
|
|
132
|
-
const
|
|
133
|
-
const ssr = await useLazyAsyncData(initFullUrl, async () => {
|
|
134
|
-
return await httpClient.get<T>(options.url, {
|
|
135
|
-
params: paramsReactive.value,
|
|
136
|
-
} as GetConfig<T>)
|
|
137
|
-
})
|
|
130
|
+
const mappedParams = resolveParams(options.initParams)
|
|
138
131
|
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
serverData.value = ssr.data.value?.data ?? null
|
|
145
|
-
const serverPayload = serverData.value as HttpResponseData<T>
|
|
146
|
-
syncResult(serverPayload)
|
|
132
|
+
try {
|
|
133
|
+
const response = await httpClient.get<T>(options.url, {
|
|
134
|
+
params: mappedParams,
|
|
135
|
+
} as GetConfig<T>)
|
|
136
|
+
const responsePayload = response.data as HttpResponseData<T>
|
|
147
137
|
|
|
148
|
-
|
|
149
|
-
result.pendingCache = false
|
|
150
|
-
result.hasFirstData = true
|
|
151
|
-
result.hasFreshData = true
|
|
138
|
+
serverData.value = responsePayload
|
|
152
139
|
|
|
153
|
-
|
|
154
|
-
effect?.(serverData.value as HttpResponseData<T>, {
|
|
140
|
+
effect?.(responsePayload, {
|
|
155
141
|
cached: false,
|
|
156
|
-
params:
|
|
142
|
+
params: mappedParams,
|
|
157
143
|
})
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
144
|
+
syncResult(responsePayload)
|
|
145
|
+
result.hasFirstData = true
|
|
146
|
+
result.hasFreshData = true
|
|
147
|
+
} catch (error) {
|
|
148
|
+
console.error(error)
|
|
149
|
+
} finally {
|
|
150
|
+
result.pending = false
|
|
151
|
+
result.pendingCache = false
|
|
162
152
|
}
|
|
163
153
|
}
|
|
164
154
|
|
|
@@ -290,7 +280,7 @@ export function createUseHttp(dependencies: CreateUseHttpDependencies): UseHttpF
|
|
|
290
280
|
|
|
291
281
|
result.fetch = runFetch
|
|
292
282
|
|
|
293
|
-
if (
|
|
283
|
+
if (options.lazy !== true) {
|
|
294
284
|
runFetch(options.initParams)
|
|
295
285
|
}
|
|
296
286
|
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"nuxt-BTEWkpXt.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) => 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 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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"}
|