@mainframework/api-request-worker 1.0.3 → 1.0.4
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 +114 -50
- package/dist/shared/output/react.d.ts +3 -3
- package/dist/shared/output/react.js +132 -67
- package/dist/shared/output/react.js.map +1 -1
- package/dist/shared/output/vanilla.d.ts +1 -1
- package/dist/shared/output/vanilla.js +1 -1
- package/dist/shared/output/vanilla.js.map +1 -1
- package/dist/{types-LYmxol0c.d.ts → types-C6nnvGO7.d.ts} +23 -49
- package/dist/workers/api/api.worker.js +202 -64
- package/dist/workers/api/api.worker.js.map +1 -1
- package/package.json +12 -9
|
@@ -3,23 +3,36 @@ const DEFAULT_FILES_FIELD = "Files";
|
|
|
3
3
|
const EMPTY_BUFFER = new ArrayBuffer(0);
|
|
4
4
|
const NO_ERROR = { message: "" };
|
|
5
5
|
const DEFAULT_ERROR = "An error occurred";
|
|
6
|
-
const callerResponse = (cacheName, data, hookId, httpStatus, error = NO_ERROR) => {
|
|
6
|
+
const callerResponse = (cacheName, data, hookId, httpStatus, error = NO_ERROR, type = "result", requestId) => {
|
|
7
7
|
self.postMessage({
|
|
8
|
+
type,
|
|
9
|
+
...requestId != null && requestId !== "" && { requestId },
|
|
8
10
|
cacheName,
|
|
9
|
-
data: error.message !== "" ? null : data ?? null,
|
|
11
|
+
data: type === "delete" ? null : error.message !== "" ? null : data ?? null,
|
|
10
12
|
hookId,
|
|
11
13
|
httpStatus,
|
|
12
14
|
error
|
|
13
15
|
});
|
|
14
16
|
};
|
|
15
|
-
const makeError = (message) =>
|
|
16
|
-
const callerResponseBinary = (cacheName, data, meta, hookId, httpStatus, error = NO_ERROR) => {
|
|
17
|
+
const makeError = (message, code) => code !== void 0 ? { message, code } : { message };
|
|
18
|
+
const callerResponseBinary = (cacheName, data, meta, hookId, httpStatus, error = NO_ERROR, requestId) => {
|
|
17
19
|
const buffer = data.byteLength ? data : EMPTY_BUFFER;
|
|
18
|
-
const payload = {
|
|
20
|
+
const payload = {
|
|
21
|
+
type: "result",
|
|
22
|
+
...requestId != null && requestId !== "" && { requestId },
|
|
23
|
+
cacheName,
|
|
24
|
+
data: buffer,
|
|
25
|
+
meta,
|
|
26
|
+
hookId,
|
|
27
|
+
httpStatus,
|
|
28
|
+
error
|
|
29
|
+
};
|
|
19
30
|
self.postMessage(payload, buffer.byteLength > 0 ? [buffer] : []);
|
|
20
31
|
};
|
|
21
|
-
const callerResponseStreamStart = (cacheName, meta, hookId, httpStatus, error = NO_ERROR) => {
|
|
32
|
+
const callerResponseStreamStart = (cacheName, meta, hookId, httpStatus, error = NO_ERROR, requestId) => {
|
|
22
33
|
self.postMessage({
|
|
34
|
+
type: "stream",
|
|
35
|
+
...requestId != null && requestId !== "" && { requestId },
|
|
23
36
|
cacheName,
|
|
24
37
|
stream: "start",
|
|
25
38
|
meta,
|
|
@@ -28,8 +41,10 @@ const callerResponseStreamStart = (cacheName, meta, hookId, httpStatus, error =
|
|
|
28
41
|
error
|
|
29
42
|
});
|
|
30
43
|
};
|
|
31
|
-
const callerResponseStreamResume = (cacheName, meta, hookId, httpStatus, error = NO_ERROR) => {
|
|
44
|
+
const callerResponseStreamResume = (cacheName, meta, hookId, httpStatus, error = NO_ERROR, requestId) => {
|
|
32
45
|
self.postMessage({
|
|
46
|
+
type: "stream",
|
|
47
|
+
...requestId != null && requestId !== "" && { requestId },
|
|
33
48
|
cacheName,
|
|
34
49
|
stream: "resume",
|
|
35
50
|
meta,
|
|
@@ -38,23 +53,52 @@ const callerResponseStreamResume = (cacheName, meta, hookId, httpStatus, error =
|
|
|
38
53
|
error
|
|
39
54
|
});
|
|
40
55
|
};
|
|
41
|
-
const callerResponseStreamChunk = (cacheName, data, hookId, error = NO_ERROR) => {
|
|
56
|
+
const callerResponseStreamChunk = (cacheName, data, hookId, error = NO_ERROR, requestId) => {
|
|
42
57
|
const buffer = data.byteLength ? data : EMPTY_BUFFER;
|
|
43
|
-
const payload = {
|
|
58
|
+
const payload = {
|
|
59
|
+
type: "stream",
|
|
60
|
+
...requestId != null && requestId !== "" && { requestId },
|
|
61
|
+
cacheName,
|
|
62
|
+
stream: "chunk",
|
|
63
|
+
data: buffer,
|
|
64
|
+
hookId,
|
|
65
|
+
error
|
|
66
|
+
};
|
|
44
67
|
self.postMessage(payload, buffer.byteLength > 0 ? [buffer] : []);
|
|
45
68
|
};
|
|
46
|
-
const callerResponseStreamEnd = (cacheName, hookId, error = NO_ERROR) => {
|
|
47
|
-
self.postMessage({
|
|
69
|
+
const callerResponseStreamEnd = (cacheName, hookId, error = NO_ERROR, requestId) => {
|
|
70
|
+
self.postMessage({
|
|
71
|
+
type: "stream",
|
|
72
|
+
...requestId != null && requestId !== "" && { requestId },
|
|
73
|
+
cacheName,
|
|
74
|
+
stream: "end",
|
|
75
|
+
hookId,
|
|
76
|
+
error
|
|
77
|
+
});
|
|
48
78
|
};
|
|
49
79
|
const transferableBuffer = (view) => view.byteOffset === 0 && view.byteLength === view.buffer.byteLength ? view.buffer : view.slice(0).buffer;
|
|
50
80
|
const store = /* @__PURE__ */ Object.create(null);
|
|
81
|
+
const storeActivity = /* @__PURE__ */ new Map();
|
|
82
|
+
const STALE_ENTRY_MS = 5e3;
|
|
83
|
+
const CLEANUP_INTERVAL_MS = 3e4;
|
|
51
84
|
const normalizeKey = (key) => key.toLocaleLowerCase();
|
|
52
|
-
const
|
|
85
|
+
const touchActivity = (key) => {
|
|
86
|
+
storeActivity.set(normalizeKey(key), Date.now());
|
|
87
|
+
};
|
|
88
|
+
const get = (key) => {
|
|
89
|
+
const nk = normalizeKey(key);
|
|
90
|
+
touchActivity(nk);
|
|
91
|
+
return store[nk];
|
|
92
|
+
};
|
|
53
93
|
const set = (key, value) => {
|
|
54
|
-
|
|
94
|
+
const nk = normalizeKey(key);
|
|
95
|
+
store[nk] = value;
|
|
96
|
+
touchActivity(nk);
|
|
55
97
|
};
|
|
56
98
|
const remove = (key) => {
|
|
57
|
-
|
|
99
|
+
const nk = normalizeKey(key);
|
|
100
|
+
delete store[nk];
|
|
101
|
+
storeActivity.delete(nk);
|
|
58
102
|
};
|
|
59
103
|
const isNonEmptyString = (v) => typeof v === "string" && v.trim() !== "";
|
|
60
104
|
const omitContentType = (headers) => {
|
|
@@ -64,13 +108,22 @@ const omitContentType = (headers) => {
|
|
|
64
108
|
return rest;
|
|
65
109
|
};
|
|
66
110
|
const isBinaryResponse = (r) => typeof r === "object" && r !== null && BINARY_MARKER in r && r.data instanceof ArrayBuffer;
|
|
67
|
-
const commit = (cacheName, data, hookId, httpStatus) => {
|
|
111
|
+
const commit = (cacheName, data, hookId, httpStatus, requestId) => {
|
|
68
112
|
if (!cacheName) {
|
|
69
|
-
callerResponse(
|
|
113
|
+
callerResponse(
|
|
114
|
+
"",
|
|
115
|
+
null,
|
|
116
|
+
hookId,
|
|
117
|
+
void 0,
|
|
118
|
+
makeError("Invalid commit: cacheName is required", "validation"),
|
|
119
|
+
"result",
|
|
120
|
+
requestId
|
|
121
|
+
);
|
|
70
122
|
return;
|
|
71
123
|
}
|
|
72
124
|
set(cacheName, data);
|
|
73
|
-
|
|
125
|
+
touchActivity(cacheName);
|
|
126
|
+
callerResponse(cacheName, data, hookId, httpStatus, NO_ERROR, "result", requestId);
|
|
74
127
|
};
|
|
75
128
|
const parseResponseByContentType = async (response) => {
|
|
76
129
|
const contentType = response.headers.get("content-type")?.toLocaleLowerCase() || "";
|
|
@@ -106,14 +159,14 @@ const appendToFormData = (formData, key, value, fileFieldName = DEFAULT_FILES_FI
|
|
|
106
159
|
return true;
|
|
107
160
|
}
|
|
108
161
|
if (value !== null && value !== void 0 && typeof value === "object") {
|
|
109
|
-
const
|
|
110
|
-
if (
|
|
111
|
-
|
|
162
|
+
const visitedSet = visited ?? /* @__PURE__ */ new WeakSet();
|
|
163
|
+
if (visitedSet.has(value)) return false;
|
|
164
|
+
visitedSet.add(value);
|
|
112
165
|
if (Array.isArray(value)) {
|
|
113
166
|
let hasFile2 = false;
|
|
114
167
|
let i = 0;
|
|
115
168
|
while (i < value.length) {
|
|
116
|
-
hasFile2 = appendToFormData(formData, key ? `${key}.${i}` : String(i), value[i], fileFieldName,
|
|
169
|
+
hasFile2 = appendToFormData(formData, key ? `${key}.${i}` : String(i), value[i], fileFieldName, visitedSet) || hasFile2;
|
|
117
170
|
i++;
|
|
118
171
|
}
|
|
119
172
|
return hasFile2;
|
|
@@ -128,7 +181,7 @@ const appendToFormData = (formData, key, value, fileFieldName = DEFAULT_FILES_FI
|
|
|
128
181
|
key ? `${key}.${k}` : k,
|
|
129
182
|
value[k],
|
|
130
183
|
fileFieldName,
|
|
131
|
-
|
|
184
|
+
visitedSet
|
|
132
185
|
) || hasFile;
|
|
133
186
|
ki++;
|
|
134
187
|
}
|
|
@@ -239,8 +292,8 @@ const prepareRequestBody = (payload, headers, options) => {
|
|
|
239
292
|
return { headers: { ...headers } };
|
|
240
293
|
}
|
|
241
294
|
};
|
|
242
|
-
const inFlightControllers = /* @__PURE__ */ new Map();
|
|
243
295
|
const inFlightByCacheName = /* @__PURE__ */ new Map();
|
|
296
|
+
const requestIdToCacheName = /* @__PURE__ */ new Map();
|
|
244
297
|
const apiRequest = async (cacheName, payload, {
|
|
245
298
|
url,
|
|
246
299
|
method,
|
|
@@ -259,21 +312,32 @@ const apiRequest = async (cacheName, payload, {
|
|
|
259
312
|
if (!skipInFlightDedupe) {
|
|
260
313
|
const existing = inFlightByCacheName.get(cacheName);
|
|
261
314
|
if (existing) {
|
|
315
|
+
if (requestId) {
|
|
316
|
+
existing.requestIds.add(requestId);
|
|
317
|
+
requestIdToCacheName.set(requestId, cacheName);
|
|
318
|
+
}
|
|
262
319
|
const cached = get(cacheName);
|
|
263
|
-
if (cached !== void 0) callerResponse(cacheName, cached, hookId);
|
|
264
|
-
await existing;
|
|
320
|
+
if (cached !== void 0) callerResponse(cacheName, cached, hookId, void 0, NO_ERROR, "result", requestId);
|
|
321
|
+
await existing.promise;
|
|
265
322
|
const fresh = get(cacheName);
|
|
266
|
-
if (fresh !== void 0) callerResponse(cacheName, fresh, hookId);
|
|
323
|
+
if (fresh !== void 0) callerResponse(cacheName, fresh, hookId, void 0, NO_ERROR, "result", requestId);
|
|
267
324
|
return;
|
|
268
325
|
}
|
|
269
326
|
}
|
|
270
327
|
const controller = new AbortController();
|
|
328
|
+
const requestIds = /* @__PURE__ */ new Set();
|
|
329
|
+
const inflightKey = skipInFlightDedupe && requestId ? requestId : cacheName;
|
|
271
330
|
if (requestId) {
|
|
272
|
-
|
|
331
|
+
requestIds.add(requestId);
|
|
332
|
+
requestIdToCacheName.set(requestId, inflightKey);
|
|
273
333
|
}
|
|
274
334
|
let timeoutId;
|
|
335
|
+
let abortedByTimeout = false;
|
|
275
336
|
if (timeoutMs != null && timeoutMs > 0) {
|
|
276
|
-
timeoutId = setTimeout(() =>
|
|
337
|
+
timeoutId = setTimeout(() => {
|
|
338
|
+
abortedByTimeout = true;
|
|
339
|
+
controller.abort();
|
|
340
|
+
}, timeoutMs);
|
|
277
341
|
}
|
|
278
342
|
const promise = (async () => {
|
|
279
343
|
const fetchOptions = {
|
|
@@ -299,6 +363,7 @@ const apiRequest = async (cacheName, payload, {
|
|
|
299
363
|
let bytesReceived = 0;
|
|
300
364
|
let streamError = NO_ERROR;
|
|
301
365
|
let attempt = 0;
|
|
366
|
+
let isPermanentError = false;
|
|
302
367
|
while (attempt <= maxRetries) {
|
|
303
368
|
try {
|
|
304
369
|
const reqHeaders = methodLower === "get" ? omitContentType({ ...fetchOptions.headers }) : { ...fetchOptions.headers };
|
|
@@ -308,24 +373,30 @@ const apiRequest = async (cacheName, payload, {
|
|
|
308
373
|
headers: reqHeaders
|
|
309
374
|
});
|
|
310
375
|
if (streamResponse.status >= 400) {
|
|
311
|
-
streamError = makeError(streamResponse.statusText || DEFAULT_ERROR);
|
|
376
|
+
streamError = makeError(streamResponse.statusText || DEFAULT_ERROR, "http");
|
|
377
|
+
isPermanentError = true;
|
|
312
378
|
break;
|
|
313
379
|
}
|
|
314
380
|
if (streamResponse.status === 204) {
|
|
315
|
-
callerResponseStreamEnd(cacheName, hookId);
|
|
381
|
+
callerResponseStreamEnd(cacheName, hookId, NO_ERROR, requestId);
|
|
316
382
|
return;
|
|
317
383
|
}
|
|
318
|
-
if (streamResponse.status === 416)
|
|
384
|
+
if (streamResponse.status === 416) {
|
|
385
|
+
streamError = makeError("Range Not Satisfiable", "http");
|
|
386
|
+
isPermanentError = true;
|
|
387
|
+
break;
|
|
388
|
+
}
|
|
319
389
|
const contentType = streamResponse.headers.get("content-type") ?? void 0;
|
|
320
390
|
const meta = {
|
|
321
391
|
contentDisposition: streamResponse.headers.get("content-disposition") ?? null,
|
|
322
392
|
...contentType !== void 0 && { contentType }
|
|
323
393
|
};
|
|
324
|
-
if (bytesReceived === 0)
|
|
325
|
-
|
|
394
|
+
if (bytesReceived === 0)
|
|
395
|
+
callerResponseStreamStart(cacheName, meta, hookId, streamResponse.status, NO_ERROR, requestId);
|
|
396
|
+
else callerResponseStreamResume(cacheName, meta, hookId, streamResponse.status, NO_ERROR, requestId);
|
|
326
397
|
const body = streamResponse.body;
|
|
327
398
|
if (!body) {
|
|
328
|
-
callerResponseStreamEnd(cacheName, hookId);
|
|
399
|
+
callerResponseStreamEnd(cacheName, hookId, NO_ERROR, requestId);
|
|
329
400
|
return;
|
|
330
401
|
}
|
|
331
402
|
const reader = body.getReader();
|
|
@@ -342,31 +413,45 @@ const apiRequest = async (cacheName, payload, {
|
|
|
342
413
|
const offset = skipRemaining;
|
|
343
414
|
skipRemaining = 0;
|
|
344
415
|
const tail = value.subarray(offset);
|
|
345
|
-
callerResponseStreamChunk(cacheName, transferableBuffer(tail), hookId);
|
|
416
|
+
callerResponseStreamChunk(cacheName, transferableBuffer(tail), hookId, NO_ERROR, requestId);
|
|
346
417
|
bytesReceived += tail.byteLength;
|
|
347
418
|
} else {
|
|
348
|
-
callerResponseStreamChunk(cacheName, transferableBuffer(value), hookId);
|
|
419
|
+
callerResponseStreamChunk(cacheName, transferableBuffer(value), hookId, NO_ERROR, requestId);
|
|
349
420
|
bytesReceived += value.byteLength;
|
|
350
421
|
}
|
|
351
422
|
}
|
|
352
423
|
break;
|
|
353
424
|
} catch (err) {
|
|
354
|
-
|
|
425
|
+
if (err.name === "AbortError") {
|
|
426
|
+
streamError = makeError("Request aborted", abortedByTimeout ? "timeout" : "aborted");
|
|
427
|
+
isPermanentError = true;
|
|
428
|
+
break;
|
|
429
|
+
}
|
|
430
|
+
streamError = makeError(err.message, "network");
|
|
355
431
|
if (attempt === maxRetries) break;
|
|
356
432
|
}
|
|
433
|
+
if (isPermanentError) break;
|
|
357
434
|
attempt++;
|
|
358
435
|
}
|
|
359
|
-
callerResponseStreamEnd(cacheName, hookId, streamError);
|
|
436
|
+
callerResponseStreamEnd(cacheName, hookId, streamError, requestId);
|
|
360
437
|
return;
|
|
361
438
|
}
|
|
362
439
|
const response = await fetch(url, fetchOptions);
|
|
363
440
|
if (response.status >= 400) {
|
|
364
|
-
callerResponse(
|
|
441
|
+
callerResponse(
|
|
442
|
+
cacheName,
|
|
443
|
+
null,
|
|
444
|
+
hookId,
|
|
445
|
+
response.status,
|
|
446
|
+
makeError(response.statusText || DEFAULT_ERROR, "http"),
|
|
447
|
+
"result",
|
|
448
|
+
requestId
|
|
449
|
+
);
|
|
365
450
|
return;
|
|
366
451
|
}
|
|
367
452
|
if (response.status === 204) {
|
|
368
453
|
set(cacheName, null);
|
|
369
|
-
callerResponse(cacheName, null, hookId, 204);
|
|
454
|
+
callerResponse(cacheName, null, hookId, 204, NO_ERROR, "result", requestId);
|
|
370
455
|
return;
|
|
371
456
|
}
|
|
372
457
|
const responseData = await parseResponseByContentType(response);
|
|
@@ -379,36 +464,52 @@ const apiRequest = async (cacheName, payload, {
|
|
|
379
464
|
contentDisposition: responseData.contentDisposition ?? null
|
|
380
465
|
},
|
|
381
466
|
hookId,
|
|
382
|
-
response.status
|
|
467
|
+
response.status,
|
|
468
|
+
NO_ERROR,
|
|
469
|
+
requestId
|
|
383
470
|
);
|
|
384
471
|
} else {
|
|
385
|
-
commit(cacheName, responseData, hookId, response.status);
|
|
472
|
+
commit(cacheName, responseData, hookId, response.status, requestId);
|
|
386
473
|
}
|
|
387
474
|
} catch (error) {
|
|
388
475
|
if (error.name === "AbortError") {
|
|
389
|
-
callerResponse(
|
|
476
|
+
callerResponse(
|
|
477
|
+
cacheName,
|
|
478
|
+
null,
|
|
479
|
+
hookId,
|
|
480
|
+
void 0,
|
|
481
|
+
makeError("Request aborted", abortedByTimeout ? "timeout" : "aborted"),
|
|
482
|
+
"result",
|
|
483
|
+
requestId
|
|
484
|
+
);
|
|
390
485
|
return;
|
|
391
486
|
}
|
|
392
487
|
const err = error;
|
|
393
|
-
callerResponse(cacheName, null, hookId, void 0, makeError(err.message));
|
|
488
|
+
callerResponse(cacheName, null, hookId, void 0, makeError(err.message, "network"), "result", requestId);
|
|
394
489
|
} finally {
|
|
395
490
|
if (timeoutId != null) clearTimeout(timeoutId);
|
|
396
|
-
|
|
397
|
-
|
|
491
|
+
for (const id of requestIds) {
|
|
492
|
+
requestIdToCacheName.delete(id);
|
|
398
493
|
}
|
|
399
|
-
inFlightByCacheName.delete(
|
|
494
|
+
inFlightByCacheName.delete(inflightKey);
|
|
400
495
|
}
|
|
401
496
|
})();
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
}
|
|
497
|
+
const entry = { promise, controller, requestIds };
|
|
498
|
+
inFlightByCacheName.set(inflightKey, entry);
|
|
405
499
|
await promise;
|
|
406
500
|
};
|
|
407
501
|
const onRequest = (dataRequest) => {
|
|
408
502
|
const { cacheName, type, payload, request, requestId, hookId } = dataRequest;
|
|
409
|
-
const responseCacheName = dataRequest.cacheName ?? "";
|
|
410
503
|
if (!isNonEmptyString(type)) {
|
|
411
|
-
callerResponse(
|
|
504
|
+
callerResponse(
|
|
505
|
+
cacheName ?? "",
|
|
506
|
+
null,
|
|
507
|
+
hookId,
|
|
508
|
+
void 0,
|
|
509
|
+
makeError("Invalid request: type is required", "validation"),
|
|
510
|
+
"result",
|
|
511
|
+
requestId
|
|
512
|
+
);
|
|
412
513
|
return;
|
|
413
514
|
}
|
|
414
515
|
const lowerType = normalizeKey(type);
|
|
@@ -417,26 +518,44 @@ const onRequest = (dataRequest) => {
|
|
|
417
518
|
return;
|
|
418
519
|
}
|
|
419
520
|
if (!isNonEmptyString(cacheName)) {
|
|
420
|
-
callerResponse(
|
|
521
|
+
callerResponse(
|
|
522
|
+
cacheName ?? "",
|
|
523
|
+
null,
|
|
524
|
+
hookId,
|
|
525
|
+
void 0,
|
|
526
|
+
makeError("Invalid request: cacheName is required", "validation"),
|
|
527
|
+
"result",
|
|
528
|
+
requestId
|
|
529
|
+
);
|
|
421
530
|
return;
|
|
422
531
|
}
|
|
423
532
|
const lowerCacheName = normalizeKey(cacheName);
|
|
424
533
|
if (lowerType === "get") {
|
|
425
534
|
const requestedData = get(lowerCacheName);
|
|
426
535
|
if (requestedData === void 0) {
|
|
427
|
-
callerResponse(
|
|
536
|
+
callerResponse(
|
|
537
|
+
lowerCacheName,
|
|
538
|
+
null,
|
|
539
|
+
hookId,
|
|
540
|
+
void 0,
|
|
541
|
+
makeError("Cache miss", "validation"),
|
|
542
|
+
"result",
|
|
543
|
+
requestId
|
|
544
|
+
);
|
|
428
545
|
} else {
|
|
429
|
-
callerResponse(lowerCacheName, requestedData, hookId);
|
|
546
|
+
callerResponse(lowerCacheName, requestedData, hookId, void 0, NO_ERROR, "result", requestId);
|
|
430
547
|
}
|
|
431
548
|
} else if (lowerType === "set") {
|
|
432
549
|
if (!request) {
|
|
433
550
|
if (payload == null) {
|
|
434
551
|
callerResponse(
|
|
435
|
-
|
|
552
|
+
cacheName ?? "",
|
|
436
553
|
null,
|
|
437
554
|
hookId,
|
|
438
555
|
void 0,
|
|
439
|
-
makeError("Invalid request: payload is required for set")
|
|
556
|
+
makeError("Invalid request: payload is required for set", "validation"),
|
|
557
|
+
"result",
|
|
558
|
+
requestId
|
|
440
559
|
);
|
|
441
560
|
return;
|
|
442
561
|
}
|
|
@@ -445,11 +564,13 @@ const onRequest = (dataRequest) => {
|
|
|
445
564
|
const methodLower = normalizeKey(request.method);
|
|
446
565
|
if (methodLower !== "get" && payload == null) {
|
|
447
566
|
callerResponse(
|
|
448
|
-
|
|
567
|
+
cacheName ?? "",
|
|
449
568
|
null,
|
|
450
569
|
hookId,
|
|
451
570
|
void 0,
|
|
452
|
-
makeError("Invalid request: payload is required for non-GET API request")
|
|
571
|
+
makeError("Invalid request: payload is required for non-GET API request", "validation"),
|
|
572
|
+
"result",
|
|
573
|
+
requestId
|
|
453
574
|
);
|
|
454
575
|
return;
|
|
455
576
|
}
|
|
@@ -457,16 +578,33 @@ const onRequest = (dataRequest) => {
|
|
|
457
578
|
}
|
|
458
579
|
} else if (lowerType === "delete") {
|
|
459
580
|
remove(lowerCacheName);
|
|
460
|
-
callerResponse(lowerCacheName,
|
|
581
|
+
callerResponse(lowerCacheName, null, hookId, void 0, NO_ERROR, "delete", requestId);
|
|
461
582
|
}
|
|
462
583
|
};
|
|
463
584
|
const onCancel = (requestId) => {
|
|
464
|
-
const
|
|
465
|
-
if (
|
|
466
|
-
|
|
467
|
-
|
|
585
|
+
const inflightKey = requestIdToCacheName.get(requestId);
|
|
586
|
+
if (!inflightKey) return;
|
|
587
|
+
const entry = inFlightByCacheName.get(inflightKey);
|
|
588
|
+
if (!entry) {
|
|
589
|
+
requestIdToCacheName.delete(requestId);
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
592
|
+
entry.requestIds.delete(requestId);
|
|
593
|
+
requestIdToCacheName.delete(requestId);
|
|
594
|
+
if (entry.requestIds.size === 0) {
|
|
595
|
+
entry.controller.abort();
|
|
596
|
+
}
|
|
597
|
+
};
|
|
598
|
+
const runStaleStoreCleanup = () => {
|
|
599
|
+
const now = Date.now();
|
|
600
|
+
for (const [key, lastAccessAt] of storeActivity) {
|
|
601
|
+
if (now - lastAccessAt < STALE_ENTRY_MS) continue;
|
|
602
|
+
if (inFlightByCacheName.has(key)) continue;
|
|
603
|
+
delete store[key];
|
|
604
|
+
storeActivity.delete(key);
|
|
468
605
|
}
|
|
469
606
|
};
|
|
607
|
+
setInterval(runStaleStoreCleanup, CLEANUP_INTERVAL_MS);
|
|
470
608
|
onmessage = (event) => {
|
|
471
609
|
const payload = event.data;
|
|
472
610
|
if (payload === null || typeof payload !== "object") return;
|