@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 CHANGED
@@ -29,7 +29,7 @@ The library supports three response types to handle different use cases:
29
29
 
30
30
  - **`responseType: "binary"`**: Full binary response is buffered in the worker and sent as an `ArrayBuffer` in a single message. Perfect for complete binary files like images, PDFs, or downloadable documents.
31
31
 
32
- - **`responseType: "stream"`**: Responses are streamed incrementally to the client. The worker sends chunks as they arrive (`start` → `chunk` → `chunk` → ... → `end`), enabling playback of audio/video streams to begin before the full file downloads. The React hook automatically accumulates chunks and returns a `Blob` when complete. For vanilla JavaScript, you handle stream events manually for maximum control.
32
+ - **`responseType: "stream"`**: Responses are streamed incrementally to the client. The worker sends chunks as they arrive (`start` → `chunk` → `chunk` → ... → `end`), enabling playback of audio/video streams to begin before the full file downloads. The React hook returns `streamChunks` (batches of `ArrayBuffer[]`) as they arrive and a final `Blob` in `data` when complete. Throttling (default: every 5 chunks or 50ms) minimizes re-renders. For vanilla JavaScript, you handle stream events manually for maximum control.
33
33
 
34
34
  Binary and stream responses are not stored in the worker cache; only json/text responses are cached.
35
35
 
@@ -45,31 +45,35 @@ yarn add @mainframework/api-request-worker
45
45
 
46
46
  If you use the optional React hook, a peer dependency `react >= 19` is required.
47
47
 
48
+ ### Public imports only
49
+
50
+ Use only these import paths. Do not import the worker script directly.
51
+
52
+ | Use case | Import from | What you get |
53
+ | ----------- | ----------------------------------------- | ------------------------------------------------------------------------------------------------------------------------- |
54
+ | **Vanilla** | `@mainframework/api-request-worker` | `createApiWorker`, `RequestConfig`, `DataRequest`, `BinaryResponseMeta`, `WorkerMessagePayload`, and other protocol types |
55
+ | **React** | `@mainframework/api-request-worker/react` | `useApiWorker`, `RequestConfig`, hook types |
56
+
57
+ The worker is not a public entry. Obtain it only by calling `createApiWorker()` from the main package (or use the React hook, which uses `createApiWorker` internally).
58
+
48
59
  ---
49
60
 
50
61
  ## Usage with Vanilla TypeScript / JavaScript
51
62
 
52
- The core of this library is a Web Worker that you communicate with via the standard `postMessage` API. This approach works in any JavaScript environment—no framework required. You create a Worker instance from the package's built worker script, send **dataRequests** via `postMessage`, and handle responses in `onmessage`.
63
+ Import from the main package entry and create the worker with `createApiWorker`. You then talk to the worker via the standard `postMessage` API: send **dataRequests** with `worker.postMessage`, and handle responses in `worker.onmessage`. No framework required.
53
64
 
54
65
  ### Setting Up the Worker
55
66
 
56
- **With a bundler (Vite, webpack, etc.):**
67
+ Create the worker with `createApiWorker`. This is the only way to obtain the worker.
57
68
 
58
69
  ```ts
59
- const worker = new Worker(
60
- new URL("node_modules/@mainframework/api-request-worker/dist/api.worker.js", import.meta.url),
61
- { type: "module" },
62
- );
63
- ```
64
-
65
- **Without a bundler:**
66
-
67
- Serve `node_modules/@mainframework/api-request-worker/dist/api.worker.js` from your web server and create the worker with that URL:
70
+ import { createApiWorker } from "@mainframework/api-request-worker";
68
71
 
69
- ```ts
70
- const worker = new Worker("/path/to/api.worker.js", { type: "module" });
72
+ const worker = createApiWorker();
71
73
  ```
72
74
 
