@wmind/site-core 0.1.1 → 0.1.2

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
@@ -4,8 +4,9 @@ The product-independent core of the site SDK: an HTTP transport, request-driven
4
4
  cache model, an atomic-swap snapshot, webhooks and status. Product modules (`@wmind/site-entitycms`,
5
5
  `@wmind/site-legal`) build on it; a site normally installs a module, not this package alone.
6
6
 
7
- - **Status:** MIT, final name, public on npm. Version `0.1.1`: the two known limits of `0.1.0`
8
- fixed, one option added (`storeTimeoutMs`), nothing removed or changed in shape.
7
+ - **Status:** MIT, final name, public on npm. Version `0.1.2`: a bug fix (the transport's timeout
8
+ survives a garbage collection on Node); `0.1.1` fixed the two known limits of `0.1.0` and added
9
+ one option (`storeTimeoutMs`). Nothing removed or changed in shape.
9
10
  - **Runs on:** Node 22, browsers and edge runtimes (Cloudflare Workers, Vercel, Netlify). Web
10
11
  platform APIs only (`fetch`, `Request`, `Response`, `crypto.subtle`, `AbortController`); zero
11
12
  runtime dependencies.
@@ -51,6 +52,12 @@ cache model, an atomic-swap snapshot, webhooks and status. Product modules (`@wm
51
52
 
52
53
  ## Known limits
53
54
 
55
+ - **Fixed in 0.1.2.** On Node 22, `fetch(request)` holds the Request's abort signal weakly: when a
56
+ garbage collection ran before an attempt's timer fired, the abort never reached the socket, and a
57
+ call to an API that never answers hung forever, past `timeoutMs` and the deadline (a flight that
58
+ never settles, a request that waits for it). The transport now keeps each Request referenced
59
+ until its fetch settles, so `timeoutMs` and `deadlineMs` hold. A `fetch` you pass gets the same
60
+ Request and needs nothing more.
54
61
  - **Fixed in 0.1.1.** A loader slower than `refreshMaxMs` no longer restarts forever without
55
62
  landing (rule 1), and a store call that never settles no longer blocks its key: every
56
63
  `CacheStore` call (`get`, `set`, `delete`) is bounded by `storeTimeoutMs` (5 s), after which it
package/dist/http.js CHANGED
@@ -5,6 +5,10 @@
5
5
  */
6
6
  import { errorFromResponse, parseRetryAfter, siteSdkError } from './errors.js';
7
7
  import { sleep, timeoutSignal } from './internal/timers.js';
8
+ /** Reads `value` so it stays reachable until the caller's promise settles (0.1.2). */
9
+ function keepAlive(value) {
10
+ void value;
11
+ }
8
12
  export const DEFAULT_TIMEOUT_MS = 10_000;
9
13
  export const DEFAULT_DEADLINE_MS = 30_000;
10
14
  export const DEFAULT_MAX_RETRIES = 6;
@@ -152,13 +156,17 @@ export function createHttp(options) {
152
156
  }));
153
157
  try {
154
158
  let res;
159
+ const outgoing = new Request(url, {
160
+ method,
161
+ headers,
162
+ ...(bodyText !== undefined ? { body: bodyText } : {}),
163
+ signal,
164
+ });
155
165
  try {
156
- res = await fetchImpl(new Request(url, {
157
- method,
158
- headers,
159
- ...(bodyText !== undefined ? { body: bodyText } : {}),
160
- signal,
161
- }));
166
+ // 0.1.2: the Request stays referenced until its fetch settles. Node's fetch holds the
167
+ // Request's signal weakly: once the Request is collected, the timeout's abort never
168
+ // reaches the socket, and a call to an API that never answers hangs forever.
169
+ res = await Promise.resolve(fetchImpl(outgoing)).finally(() => keepAlive(outgoing));
162
170
  }
163
171
  catch (error) {
164
172
  throw failure(error);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wmind/site-core",
3
- "version": "0.1.1",
3
+ "version": "0.1.2",
4
4
  "description": "Site SDK core: HTTP transport, request-driven refresh, snapshot store, webhooks, status",
5
5
  "license": "MIT",
6
6
  "repository": {