@mainframework/api-request-worker 1.0.0 → 1.0.1
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 +71 -45
- package/dist/shared/output/react.d.ts +6 -0
- package/dist/shared/output/react.js +233 -0
- package/dist/shared/output/react.js.map +1 -0
- package/dist/shared/output/vanilla.d.ts +9 -0
- package/dist/shared/output/vanilla.js +4 -0
- package/dist/shared/output/vanilla.js.map +1 -0
- package/dist/{shared/types/types.d.ts → types-CTW-HSpg.d.ts} +20 -34
- package/dist/workers/api/api.worker.js +433 -0
- package/dist/workers/api/api.worker.js.map +1 -0
- package/package.json +25 -24
- package/dist/api.worker.js +0 -463
- package/dist/api.worker.js.map +0 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js +0 -223
- package/dist/index.js.map +0 -1
- package/dist/shared/hooks/useApiWorker.d.ts +0 -4
- package/dist/shared/hooks/useApiWorker.d.ts.map +0 -1
- package/dist/shared/hooks/useCustomCallback.d.ts +0 -2
- package/dist/shared/hooks/useCustomCallback.d.ts.map +0 -1
- package/dist/shared/types/types.d.ts.map +0 -1
- package/dist/shared/utils/uniqueId.d.ts +0 -6
- package/dist/shared/utils/uniqueId.d.ts.map +0 -1
- package/dist/shared/workers/api/api.worker.d.ts +0 -2
- package/dist/shared/workers/api/api.worker.d.ts.map +0 -1
package/package.json
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@mainframework/api-request-worker",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.1",
|
|
4
4
|
"description": "Offloads API requests and application state to a Web Worker to keep the UI thread fast.",
|
|
5
5
|
"type": "module",
|
|
6
|
-
"main": "./dist/
|
|
6
|
+
"main": "./dist/shared/output/vanilla.js",
|
|
7
7
|
"exports": {
|
|
8
8
|
".": {
|
|
9
|
-
"types": "./dist/
|
|
10
|
-
"import": "./dist/
|
|
11
|
-
"default": "./dist/
|
|
9
|
+
"types": "./dist/shared/output/vanilla.d.ts",
|
|
10
|
+
"import": "./dist/shared/output/vanilla.js",
|
|
11
|
+
"default": "./dist/shared/output/vanilla.js"
|
|
12
|
+
},
|
|
13
|
+
"./react": {
|
|
14
|
+
"types": "./dist/shared/output/react.d.ts",
|
|
15
|
+
"import": "./dist/shared/output/react.js",
|
|
16
|
+
"default": "./dist/shared/output/react.js"
|
|
12
17
|
}
|
|
13
18
|
},
|
|
14
|
-
"types": "./dist/
|
|
19
|
+
"types": "./dist/shared/output/vanilla.d.ts",
|
|
15
20
|
"repository": {
|
|
16
21
|
"type": "git",
|
|
17
22
|
"url": "git+https://github.com/TerrySlack/mainframework-apiworker.git"
|
|
@@ -24,13 +29,10 @@
|
|
|
24
29
|
"husky-setup": "npx husky init",
|
|
25
30
|
"husky": "husky",
|
|
26
31
|
"prepare": "husky",
|
|
27
|
-
"clean": "rimraf dist tsconfig.
|
|
32
|
+
"clean": "rimraf dist tsconfig.tsbuildinfo",
|
|
28
33
|
"lint-staged": "lint-staged",
|
|
29
34
|
"prebuild": "yarn husky && yarn clean",
|
|
30
|
-
"build": "yarn prebuild && rollup -c
|
|
31
|
-
"test": "jest -c jestconfig.json --runInBand",
|
|
32
|
-
"test:watch": "jest -c jestconfig.json --watchAll --runInBand",
|
|
33
|
-
"test:coverage": "jest -c jestconfig.json --coverage --runInBand",
|
|
35
|
+
"build": "yarn prebuild && rollup -c",
|
|
34
36
|
"tscheck": "tsc"
|
|
35
37
|
},
|
|
36
38
|
"lint-staged": {
|
|
@@ -46,7 +48,7 @@
|
|
|
46
48
|
},
|
|
47
49
|
"peerDependenciesMeta": {
|
|
48
50
|
"react": {
|
|
49
|
-
"optional":
|
|
51
|
+
"optional": true
|
|
50
52
|
}
|
|
51
53
|
},
|
|
52
54
|
"files": [
|
|
@@ -64,31 +66,30 @@
|
|
|
64
66
|
"license": "MIT",
|
|
65
67
|
"devDependencies": {
|
|
66
68
|
"@eslint/js": "^10.0.1",
|
|
67
|
-
"@mainframework/is-deep-equal": "^1.0.
|
|
69
|
+
"@mainframework/is-deep-equal": "^1.0.10",
|
|
68
70
|
"@rollup/plugin-node-resolve": "^16.0.3",
|
|
69
71
|
"@rollup/plugin-replace": "^6.0.3",
|
|
70
|
-
"@rollup/plugin-typescript": "^12.3.0",
|
|
71
72
|
"@testing-library/dom": "^10.4.1",
|
|
72
73
|
"@testing-library/react": "^16.3.2",
|
|
73
|
-
"@types/jest": "^30.0.0",
|
|
74
74
|
"@types/react": "^19.2.14",
|
|
75
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
76
|
-
"@typescript-eslint/parser": "^8.
|
|
77
|
-
"
|
|
75
|
+
"@typescript-eslint/eslint-plugin": "^8.56.0",
|
|
76
|
+
"@typescript-eslint/parser": "^8.56.0",
|
|
77
|
+
"esbuild": "^0.27.3",
|
|
78
|
+
"eslint": "10.0.1",
|
|
78
79
|
"eslint-plugin-react": "^7.37.5",
|
|
79
80
|
"eslint-plugin-react-hooks": "^7.0.1",
|
|
80
81
|
"globals": "^17.3.0",
|
|
81
82
|
"husky": "^9.1.7",
|
|
82
|
-
"jest": "^30.2.0",
|
|
83
|
-
"jest-environment-jsdom": "^30.2.0",
|
|
84
83
|
"lint-staged": "^16.2.7",
|
|
85
84
|
"prettier": "^3.8.1",
|
|
86
85
|
"react": "^19.2.4",
|
|
87
86
|
"react-dom": "^19.2.4",
|
|
88
|
-
"rimraf": "^6.1.
|
|
89
|
-
"rollup": "^4.
|
|
90
|
-
"
|
|
87
|
+
"rimraf": "^6.1.3",
|
|
88
|
+
"rollup": "^4.59.0",
|
|
89
|
+
"rollup-plugin-dts": "^6.3.0",
|
|
90
|
+
"rollup-plugin-esbuild": "^6.2.1",
|
|
91
|
+
"tslib": "^2.8.1",
|
|
91
92
|
"typescript": "^5.9.3",
|
|
92
|
-
"typescript-eslint": "^8.
|
|
93
|
+
"typescript-eslint": "^8.56.0"
|
|
93
94
|
}
|
|
94
95
|
}
|
package/dist/api.worker.js
DELETED
|
@@ -1,463 +0,0 @@
|
|
|
1
|
-
/// <reference lib="webworker" />
|
|
2
|
-
const BINARY_MARKER = Symbol.for("WorkerApiBinary");
|
|
3
|
-
const DEFAULT_FILES_FIELD = "Files";
|
|
4
|
-
const NO_ERROR = { message: "" };
|
|
5
|
-
const callerResponse = (cacheName, data, hookId, httpStatus, error = NO_ERROR) => {
|
|
6
|
-
self.postMessage({
|
|
7
|
-
cacheName,
|
|
8
|
-
data: error.message !== "" ? null : (data ?? null),
|
|
9
|
-
hookId,
|
|
10
|
-
httpStatus,
|
|
11
|
-
error,
|
|
12
|
-
});
|
|
13
|
-
};
|
|
14
|
-
const makeError = (message) => ({ message });
|
|
15
|
-
/**
|
|
16
|
-
* Binary response - transferred via postMessage, not stored in cache.
|
|
17
|
-
* Client receives ArrayBuffer + meta for reconstruction (e.g. new Blob([data], { type })).
|
|
18
|
-
* Always sends a message; empty/zero-length body uses an empty ArrayBuffer so the client does not hang.
|
|
19
|
-
*/
|
|
20
|
-
const callerResponseBinary = (cacheName, data, meta, hookId, httpStatus, error = NO_ERROR) => {
|
|
21
|
-
const buffer = data?.byteLength ? data : new ArrayBuffer(0);
|
|
22
|
-
const payload = { cacheName, data: buffer, meta, hookId, httpStatus, error };
|
|
23
|
-
self.postMessage(payload, buffer.byteLength > 0 ? [buffer] : []);
|
|
24
|
-
};
|
|
25
|
-
const callerResponseStreamStart = (cacheName, meta, hookId, httpStatus, error = NO_ERROR) => {
|
|
26
|
-
self.postMessage({ cacheName, stream: "start", meta, hookId, httpStatus, error });
|
|
27
|
-
};
|
|
28
|
-
const callerResponseStreamResume = (cacheName, meta, hookId, httpStatus, error = NO_ERROR) => {
|
|
29
|
-
self.postMessage({ cacheName, stream: "resume", meta, hookId, httpStatus, error });
|
|
30
|
-
};
|
|
31
|
-
const callerResponseStreamChunk = (cacheName, data, hookId, error = NO_ERROR) => {
|
|
32
|
-
const buffer = data?.byteLength ? data : new ArrayBuffer(0);
|
|
33
|
-
const payload = { cacheName, stream: "chunk", data: buffer, hookId, error };
|
|
34
|
-
self.postMessage(payload, buffer.byteLength > 0 ? [buffer] : []);
|
|
35
|
-
};
|
|
36
|
-
const callerResponseStreamEnd = (cacheName, hookId, error = NO_ERROR) => {
|
|
37
|
-
self.postMessage({ cacheName, stream: "end", hookId, error });
|
|
38
|
-
};
|
|
39
|
-
const transferableBuffer = (view) => view.byteOffset === 0 && view.byteLength === view.buffer.byteLength
|
|
40
|
-
? view.buffer
|
|
41
|
-
: view.slice(0).buffer;
|
|
42
|
-
const store = Object.create(null);
|
|
43
|
-
const normalizeKey = (key) => key.toLocaleLowerCase();
|
|
44
|
-
const get = (key) => store[normalizeKey(key)];
|
|
45
|
-
const set = (key, value) => {
|
|
46
|
-
store[normalizeKey(key)] = value;
|
|
47
|
-
};
|
|
48
|
-
const remove = (key) => {
|
|
49
|
-
delete store[normalizeKey(key)];
|
|
50
|
-
};
|
|
51
|
-
const isNonEmptyString = (v) => typeof v === "string" && v.trim() !== "";
|
|
52
|
-
/** Returns headers without Content-Type (either casing). Use when FormData sets it automatically. */
|
|
53
|
-
const omitContentType = (headers) => {
|
|
54
|
-
const rest = { ...headers };
|
|
55
|
-
delete rest["Content-Type"];
|
|
56
|
-
delete rest["content-type"];
|
|
57
|
-
return rest;
|
|
58
|
-
};
|
|
59
|
-
const isBinaryResponse = (r) => typeof r === "object" &&
|
|
60
|
-
r !== null &&
|
|
61
|
-
BINARY_MARKER in r &&
|
|
62
|
-
r.data instanceof ArrayBuffer;
|
|
63
|
-
const commit = (cacheName, data, hookId, httpStatus) => {
|
|
64
|
-
if (!cacheName) {
|
|
65
|
-
callerResponse("", null, hookId, undefined, makeError("Invalid commit: cacheName is required"));
|
|
66
|
-
return;
|
|
67
|
-
}
|
|
68
|
-
set(normalizeKey(cacheName), data);
|
|
69
|
-
callerResponse(cacheName, data, hookId, httpStatus);
|
|
70
|
-
};
|
|
71
|
-
/**
|
|
72
|
-
* Parses response based on content-type.
|
|
73
|
-
* Returns parsed data for JSON/text, or binary result with BINARY_MARKER, data (ArrayBuffer), contentType, contentDisposition.
|
|
74
|
-
*/
|
|
75
|
-
const parseResponseByContentType = async (response) => {
|
|
76
|
-
const contentType = response.headers.get("content-type")?.toLocaleLowerCase() || "";
|
|
77
|
-
const contentLength = response.headers.get("content-length");
|
|
78
|
-
// No content
|
|
79
|
-
if (response.status === 204 || contentLength === "0") {
|
|
80
|
-
return null;
|
|
81
|
-
}
|
|
82
|
-
// JSON types - let it throw if malformed
|
|
83
|
-
if (contentType.includes("json")) {
|
|
84
|
-
return await response.json();
|
|
85
|
-
}
|
|
86
|
-
// Text-based types
|
|
87
|
-
if (contentType.startsWith("text/") ||
|
|
88
|
-
contentType.includes("xml") ||
|
|
89
|
-
contentType.includes("javascript") ||
|
|
90
|
-
contentType.includes("x-www-form-urlencoded")) {
|
|
91
|
-
return await response.text();
|
|
92
|
-
}
|
|
93
|
-
// Binary types (known or fallback) - use arrayBuffer for zero-copy transfer to client
|
|
94
|
-
const arrayBuffer = await response.arrayBuffer();
|
|
95
|
-
return {
|
|
96
|
-
[BINARY_MARKER]: true,
|
|
97
|
-
data: arrayBuffer,
|
|
98
|
-
contentType,
|
|
99
|
-
contentDisposition: response.headers.get("content-disposition"),
|
|
100
|
-
};
|
|
101
|
-
};
|
|
102
|
-
/** File/Blob use fileFieldName (default "Files"); all other fields use property name (key). */
|
|
103
|
-
const appendToFormData = (formData, key, value, fileFieldName = DEFAULT_FILES_FIELD, visited) => {
|
|
104
|
-
if (value instanceof File) {
|
|
105
|
-
formData.append(fileFieldName, value, value.name);
|
|
106
|
-
return true;
|
|
107
|
-
}
|
|
108
|
-
if (value instanceof Blob) {
|
|
109
|
-
formData.append(fileFieldName, value, "blob");
|
|
110
|
-
return true;
|
|
111
|
-
}
|
|
112
|
-
if (value !== null && value !== undefined && typeof value === "object") {
|
|
113
|
-
const set = visited ?? new WeakSet();
|
|
114
|
-
if (set.has(value))
|
|
115
|
-
return false;
|
|
116
|
-
set.add(value);
|
|
117
|
-
if (Array.isArray(value)) {
|
|
118
|
-
let hasFile = false;
|
|
119
|
-
let i = 0;
|
|
120
|
-
while (i < value.length) {
|
|
121
|
-
hasFile = appendToFormData(formData, key ? `${key}.${i}` : String(i), value[i], fileFieldName, set) || hasFile;
|
|
122
|
-
i++;
|
|
123
|
-
}
|
|
124
|
-
return hasFile;
|
|
125
|
-
}
|
|
126
|
-
let hasFile = false;
|
|
127
|
-
const keys = Object.keys(value);
|
|
128
|
-
let ki = 0;
|
|
129
|
-
while (ki < keys.length) {
|
|
130
|
-
const k = keys[ki];
|
|
131
|
-
if (Object.prototype.hasOwnProperty.call(value, k)) {
|
|
132
|
-
hasFile =
|
|
133
|
-
appendToFormData(formData, key ? `${key}.${k}` : k, value[k], fileFieldName, set) || hasFile;
|
|
134
|
-
}
|
|
135
|
-
ki++;
|
|
136
|
-
}
|
|
137
|
-
return hasFile;
|
|
138
|
-
}
|
|
139
|
-
if (value !== undefined && value !== null) {
|
|
140
|
-
const primitive = value;
|
|
141
|
-
formData.append(key, primitive);
|
|
142
|
-
}
|
|
143
|
-
return false;
|
|
144
|
-
};
|
|
145
|
-
const createFormDataIfBlobOrFile = (payload, fileFieldName = DEFAULT_FILES_FIELD, formDataKey = DEFAULT_FILES_FIELD) => {
|
|
146
|
-
if (payload === null || payload === undefined || typeof payload !== "object") {
|
|
147
|
-
return null;
|
|
148
|
-
}
|
|
149
|
-
const formData = new FormData();
|
|
150
|
-
const visited = new WeakSet();
|
|
151
|
-
const hasFile = appendToFormData(formData, formDataKey, payload, fileFieldName, visited);
|
|
152
|
-
return hasFile ? formData : null;
|
|
153
|
-
};
|
|
154
|
-
const getContentType = (headers = {}) => headers["Content-Type"] || headers["content-type"] || "application/json";
|
|
155
|
-
const getPayloadType = (payload) => {
|
|
156
|
-
switch (true) {
|
|
157
|
-
case payload instanceof FormData:
|
|
158
|
-
return "formdata";
|
|
159
|
-
case payload instanceof Blob:
|
|
160
|
-
return "blob";
|
|
161
|
-
case payload instanceof ArrayBuffer:
|
|
162
|
-
return "arraybuffer";
|
|
163
|
-
case ArrayBuffer.isView(payload):
|
|
164
|
-
return "arraybufferview";
|
|
165
|
-
case typeof ReadableStream !== "undefined" && payload instanceof ReadableStream:
|
|
166
|
-
return "stream";
|
|
167
|
-
case typeof payload === "string":
|
|
168
|
-
return "string";
|
|
169
|
-
default:
|
|
170
|
-
return "object";
|
|
171
|
-
}
|
|
172
|
-
};
|
|
173
|
-
const buildJsonBody = (payload) => JSON.stringify(payload);
|
|
174
|
-
const buildUrlEncodedBody = (payload) => new URLSearchParams(payload).toString();
|
|
175
|
-
const buildTextBody = (payload) => String(payload);
|
|
176
|
-
/**
|
|
177
|
-
* Builds body and headers for fetch. Each branch handles one payload type; add new cases here for new body types.
|
|
178
|
-
*/
|
|
179
|
-
const prepareRequestBody = (payload, headers, options) => {
|
|
180
|
-
const payloadType = getPayloadType(payload);
|
|
181
|
-
switch (payloadType) {
|
|
182
|
-
case "formdata":
|
|
183
|
-
return { body: payload, headers: omitContentType({ ...headers }) };
|
|
184
|
-
case "blob":
|
|
185
|
-
return { body: payload, headers: { ...headers } };
|
|
186
|
-
case "arraybuffer":
|
|
187
|
-
return { body: payload, headers: { ...headers } };
|
|
188
|
-
case "arraybufferview":
|
|
189
|
-
return { body: payload, headers: { ...headers } };
|
|
190
|
-
case "stream":
|
|
191
|
-
return { body: payload, headers: { ...headers } };
|
|
192
|
-
case "string":
|
|
193
|
-
return { body: payload, headers: { ...headers } };
|
|
194
|
-
case "object": {
|
|
195
|
-
const h = { ...headers };
|
|
196
|
-
const contentType = getContentType(h);
|
|
197
|
-
const fileFieldName = options?.formDataFileFieldName ?? DEFAULT_FILES_FIELD;
|
|
198
|
-
const formDataKey = options?.formDataKey ?? DEFAULT_FILES_FIELD;
|
|
199
|
-
let body;
|
|
200
|
-
if (contentType.includes("application/json")) {
|
|
201
|
-
body = buildJsonBody(payload);
|
|
202
|
-
}
|
|
203
|
-
else if (contentType.includes("application/x-www-form-urlencoded")) {
|
|
204
|
-
body = buildUrlEncodedBody(payload);
|
|
205
|
-
}
|
|
206
|
-
else if (contentType.startsWith("text/") || contentType.includes("xml")) {
|
|
207
|
-
body = buildTextBody(payload);
|
|
208
|
-
}
|
|
209
|
-
else if (contentType.includes("multipart/form-data")) {
|
|
210
|
-
const formData = createFormDataIfBlobOrFile(payload, fileFieldName, formDataKey);
|
|
211
|
-
if (formData) {
|
|
212
|
-
return { body: formData, headers: omitContentType(h) };
|
|
213
|
-
}
|
|
214
|
-
body = buildJsonBody(payload);
|
|
215
|
-
h["Content-Type"] = "application/json";
|
|
216
|
-
}
|
|
217
|
-
else {
|
|
218
|
-
body = buildJsonBody(payload);
|
|
219
|
-
}
|
|
220
|
-
if (!h["Content-Type"] && !h["content-type"]) {
|
|
221
|
-
h["Content-Type"] = contentType;
|
|
222
|
-
}
|
|
223
|
-
return { body, headers: h };
|
|
224
|
-
}
|
|
225
|
-
default:
|
|
226
|
-
return { headers: { ...headers } };
|
|
227
|
-
}
|
|
228
|
-
};
|
|
229
|
-
const inFlightControllers = new Map();
|
|
230
|
-
const inFlightByCacheName = new Map();
|
|
231
|
-
const apiRequest = async (cacheName, payload, { url, method, headers = {}, mode = "cors", credentials = "same-origin", responseType, timeoutMs, formDataFileFieldName, formDataKey, retries, }, requestId, hookId) => {
|
|
232
|
-
const methodLower = method.toLocaleLowerCase();
|
|
233
|
-
const responseTypeLower = responseType?.toLocaleLowerCase();
|
|
234
|
-
// Early return (cached then fresh) allowed for any HTTP method, except when response is binary or streaming.
|
|
235
|
-
const skipInFlightDedupe = responseTypeLower === "binary" || responseTypeLower === "stream";
|
|
236
|
-
if (!skipInFlightDedupe) {
|
|
237
|
-
const existing = inFlightByCacheName.get(cacheName);
|
|
238
|
-
if (existing) {
|
|
239
|
-
const cached = get(cacheName);
|
|
240
|
-
if (cached !== undefined)
|
|
241
|
-
callerResponse(cacheName, cached, hookId);
|
|
242
|
-
await existing;
|
|
243
|
-
const fresh = get(cacheName);
|
|
244
|
-
if (fresh !== undefined)
|
|
245
|
-
callerResponse(cacheName, fresh, hookId);
|
|
246
|
-
return;
|
|
247
|
-
}
|
|
248
|
-
}
|
|
249
|
-
const controller = new AbortController();
|
|
250
|
-
if (requestId) {
|
|
251
|
-
inFlightControllers.set(requestId, controller);
|
|
252
|
-
}
|
|
253
|
-
let timeoutId;
|
|
254
|
-
if (timeoutMs != null && timeoutMs > 0) {
|
|
255
|
-
timeoutId = setTimeout(() => controller.abort(), timeoutMs);
|
|
256
|
-
}
|
|
257
|
-
const promise = (async () => {
|
|
258
|
-
const fetchOptions = {
|
|
259
|
-
method,
|
|
260
|
-
mode,
|
|
261
|
-
credentials,
|
|
262
|
-
signal: controller.signal,
|
|
263
|
-
};
|
|
264
|
-
if (methodLower !== "get" && payload != null) {
|
|
265
|
-
const prepareOptions = {};
|
|
266
|
-
if (formDataFileFieldName != null && formDataFileFieldName !== "")
|
|
267
|
-
prepareOptions.formDataFileFieldName = formDataFileFieldName;
|
|
268
|
-
if (formDataKey != null && formDataKey !== "")
|
|
269
|
-
prepareOptions.formDataKey = formDataKey;
|
|
270
|
-
const { body, headers: processedHeaders } = prepareRequestBody(payload, headers, prepareOptions);
|
|
271
|
-
if (body !== undefined)
|
|
272
|
-
fetchOptions.body = body;
|
|
273
|
-
fetchOptions.headers = processedHeaders;
|
|
274
|
-
}
|
|
275
|
-
else {
|
|
276
|
-
fetchOptions.headers = omitContentType({ ...headers });
|
|
277
|
-
}
|
|
278
|
-
try {
|
|
279
|
-
if (responseTypeLower === "stream") {
|
|
280
|
-
const maxRetries = Math.min(retries ?? 3, 5);
|
|
281
|
-
let bytesReceived = 0;
|
|
282
|
-
let streamError = NO_ERROR;
|
|
283
|
-
let attempt = 0;
|
|
284
|
-
while (attempt <= maxRetries) {
|
|
285
|
-
try {
|
|
286
|
-
const reqHeaders = methodLower === "get" ? omitContentType({ ...fetchOptions.headers }) : fetchOptions.headers;
|
|
287
|
-
if (bytesReceived > 0)
|
|
288
|
-
reqHeaders["Range"] = `bytes=${bytesReceived}-`;
|
|
289
|
-
const streamResponse = await fetch(url, { ...fetchOptions, headers: reqHeaders });
|
|
290
|
-
if (streamResponse.status >= 400) {
|
|
291
|
-
streamError = makeError(streamResponse.statusText);
|
|
292
|
-
break;
|
|
293
|
-
}
|
|
294
|
-
if (streamResponse.status === 204) {
|
|
295
|
-
callerResponseStreamEnd(cacheName, hookId);
|
|
296
|
-
return;
|
|
297
|
-
}
|
|
298
|
-
if (streamResponse.status === 416)
|
|
299
|
-
break;
|
|
300
|
-
const contentType = streamResponse.headers.get("content-type") ?? undefined;
|
|
301
|
-
const meta = {
|
|
302
|
-
contentDisposition: streamResponse.headers.get("content-disposition") ?? null,
|
|
303
|
-
...(contentType !== undefined && { contentType }),
|
|
304
|
-
};
|
|
305
|
-
if (bytesReceived === 0)
|
|
306
|
-
callerResponseStreamStart(cacheName, meta, hookId, streamResponse.status);
|
|
307
|
-
else
|
|
308
|
-
callerResponseStreamResume(cacheName, meta, hookId, streamResponse.status);
|
|
309
|
-
const body = streamResponse.body;
|
|
310
|
-
if (!body) {
|
|
311
|
-
callerResponseStreamEnd(cacheName, hookId);
|
|
312
|
-
return;
|
|
313
|
-
}
|
|
314
|
-
const reader = body.getReader();
|
|
315
|
-
let skipRemaining = streamResponse.status === 200 && bytesReceived > 0 ? bytesReceived : 0;
|
|
316
|
-
while (true) {
|
|
317
|
-
const { done, value } = await reader.read();
|
|
318
|
-
if (done)
|
|
319
|
-
break;
|
|
320
|
-
if (!value || value.byteLength === 0)
|
|
321
|
-
continue;
|
|
322
|
-
if (skipRemaining > 0) {
|
|
323
|
-
if (value.byteLength <= skipRemaining) {
|
|
324
|
-
skipRemaining -= value.byteLength;
|
|
325
|
-
continue;
|
|
326
|
-
}
|
|
327
|
-
const offset = skipRemaining;
|
|
328
|
-
skipRemaining = 0;
|
|
329
|
-
const tail = value.subarray(offset);
|
|
330
|
-
callerResponseStreamChunk(cacheName, transferableBuffer(tail), hookId);
|
|
331
|
-
bytesReceived += tail.byteLength;
|
|
332
|
-
}
|
|
333
|
-
else {
|
|
334
|
-
callerResponseStreamChunk(cacheName, transferableBuffer(value), hookId);
|
|
335
|
-
bytesReceived += value.byteLength;
|
|
336
|
-
}
|
|
337
|
-
}
|
|
338
|
-
break;
|
|
339
|
-
}
|
|
340
|
-
catch (err) {
|
|
341
|
-
streamError =
|
|
342
|
-
err.name === "AbortError" ? makeError("Request aborted") : makeError(err.message);
|
|
343
|
-
if (attempt === maxRetries)
|
|
344
|
-
break;
|
|
345
|
-
}
|
|
346
|
-
attempt++;
|
|
347
|
-
}
|
|
348
|
-
callerResponseStreamEnd(cacheName, hookId, streamError);
|
|
349
|
-
return;
|
|
350
|
-
}
|
|
351
|
-
const response = await fetch(url, fetchOptions);
|
|
352
|
-
if (response.status >= 400) {
|
|
353
|
-
callerResponse(cacheName, null, hookId, response.status, makeError(response.statusText));
|
|
354
|
-
return;
|
|
355
|
-
}
|
|
356
|
-
if (response.status === 204) {
|
|
357
|
-
set(normalizeKey(cacheName), null);
|
|
358
|
-
callerResponse(cacheName, null, hookId, 204);
|
|
359
|
-
return;
|
|
360
|
-
}
|
|
361
|
-
const responseData = await parseResponseByContentType(response);
|
|
362
|
-
if (isBinaryResponse(responseData)) {
|
|
363
|
-
callerResponseBinary(cacheName, responseData.data, {
|
|
364
|
-
contentType: responseData.contentType,
|
|
365
|
-
contentDisposition: responseData.contentDisposition ?? null,
|
|
366
|
-
}, hookId, response.status);
|
|
367
|
-
}
|
|
368
|
-
else {
|
|
369
|
-
commit(cacheName, responseData, hookId, response.status);
|
|
370
|
-
}
|
|
371
|
-
}
|
|
372
|
-
catch (error) {
|
|
373
|
-
if (error.name === "AbortError") {
|
|
374
|
-
callerResponse(cacheName, null, hookId, undefined, makeError("Request aborted"));
|
|
375
|
-
return;
|
|
376
|
-
}
|
|
377
|
-
const err = error;
|
|
378
|
-
callerResponse(cacheName, null, hookId, undefined, makeError(err.message));
|
|
379
|
-
}
|
|
380
|
-
finally {
|
|
381
|
-
if (timeoutId != null)
|
|
382
|
-
clearTimeout(timeoutId);
|
|
383
|
-
if (requestId) {
|
|
384
|
-
inFlightControllers.delete(requestId);
|
|
385
|
-
}
|
|
386
|
-
inFlightByCacheName.delete(cacheName);
|
|
387
|
-
}
|
|
388
|
-
})();
|
|
389
|
-
inFlightByCacheName.set(cacheName, promise);
|
|
390
|
-
await promise;
|
|
391
|
-
};
|
|
392
|
-
const onRequest = (dataRequest) => {
|
|
393
|
-
const { cacheName, type, payload, request, requestId, hookId } = dataRequest;
|
|
394
|
-
const responseCacheName = dataRequest.cacheName ?? "";
|
|
395
|
-
if (!isNonEmptyString(type)) {
|
|
396
|
-
callerResponse(responseCacheName, null, hookId, undefined, makeError("Invalid request: type is required"));
|
|
397
|
-
return;
|
|
398
|
-
}
|
|
399
|
-
const lowerType = normalizeKey(type);
|
|
400
|
-
if (lowerType === "cancel") {
|
|
401
|
-
if (requestId)
|
|
402
|
-
onCancel(requestId);
|
|
403
|
-
return;
|
|
404
|
-
}
|
|
405
|
-
if (!isNonEmptyString(cacheName)) {
|
|
406
|
-
callerResponse(responseCacheName, null, hookId, undefined, makeError("Invalid request: cacheName is required"));
|
|
407
|
-
return;
|
|
408
|
-
}
|
|
409
|
-
const lowerCacheName = normalizeKey(cacheName);
|
|
410
|
-
if (lowerType === "get") {
|
|
411
|
-
const requestedData = get(lowerCacheName);
|
|
412
|
-
if (requestedData === undefined) {
|
|
413
|
-
callerResponse(lowerCacheName, null, hookId, undefined, makeError("Cache miss"));
|
|
414
|
-
}
|
|
415
|
-
else {
|
|
416
|
-
callerResponse(lowerCacheName, requestedData, hookId);
|
|
417
|
-
}
|
|
418
|
-
}
|
|
419
|
-
else if (lowerType === "set") {
|
|
420
|
-
if (!request) {
|
|
421
|
-
if (payload == null) {
|
|
422
|
-
callerResponse(responseCacheName, null, hookId, undefined, makeError("Invalid request: payload is required for set"));
|
|
423
|
-
return;
|
|
424
|
-
}
|
|
425
|
-
set(lowerCacheName, payload);
|
|
426
|
-
}
|
|
427
|
-
else {
|
|
428
|
-
const methodLower = normalizeKey(request.method);
|
|
429
|
-
if (methodLower !== "get" && payload == null) {
|
|
430
|
-
callerResponse(responseCacheName, null, hookId, undefined, makeError("Invalid request: payload is required for non-GET API request"));
|
|
431
|
-
return;
|
|
432
|
-
}
|
|
433
|
-
void apiRequest(lowerCacheName, payload ?? null, request, requestId, hookId);
|
|
434
|
-
}
|
|
435
|
-
}
|
|
436
|
-
else if (lowerType === "delete") {
|
|
437
|
-
remove(lowerCacheName);
|
|
438
|
-
callerResponse(lowerCacheName, { deleted: true }, hookId);
|
|
439
|
-
}
|
|
440
|
-
};
|
|
441
|
-
const onCancel = (requestId) => {
|
|
442
|
-
const controller = inFlightControllers.get(requestId);
|
|
443
|
-
if (controller) {
|
|
444
|
-
controller.abort();
|
|
445
|
-
inFlightControllers.delete(requestId);
|
|
446
|
-
}
|
|
447
|
-
};
|
|
448
|
-
/**
|
|
449
|
-
* Incoming messages from the main thread. Expects payload shape { dataRequest?: DataRequest }.
|
|
450
|
-
* Responses via postMessage: { cacheName, data?, meta?, hookId?, httpStatus?, error }.
|
|
451
|
-
* error is always present: { message: "" } when no error, { message: "..." } when the request failed.
|
|
452
|
-
*/
|
|
453
|
-
onmessage = (event) => {
|
|
454
|
-
const payload = event.data;
|
|
455
|
-
if (payload === null || typeof payload !== "object")
|
|
456
|
-
return;
|
|
457
|
-
const dataRequest = payload.dataRequest;
|
|
458
|
-
if (dataRequest !== undefined)
|
|
459
|
-
onRequest(dataRequest);
|
|
460
|
-
};
|
|
461
|
-
|
|
462
|
-
export { BINARY_MARKER };
|
|
463
|
-
//# sourceMappingURL=api.worker.js.map
|
package/dist/api.worker.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"api.worker.js","sources":["../src/shared/workers/api/api.worker.ts"],"sourcesContent":["/// <reference lib=\"webworker\" />\r\n\r\nimport type {\r\n AbortControllers,\r\n BinaryParseResult,\r\n BinaryResponseMeta,\r\n DataRequest,\r\n WorkerApiRequest,\r\n WorkerErrorPayload,\r\n WorkerMessageData,\r\n} from \"../../types/types\";\r\n\r\nexport const BINARY_MARKER = Symbol.for(\"WorkerApiBinary\");\r\n\r\nconst DEFAULT_FILES_FIELD = \"Files\";\r\n\r\nconst NO_ERROR: WorkerErrorPayload = { message: \"\" };\r\n\r\nconst callerResponse = (\r\n cacheName: string,\r\n data: unknown,\r\n hookId?: string | null,\r\n httpStatus?: number,\r\n error: WorkerErrorPayload = NO_ERROR,\r\n): void => {\r\n self.postMessage({\r\n cacheName,\r\n data: error.message !== \"\" ? null : (data ?? null),\r\n hookId,\r\n httpStatus,\r\n error,\r\n });\r\n};\r\n\r\nconst makeError = (message: string): WorkerErrorPayload => ({ message });\r\n\r\n/**\r\n * Binary response - transferred via postMessage, not stored in cache.\r\n * Client receives ArrayBuffer + meta for reconstruction (e.g. new Blob([data], { type })).\r\n * Always sends a message; empty/zero-length body uses an empty ArrayBuffer so the client does not hang.\r\n */\r\nconst callerResponseBinary = (\r\n cacheName: string,\r\n data: ArrayBuffer,\r\n meta: BinaryResponseMeta,\r\n hookId?: string | null,\r\n httpStatus?: number,\r\n error: WorkerErrorPayload = NO_ERROR,\r\n): void => {\r\n const buffer = data?.byteLength ? data : new ArrayBuffer(0);\r\n const payload = { cacheName, data: buffer, meta, hookId, httpStatus, error };\r\n self.postMessage(payload, buffer.byteLength > 0 ? [buffer] : []);\r\n};\r\n\r\nconst callerResponseStreamStart = (\r\n cacheName: string,\r\n meta: BinaryResponseMeta | null,\r\n hookId?: string | null,\r\n httpStatus?: number,\r\n error: WorkerErrorPayload = NO_ERROR,\r\n): void => {\r\n self.postMessage({ cacheName, stream: \"start\", meta, hookId, httpStatus, error });\r\n};\r\n\r\nconst callerResponseStreamResume = (\r\n cacheName: string,\r\n meta: BinaryResponseMeta | null,\r\n hookId?: string | null,\r\n httpStatus?: number,\r\n error: WorkerErrorPayload = NO_ERROR,\r\n): void => {\r\n self.postMessage({ cacheName, stream: \"resume\", meta, hookId, httpStatus, error });\r\n};\r\n\r\nconst callerResponseStreamChunk = (\r\n cacheName: string,\r\n data: ArrayBuffer,\r\n hookId?: string | null,\r\n error: WorkerErrorPayload = NO_ERROR,\r\n): void => {\r\n const buffer = data?.byteLength ? data : new ArrayBuffer(0);\r\n const payload = { cacheName, stream: \"chunk\", data: buffer, hookId, error };\r\n self.postMessage(payload, buffer.byteLength > 0 ? [buffer] : []);\r\n};\r\n\r\nconst callerResponseStreamEnd = (\r\n cacheName: string,\r\n hookId?: string | null,\r\n error: WorkerErrorPayload = NO_ERROR,\r\n): void => {\r\n self.postMessage({ cacheName, stream: \"end\", hookId, error });\r\n};\r\n\r\nconst transferableBuffer = (view: Uint8Array): ArrayBuffer =>\r\n view.byteOffset === 0 && view.byteLength === view.buffer.byteLength\r\n ? (view.buffer as ArrayBuffer)\r\n : view.slice(0).buffer;\r\n\r\nconst store = Object.create(null) as Record<string, unknown>;\r\nconst normalizeKey = (key: string) => key.toLocaleLowerCase();\r\nconst get = <TData>(key: string): TData | undefined => store[normalizeKey(key)] as TData | undefined;\r\nconst set = <TData>(key: string, value: TData): void => {\r\n store[normalizeKey(key)] = value;\r\n};\r\nconst remove = (key: string): void => {\r\n delete store[normalizeKey(key)];\r\n};\r\n\r\nconst isNonEmptyString = (v: unknown): v is string => typeof v === \"string\" && v.trim() !== \"\";\r\n\r\n/** Returns headers without Content-Type (either casing). Use when FormData sets it automatically. */\r\nconst omitContentType = (headers: Record<string, string>): Record<string, string> => {\r\n const rest = { ...headers };\r\n delete rest[\"Content-Type\"];\r\n delete rest[\"content-type\"];\r\n return rest;\r\n};\r\n\r\nconst isBinaryResponse = (r: unknown): r is BinaryParseResult =>\r\n typeof r === \"object\" &&\r\n r !== null &&\r\n BINARY_MARKER in r &&\r\n (r as unknown as BinaryParseResult).data instanceof ArrayBuffer;\r\n\r\nconst commit = <TData>(cacheName: string, data: TData, hookId?: string | null, httpStatus?: number): void => {\r\n if (!cacheName) {\r\n callerResponse(\"\", null, hookId, undefined, makeError(\"Invalid commit: cacheName is required\"));\r\n return;\r\n }\r\n set(normalizeKey(cacheName), data);\r\n callerResponse(cacheName, data, hookId, httpStatus);\r\n};\r\n\r\n/**\r\n * Parses response based on content-type.\r\n * Returns parsed data for JSON/text, or binary result with BINARY_MARKER, data (ArrayBuffer), contentType, contentDisposition.\r\n */\r\nconst parseResponseByContentType = async (response: Response): Promise<unknown> => {\r\n const contentType = response.headers.get(\"content-type\")?.toLocaleLowerCase() || \"\";\r\n const contentLength = response.headers.get(\"content-length\");\r\n\r\n // No content\r\n if (response.status === 204 || contentLength === \"0\") {\r\n return null;\r\n }\r\n\r\n // JSON types - let it throw if malformed\r\n if (contentType.includes(\"json\")) {\r\n return await response.json();\r\n }\r\n\r\n // Text-based types\r\n if (\r\n contentType.startsWith(\"text/\") ||\r\n contentType.includes(\"xml\") ||\r\n contentType.includes(\"javascript\") ||\r\n contentType.includes(\"x-www-form-urlencoded\")\r\n ) {\r\n return await response.text();\r\n }\r\n\r\n // Binary types (known or fallback) - use arrayBuffer for zero-copy transfer to client\r\n const arrayBuffer = await response.arrayBuffer();\r\n return {\r\n [BINARY_MARKER]: true as const,\r\n data: arrayBuffer,\r\n contentType,\r\n contentDisposition: response.headers.get(\"content-disposition\"),\r\n };\r\n};\r\n\r\n/** File/Blob use fileFieldName (default \"Files\"); all other fields use property name (key). */\r\nconst appendToFormData = (\r\n formData: FormData,\r\n key: string,\r\n value: unknown,\r\n fileFieldName: string = DEFAULT_FILES_FIELD,\r\n visited?: WeakSet<object>,\r\n): boolean => {\r\n if (value instanceof File) {\r\n formData.append(fileFieldName, value, value.name);\r\n return true;\r\n }\r\n\r\n if (value instanceof Blob) {\r\n formData.append(fileFieldName, value, \"blob\");\r\n return true;\r\n }\r\n\r\n if (value !== null && value !== undefined && typeof value === \"object\") {\r\n const set = visited ?? new WeakSet<object>();\r\n if (set.has(value)) return false;\r\n set.add(value);\r\n if (Array.isArray(value)) {\r\n let hasFile = false;\r\n let i = 0;\r\n while (i < value.length) {\r\n hasFile = appendToFormData(formData, key ? `${key}.${i}` : String(i), value[i], fileFieldName, set) || hasFile;\r\n i++;\r\n }\r\n return hasFile;\r\n }\r\n let hasFile = false;\r\n const keys = Object.keys(value);\r\n let ki = 0;\r\n while (ki < keys.length) {\r\n const k = keys[ki] as string;\r\n if (Object.prototype.hasOwnProperty.call(value, k)) {\r\n hasFile =\r\n appendToFormData(\r\n formData,\r\n key ? `${key}.${k}` : k,\r\n (value as Record<string, unknown>)[k],\r\n fileFieldName,\r\n set,\r\n ) || hasFile;\r\n }\r\n ki++;\r\n }\r\n return hasFile;\r\n }\r\n\r\n if (value !== undefined && value !== null) {\r\n const primitive = value as string | number | boolean | bigint | symbol;\r\n formData.append(key, primitive as string | Blob);\r\n }\r\n return false;\r\n};\r\n\r\nconst createFormDataIfBlobOrFile = (\r\n payload: unknown,\r\n fileFieldName: string = DEFAULT_FILES_FIELD,\r\n formDataKey: string = DEFAULT_FILES_FIELD,\r\n): FormData | null => {\r\n if (payload === null || payload === undefined || typeof payload !== \"object\") {\r\n return null;\r\n }\r\n\r\n const formData = new FormData();\r\n const visited = new WeakSet<object>();\r\n const hasFile = appendToFormData(formData, formDataKey, payload, fileFieldName, visited);\r\n return hasFile ? formData : null;\r\n};\r\n\r\nconst getContentType = (headers: Record<string, string> = {}): string =>\r\n headers[\"Content-Type\"] || headers[\"content-type\"] || \"application/json\";\r\n\r\nconst getPayloadType = (payload: unknown): string => {\r\n switch (true) {\r\n case payload instanceof FormData:\r\n return \"formdata\";\r\n case payload instanceof Blob:\r\n return \"blob\";\r\n case payload instanceof ArrayBuffer:\r\n return \"arraybuffer\";\r\n case ArrayBuffer.isView(payload):\r\n return \"arraybufferview\";\r\n case typeof ReadableStream !== \"undefined\" && payload instanceof ReadableStream:\r\n return \"stream\";\r\n case typeof payload === \"string\":\r\n return \"string\";\r\n default:\r\n return \"object\";\r\n }\r\n};\r\n\r\nconst buildJsonBody = (payload: unknown): BodyInit => JSON.stringify(payload);\r\nconst buildUrlEncodedBody = (payload: Record<string, string>): BodyInit => new URLSearchParams(payload).toString();\r\nconst buildTextBody = (payload: unknown): BodyInit => String(payload);\r\n\r\n/**\r\n * Builds body and headers for fetch. Each branch handles one payload type; add new cases here for new body types.\r\n */\r\nconst prepareRequestBody = (\r\n payload: unknown,\r\n headers: Record<string, string>,\r\n options?: { formDataFileFieldName?: string; formDataKey?: string },\r\n): { body?: BodyInit; headers: Record<string, string> } => {\r\n const payloadType = getPayloadType(payload);\r\n\r\n switch (payloadType) {\r\n case \"formdata\":\r\n return { body: payload as FormData, headers: omitContentType({ ...headers }) };\r\n case \"blob\":\r\n return { body: payload as Blob, headers: { ...headers } };\r\n case \"arraybuffer\":\r\n return { body: payload as ArrayBuffer, headers: { ...headers } };\r\n case \"arraybufferview\":\r\n return { body: payload as BodyInit, headers: { ...headers } };\r\n case \"stream\":\r\n return { body: payload as ReadableStream<Uint8Array>, headers: { ...headers } };\r\n case \"string\":\r\n return { body: payload as string, headers: { ...headers } };\r\n case \"object\": {\r\n const h = { ...headers };\r\n const contentType = getContentType(h);\r\n const fileFieldName = options?.formDataFileFieldName ?? DEFAULT_FILES_FIELD;\r\n const formDataKey = options?.formDataKey ?? DEFAULT_FILES_FIELD;\r\n\r\n let body: BodyInit;\r\n if (contentType.includes(\"application/json\")) {\r\n body = buildJsonBody(payload);\r\n } else if (contentType.includes(\"application/x-www-form-urlencoded\")) {\r\n body = buildUrlEncodedBody(payload as Record<string, string>);\r\n } else if (contentType.startsWith(\"text/\") || contentType.includes(\"xml\")) {\r\n body = buildTextBody(payload);\r\n } else if (contentType.includes(\"multipart/form-data\")) {\r\n const formData = createFormDataIfBlobOrFile(payload, fileFieldName, formDataKey);\r\n if (formData) {\r\n return { body: formData, headers: omitContentType(h) };\r\n }\r\n body = buildJsonBody(payload);\r\n h[\"Content-Type\"] = \"application/json\";\r\n } else {\r\n body = buildJsonBody(payload);\r\n }\r\n\r\n if (!h[\"Content-Type\"] && !h[\"content-type\"]) {\r\n h[\"Content-Type\"] = contentType;\r\n }\r\n return { body, headers: h };\r\n }\r\n\r\n default:\r\n return { headers: { ...headers } };\r\n }\r\n};\r\n\r\nconst inFlightControllers: AbortControllers = new Map();\r\nconst inFlightByCacheName = new Map<string, Promise<void>>();\r\n\r\nconst apiRequest = async <TData>(\r\n cacheName: string,\r\n payload: TData | FormData | null,\r\n {\r\n url,\r\n method,\r\n headers = {},\r\n mode = \"cors\",\r\n credentials = \"same-origin\",\r\n responseType,\r\n timeoutMs,\r\n formDataFileFieldName,\r\n formDataKey,\r\n retries,\r\n }: WorkerApiRequest,\r\n requestId?: string | null,\r\n hookId?: string | null,\r\n): Promise<void> => {\r\n const methodLower = method.toLocaleLowerCase();\r\n const responseTypeLower = responseType?.toLocaleLowerCase();\r\n\r\n // Early return (cached then fresh) allowed for any HTTP method, except when response is binary or streaming.\r\n const skipInFlightDedupe = responseTypeLower === \"binary\" || responseTypeLower === \"stream\";\r\n if (!skipInFlightDedupe) {\r\n const existing = inFlightByCacheName.get(cacheName);\r\n if (existing) {\r\n const cached = get(cacheName);\r\n if (cached !== undefined) callerResponse(cacheName, cached, hookId);\r\n await existing;\r\n const fresh = get(cacheName);\r\n if (fresh !== undefined) callerResponse(cacheName, fresh, hookId);\r\n return;\r\n }\r\n }\r\n\r\n const controller = new AbortController();\r\n if (requestId) {\r\n inFlightControllers.set(requestId, controller);\r\n }\r\n\r\n let timeoutId: ReturnType<typeof setTimeout> | undefined;\r\n if (timeoutMs != null && timeoutMs > 0) {\r\n timeoutId = setTimeout(() => controller.abort(), timeoutMs);\r\n }\r\n\r\n const promise = (async (): Promise<void> => {\r\n const fetchOptions: RequestInit = {\r\n method,\r\n mode,\r\n credentials,\r\n signal: controller.signal,\r\n };\r\n\r\n if (methodLower !== \"get\" && payload != null) {\r\n const prepareOptions: { formDataFileFieldName?: string; formDataKey?: string } = {};\r\n if (formDataFileFieldName != null && formDataFileFieldName !== \"\")\r\n prepareOptions.formDataFileFieldName = formDataFileFieldName;\r\n if (formDataKey != null && formDataKey !== \"\") prepareOptions.formDataKey = formDataKey;\r\n const { body, headers: processedHeaders } = prepareRequestBody(payload, headers, prepareOptions);\r\n if (body !== undefined) fetchOptions.body = body;\r\n fetchOptions.headers = processedHeaders;\r\n } else {\r\n fetchOptions.headers = omitContentType({ ...headers });\r\n }\r\n\r\n try {\r\n if (responseTypeLower === \"stream\") {\r\n const maxRetries = Math.min(retries ?? 3, 5);\r\n let bytesReceived = 0;\r\n let streamError: WorkerErrorPayload = NO_ERROR;\r\n let attempt = 0;\r\n while (attempt <= maxRetries) {\r\n try {\r\n const reqHeaders =\r\n methodLower === \"get\" ? omitContentType({ ...fetchOptions.headers }) : fetchOptions.headers;\r\n if (bytesReceived > 0) reqHeaders[\"Range\"] = `bytes=${bytesReceived}-`;\r\n const streamResponse = await fetch(url, { ...fetchOptions, headers: reqHeaders });\r\n if (streamResponse.status >= 400) {\r\n streamError = makeError(streamResponse.statusText);\r\n break;\r\n }\r\n if (streamResponse.status === 204) {\r\n callerResponseStreamEnd(cacheName, hookId);\r\n return;\r\n }\r\n if (streamResponse.status === 416) break;\r\n const contentType = streamResponse.headers.get(\"content-type\") ?? undefined;\r\n const meta: BinaryResponseMeta = {\r\n contentDisposition: streamResponse.headers.get(\"content-disposition\") ?? null,\r\n ...(contentType !== undefined && { contentType }),\r\n };\r\n if (bytesReceived === 0) callerResponseStreamStart(cacheName, meta, hookId, streamResponse.status);\r\n else callerResponseStreamResume(cacheName, meta, hookId, streamResponse.status);\r\n const body = streamResponse.body;\r\n if (!body) {\r\n callerResponseStreamEnd(cacheName, hookId);\r\n return;\r\n }\r\n const reader = body.getReader();\r\n let skipRemaining = streamResponse.status === 200 && bytesReceived > 0 ? bytesReceived : 0;\r\n while (true) {\r\n const { done, value } = await reader.read();\r\n if (done) break;\r\n if (!value || value.byteLength === 0) continue;\r\n if (skipRemaining > 0) {\r\n if (value.byteLength <= skipRemaining) {\r\n skipRemaining -= value.byteLength;\r\n continue;\r\n }\r\n const offset = skipRemaining;\r\n skipRemaining = 0;\r\n const tail = value.subarray(offset);\r\n callerResponseStreamChunk(cacheName, transferableBuffer(tail), hookId);\r\n bytesReceived += tail.byteLength;\r\n } else {\r\n callerResponseStreamChunk(cacheName, transferableBuffer(value), hookId);\r\n bytesReceived += value.byteLength;\r\n }\r\n }\r\n break;\r\n } catch (err) {\r\n streamError =\r\n (err as Error).name === \"AbortError\" ? makeError(\"Request aborted\") : makeError((err as Error).message);\r\n if (attempt === maxRetries) break;\r\n }\r\n attempt++;\r\n }\r\n callerResponseStreamEnd(cacheName, hookId, streamError);\r\n return;\r\n }\r\n\r\n const response = await fetch(url, fetchOptions);\r\n\r\n if (response.status >= 400) {\r\n callerResponse(cacheName, null, hookId, response.status, makeError(response.statusText));\r\n return;\r\n }\r\n\r\n if (response.status === 204) {\r\n set(normalizeKey(cacheName), null);\r\n callerResponse(cacheName, null, hookId, 204);\r\n return;\r\n }\r\n\r\n const responseData = await parseResponseByContentType(response);\r\n\r\n if (isBinaryResponse(responseData)) {\r\n callerResponseBinary(\r\n cacheName,\r\n responseData.data,\r\n {\r\n contentType: responseData.contentType,\r\n contentDisposition: responseData.contentDisposition ?? null,\r\n },\r\n hookId,\r\n response.status,\r\n );\r\n } else {\r\n commit(cacheName, responseData, hookId, response.status);\r\n }\r\n } catch (error) {\r\n if ((error as Error).name === \"AbortError\") {\r\n callerResponse(cacheName, null, hookId, undefined, makeError(\"Request aborted\"));\r\n return;\r\n }\r\n const err = error as Error;\r\n callerResponse(cacheName, null, hookId, undefined, makeError(err.message));\r\n } finally {\r\n if (timeoutId != null) clearTimeout(timeoutId);\r\n if (requestId) {\r\n inFlightControllers.delete(requestId);\r\n }\r\n inFlightByCacheName.delete(cacheName);\r\n }\r\n })();\r\n\r\n inFlightByCacheName.set(cacheName, promise);\r\n await promise;\r\n};\r\n\r\nconst onRequest = <TData>(dataRequest: DataRequest<TData>): void => {\r\n const { cacheName, type, payload, request, requestId, hookId } = dataRequest;\r\n const responseCacheName = dataRequest.cacheName ?? \"\";\r\n\r\n if (!isNonEmptyString(type)) {\r\n callerResponse(responseCacheName, null, hookId, undefined, makeError(\"Invalid request: type is required\"));\r\n return;\r\n }\r\n const lowerType = normalizeKey(type);\r\n\r\n if (lowerType === \"cancel\") {\r\n if (requestId) onCancel(requestId);\r\n return;\r\n }\r\n\r\n if (!isNonEmptyString(cacheName)) {\r\n callerResponse(responseCacheName, null, hookId, undefined, makeError(\"Invalid request: cacheName is required\"));\r\n return;\r\n }\r\n const lowerCacheName = normalizeKey(cacheName);\r\n\r\n if (lowerType === \"get\") {\r\n const requestedData = get(lowerCacheName);\r\n if (requestedData === undefined) {\r\n callerResponse(lowerCacheName, null, hookId, undefined, makeError(\"Cache miss\"));\r\n } else {\r\n callerResponse(lowerCacheName, requestedData, hookId);\r\n }\r\n } else if (lowerType === \"set\") {\r\n if (!request) {\r\n if (payload == null) {\r\n callerResponse(\r\n responseCacheName,\r\n null,\r\n hookId,\r\n undefined,\r\n makeError(\"Invalid request: payload is required for set\"),\r\n );\r\n return;\r\n }\r\n set(lowerCacheName, payload);\r\n } else {\r\n const methodLower = normalizeKey(request.method);\r\n if (methodLower !== \"get\" && payload == null) {\r\n callerResponse(\r\n responseCacheName,\r\n null,\r\n hookId,\r\n undefined,\r\n makeError(\"Invalid request: payload is required for non-GET API request\"),\r\n );\r\n return;\r\n }\r\n void apiRequest(lowerCacheName, payload ?? null, request, requestId, hookId);\r\n }\r\n } else if (lowerType === \"delete\") {\r\n remove(lowerCacheName);\r\n callerResponse(lowerCacheName, { deleted: true }, hookId);\r\n }\r\n};\r\n\r\nconst onCancel = (requestId: string): void => {\r\n const controller = inFlightControllers.get(requestId);\r\n if (controller) {\r\n controller.abort();\r\n inFlightControllers.delete(requestId);\r\n }\r\n};\r\n\r\n/**\r\n * Incoming messages from the main thread. Expects payload shape { dataRequest?: DataRequest }.\r\n * Responses via postMessage: { cacheName, data?, meta?, hookId?, httpStatus?, error }.\r\n * error is always present: { message: \"\" } when no error, { message: \"...\" } when the request failed.\r\n */\r\nonmessage = (event: MessageEvent<WorkerMessageData>): void => {\r\n const payload = event.data;\r\n if (payload === null || typeof payload !== \"object\") return;\r\n const dataRequest = payload.dataRequest;\r\n if (dataRequest !== undefined) onRequest(dataRequest);\r\n};\r\n"],"names":[],"mappings":"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"}
|
package/dist/index.d.ts
DELETED
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,6BAA6B,CAAC;AAC3D,YAAY,EAAE,aAAa,EAAE,kBAAkB,EAAE,kBAAkB,EAAE,MAAM,6BAA6B,CAAC"}
|