@brickflow/http 0.0.14 → 0.0.15
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +296 -277
- package/dist/http.d.ts +61 -0
- package/dist/http.d.ts.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.mjs +144 -0
- package/dist/index.mjs.map +1 -0
- package/dist/nuxt.d.ts +72 -0
- package/dist/nuxt.d.ts.map +1 -0
- package/dist/nuxt.mjs +222 -0
- package/dist/nuxt.mjs.map +1 -0
- package/dist/utils-DMSINHi5.js +39 -0
- package/dist/utils-DMSINHi5.js.map +1 -0
- package/dist/utils.d.ts +5 -0
- package/dist/utils.d.ts.map +1 -0
- package/package.json +27 -16
- package/dist/module.d.mts +0 -73
- package/dist/module.json +0 -12
- package/dist/module.mjs +0 -59
- package/dist/runtime/composables/useHttp.d.ts +0 -27
- package/dist/runtime/composables/useHttp.js +0 -197
- package/dist/runtime/http/client.d.ts +0 -3
- package/dist/runtime/http/client.js +0 -217
- package/dist/runtime/plugin.d.ts +0 -7
- package/dist/runtime/plugin.js +0 -56
- package/dist/runtime/types.d.ts +0 -21
- package/dist/runtime/utils/helpers.d.ts +0 -5
- package/dist/runtime/utils/helpers.js +0 -14
- package/dist/runtime/utils/index.d.ts +0 -6
- package/dist/runtime/utils/index.js +0 -5
- package/dist/runtime/utils/indexeddb.d.ts +0 -14
- package/dist/runtime/utils/indexeddb.js +0 -222
- package/dist/runtime/utils/middleware.d.ts +0 -8
- package/dist/runtime/utils/middleware.js +0 -20
- package/dist/runtime/utils/shared.d.ts +0 -83
- package/dist/runtime/utils/shared.js +0 -50
- package/dist/runtime/utils/typed.d.ts +0 -46
- package/dist/runtime/utils/typed.js +0 -9
- package/dist/types.d.mts +0 -11
package/package.json
CHANGED
|
@@ -1,23 +1,32 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@brickflow/http",
|
|
3
|
-
"version": "0.0.
|
|
4
|
-
"
|
|
5
|
-
"
|
|
3
|
+
"version": "0.0.15",
|
|
4
|
+
"description": "Minimal HTTP transport and Nuxt state helpers for brickflow.",
|
|
5
|
+
"sideEffects": false,
|
|
6
6
|
"files": [
|
|
7
7
|
"dist"
|
|
8
8
|
],
|
|
9
|
-
"main": "./dist/
|
|
10
|
-
"
|
|
9
|
+
"main": "./dist/index.mjs",
|
|
10
|
+
"module": "./dist/index.mjs",
|
|
11
|
+
"types": "./dist/index.d.ts",
|
|
11
12
|
"exports": {
|
|
12
13
|
".": {
|
|
13
|
-
"types": "./dist/
|
|
14
|
-
"
|
|
14
|
+
"types": "./dist/index.d.ts",
|
|
15
|
+
"development": "./src/index.ts",
|
|
16
|
+
"import": "./dist/index.mjs",
|
|
17
|
+
"default": "./dist/index.mjs"
|
|
18
|
+
},
|
|
19
|
+
"./nuxt": {
|
|
20
|
+
"types": "./dist/nuxt.d.ts",
|
|
21
|
+
"development": "./src/nuxt.ts",
|
|
22
|
+
"import": "./dist/nuxt.mjs",
|
|
23
|
+
"default": "./dist/nuxt.mjs"
|
|
15
24
|
}
|
|
16
25
|
},
|
|
17
26
|
"scripts": {
|
|
18
|
-
"build": "
|
|
19
|
-
"typecheck": "NODE_OPTIONS='--conditions=development'
|
|
20
|
-
"lint": "pnpm run --if-present typecheck
|
|
27
|
+
"build": "rolldown -c build.config.ts && tsc --project tsconfig.build.json",
|
|
28
|
+
"typecheck": "NODE_OPTIONS='--conditions=development' tsc --project tsconfig.json --noEmit",
|
|
29
|
+
"lint": "pnpm run --if-present typecheck",
|
|
21
30
|
"lint:fix": "pnpm exec eslint . --fix",
|
|
22
31
|
"format": "pnpm exec prettier . --ignore-path ../../.prettierignore --write",
|
|
23
32
|
"format:check": "pnpm exec prettier . --ignore-path ../../.prettierignore --check"
|
|
@@ -25,15 +34,17 @@
|
|
|
25
34
|
"publishConfig": {
|
|
26
35
|
"access": "public"
|
|
27
36
|
},
|
|
37
|
+
"dependencies": {
|
|
38
|
+
"@nuxt/kit": "3.21.7"
|
|
39
|
+
},
|
|
28
40
|
"devDependencies": {
|
|
29
41
|
"@brickflow/lint": "workspace:*",
|
|
30
42
|
"@brickflow/prettier": "workspace:*",
|
|
31
|
-
"
|
|
32
|
-
"@nuxt/module-builder": "1.0.2",
|
|
33
|
-
"nuxt": "4.4.6",
|
|
34
|
-
"vue": "3.5.35",
|
|
43
|
+
"rolldown": "1.0.3",
|
|
35
44
|
"vue-tsc": "3.3.2"
|
|
36
45
|
},
|
|
37
|
-
"
|
|
38
|
-
|
|
46
|
+
"peerDependencies": {
|
|
47
|
+
"nuxt": ">=3",
|
|
48
|
+
"vue": ">=3"
|
|
49
|
+
}
|
|
39
50
|
}
|
package/dist/module.d.mts
DELETED
|
@@ -1,73 +0,0 @@
|
|
|
1
|
-
import * as _nuxt_schema from '@nuxt/schema';
|
|
2
|
-
import { HttpRetryConfig } from '../dist/runtime/utils/shared.js';
|
|
3
|
-
export { CreateHttpClientOptions, GetConfig, HttpBaseURL, HttpBaseURLResolver, HttpClient, HttpConfig, HttpErrorPayload, HttpParam, HttpPayload, HttpRequestContext, HttpRequestMiddleware, HttpResponse, HttpResponseMiddleware, HttpRetryConfig, HttpRuntimeConfig, PostConfig } from '../dist/runtime/utils/shared.js';
|
|
4
|
-
export { createHttpClient } from '../dist/runtime/http/client.js';
|
|
5
|
-
export { addHttpRequestMiddleware, addHttpResponseMiddleware, removeHttpRequestMiddleware, removeHttpResponseMiddleware } from '../dist/runtime/utils/middleware.js';
|
|
6
|
-
export { HttpRouteBody, HttpRouteData, HttpRouteDefinition, HttpRouteError, HttpRouteMap, HttpRouteParams, ResolveHttpRoute, StrictTypedHttpClient, TypedGetConfig, TypedHttpClient, TypedHttpResponse, TypedPostConfig, createStrictHttpClient, createTypedHttpClient, defineHttpRoutes } from '../dist/runtime/utils/typed.js';
|
|
7
|
-
|
|
8
|
-
interface ModuleOptions {
|
|
9
|
-
/**
|
|
10
|
-
* Base URL used by the injected Nuxt HTTP client.
|
|
11
|
-
*
|
|
12
|
-
* @default ''
|
|
13
|
-
*/
|
|
14
|
-
baseURL?: string;
|
|
15
|
-
/**
|
|
16
|
-
* Enables client-side IndexedDB caching in `useHttp()`.
|
|
17
|
-
*
|
|
18
|
-
* @default true
|
|
19
|
-
*/
|
|
20
|
-
cache?: boolean;
|
|
21
|
-
/**
|
|
22
|
-
* IndexedDB database name used for cached responses.
|
|
23
|
-
*
|
|
24
|
-
* @default 'smart-cache-v2'
|
|
25
|
-
*/
|
|
26
|
-
cacheDbName?: 'smart-cache-v2';
|
|
27
|
-
/**
|
|
28
|
-
* IndexedDB store name used for cached responses.
|
|
29
|
-
*
|
|
30
|
-
* @default 'data'
|
|
31
|
-
*/
|
|
32
|
-
cacheStoreName?: string;
|
|
33
|
-
/**
|
|
34
|
-
* Cache TTL in milliseconds.
|
|
35
|
-
*
|
|
36
|
-
* @default 604800000
|
|
37
|
-
*/
|
|
38
|
-
cacheTtlMs?: number;
|
|
39
|
-
/**
|
|
40
|
-
* Adds `Client-Env: development` in dev mode.
|
|
41
|
-
*
|
|
42
|
-
* @default true
|
|
43
|
-
*/
|
|
44
|
-
clientEnvHeader?: boolean;
|
|
45
|
-
/**
|
|
46
|
-
* Default headers merged into every request.
|
|
47
|
-
*
|
|
48
|
-
* @default {}
|
|
49
|
-
*/
|
|
50
|
-
defaultHeaders?: Record<string, string>;
|
|
51
|
-
/**
|
|
52
|
-
* Disables IndexedDB cache when `import.meta.dev` is enabled.
|
|
53
|
-
*
|
|
54
|
-
* @default true
|
|
55
|
-
*/
|
|
56
|
-
disableCacheInDev?: boolean;
|
|
57
|
-
/**
|
|
58
|
-
* Request timeout in milliseconds.
|
|
59
|
-
*
|
|
60
|
-
* @default 80000
|
|
61
|
-
*/
|
|
62
|
-
requestTimeoutMs?: number;
|
|
63
|
-
/**
|
|
64
|
-
* Retry policy for GET requests on retryable responses and network failures.
|
|
65
|
-
*
|
|
66
|
-
* @default { delay: 300, retries: 3 }
|
|
67
|
-
*/
|
|
68
|
-
retry?: HttpRetryConfig;
|
|
69
|
-
}
|
|
70
|
-
declare const _default: _nuxt_schema.NuxtModule<ModuleOptions, ModuleOptions, false>;
|
|
71
|
-
|
|
72
|
-
export { _default as default };
|
|
73
|
-
export type { ModuleOptions };
|
package/dist/module.json
DELETED
package/dist/module.mjs
DELETED
|
@@ -1,59 +0,0 @@
|
|
|
1
|
-
import { defineNuxtModule, createResolver, addPlugin, addImportsDir } from '@nuxt/kit';
|
|
2
|
-
export { createHttpClient } from '../dist/runtime/http/client.js';
|
|
3
|
-
export { addHttpRequestMiddleware, addHttpResponseMiddleware, removeHttpRequestMiddleware, removeHttpResponseMiddleware } from '../dist/runtime/utils/middleware.js';
|
|
4
|
-
export { createStrictHttpClient, createTypedHttpClient, defineHttpRoutes } from '../dist/runtime/utils/typed.js';
|
|
5
|
-
|
|
6
|
-
const DAY = 1e3 * 60 * 60 * 24;
|
|
7
|
-
const defaultRuntimeConfig = {
|
|
8
|
-
baseURL: "",
|
|
9
|
-
cache: true,
|
|
10
|
-
cacheDbName: "smart-cache-v2",
|
|
11
|
-
cacheStoreName: "data",
|
|
12
|
-
cacheTtlMs: DAY * 7,
|
|
13
|
-
clientEnvHeader: true,
|
|
14
|
-
defaultHeaders: {},
|
|
15
|
-
disableCacheInDev: true,
|
|
16
|
-
requestTimeoutMs: 8e4,
|
|
17
|
-
retry: {
|
|
18
|
-
delay: 300,
|
|
19
|
-
retries: 3
|
|
20
|
-
}
|
|
21
|
-
};
|
|
22
|
-
const module$1 = defineNuxtModule({
|
|
23
|
-
defaults: defaultRuntimeConfig,
|
|
24
|
-
meta: {
|
|
25
|
-
compatibility: {
|
|
26
|
-
nuxt: ">=4.0.0"
|
|
27
|
-
},
|
|
28
|
-
configKey: "brickflowHttp",
|
|
29
|
-
name: "@brickflow/http"
|
|
30
|
-
},
|
|
31
|
-
setup(options, nuxt) {
|
|
32
|
-
const resolver = createResolver(import.meta.url);
|
|
33
|
-
const currentConfig = nuxt.options.runtimeConfig.public.brickflowHttp ?? {};
|
|
34
|
-
nuxt.options.runtimeConfig.public.brickflowHttp = {
|
|
35
|
-
...defaultRuntimeConfig,
|
|
36
|
-
...currentConfig,
|
|
37
|
-
...options,
|
|
38
|
-
defaultHeaders: {
|
|
39
|
-
...defaultRuntimeConfig.defaultHeaders,
|
|
40
|
-
...currentConfig.defaultHeaders ?? {},
|
|
41
|
-
...options.defaultHeaders ?? {}
|
|
42
|
-
},
|
|
43
|
-
retry: {
|
|
44
|
-
...defaultRuntimeConfig.retry,
|
|
45
|
-
...currentConfig.retry ?? {},
|
|
46
|
-
...options.retry ?? {}
|
|
47
|
-
}
|
|
48
|
-
};
|
|
49
|
-
addPlugin(resolver.resolve("./runtime/plugin"));
|
|
50
|
-
addImportsDir(resolver.resolve("./runtime/composables"));
|
|
51
|
-
nuxt.hook("prepare:types", ({ references }) => {
|
|
52
|
-
references.push({
|
|
53
|
-
path: resolver.resolve("./runtime/types.d.ts")
|
|
54
|
-
});
|
|
55
|
-
});
|
|
56
|
-
}
|
|
57
|
-
});
|
|
58
|
-
|
|
59
|
-
export { module$1 as default };
|
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { type ShallowReactive } from 'vue';
|
|
2
|
-
import type { HttpRouteData, HttpRouteError, HttpRouteMap, HttpRouteParams, ResolveHttpRoute } from '../utils/typed.js';
|
|
3
|
-
import { type HttpErrorPayload, type HttpParam, type HttpPayload } from '../utils/shared.js';
|
|
4
|
-
type UseHttpState<TData, TError extends HttpErrorPayload, TParams extends HttpParam> = ShallowReactive<{
|
|
5
|
-
data: null | TData;
|
|
6
|
-
error: null | TError;
|
|
7
|
-
fetch: (params?: TParams, opt?: {
|
|
8
|
-
signal: AbortSignal;
|
|
9
|
-
}) => Promise<void>;
|
|
10
|
-
hasFirstData: boolean;
|
|
11
|
-
hasFreshData: boolean;
|
|
12
|
-
pending: boolean;
|
|
13
|
-
pendingCache: boolean;
|
|
14
|
-
}>;
|
|
15
|
-
export declare function useHttp<TUrl extends Extract<keyof HttpRouteMap, string>>(options: {
|
|
16
|
-
effect?: (payload: HttpPayload<HttpRouteData<ResolveHttpRoute<HttpRouteMap, TUrl>>, HttpRouteError<ResolveHttpRoute<HttpRouteMap, TUrl>>>, config: {
|
|
17
|
-
cached: boolean;
|
|
18
|
-
params: HttpRouteParams<ResolveHttpRoute<HttpRouteMap, TUrl>>;
|
|
19
|
-
}) => undefined | void;
|
|
20
|
-
initParams?: HttpRouteParams<ResolveHttpRoute<HttpRouteMap, TUrl>>;
|
|
21
|
-
lazy?: true;
|
|
22
|
-
mapParams?: <TMapped extends HttpRouteParams<ResolveHttpRoute<HttpRouteMap, TUrl>>>(params?: TMapped) => TMapped;
|
|
23
|
-
server?: boolean;
|
|
24
|
-
url: TUrl;
|
|
25
|
-
}): Promise<UseHttpState<HttpRouteData<ResolveHttpRoute<HttpRouteMap, TUrl>>, HttpRouteError<ResolveHttpRoute<HttpRouteMap, TUrl>>, HttpRouteParams<ResolveHttpRoute<HttpRouteMap, TUrl>>>>;
|
|
26
|
-
export {};
|
|
27
|
-
//# sourceMappingURL=useHttp.d.ts.map
|
|
@@ -1,197 +0,0 @@
|
|
|
1
|
-
import { useLazyAsyncData, useNuxtApp, useRuntimeConfig, useState } from "nuxt/app";
|
|
2
|
-
import { onScopeDispose, shallowReactive, shallowRef } from "vue";
|
|
3
|
-
import { dbDeleteKeysWithPart, dbGet, dbSafeSet, getRandom, hashData } from "../utils/index.js";
|
|
4
|
-
import {
|
|
5
|
-
createHttpUrl,
|
|
6
|
-
createNetworkError,
|
|
7
|
-
isHttpErrorPayload
|
|
8
|
-
} from "../utils/shared.js";
|
|
9
|
-
const CHANNEL_NAME = "brickflow-http-tab-sync";
|
|
10
|
-
let channel;
|
|
11
|
-
export async function useHttp(options) {
|
|
12
|
-
const app = useNuxtApp();
|
|
13
|
-
const runtimeConfig = useRuntimeConfig();
|
|
14
|
-
const httpConfig = runtimeConfig.public.brickflowHttp;
|
|
15
|
-
const mapParams = (params) => {
|
|
16
|
-
if (options.mapParams) {
|
|
17
|
-
return options.mapParams(params ?? {});
|
|
18
|
-
}
|
|
19
|
-
return params ?? {};
|
|
20
|
-
};
|
|
21
|
-
const cacheEnabled = httpConfig.cache && !(httpConfig.disableCacheInDev && import.meta.dev);
|
|
22
|
-
const initFullUrl = createHttpUrl(options.url, mapParams(options.initParams));
|
|
23
|
-
let hasDataFromServer = false;
|
|
24
|
-
const result = shallowReactive({
|
|
25
|
-
data: null,
|
|
26
|
-
error: null,
|
|
27
|
-
fetch: async () => await void 0,
|
|
28
|
-
hasFirstData: false,
|
|
29
|
-
hasFreshData: false,
|
|
30
|
-
pending: true,
|
|
31
|
-
pendingCache: true
|
|
32
|
-
});
|
|
33
|
-
const controller = new AbortController();
|
|
34
|
-
const serverData = useState(`http:${initFullUrl}`, () => null);
|
|
35
|
-
if (options.server && import.meta.server) {
|
|
36
|
-
const paramsReactive = shallowRef(mapParams(options.initParams));
|
|
37
|
-
const ssr = await useLazyAsyncData(initFullUrl, async () => {
|
|
38
|
-
return await app.$http.get(options.url, {
|
|
39
|
-
params: paramsReactive.value
|
|
40
|
-
});
|
|
41
|
-
});
|
|
42
|
-
result.fetch = async (params) => {
|
|
43
|
-
paramsReactive.value = mapParams(params);
|
|
44
|
-
await ssr.refresh();
|
|
45
|
-
};
|
|
46
|
-
const payload = ssr.data.value?.data ?? null;
|
|
47
|
-
serverData.value = payload;
|
|
48
|
-
if (payload === null) {
|
|
49
|
-
result.pending = false;
|
|
50
|
-
result.pendingCache = false;
|
|
51
|
-
} else {
|
|
52
|
-
applyPayload(payload, result);
|
|
53
|
-
result.hasFirstData = true;
|
|
54
|
-
result.hasFreshData = true;
|
|
55
|
-
result.pending = false;
|
|
56
|
-
result.pendingCache = false;
|
|
57
|
-
options.effect?.(payload, {
|
|
58
|
-
cached: false,
|
|
59
|
-
params: mapParams(options.initParams)
|
|
60
|
-
});
|
|
61
|
-
if (!isHttpErrorPayload(payload)) {
|
|
62
|
-
hasDataFromServer = true;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
}
|
|
66
|
-
if (import.meta.client) {
|
|
67
|
-
let onMessage = function(event) {
|
|
68
|
-
if (!event.data.fullUrl || !fullUrlHistory[event.data.fullUrl] || event.data.data === void 0) {
|
|
69
|
-
return;
|
|
70
|
-
}
|
|
71
|
-
const payload = event.data.data;
|
|
72
|
-
applyPayload(payload, result);
|
|
73
|
-
result.hasFirstData = true;
|
|
74
|
-
result.hasFreshData = true;
|
|
75
|
-
options.effect?.(payload, {
|
|
76
|
-
cached: false,
|
|
77
|
-
params: event.data.params ?? mapParams()
|
|
78
|
-
});
|
|
79
|
-
};
|
|
80
|
-
const fullUrlHistory = {};
|
|
81
|
-
const clientChannel = getChannel();
|
|
82
|
-
clientChannel?.addEventListener("message", onMessage);
|
|
83
|
-
if (serverData.value !== null) {
|
|
84
|
-
applyPayload(serverData.value, result);
|
|
85
|
-
result.pending = false;
|
|
86
|
-
result.pendingCache = false;
|
|
87
|
-
result.hasFirstData = true;
|
|
88
|
-
result.hasFreshData = true;
|
|
89
|
-
}
|
|
90
|
-
const raceCondition = {};
|
|
91
|
-
const runFetch = async (params, fetchOpt) => {
|
|
92
|
-
const mappedParams = mapParams(params);
|
|
93
|
-
const fullUrl = createHttpUrl(options.url, mappedParams);
|
|
94
|
-
const fetchId = Date.now() + getRandom(0, 300);
|
|
95
|
-
if (raceCondition[fullUrl]) {
|
|
96
|
-
return;
|
|
97
|
-
}
|
|
98
|
-
raceCondition[fullUrl] = fetchId;
|
|
99
|
-
try {
|
|
100
|
-
result.pending = true;
|
|
101
|
-
result.pendingCache = true;
|
|
102
|
-
const cachedFetch = cacheEnabled && httpConfig.cacheDbName && httpConfig.cacheStoreName ? await dbGet(fullUrl, "smart-cache-v2", httpConfig.cacheStoreName) : null;
|
|
103
|
-
if (cachedFetch) {
|
|
104
|
-
applyPayload(cachedFetch.value, result);
|
|
105
|
-
result.hasFirstData = true;
|
|
106
|
-
result.pendingCache = false;
|
|
107
|
-
options.effect?.(cachedFetch.value, {
|
|
108
|
-
cached: true,
|
|
109
|
-
params: mappedParams
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
if (controller.signal.aborted || fetchOpt?.signal?.aborted) {
|
|
113
|
-
throw new DOMException("Aborted", "AbortError");
|
|
114
|
-
}
|
|
115
|
-
const signal = fetchOpt?.signal ? [controller.signal, fetchOpt.signal] : controller.signal;
|
|
116
|
-
const response = await app.$http.get(options.url, {
|
|
117
|
-
params: mappedParams,
|
|
118
|
-
signal
|
|
119
|
-
});
|
|
120
|
-
applyPayload(response.data, result);
|
|
121
|
-
result.hasFirstData = true;
|
|
122
|
-
result.hasFreshData = true;
|
|
123
|
-
fullUrlHistory[fullUrl] = true;
|
|
124
|
-
clientChannel?.postMessage({
|
|
125
|
-
data: normalizeBroadcastValue(response.data),
|
|
126
|
-
fullUrl,
|
|
127
|
-
params: normalizeBroadcastValue(mappedParams),
|
|
128
|
-
type: "STATE_UPDATE"
|
|
129
|
-
});
|
|
130
|
-
options.effect?.(response.data, {
|
|
131
|
-
cached: false,
|
|
132
|
-
params: mappedParams
|
|
133
|
-
});
|
|
134
|
-
if (cacheEnabled && response.status === 200) {
|
|
135
|
-
if (cachedFetch !== null) {
|
|
136
|
-
const currentHash = await hashData(response.data);
|
|
137
|
-
if (currentHash !== cachedFetch.hash) {
|
|
138
|
-
await dbDeleteKeysWithPart(options.url, "smart-cache-v2", httpConfig.cacheStoreName);
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
await dbSafeSet(
|
|
142
|
-
fullUrl,
|
|
143
|
-
response.data,
|
|
144
|
-
"smart-cache-v2",
|
|
145
|
-
httpConfig.cacheStoreName,
|
|
146
|
-
httpConfig.cacheTtlMs
|
|
147
|
-
);
|
|
148
|
-
}
|
|
149
|
-
} catch (error) {
|
|
150
|
-
if (!isHttpErrorPayload(result.error)) {
|
|
151
|
-
result.error = createNetworkError(error);
|
|
152
|
-
}
|
|
153
|
-
} finally {
|
|
154
|
-
if (raceCondition[fullUrl] === fetchId) {
|
|
155
|
-
delete raceCondition[fullUrl];
|
|
156
|
-
}
|
|
157
|
-
result.pending = false;
|
|
158
|
-
result.pendingCache = false;
|
|
159
|
-
}
|
|
160
|
-
};
|
|
161
|
-
result.fetch = runFetch;
|
|
162
|
-
if (!hasDataFromServer && options.lazy !== true) {
|
|
163
|
-
await runFetch(options.initParams);
|
|
164
|
-
}
|
|
165
|
-
onScopeDispose(() => {
|
|
166
|
-
clientChannel?.removeEventListener("message", onMessage);
|
|
167
|
-
controller.abort(`Http Abort -> onScopeDispose ${options.url}`);
|
|
168
|
-
if (serverData.value !== null) {
|
|
169
|
-
serverData.value = null;
|
|
170
|
-
}
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
return result;
|
|
174
|
-
}
|
|
175
|
-
function applyPayload(payload, result) {
|
|
176
|
-
if (isHttpErrorPayload(payload)) {
|
|
177
|
-
result.data = null;
|
|
178
|
-
result.error = payload;
|
|
179
|
-
return;
|
|
180
|
-
}
|
|
181
|
-
result.data = payload;
|
|
182
|
-
result.error = null;
|
|
183
|
-
}
|
|
184
|
-
function getChannel() {
|
|
185
|
-
if (!import.meta.client) {
|
|
186
|
-
return void 0;
|
|
187
|
-
}
|
|
188
|
-
channel ??= new BroadcastChannel(CHANNEL_NAME);
|
|
189
|
-
return channel;
|
|
190
|
-
}
|
|
191
|
-
function normalizeBroadcastValue(payload) {
|
|
192
|
-
try {
|
|
193
|
-
return structuredClone(payload);
|
|
194
|
-
} catch {
|
|
195
|
-
return JSON.parse(JSON.stringify(payload));
|
|
196
|
-
}
|
|
197
|
-
}
|
|
@@ -1,217 +0,0 @@
|
|
|
1
|
-
import { getRetryDelay, isFormData, sleep } from "../utils/helpers.js";
|
|
2
|
-
import { getHttpRequestMiddlewares, getHttpResponseMiddlewares } from "../utils/middleware.js";
|
|
3
|
-
import {
|
|
4
|
-
joinUrl
|
|
5
|
-
} from "../utils/shared.js";
|
|
6
|
-
export function createHttpClient(options = {}) {
|
|
7
|
-
const requestTimeoutMs = options.requestTimeoutMs ?? 8e4;
|
|
8
|
-
const defaultRetry = {
|
|
9
|
-
delay: options.retry?.delay ?? 300,
|
|
10
|
-
retries: options.retry?.retries ?? 3
|
|
11
|
-
};
|
|
12
|
-
return {
|
|
13
|
-
async get(url, config = {}) {
|
|
14
|
-
const retry = {
|
|
15
|
-
delay: config.retry?.delay ?? defaultRetry.delay,
|
|
16
|
-
retries: config.retry?.retries ?? defaultRetry.retries
|
|
17
|
-
};
|
|
18
|
-
const attemptRequest = async (attempt) => {
|
|
19
|
-
const request = await createRequestContext({
|
|
20
|
-
method: "GET",
|
|
21
|
-
options,
|
|
22
|
-
params: config.params,
|
|
23
|
-
requestTimeoutMs,
|
|
24
|
-
signal: config.signal,
|
|
25
|
-
url
|
|
26
|
-
});
|
|
27
|
-
try {
|
|
28
|
-
const result = await fetch(request.url, {
|
|
29
|
-
credentials: request.credentials,
|
|
30
|
-
headers: request.headers,
|
|
31
|
-
method: request.method,
|
|
32
|
-
signal: request.signal
|
|
33
|
-
});
|
|
34
|
-
const response = buildResponse(
|
|
35
|
-
request.url,
|
|
36
|
-
await readResponseBody(result),
|
|
37
|
-
result.status
|
|
38
|
-
);
|
|
39
|
-
if (!result.ok && isRetryableStatus(result.status) && attempt < retry.retries) {
|
|
40
|
-
await sleep(getRetryDelay(attempt, retry.delay));
|
|
41
|
-
return await attemptRequest(attempt + 1);
|
|
42
|
-
}
|
|
43
|
-
await runResponseMiddlewares(response, request, options.responseMiddleware);
|
|
44
|
-
return response;
|
|
45
|
-
} catch (error) {
|
|
46
|
-
if (isAbortError(error) || attempt >= retry.retries) {
|
|
47
|
-
throw error;
|
|
48
|
-
}
|
|
49
|
-
await sleep(getRetryDelay(attempt, retry.delay));
|
|
50
|
-
return await attemptRequest(attempt + 1);
|
|
51
|
-
}
|
|
52
|
-
};
|
|
53
|
-
return await attemptRequest(0);
|
|
54
|
-
},
|
|
55
|
-
async post(url, data, config = {}) {
|
|
56
|
-
const request = await createRequestContext({
|
|
57
|
-
body: data,
|
|
58
|
-
method: "POST",
|
|
59
|
-
options,
|
|
60
|
-
params: config.params,
|
|
61
|
-
requestTimeoutMs,
|
|
62
|
-
signal: config.signal,
|
|
63
|
-
url
|
|
64
|
-
});
|
|
65
|
-
let requestBody;
|
|
66
|
-
if (request.body !== void 0) {
|
|
67
|
-
requestBody = isFormData(request.body) ? request.body : JSON.stringify(request.body);
|
|
68
|
-
}
|
|
69
|
-
const result = await fetch(request.url, {
|
|
70
|
-
body: requestBody,
|
|
71
|
-
credentials: request.credentials,
|
|
72
|
-
headers: request.headers,
|
|
73
|
-
method: request.method,
|
|
74
|
-
signal: request.signal
|
|
75
|
-
});
|
|
76
|
-
const response = buildResponse(
|
|
77
|
-
request.url,
|
|
78
|
-
await readResponseBody(result),
|
|
79
|
-
result.status
|
|
80
|
-
);
|
|
81
|
-
await runResponseMiddlewares(response, request, options.responseMiddleware);
|
|
82
|
-
return response;
|
|
83
|
-
}
|
|
84
|
-
};
|
|
85
|
-
}
|
|
86
|
-
function buildRequestUrl(url, params, method) {
|
|
87
|
-
if (!params || Object.keys(params).length === 0) {
|
|
88
|
-
return url;
|
|
89
|
-
}
|
|
90
|
-
const searchParams = new URLSearchParams();
|
|
91
|
-
Object.entries(params ?? {}).forEach(([key, value]) => {
|
|
92
|
-
if (value === void 0 || value === null) {
|
|
93
|
-
return;
|
|
94
|
-
}
|
|
95
|
-
if (Array.isArray(value)) {
|
|
96
|
-
if (method === "POST") {
|
|
97
|
-
value.forEach((item) => {
|
|
98
|
-
searchParams.append(`${key}[]`, String(item));
|
|
99
|
-
});
|
|
100
|
-
return;
|
|
101
|
-
}
|
|
102
|
-
searchParams.append(key, JSON.stringify(value));
|
|
103
|
-
return;
|
|
104
|
-
}
|
|
105
|
-
searchParams.append(key, String(value));
|
|
106
|
-
});
|
|
107
|
-
const query = searchParams.toString();
|
|
108
|
-
if (!query) {
|
|
109
|
-
return url;
|
|
110
|
-
}
|
|
111
|
-
const separator = url.includes("?") ? "&" : "?";
|
|
112
|
-
return `${url}${separator}${query}`;
|
|
113
|
-
}
|
|
114
|
-
function buildResponse(url, data, status) {
|
|
115
|
-
return {
|
|
116
|
-
config: {
|
|
117
|
-
url
|
|
118
|
-
},
|
|
119
|
-
data,
|
|
120
|
-
status
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function createAnySignal(signals) {
|
|
124
|
-
if (typeof AbortSignal.any === "function") {
|
|
125
|
-
return AbortSignal.any(signals);
|
|
126
|
-
}
|
|
127
|
-
const controller = new AbortController();
|
|
128
|
-
signals.filter(Boolean).forEach((signal) => {
|
|
129
|
-
signal.addEventListener("abort", () => controller.abort(signal.reason), { once: true });
|
|
130
|
-
});
|
|
131
|
-
return controller.signal;
|
|
132
|
-
}
|
|
133
|
-
async function createRequestContext(input) {
|
|
134
|
-
const signal = resolveSignal(input.signal, input.requestTimeoutMs);
|
|
135
|
-
const headers = await createRequestHeaders(
|
|
136
|
-
input.options.createHeaders,
|
|
137
|
-
input.method === "POST" && input.body !== void 0 && !isFormData(input.body) ? {
|
|
138
|
-
"Content-Type": "application/json"
|
|
139
|
-
} : void 0
|
|
140
|
-
);
|
|
141
|
-
const request = {
|
|
142
|
-
baseURL: await resolveBaseURL(input.options.baseURL),
|
|
143
|
-
body: input.body,
|
|
144
|
-
credentials: "include",
|
|
145
|
-
headers,
|
|
146
|
-
method: input.method,
|
|
147
|
-
params: input.params,
|
|
148
|
-
signal,
|
|
149
|
-
url: input.url
|
|
150
|
-
};
|
|
151
|
-
await runRequestMiddlewares(request, input.options.requestMiddleware);
|
|
152
|
-
request.url = buildRequestUrl(joinUrl(request.baseURL, request.url), request.params, request.method);
|
|
153
|
-
return request;
|
|
154
|
-
}
|
|
155
|
-
async function createRequestHeaders(createHeaders, extraHeaders) {
|
|
156
|
-
const headers = new Headers(createHeaders ? await createHeaders() : void 0);
|
|
157
|
-
const extra = new Headers(extraHeaders);
|
|
158
|
-
extra.forEach((value, key) => {
|
|
159
|
-
headers.set(key, value);
|
|
160
|
-
});
|
|
161
|
-
return headers;
|
|
162
|
-
}
|
|
163
|
-
function createTimeoutSignal(ms) {
|
|
164
|
-
if (typeof AbortSignal.timeout === "function") {
|
|
165
|
-
return AbortSignal.timeout(ms);
|
|
166
|
-
}
|
|
167
|
-
const controller = new AbortController();
|
|
168
|
-
const timeoutId = setTimeout(() => controller.abort(new DOMException("Timed out", "AbortError")), ms);
|
|
169
|
-
controller.signal.addEventListener("abort", () => clearTimeout(timeoutId), { once: true });
|
|
170
|
-
return controller.signal;
|
|
171
|
-
}
|
|
172
|
-
function isAbortError(error) {
|
|
173
|
-
return error instanceof DOMException && error.name === "AbortError";
|
|
174
|
-
}
|
|
175
|
-
function isRetryableStatus(status) {
|
|
176
|
-
return status >= 500 || status === 429;
|
|
177
|
-
}
|
|
178
|
-
async function readResponseBody(response) {
|
|
179
|
-
const raw = await response.text();
|
|
180
|
-
if (!raw) {
|
|
181
|
-
return null;
|
|
182
|
-
}
|
|
183
|
-
try {
|
|
184
|
-
return JSON.parse(raw);
|
|
185
|
-
} catch {
|
|
186
|
-
return raw;
|
|
187
|
-
}
|
|
188
|
-
}
|
|
189
|
-
async function resolveBaseURL(baseURL) {
|
|
190
|
-
if (!baseURL) {
|
|
191
|
-
return "";
|
|
192
|
-
}
|
|
193
|
-
if (typeof baseURL === "function") {
|
|
194
|
-
return await baseURL() || "";
|
|
195
|
-
}
|
|
196
|
-
return baseURL;
|
|
197
|
-
}
|
|
198
|
-
function resolveSignal(signal, requestTimeoutMs) {
|
|
199
|
-
const timeoutSignal = createTimeoutSignal(requestTimeoutMs);
|
|
200
|
-
if (Array.isArray(signal)) {
|
|
201
|
-
return createAnySignal([...signal, timeoutSignal]);
|
|
202
|
-
}
|
|
203
|
-
if (signal) {
|
|
204
|
-
return createAnySignal([signal, timeoutSignal]);
|
|
205
|
-
}
|
|
206
|
-
return timeoutSignal;
|
|
207
|
-
}
|
|
208
|
-
async function runRequestMiddlewares(request, middlewares) {
|
|
209
|
-
for (const middleware of [...getHttpRequestMiddlewares(), ...middlewares ?? []]) {
|
|
210
|
-
await middleware(request);
|
|
211
|
-
}
|
|
212
|
-
}
|
|
213
|
-
async function runResponseMiddlewares(response, request, middlewares) {
|
|
214
|
-
for (const middleware of [...getHttpResponseMiddlewares(), ...middlewares ?? []]) {
|
|
215
|
-
await middleware(response, request);
|
|
216
|
-
}
|
|
217
|
-
}
|
package/dist/runtime/plugin.d.ts
DELETED