@magicvr/schema-ui-protocol 0.2.1 → 0.2.3

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.
@@ -0,0 +1,43 @@
1
+ /**
2
+ * W10 F-002: fetch timeout wrapper.
3
+ *
4
+ * Wraps a fetch implementation so a hung request (slow network, stalled
5
+ * server) aborts after a bounded window instead of pending forever. The
6
+ * returned function is drop-in compatible with `typeof fetch`; a caller-
7
+ * provided AbortSignal in `init` is composed with the timeout signal (either
8
+ * firing aborts the request). Timers are cleared once the request settles, so
9
+ * no handles leak on the happy path.
10
+ */
11
+ /** Default ceiling for a single request (30s). */
12
+ export const DEFAULT_FETCH_TIMEOUT_MS = 30_000;
13
+ export function withTimeout(fetchImpl, timeoutMs = DEFAULT_FETCH_TIMEOUT_MS) {
14
+ return async function fetchWithTimeout(input, init) {
15
+ // Resolved per call (not at wrap time) so a later global fetch stub —
16
+ // test doubles, service workers — is always honored.
17
+ const doFetch = fetchImpl ?? globalThis.fetch;
18
+ // RequestInit.signal is `AbortSignal | null | undefined`; normalize to
19
+ // undefined so the guards below stay simple.
20
+ const outer = init?.signal ?? undefined;
21
+ // An already-aborted caller signal must fail fast without touching the
22
+ // network (no fetch call, no timer).
23
+ if (outer?.aborted === true) {
24
+ throw new DOMException("The operation was aborted.", "AbortError");
25
+ }
26
+ const controller = new AbortController();
27
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
28
+ // Relay the caller signal onto our controller; the relay listener is
29
+ // removed once the request settles so a long-lived shared signal does not
30
+ // accumulate listeners across calls (A-003 recommended F-002).
31
+ const relayAbort = () => controller.abort();
32
+ if (outer !== undefined) {
33
+ outer.addEventListener("abort", relayAbort, { once: true });
34
+ }
35
+ try {
36
+ return await doFetch(input, { ...init, signal: controller.signal });
37
+ }
38
+ finally {
39
+ clearTimeout(timer);
40
+ outer?.removeEventListener("abort", relayAbort);
41
+ }
42
+ };
43
+ }
package/package.json CHANGED
@@ -1,13 +1,13 @@
1
1
  {
2
2
  "name": "@magicvr/schema-ui-protocol",
3
- "version": "0.2.1",
3
+ "version": "0.2.3",
4
4
  "type": "module",
5
- "description": "schema-ui-core 协议面(v0.2.0 · R4 升级演练=normalizePageID additive)",
6
- "main": "index.js",
7
- "types": "./protocol/index.d.ts",
5
+ "description": "schema-ui-core 包面(protocol)",
6
+ "main": "protocol/index.js",
7
+ "types": "protocol/index.d.ts",
8
8
  "exports": {
9
9
  ".": {
10
- "types": "./protocol/index.d.ts",
10
+ "types": "protocol/index.d.ts",
11
11
  "import": "./index.js"
12
12
  },
13
13
  "./*": "./*"