75
+ Set `worker.onmessage` to handle responses (see [Message Protocol](#message-protocol)). Use the built-in `worker.postMessage` to send requests; do not overwrite `postMessage`.
76
+
73
77
  ### Message Protocol
74
78
 
75
79
  **Outgoing messages (main thread → worker):**
@@ -131,19 +135,22 @@ interface RequestConfig {
131
135
  formDataFileFieldName?: string; // FormData field name for File/Blob parts (default: "Files")
132
136
  formDataKey?: string; // FormData key for root payload when building multipart form data
133
137
  retries?: number; // For responseType "stream": retry attempts on connection loss (default: 3, max: 5)
138
+ streamChunkBatchSize?: number; // For responseType "stream": flush to streamChunks every N chunks (default: 5)
134
139
  }
135
140
  ```
136
141
 
137
142
  - **`responseType: "binary"`**: Use for complete binary files. The worker returns an `ArrayBuffer` and sets `meta.contentType` and `meta.contentDisposition` so you can construct a proper `Blob`: `new Blob([data], { type: meta?.contentType })`.
138
143
 
139
- - **`responseType: "stream"`**: Use for streaming audio/video or large files. The worker sends chunks incrementally. Supports automatic reconnection with configurable retries (default 3, max 5).
144
+ - **`responseType: "stream"`**: Use for streaming audio/video or large files. The worker sends chunks incrementally. The hook returns `streamChunks` (batches of `ArrayBuffer[]`) as they arrive and a final `Blob` in `data` when complete. Batching via `streamChunkBatchSize` (default 5) controls how many chunks are delivered per update. Supports automatic reconnection with configurable retries (default 3, max 5).
140
145
 
141
146
  ### Vanilla JavaScript Examples
142
147
 
143
148
  **GET request from API (JSON response):**
144
149
 
145
150
  ```ts
146
- const worker = new Worker(workerUrl, { type: "module" });
151
+ import { createApiWorker } from "@mainframework/api-request-worker";
152
+
153
+ const worker = createApiWorker();
147
154
  const cacheName = "api-get-" + Date.now();
148
155
 
149
156
  worker.onmessage = (event) => {
@@ -396,7 +403,7 @@ For React applications, the library provides an optional `useApiWorker` hook tha
396
403
  ### Hook API
397
404
 
398
405
  ```ts
399
- import { useApiWorker } from "@mainframework/api-request-worker";
406
+ import { useApiWorker } from "@mainframework/api-request-worker/react";
400
407
 
401
408
  const result = useApiWorker({
402
409
  cacheName: "my-cache", // required
@@ -422,14 +429,15 @@ const result = useApiWorker({
422
429
 
423
430
  **Return value:**
424
431
 
425
- | Property | Type | Description |
426
- | ------------- | ---------------------------- | ------------------------------------------------------------------------------------------------------------------------------------- |
427
- | `data` | `T \| null` | Response body: JSON/text for `responseType: "json"`, `ArrayBuffer` for `responseType: "binary"`, `Blob` for `responseType: "stream"`. |
428
- | `meta` | `BinaryResponseMeta \| null` | For binary and stream responses: `contentType`, `contentDisposition`. |
429
- | `loading` | `boolean` | `true` while a request is in flight. |
430
- | `error` | `string \| null` | Error message when the request failed; `null` when there is no error. See [Errors](#errors). |
431
- | `refetch` | `() => void` | Re-runs the same logical request. See [Refetch semantics](#refetch-semantics). |
432
- | `deleteCache` | `() => void` | Tells the worker to delete the cache entry for this `cacheName`. |
432
+ | Property | Type | Description |
433
+ | -------------- | ---------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------- |
434
+ | `data` | `T \| null` | Response body: JSON/text for `responseType: "json"`, `ArrayBuffer` for `responseType: "binary"`, `Blob` for `responseType: "stream"`. |
435
+ | `meta` | `BinaryResponseMeta \| null` | For binary and stream responses: `contentType`, `contentDisposition`. |
436
+ | `loading` | `boolean` | `true` while a request is in flight. |
437
+ | `error` | `string \| null` | Error message when the request failed; `null` when there is no error. See [Errors](#errors). |
438
+ | `refetch` | `() => void` | Re-runs the same logical request. See [Refetch semantics](#refetch-semantics). |
439
+ | `deleteCache` | `() => void` | Tells the worker to delete the cache entry for this `cacheName`. |
440
+ | `streamChunks` | `ArrayBuffer[] \| undefined` | For `responseType: "stream"`: batches of chunks as they arrive. Append to `MediaSource` or process incrementally. `undefined` for non-stream. |
433
441
 
434
442
  ### React Examples
435
443
 
@@ -552,20 +560,21 @@ const { data, meta, loading } = useApiWorker({
552
560
  **Streaming response (audio/video):**
553
561
 
554
562
  ```ts
555
- const { data, meta, loading, error } = useApiWorker({
563
+ const { data, meta, loading, error, streamChunks } = useApiWorker({
556
564
  cacheName: "video-stream",
557
565
  request: {
558
566
  url: "https://example.com/video.mp4",
559
567
  method: "GET",
560
568
  responseType: "stream",
561
569
  retries: 3, // Retry on connection loss (default 3, max 5)
570
+ streamChunkBatchSize: 5, // Optional: flush every N chunks (default 5)
562
571
  },
563
572
  runMode: "auto",
564
573
  });
565
574
 
566
- // data is a Blob when the stream completes
567
- // loading is true until stream ends
568
- // Use with media elements:
575
+ // streamChunks: batches of ArrayBuffer[] as chunks arrive (append to MediaSource, etc.)
576
+ // data: Blob when the stream completes
577
+ // loading: true until stream ends
569
578
  // const videoUrl = data ? URL.createObjectURL(data) : null;
570
579
  // <video src={videoUrl} controls />
571
580
  ```
@@ -623,48 +632,65 @@ Responses are routed to the requesting component by `cacheName` or, when `cacheN
623
632
 
624
633
  ## TypeScript Types
625
634
 
626
- **For React:**
635
+ **Vanilla (main entry):** Request and protocol types:
627
636
 
628
637
  ```ts
629
- import type { RequestConfig, UseApiWorkerConfig, UseApiWorkerReturn } from "@mainframework/api-request-worker";
638
+ import type {
639
+ RequestConfig,
640
+ DataRequest,
641
+ BinaryResponseMeta,
642
+ WorkerMessagePayload,
643
+ WorkerErrorPayload,
644
+ WorkerResponseMessage,
645
+ ResponseType,
646
+ RunMode,
647
+ WorkerDataRequestType,
648
+ WorkerMessageData,
649
+ BinaryParseResult,
650
+ } from "@mainframework/api-request-worker";
630
651
  ```
631
652
 
632
- **For vanilla JavaScript/TypeScript:**
653
+ - `WorkerDataRequestType`: `"get" | "set" | "delete" | "cancel"` — for narrowing `DataRequest.type`
654
+ - `WorkerMessageData`: `{ dataRequest?: DataRequest }` — shape for `postMessage` payloads
655
+ - `BinaryParseResult`: internal binary marker type; mainly for advanced worker extensions
633
656
 
634
- The worker expects the `dataRequest` shape described in the protocol documentation above. You can define minimal types for message payloads or reuse `RequestConfig` for the `request` field.
657
+ **React:**
658
+
659
+ ```ts
660
+ import type { RequestConfig, UseApiWorkerConfig, UseApiWorkerReturn } from "@mainframework/api-request-worker/react";
661
+ ```
635
662
 
636
663
  ---
637
664
 
638
665
  ## Quick Reference
639
666
 
640
- | Use case | Entry point | Primary API |
641
- | ----------------- | -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------- |
642
- | **Vanilla JS/TS** | Worker from `dist/api.worker.js` | `worker.postMessage({ dataRequest: { type, cacheName, request?, payload?, ... } })` and `worker.onmessage` for responses |
643
- | **React** | Optional: `useApiWorker` hook | `useApiWorker({ cacheName, request?, data?, runMode?, enabled? })` → `{ data, meta, loading, error, refetch, deleteCache }` (or use worker protocol above) |
667
+ | Use case | Entry point | Primary API |
668
+ | ----------------- | ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- |
669
+ | **Vanilla JS/TS** | `@mainframework/api-request-worker` | `createApiWorker()`; set `worker.onmessage`, use `worker.postMessage` |
670
+ | **React** | `@mainframework/api-request-worker/react` | `useApiWorker({ cacheName, request?, data?, runMode?, enabled? })` → `{ data, meta, loading, error, refetch, deleteCache }` |
644
671
 
645
672
  ---
646
673
 
647
674
  ## Framework Integrations
648
675
 
649
- **Core:** The worker and message protocol work with any environment (vanilla JavaScript/TypeScript or any framework).
676
+ **Core:** The worker and message protocol work in any environment (vanilla JavaScript/TypeScript or any framework). The worker is always created via `createApiWorker`; the vanilla bundle and the React hook both use it.
650
677
 
651
- **Optional integration:** A React hook (`useApiWorker`) is included to make adoption easier for React projects; React teams may instead integrate using the worker protocol directly.
678
+ **React:** A hook (`useApiWorker`) is included; it uses `createApiWorker` internally and exposes a simple API. You can instead use the [Message Protocol](#message-protocol) from React with your own `createApiWorker()` instance.
652
679
 
653
- **Coming soon:** Idiomatic helpers for other frameworks (Angular, Vue, Preact, SolidJS) are planned; until then, use the protocol from those frameworks as with vanilla JS.
680
+ **Other frameworks:** Use the main package entry and the protocol as with vanilla JS (Angular, Vue, Preact, SolidJS, etc.).
654
681
 
655
682
  ---
656
683
 
657
684
  ## Testing
658
685
 
659
- This library is thoroughly tested with comprehensive test suites:
686
+ Tests use Vitest in browser mode (Playwright Chromium). The worker is created inside `useApiWorker`; there are no mocks.
660
687
 
661
- - React hook tests (`useApiWorker.test.ts`)
662
- - Worker protocol tests (`api.worker.test.ts`)
688
+ - **useApiWorker** `src/shared/hooks/useApiWorker.test.ts` (React hook, real Worker and network)
663
689
 
664
- Key behaviors and examples in this README are covered by the test suites.
690
+ Run tests: `yarn test` (or `yarn test:watch`, `yarn test:coverage`). Ensure Chromium is installed: `npx playwright install chromium`.
665
691
 
666
692
  ---
667
693
 
668
694
  ## License
669
695
 
670
- See the License file in the repo
696
+ See LICENSE in the repository.
@@ -0,0 +1,6 @@
1
+ import { U as UseApiWorkerConfig, h as UseApiWorkerReturn } from '../../types-CTW-HSpg.js';
2
+ export { R as RequestConfig } from '../../types-CTW-HSpg.js';
3
+
4
+ declare const useApiWorker: <T>(config: UseApiWorkerConfig) => UseApiWorkerReturn<T>;
5
+
6
+ export { UseApiWorkerConfig, UseApiWorkerReturn, useApiWorker };
@@ -0,0 +1,233 @@
1
+ import { useRef, useState, useCallback, useEffect } from 'react';
2
+ import { createApiWorker } from './vanilla.js';
3
+
4
+ let idCounter = 0;
5
+ const uniqueId = () => {
6
+ idCounter += 1;
7
+ return idCounter.toString();
8
+ };
9
+
10
+ const e=e=>"object"==typeof e&&null!==e,t=e=>"function"==typeof e,r=e=>e instanceof Date,n=e=>e instanceof RegExp,o=e=>e instanceof Set,f=e=>e instanceof Map,i=e=>e instanceof String||e instanceof Number||e instanceof Boolean,a=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),s=e=>Object.getPrototypeOf(e),u=e=>null==e||"object"!=typeof e&&"function"!=typeof e,c=(l,y,p=new WeakMap,b={})=>{if(l===y)return true;if("number"==typeof l&&"number"==typeof y&&Number.isNaN(l)&&Number.isNaN(y))return true;if(b.normalizeBoxedPrimitives&&(i(l)&&(l=l.valueOf()),i(y)&&(y=y.valueOf()),u(l)&&u(y)))return l===y;if(u(l)||u(y))return false;if(t(l)||t(y))return l===y;if(!e(l)||!e(y))return false;let g=p.get(l)??(()=>{const e=new WeakMap;return p.set(l,e),e})();const h=g.get(y);if(void 0!==h)return h;g.set(y,true);const w=s(l),A=s(y);let m;return m=Array.isArray(l)&&Array.isArray(y)?((e,t,r,n)=>{if(e.length!==t.length)return false;for(let o=0;o<e.length;o++){if(n.strictSparseArrays){const r=Object.prototype.hasOwnProperty.call(e,o),n=Object.prototype.hasOwnProperty.call(t,o);if(r!==n)return false;if(!r&&!n)continue}if(!c(e[o],t[o],r,n))return false}return true})(l,y,p,b):!Array.isArray(l)&&!Array.isArray(y)&&(r(l)&&r(y)?((e,t)=>e.getTime()===t.getTime())(l,y):n(l)&&n(y)?((e,t)=>e.source===t.source&&e.flags===t.flags)(l,y):a(l)&&a(y)?((e,t)=>{if(e.constructor!==t.constructor||e.byteLength!==t.byteLength)return false;const r=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),n=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);for(let e=0;e<r.length;e++)if(r[e]!==n[e])return false;return true})(l,y):o(l)&&o(y)?((e,t,r,n)=>{if(e.size!==t.size)return false;const o=Array.from(t),f=new Set;for(const t of e){const e=o.findIndex((e,r)=>!f.has(r)&&t===e);if(-1!==e){f.add(e);continue}let i=false;for(let e=0;e<o.length;e++)if(!f.has(e)&&c(t,o[e],r,n)){f.add(e),i=true;break}if(!i)return false}return true})(l,y,p,b):f(l)&&f(y)?((e,t,r,n)=>{if(e.size!==t.size)return false;const o=Array.from(t),f=new Set;for(const[i,a]of e){if(u(i)){const e=t.get(i);if(void 0===e&&!t.has(i))return false;if(!c(a,e,r,n))return false;continue}let e=false;for(let t=0;t<o.length;t++)if(!f.has(t)){const[s,u]=o[t];if(c(i,s,r,n)&&c(a,u,r,n)){f.add(t),e=true;break}}if(!e)return false}return true})(l,y,p,b):!(!b.allowPrototypeMismatch&&w!==A)&&((e,t,r,n)=>{let o=0;for(const f of Reflect.ownKeys(e)){if(!Object.prototype.hasOwnProperty.call(t,f))return false;if(!c(e[f],t[f],r,n))return false;o++;}return Reflect.ownKeys(t).length===o})(l,y,p,b)),g.set(y,m),m},l=(e,t,r)=>c(e,t,new WeakMap,r);
11
+
12
+ const useCustomCallback = (callback, dependencies) => {
13
+ const refCallback = useRef(callback);
14
+ const refDependencies = useRef(dependencies);
15
+ if (!dependencies.every((dep, index) => l(dep, refDependencies.current[index]))) {
16
+ refDependencies.current = dependencies;
17
+ refCallback.current = callback;
18
+ }
19
+ const stableCallback = useRef(
20
+ (...args) => refCallback.current(...args)
21
+ ).current;
22
+ return stableCallback;
23
+ };
24
+
25
+ const DEFAULT_CHUNK_BATCH = 5;
26
+ const toNumber = (val, fallback) => typeof val === "number" && Number.isFinite(val) ? val : fallback;
27
+ const toStreamChunks = (val) => val === void 0 || val === null ? void 0 : Array.isArray(val) ? val : void 0;
28
+ const apiWorker = createApiWorker();
29
+ const STALE_ENTRY_MS = 5e3;
30
+ const CLEANUP_INTERVAL_MS = 3e4;
31
+ const normalizeKey = (key) => key.toLocaleLowerCase();
32
+ const cleanupState = { isDeleting: false, lastRun: 0 };
33
+ const runStaleEntryCleanup = () => {
34
+ const now = Date.now();
35
+ if (cleanupState.isDeleting || now < cleanupState.lastRun + CLEANUP_INTERVAL_MS) return;
36
+ cleanupState.isDeleting = true;
37
+ try {
38
+ const keys = Object.keys(responseQueue);
39
+ let i = 0;
40
+ while (i < keys.length) {
41
+ const key = keys[i];
42
+ const entry = responseQueue[key];
43
+ const streamInProgress = streamThrottleState[key] != null || streamAccumulators[key] != null;
44
+ if (entry && !streamInProgress && entry.data != null && entry.lastActivityAt != null && now - entry.lastActivityAt >= STALE_ENTRY_MS) {
45
+ entry.loading = null;
46
+ entry.data = null;
47
+ entry.meta = null;
48
+ entry.error = null;
49
+ entry.setUpdateTrigger = null;
50
+ entry.requestId = null;
51
+ delete entry.streamChunks;
52
+ delete streamThrottleState[key];
53
+ }
54
+ i++;
55
+ }
56
+ } finally {
57
+ cleanupState.isDeleting = false;
58
+ cleanupState.lastRun = now;
59
+ }
60
+ };
61
+ const responseQueue = {};
62
+ const streamAccumulators = {};
63
+ const streamThrottleState = {};
64
+ const updater = (n) => n + 1;
65
+ const flushStreamBatch = (key, entry) => {
66
+ const state = streamThrottleState[key];
67
+ if (!state || state.pendingChunks.length === 0) return;
68
+ entry.streamChunks = state.pendingChunks.slice();
69
+ state.pendingChunks.length = 0;
70
+ entry.setUpdateTrigger?.(updater);
71
+ };
72
+ const findEntry = (cacheName, hookId) => cacheName ? responseQueue[normalizeKey(cacheName)] : hookId ? Object.values(responseQueue).find((e) => e.hookId === hookId) ?? null : null;
73
+ const finalizeEntry = (entry) => {
74
+ entry.requestId = null;
75
+ entry.setUpdateTrigger?.(updater);
76
+ };
77
+ apiWorker.onmessage = (event) => {
78
+ const msg = event.data;
79
+ const cacheName = msg.cacheName;
80
+ const hookId = msg.hookId;
81
+ const error = msg.error;
82
+ const key = cacheName ? normalizeKey(cacheName) : "";
83
+ if ("stream" in msg && msg.stream) {
84
+ const entry2 = findEntry(cacheName, hookId);
85
+ if (!entry2) return;
86
+ const batchSize = toNumber(entry2.streamChunkBatchSize, DEFAULT_CHUNK_BATCH);
87
+ switch (msg.stream) {
88
+ case "start": {
89
+ streamAccumulators[key] = { chunks: [], meta: msg.meta ?? null };
90
+ streamThrottleState[key] = { pendingChunks: [] };
91
+ entry2.streamChunks = [];
92
+ entry2.meta = msg.meta ?? null;
93
+ entry2.setUpdateTrigger?.(updater);
94
+ return;
95
+ }
96
+ case "resume":
97
+ if (!streamAccumulators[key]) streamAccumulators[key] = { chunks: [], meta: msg.meta ?? null };
98
+ else if (msg.meta) streamAccumulators[key].meta = msg.meta;
99
+ if (!streamThrottleState[key]) streamThrottleState[key] = { pendingChunks: [] };
100
+ if (msg.meta) entry2.meta = msg.meta ?? null;
101
+ return;
102
+ case "chunk": {
103
+ const acc = streamAccumulators[key];
104
+ const throttle = streamThrottleState[key];
105
+ if (acc && msg.data) acc.chunks.push(msg.data);
106
+ if (throttle && msg.data) {
107
+ throttle.pendingChunks.push(msg.data);
108
+ if (throttle.pendingChunks.length >= batchSize) {
109
+ flushStreamBatch(key, entry2);
110
+ }
111
+ }
112
+ return;
113
+ }
114
+ case "end": {
115
+ const acc = streamAccumulators[key];
116
+ const throttle = streamThrottleState[key];
117
+ if (throttle?.pendingChunks.length) flushStreamBatch(key, entry2);
118
+ delete streamThrottleState[key];
119
+ delete streamAccumulators[key];
120
+ const errMsg = error?.message ?? "";
121
+ if (errMsg !== "") {
122
+ entry2.error = errMsg;
123
+ } else if (acc) {
124
+ entry2.data = new Blob(acc.chunks, acc.meta?.contentType ? { type: acc.meta.contentType } : void 0);
125
+ entry2.meta = acc.meta ?? null;
126
+ entry2.error = null;
127
+ entry2.lastActivityAt = Date.now();
128
+ }
129
+ entry2.loading = false;
130
+ finalizeEntry(entry2);
131
+ return;
132
+ }
133
+ }
134
+ }
135
+ const entry = findEntry(cacheName, hookId);
136
+ if (!entry) return;
137
+ const message = error?.message ?? "";
138
+ if (message !== "") {
139
+ entry.error = message;
140
+ entry.loading = false;
141
+ } else {
142
+ entry.data = msg.data ?? null;
143
+ entry.meta = msg.meta ?? null;
144
+ entry.lastActivityAt = Date.now();
145
+ entry.error = null;
146
+ entry.loading = false;
147
+ }
148
+ finalizeEntry(entry);
149
+ };
150
+ const useApiWorker = (config) => {
151
+ const { cacheName, request: requestConfig, data: configData, runMode = "auto", enabled = true } = config;
152
+ const hookIdRef = useRef("");
153
+ const queueKey = normalizeKey(cacheName);
154
+ const hasExecutedRef = useRef(false);
155
+ const [, setUpdateTrigger] = useState(0);
156
+ let storeEntry = responseQueue[queueKey];
157
+ if (!storeEntry) {
158
+ const hookId2 = uniqueId();
159
+ storeEntry = responseQueue[queueKey] = {
160
+ hookId: hookId2,
161
+ cacheName,
162
+ data: null,
163
+ loading: false,
164
+ error: null,
165
+ setUpdateTrigger: () => {
166
+ },
167
+ requestId: null,
168
+ meta: null,
169
+ lastActivityAt: null
170
+ };
171
+ hookIdRef.current = hookId2;
172
+ } else {
173
+ hookIdRef.current = storeEntry.hookId;
174
+ storeEntry.lastActivityAt = Date.now();
175
+ }
176
+ const entry = storeEntry;
177
+ entry.setUpdateTrigger = setUpdateTrigger;
178
+ const hookId = hookIdRef.current;
179
+ const deleteCache = useCallback(() => {
180
+ if (cacheName) {
181
+ apiWorker.postMessage({
182
+ dataRequest: { type: "delete", cacheName, hookId: hookIdRef.current }
183
+ });
184
+ }
185
+ }, [cacheName]);
186
+ useEffect(() => {
187
+ runStaleEntryCleanup();
188
+ });
189
+ const doRequest = useCallback(() => {
190
+ const entry2 = responseQueue[queueKey];
191
+ if (!entry2 || entry2.loading) return;
192
+ entry2.loading = true;
193
+ entry2.error = null;
194
+ entry2.lastActivityAt = Date.now();
195
+ entry2.setUpdateTrigger?.(updater);
196
+ if (requestConfig) {
197
+ const requestId = uniqueId();
198
+ entry2.requestId = requestId;
199
+ const isStream = requestConfig.responseType?.toLowerCase() === "stream";
200
+ if (isStream) {
201
+ entry2.streamChunkBatchSize = toNumber(requestConfig.streamChunkBatchSize, DEFAULT_CHUNK_BATCH);
202
+ }
203
+ const request = isStream && requestConfig.retries === void 0 ? { ...requestConfig, retries: 3 } : requestConfig;
204
+ apiWorker.postMessage({
205
+ dataRequest: { type: "set", cacheName, hookId, requestId, payload: configData, request }
206
+ });
207
+ } else {
208
+ apiWorker.postMessage({ dataRequest: { type: "get", cacheName, hookId } });
209
+ }
210
+ hasExecutedRef.current = true;
211
+ }, [queueKey, cacheName, hookId, requestConfig, configData]);
212
+ const makeRequest = useCustomCallback(() => {
213
+ if (!enabled || runMode === "once" && hasExecutedRef.current) return;
214
+ doRequest();
215
+ }, [enabled, runMode, doRequest]);
216
+ const hasAlreadyRunOnce = runMode === "once" && hasExecutedRef.current;
217
+ const shouldRun = (runMode === "auto" || runMode === "once") && enabled && (requestConfig || cacheName);
218
+ if (shouldRun && !hasAlreadyRunOnce && !entry.loading) {
219
+ doRequest();
220
+ }
221
+ return {
222
+ data: entry.data ?? null,
223
+ meta: entry.meta ?? null,
224
+ loading: entry.loading ?? false,
225
+ error: entry.error ?? null,
226
+ refetch: makeRequest,
227
+ deleteCache,
228
+ streamChunks: toStreamChunks(entry.streamChunks)
229
+ };
230
+ };
231
+
232
+ export { useApiWorker };
233
+ //# sourceMappingURL=react.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"react.js","sources":["../../../src/shared/utils/uniqueId.ts","../../../node_modules/@mainframework/is-deep-equal/dist/index.mjs","../../../src/shared/hooks/useCustomCallback.ts","../../../src/shared/hooks/useApiWorker.ts"],"sourcesContent":["// utils/uniqueId.ts\r\nlet idCounter = 0;\r\n\r\n/**\r\n * Generates a stable, unique string ID.\r\n * SSR-safe and works in any environment.\r\n */\r\nexport const uniqueId = (): string => {\r\n idCounter += 1;\r\n return idCounter.toString();\r\n};\r\n","const e=e=>\"object\"==typeof e&&null!==e,t=e=>\"function\"==typeof e,r=e=>e instanceof Date,n=e=>e instanceof RegExp,o=e=>e instanceof Set,f=e=>e instanceof Map,i=e=>e instanceof String||e instanceof Number||e instanceof Boolean,a=e=>ArrayBuffer.isView(e)&&!(e instanceof DataView),s=e=>Object.getPrototypeOf(e),u=e=>null==e||\"object\"!=typeof e&&\"function\"!=typeof e,c=(l,y,p=new WeakMap,b={})=>{if(l===y)return!0;if(\"number\"==typeof l&&\"number\"==typeof y&&Number.isNaN(l)&&Number.isNaN(y))return!0;if(b.normalizeBoxedPrimitives&&(i(l)&&(l=l.valueOf()),i(y)&&(y=y.valueOf()),u(l)&&u(y)))return l===y;if(u(l)||u(y))return!1;if(t(l)||t(y))return l===y;if(!e(l)||!e(y))return!1;let g=p.get(l)??(()=>{const e=new WeakMap;return p.set(l,e),e})();const h=g.get(y);if(void 0!==h)return h;g.set(y,!0);const w=s(l),A=s(y);let m;return m=Array.isArray(l)&&Array.isArray(y)?((e,t,r,n)=>{if(e.length!==t.length)return!1;for(let o=0;o<e.length;o++){if(n.strictSparseArrays){const r=Object.prototype.hasOwnProperty.call(e,o),n=Object.prototype.hasOwnProperty.call(t,o);if(r!==n)return!1;if(!r&&!n)continue}if(!c(e[o],t[o],r,n))return!1}return!0})(l,y,p,b):!Array.isArray(l)&&!Array.isArray(y)&&(r(l)&&r(y)?((e,t)=>e.getTime()===t.getTime())(l,y):n(l)&&n(y)?((e,t)=>e.source===t.source&&e.flags===t.flags)(l,y):a(l)&&a(y)?((e,t)=>{if(e.constructor!==t.constructor||e.byteLength!==t.byteLength)return!1;const r=new Uint8Array(e.buffer,e.byteOffset,e.byteLength),n=new Uint8Array(t.buffer,t.byteOffset,t.byteLength);for(let e=0;e<r.length;e++)if(r[e]!==n[e])return!1;return!0})(l,y):o(l)&&o(y)?((e,t,r,n)=>{if(e.size!==t.size)return!1;const o=Array.from(t),f=new Set;for(const t of e){const e=o.findIndex((e,r)=>!f.has(r)&&t===e);if(-1!==e){f.add(e);continue}let i=!1;for(let e=0;e<o.length;e++)if(!f.has(e)&&c(t,o[e],r,n)){f.add(e),i=!0;break}if(!i)return!1}return!0})(l,y,p,b):f(l)&&f(y)?((e,t,r,n)=>{if(e.size!==t.size)return!1;const o=Array.from(t),f=new Set;for(const[i,a]of e){if(u(i)){const e=t.get(i);if(void 0===e&&!t.has(i))return!1;if(!c(a,e,r,n))return!1;continue}let e=!1;for(let t=0;t<o.length;t++)if(!f.has(t)){const[s,u]=o[t];if(c(i,s,r,n)&&c(a,u,r,n)){f.add(t),e=!0;break}}if(!e)return!1}return!0})(l,y,p,b):!(!b.allowPrototypeMismatch&&w!==A)&&((e,t,r,n)=>{let o=0;for(const f of Reflect.ownKeys(e)){if(!Object.prototype.hasOwnProperty.call(t,f))return!1;if(!c(e[f],t[f],r,n))return!1;o++}return Reflect.ownKeys(t).length===o})(l,y,p,b)),g.set(y,m),m},l=(e,t,r)=>c(e,t,new WeakMap,r);export{l as isEqual};\n//# sourceMappingURL=index.mjs.map\n","\"use client\";\r\nimport { useRef } from \"react\";\r\nimport { isEqual } from \"@mainframework/is-deep-equal\";\r\n\r\nexport const useCustomCallback = <T extends (...args: unknown[]) => unknown>(\r\n callback: T,\r\n dependencies: unknown[],\r\n): T => {\r\n const refCallback = useRef<T>(callback);\r\n const refDependencies = useRef<unknown[]>(dependencies);\r\n\r\n // Update refs synchronously during render\r\n if (!dependencies.every((dep, index) => isEqual(dep, refDependencies.current[index]))) {\r\n refDependencies.current = dependencies;\r\n refCallback.current = callback;\r\n }\r\n\r\n // Stable callback, always calls latest callback\r\n const stableCallback = useRef(\r\n (...args: Parameters<T>): ReturnType<T> => refCallback.current(...args) as ReturnType<T>,\r\n ).current;\r\n\r\n return stableCallback as T;\r\n};\r\n","// useApiWorker.ts\r\nimport { useRef, useState, useCallback, useEffect } from \"react\";\r\nimport { createApiWorker } from \"../utils/createApiWorker\";\r\nimport { uniqueId } from \"../utils/uniqueId\";\r\nimport type {\r\n BinaryResponseMeta,\r\n DataRequest,\r\n QueueEntry,\r\n UseApiWorkerConfig,\r\n UseApiWorkerReturn,\r\n WorkerMessagePayload,\r\n} from \"../types/types\";\r\n\r\ntype StreamAccumulator = { chunks: ArrayBuffer[]; meta: BinaryResponseMeta | null };\r\n\r\ntype StreamThrottleState = {\r\n pendingChunks: ArrayBuffer[];\r\n};\r\n\r\nconst DEFAULT_CHUNK_BATCH = 5;\r\n\r\nconst toNumber = (val: unknown, fallback: number): number =>\r\n typeof val === \"number\" && Number.isFinite(val) ? val : fallback;\r\n\r\nconst toStreamChunks = (val: unknown): ArrayBuffer[] | undefined =>\r\n val === undefined || val === null ? undefined : Array.isArray(val) ? (val as ArrayBuffer[]) : undefined;\r\n\r\nimport { useCustomCallback } from \"./useCustomCallback\";\r\n\r\n// ============================================================================\r\n// MODULE-LEVEL WORKER & QUEUE\r\n// ============================================================================\r\n\r\nconst apiWorker = createApiWorker();\r\n\r\nconst STALE_ENTRY_MS = 5000;\r\nconst CLEANUP_INTERVAL_MS = 30000;\r\n\r\nconst normalizeKey = (key: string) => key.toLocaleLowerCase();\r\n\r\nconst cleanupState = { isDeleting: false, lastRun: 0 };\r\n\r\nconst runStaleEntryCleanup = (): void => {\r\n const now = Date.now();\r\n if (cleanupState.isDeleting || now < cleanupState.lastRun + CLEANUP_INTERVAL_MS) return;\r\n\r\n cleanupState.isDeleting = true;\r\n\r\n try {\r\n const keys = Object.keys(responseQueue);\r\n let i = 0;\r\n while (i < keys.length) {\r\n const key = keys[i] as string;\r\n const entry = responseQueue[key];\r\n const streamInProgress = streamThrottleState[key] != null || streamAccumulators[key] != null;\r\n if (\r\n entry &&\r\n !streamInProgress &&\r\n entry.data != null &&\r\n entry.lastActivityAt != null &&\r\n now - entry.lastActivityAt >= STALE_ENTRY_MS\r\n ) {\r\n entry.loading = null;\r\n entry.data = null;\r\n entry.meta = null;\r\n entry.error = null;\r\n entry.setUpdateTrigger = null;\r\n entry.requestId = null;\r\n delete entry.streamChunks;\r\n delete streamThrottleState[key];\r\n }\r\n i++;\r\n }\r\n } finally {\r\n cleanupState.isDeleting = false;\r\n cleanupState.lastRun = now;\r\n }\r\n};\r\n\r\nconst responseQueue: Record<string, QueueEntry<unknown>> = {};\r\n\r\nconst streamAccumulators: Record<string, StreamAccumulator> = {};\r\nconst streamThrottleState: Record<string, StreamThrottleState> = {};\r\n\r\nconst updater = (n: number) => n + 1;\r\n\r\nconst flushStreamBatch = (key: string, entry: QueueEntry<unknown>): void => {\r\n const state = streamThrottleState[key];\r\n if (!state || state.pendingChunks.length === 0) return;\r\n entry.streamChunks = state.pendingChunks.slice();\r\n state.pendingChunks.length = 0;\r\n entry.setUpdateTrigger?.(updater);\r\n};\r\n\r\nconst findEntry = (cacheName: string | undefined, hookId: string | undefined) =>\r\n cacheName\r\n ? responseQueue[normalizeKey(cacheName)]\r\n : hookId\r\n ? (Object.values(responseQueue).find((e) => e.hookId === hookId) ?? null)\r\n : null;\r\n\r\nconst finalizeEntry = (entry: QueueEntry<unknown>): void => {\r\n entry.requestId = null;\r\n entry.setUpdateTrigger?.(updater);\r\n};\r\n\r\n// Worker always sends error ({ message: string }). Entry is found by cacheName or hookId.\r\n// Stream responses: start → chunk(s) → end; we accumulate chunks then set data = new Blob(chunks) on end.\r\napiWorker.onmessage = (event: MessageEvent<WorkerMessagePayload>) => {\r\n const msg = event.data;\r\n const cacheName = msg.cacheName;\r\n const hookId = msg.hookId;\r\n const error = msg.error;\r\n const key = cacheName ? normalizeKey(cacheName) : \"\";\r\n\r\n if (\"stream\" in msg && msg.stream) {\r\n const entry = findEntry(cacheName, hookId);\r\n if (!entry) return;\r\n const batchSize = toNumber(entry.streamChunkBatchSize, DEFAULT_CHUNK_BATCH);\r\n switch (msg.stream) {\r\n case \"start\": {\r\n streamAccumulators[key] = { chunks: [], meta: msg.meta ?? null };\r\n streamThrottleState[key] = { pendingChunks: [] };\r\n entry.streamChunks = [];\r\n entry.meta = msg.meta ?? null;\r\n entry.setUpdateTrigger?.(updater);\r\n return;\r\n }\r\n case \"resume\":\r\n if (!streamAccumulators[key]) streamAccumulators[key] = { chunks: [], meta: msg.meta ?? null };\r\n else if (msg.meta) streamAccumulators[key].meta = msg.meta;\r\n if (!streamThrottleState[key]) streamThrottleState[key] = { pendingChunks: [] };\r\n if (msg.meta) entry.meta = msg.meta ?? null;\r\n return;\r\n case \"chunk\": {\r\n const acc = streamAccumulators[key];\r\n const throttle = streamThrottleState[key];\r\n if (acc && msg.data) acc.chunks.push(msg.data);\r\n if (throttle && msg.data) {\r\n throttle.pendingChunks.push(msg.data);\r\n if (throttle.pendingChunks.length >= batchSize) {\r\n flushStreamBatch(key, entry);\r\n }\r\n }\r\n return;\r\n }\r\n case \"end\": {\r\n const acc = streamAccumulators[key];\r\n const throttle = streamThrottleState[key];\r\n if (throttle?.pendingChunks.length) flushStreamBatch(key, entry);\r\n delete streamThrottleState[key];\r\n delete streamAccumulators[key];\r\n const errMsg = error?.message ?? \"\";\r\n if (errMsg !== \"\") {\r\n entry.error = errMsg;\r\n } else if (acc) {\r\n entry.data = new Blob(acc.chunks, acc.meta?.contentType ? { type: acc.meta.contentType } : undefined);\r\n entry.meta = acc.meta ?? null;\r\n entry.error = null;\r\n entry.lastActivityAt = Date.now();\r\n }\r\n entry.loading = false;\r\n finalizeEntry(entry);\r\n return;\r\n }\r\n }\r\n }\r\n\r\n const entry = findEntry(cacheName, hookId);\r\n if (!entry) return;\r\n\r\n const message = error?.message ?? \"\";\r\n if (message !== \"\") {\r\n entry.error = message;\r\n entry.loading = false;\r\n } else {\r\n entry.data = msg.data ?? null;\r\n entry.meta = msg.meta ?? null;\r\n entry.lastActivityAt = Date.now();\r\n entry.error = null;\r\n entry.loading = false;\r\n }\r\n finalizeEntry(entry);\r\n};\r\n\r\n// ============================================================================\r\n// HOOK\r\n// ============================================================================\r\n\r\nexport type { RequestConfig, UseApiWorkerConfig, UseApiWorkerReturn } from \"../types/types\";\r\n\r\nexport const useApiWorker = <T>(config: UseApiWorkerConfig): UseApiWorkerReturn<T> => {\r\n const { cacheName, request: requestConfig, data: configData, runMode = \"auto\", enabled = true } = config;\r\n\r\n const hookIdRef = useRef<string>(\"\");\r\n const queueKey = normalizeKey(cacheName);\r\n\r\n const hasExecutedRef = useRef(false);\r\n const [, setUpdateTrigger] = useState(0);\r\n\r\n let storeEntry = responseQueue[queueKey];\r\n\r\n if (!storeEntry) {\r\n const hookId = uniqueId();\r\n storeEntry = responseQueue[queueKey] = {\r\n hookId,\r\n cacheName,\r\n data: null,\r\n loading: false,\r\n error: null,\r\n setUpdateTrigger: () => {},\r\n requestId: null,\r\n meta: null,\r\n lastActivityAt: null,\r\n };\r\n hookIdRef.current = hookId;\r\n } else {\r\n hookIdRef.current = storeEntry.hookId;\r\n storeEntry.lastActivityAt = Date.now();\r\n }\r\n const entry = storeEntry;\r\n entry.setUpdateTrigger = setUpdateTrigger;\r\n\r\n const hookId = hookIdRef.current;\r\n\r\n const deleteCache = useCallback(() => {\r\n if (cacheName) {\r\n apiWorker.postMessage({\r\n dataRequest: { type: \"delete\", cacheName, hookId: hookIdRef.current },\r\n });\r\n }\r\n }, [cacheName]);\r\n\r\n //This runs on every render, as the cleanup. Look at the function, it's has an early return if cleanup is happening\r\n useEffect(() => {\r\n runStaleEntryCleanup();\r\n });\r\n\r\n const doRequest = useCallback(() => {\r\n const entry = responseQueue[queueKey];\r\n if (!entry || entry.loading) return;\r\n entry.loading = true;\r\n entry.error = null;\r\n entry.lastActivityAt = Date.now();\r\n entry.setUpdateTrigger?.(updater);\r\n if (requestConfig) {\r\n const requestId = uniqueId();\r\n entry.requestId = requestId;\r\n const isStream = requestConfig.responseType?.toLowerCase() === \"stream\";\r\n if (isStream) {\r\n entry.streamChunkBatchSize = toNumber(requestConfig.streamChunkBatchSize, DEFAULT_CHUNK_BATCH);\r\n }\r\n const request =\r\n isStream && requestConfig.retries === undefined ? { ...requestConfig, retries: 3 } : requestConfig;\r\n apiWorker.postMessage({\r\n dataRequest: { type: \"set\", cacheName, hookId, requestId, payload: configData, request },\r\n });\r\n } else {\r\n apiWorker.postMessage({ dataRequest: { type: \"get\", cacheName, hookId } as DataRequest<unknown> });\r\n }\r\n hasExecutedRef.current = true;\r\n }, [queueKey, cacheName, hookId, requestConfig, configData]);\r\n\r\n const makeRequest = useCustomCallback(() => {\r\n if (!enabled || (runMode === \"once\" && hasExecutedRef.current)) return;\r\n doRequest();\r\n }, [enabled, runMode, doRequest]);\r\n\r\n const hasAlreadyRunOnce = runMode === \"once\" && hasExecutedRef.current;\r\n const shouldRun = (runMode === \"auto\" || runMode === \"once\") && enabled && (requestConfig || cacheName);\r\n if (shouldRun && !hasAlreadyRunOnce && !entry.loading) {\r\n doRequest();\r\n }\r\n return {\r\n data: (entry.data as T) ?? null,\r\n meta: entry.meta ?? null,\r\n loading: entry.loading ?? false,\r\n error: entry.error ?? null,\r\n refetch: makeRequest,\r\n deleteCache,\r\n streamChunks: toStreamChunks(entry.streamChunks),\r\n };\r\n};\r\n"],"names":["isEqual","entry","hookId"],"mappings":"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","x_google_ignoreList":[1]}
@@ -0,0 +1,9 @@
1
+ export { B as BinaryParseResult, a as BinaryResponseMeta, D as DataRequest, R as RequestConfig, b as ResponseType, c as RunMode, W as WorkerDataRequestType, d as WorkerErrorPayload, e as WorkerMessageData, f as WorkerMessagePayload, g as WorkerResponseMessage } from '../../types-CTW-HSpg.js';
2
+
3
+ /**
4
+ * Creates a Worker instance for the API request worker.
5
+ * Use this for vanilla JS/TS or to build your own framework integration.
6
+ */
7
+ declare const createApiWorker: () => Worker;
8
+
9
+ export { createApiWorker };
@@ -0,0 +1,4 @@
1
+ const createApiWorker = () => new Worker(new URL("../../workers/api/api.worker.js", import.meta.url), { type: "module" });
2
+
3
+ export { createApiWorker };
4
+ //# sourceMappingURL=vanilla.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vanilla.js","sources":["../../../src/shared/utils/createApiWorker.ts"],"sourcesContent":["/**\r\n * Creates a Worker instance for the API request worker.\r\n * Use this for vanilla JS/TS or to build your own framework integration.\r\n */\r\nexport const createApiWorker = (): Worker =>\r\n new Worker(new URL(\"../../workers/api/api.worker.js\", import.meta.url), { type: \"module\" });\r\n"],"names":[],"mappings":"AAIO,MAAM,eAAA,GAAkB,MAC7B,IAAI,MAAA,CAAO,IAAI,GAAA,CAAI,iCAAA,EAAmC,MAAA,CAAA,IAAA,CAAY,GAAG,CAAA,EAAG,EAAE,IAAA,EAAM,UAAU;;;;"}