manifest 7.2.0 → 7.3.0

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/CONTRACT.md CHANGED
@@ -71,4 +71,6 @@ Every call the SDK sees and does not send to `POST /v1/heal`, whatever its statu
71
71
 
72
72
  Metadata only. The URL carries scheme, host, port and path: no query string, userinfo or fragment. No headers and no request or response body are sent, and a response body is never read to record a call. A call sent to `/v1/heal` is not also tracked.
73
73
 
74
- Recording is an in-memory append and never delays or fails the caller's request. A batch is sent when 500 calls are queued or every five seconds, at most once per second, one send at a time, up to 500 calls per request, with a five-second deadline. At most 5,000 calls are buffered; newer calls are dropped past that. A network error, timeout, 429 or 5xx is retried once, then the batch is dropped; any other answer, including 404 from a server without the route, drops it. HTTP 403 with `{"error":"project_disabled"}` suspends sending for five minutes, as for healing. Methods are upper-cased; a record whose method exceeds 16 characters or whose URL exceeds 4,096 is not sent. Buffered calls are sent once when the event loop drains (`beforeExit`), for at most two seconds: a send still in flight then is aborted and the rest is dropped, so a script never hangs on an unreachable server. A process killed or frozen first (serverless) can lose them.
74
+ Recording is an in-memory append and never delays or fails the caller's request. A batch is sent when 500 calls are queued or every five seconds, at most once per second, one send at a time, up to 500 calls per request, with a five-second deadline. At most 5,000 calls are buffered; newer calls are dropped past that. A network error, timeout, 429 or 5xx is retried once, then the batch is dropped; any other answer, including 404 from a server without the route, drops it. HTTP 403 with `{"error":"project_disabled"}` suspends sending for five minutes, as for healing. Methods are upper-cased; a record whose method exceeds 16 characters or whose URL exceeds 4,096 is not sent. Buffered calls are sent once when the event loop drains (`beforeExit`), for at most two seconds: a send still in flight then is aborted and the rest is dropped, so a script never hangs on an unreachable server. A process killed first can lose them.
75
+
76
+ On a serverless platform (`VERCEL`, `AWS_LAMBDA_FUNCTION_NAME` or `K_SERVICE` set), the function freezes as soon as it responds, so neither the interval nor the exit flush would run. There, each call is sent as soon as it is recorded, still at most once per second and one send at a time, and the send and every outcome report are handed to the platform's `waitUntil` (Vercel's request context, or Next.js's own), so the function stays alive until they are delivered. Where no `waitUntil` exists, the send still starts during the invocation.
package/README.md CHANGED
@@ -4,7 +4,7 @@
4
4
 
5
5
  # Manifest for Node.js
6
6
 
7
- **Turn 🔴 4xx API errors into 🟢 2xx in real time.**
7
+ **The API resilience layer for your Node.js apps.**
8
8
 
9
9
  [![CI](https://github.com/mnfst/manifest-node/actions/workflows/ci.yml/badge.svg?branch=main)](https://github.com/mnfst/manifest-node/actions/workflows/ci.yml)
10
10
  [![npm version](https://img.shields.io/npm/v/manifest?label=npm)](https://www.npmjs.com/package/manifest)
@@ -16,11 +16,11 @@
16
16
 
17
17
  ## What is Manifest
18
18
 
19
- Manifest is a self-healing layer that fixes and retries failed API requests on the fly.
19
+ Manifest is the API resilience layer for your apps and agents. It works with every API they call: external services, your internal APIs and MCP tools.
20
20
 
21
- * 🎯 **Fix failures automatically** before they impact your users.
22
- * 🔔 **Get notified of root causes** so you can fix them permanently.
23
- * 🔌 **Works across your stack** with internal APIs, external services, and agent tools.
21
+ * 🗺️ **See every API your app depends on**, and how reliable each one is.
22
+ * 🎯 **Repair failed API requests on the fly**, so your app keeps working.
23
+ * 🛠️ **Know what to fix in your code**, with a prompt for your coding agent.
24
24
 
25
25
  ## How it works
26
26
 
@@ -46,47 +46,73 @@ The prompt adds the one-line install to your entry file and stops to let you pas
46
46
 
47
47
  ### Start with code
48
48
 
49
- ```sh
50
- npm install manifest
51
- ```
49
+ 1. Create a project in your [Manifest dashboard](https://dashboard.manifest.build) and copy its project key.
52
50
 
53
- ```js
54
- import { manifest } from 'manifest';
51
+ 2. Install the SDK:
55
52
 
56
- manifest(); // Once, at startup.
57
- // Keep making your API calls as usual.
58
- ```
53
+ ```sh
54
+ npm install manifest
55
+ ```
59
56
 
60
- TypeScript, ESM and CommonJS. Zero dependencies.
57
+ 3. Call `manifest()` from the first import of the file that starts your app, before any client is constructed:
61
58
 
62
- ## Setup
59
+ ```js
60
+ import { manifest } from 'manifest';
63
61
 
64
- 1. Create a project in your [Manifest dashboard](https://dashboard.manifest.build) and copy its project key.
65
- 2. Set the key as an environment variable:
62
+ manifest(); // Once, at startup.
63
+ // Keep making your API calls as usual.
64
+ ```
66
65
 
67
- ```sh
68
- export MNFST_KEY='your-project-key'
69
- ```
66
+ TypeScript, ESM and CommonJS. Zero dependencies.
67
+
68
+ 4. Set your key in the environment of your app:
69
+
70
+ ```sh
71
+ export MNFST_KEY='your-project-key'
72
+ ```
70
73
 
71
- Call `manifest()` from the first import of the file that starts your app, before any client is constructed. Some clients keep the `fetch` they saw when they were built, and a client built at import time runs before your call. Where that happens, or where the start command is not yours to change, preload the SDK instead:
74
+ 5. Restart your app, then check the install from your project directory:
75
+
76
+ ```sh
77
+ npx manifest doctor
78
+ ```
79
+
80
+ It resolves the installed SDK version, masks and validates the key, checks that Manifest loads before your app, and prints the runtime coverage.
81
+
82
+ Some clients keep the `fetch` they saw when they were built, and a client built at import time runs before your call. Where that happens, or where the start command is not yours to change, preload the SDK instead:
72
83
 
73
84
  ```sh
74
85
  node -r manifest/register app.js
75
86
  ```
76
87
 
77
- Self-healing is enabled by default in your project settings.
88
+ ### n8n
78
89
 
79
- Verify the install from your project directory:
90
+ Manifest runs in a self-hosted n8n with Docker Compose, through this SDK. n8n Cloud cannot load it. Run the steps in this order:
80
91
 
81
- ```sh
82
- npx manifest doctor
83
- ```
92
+ 1. Install the SDK from the folder of your `docker-compose.yml`:
93
+
94
+ ```sh
95
+ docker compose exec n8n npm install --prefix /home/node/.n8n/manifest manifest
96
+ ```
97
+
98
+ 2. Add these two lines to the `environment` of your n8n service, and of every worker service in queue mode:
99
+
100
+ ```yaml
101
+ MNFST_KEY: your-project-key
102
+ NODE_OPTIONS: --require /home/node/.n8n/manifest/node_modules/manifest/dist/register.cjs
103
+ ```
104
+
105
+ 3. Restart n8n:
106
+
107
+ ```sh
108
+ docker compose up -d
109
+ ```
84
110
 
85
- It resolves the installed SDK version, masks and validates the key against the handshake endpoint, checks that Manifest loads before your app, and prints the runtime coverage.
111
+ n8n does not start when `NODE_OPTIONS` names a file that is not installed yet, so keep this order.
86
112
 
87
113
  ## Try it
88
114
 
89
- Send a request that would normally fail. Manifest catches it, repairs it, and retries:
115
+ Send a request that fails with a 4xx error, such as a value the API rejects:
90
116
 
91
117
  ```js
92
118
  import { manifest } from 'manifest';
@@ -100,13 +126,13 @@ manifest({
100
126
  const res = await fetch('https://api.example.com/orders', {
101
127
  method: 'POST',
102
128
  headers: { 'content-type': 'application/json' },
103
- body: JSON.stringify({ limit: 500 }), // Invalid? Manifest fixes it and retries.
129
+ body: JSON.stringify({ limit: 500 }), // rejected by the API
104
130
  });
105
- console.log(res.status); // See the 200 OK response.
131
+ console.log(res.status);
106
132
  ```
107
133
 
108
- Check your [Manifest dashboard](https://dashboard.manifest.build) to see all repairs and insights.
134
+ The failed request appears in your [Manifest dashboard](https://dashboard.manifest.build), grouped with others like it in an issue. Once Manifest has a patch for that error, the next request that fails the same way is repaired and retried: `onHeal` reports `patched` or `unverified` with the retry's status code, and your app receives the answer to the retry.
109
135
 
110
136
  ## More
111
137
 
112
- [Configuration, limits & development](docs/guide.md) · [API contract](CONTRACT.md) · [Python SDK](https://github.com/mnfst/manifest-python) · [Website](https://manifest.build)
138
+ [Documentation](https://docs.manifest.build) · [Configuration, limits & development](docs/guide.md) · [API contract](CONTRACT.md) · [Python SDK](https://github.com/mnfst/manifest-python) · [PHP SDK](https://github.com/mnfst/manifest-php) · [Website](https://manifest.build)
package/dist/bin.cjs CHANGED
@@ -33,7 +33,7 @@ var import_node_path = __toESM(require("path"), 1);
33
33
  var isObject = (value) => value !== null && typeof value === "object" && !Array.isArray(value);
34
34
 
35
35
  // src/api.ts
36
- var VERSION = "7.2.0";
36
+ var VERSION = "7.3.0";
37
37
 
38
38
  // src/cli.ts
39
39
  var DEFAULT_URL = "https://api.manifest.build";
package/dist/bin.js CHANGED
@@ -2,7 +2,7 @@
2
2
  import {
3
3
  VERSION,
4
4
  isObject
5
- } from "./chunk-NHEF7GUP.js";
5
+ } from "./chunk-VEIUJBK7.js";
6
6
 
7
7
  // src/cli.ts
8
8
  import { createRequire } from "module";
@@ -5,6 +5,8 @@ import {
5
5
  captureRequest,
6
6
  captureResponse,
7
7
  isObject,
8
+ isServerless,
9
+ keepAlive,
8
10
  mergeBody,
9
11
  parseRequestBody,
10
12
  safeHeaders,
@@ -13,7 +15,7 @@ import {
13
15
  trackedUrl,
14
16
  travelingBody,
15
17
  warn
16
- } from "./chunk-NHEF7GUP.js";
18
+ } from "./chunk-VEIUJBK7.js";
17
19
 
18
20
  // src/http.ts
19
21
  import http from "http";
@@ -33,6 +35,8 @@ var CallBuffer = class {
33
35
  this.send = send;
34
36
  this.flushAt = options.flushAt ?? 500;
35
37
  this.minGapMs = options.minGapMs ?? 1e3;
38
+ this.immediate = options.immediate ?? false;
39
+ this.keepAlive = options.keepAlive ?? keepAlive;
36
40
  this.timer = setInterval(() => void this.kick(), options.intervalMs ?? 5e3);
37
41
  this.timer.unref();
38
42
  }
@@ -46,10 +50,14 @@ var CallBuffer = class {
46
50
  timer;
47
51
  flushAt;
48
52
  minGapMs;
53
+ immediate;
54
+ keepAlive;
55
+ draining = null;
49
56
  record(call) {
50
57
  if (this.queue.length >= MAX_BUFFER) return;
51
58
  this.queue.push(call);
52
- if (this.queue.length >= this.flushAt) void this.kick();
59
+ if (this.immediate) this.drain();
60
+ else if (this.queue.length >= this.flushAt) void this.kick();
53
61
  }
54
62
  size() {
55
63
  return this.queue.length;
@@ -80,6 +88,21 @@ var CallBuffer = class {
80
88
  stop() {
81
89
  clearInterval(this.timer);
82
90
  }
91
+ /**
92
+ * Serverless: the function may freeze as soon as its response is sent, before
93
+ * any timer fires. So send now, through `flush()` (same gap, same single send
94
+ * in flight), and let the platform wait for it. Calls recorded meanwhile ride
95
+ * the same drain; one that lands as it settles starts the next.
96
+ */
97
+ drain() {
98
+ if (this.draining) return;
99
+ const run = this.flush().finally(() => {
100
+ this.draining = null;
101
+ if (this.queue.length > 0) this.drain();
102
+ });
103
+ this.draining = run;
104
+ this.keepAlive(run);
105
+ }
83
106
  kick() {
84
107
  if (this.inFlight || this.queue.length === 0) return;
85
108
  if (performance.now() - this.lastSentAt < this.minGapMs) return;
@@ -127,7 +150,10 @@ var Runtime = class {
127
150
  this.options = options;
128
151
  this.original = original;
129
152
  this.api = api ?? new HealApi(original, options.key, options.url);
130
- this.tracker = new CallBuffer((batch, signal) => this.api.sendRequests(batch, signal));
153
+ this.tracker = new CallBuffer(
154
+ (batch, signal) => this.api.sendRequests(batch, signal),
155
+ { immediate: isServerless() }
156
+ );
131
157
  }
132
158
  options;
133
159
  original;
@@ -293,8 +293,28 @@ async function captureResponse(original, limit = RESPONSE_LIMIT, timeoutMs = CAP
293
293
  return { response, body: errorBody(captured.bytes), truncated: !captured.complete || Buffer.byteLength(Buffer.from(captured.bytes).toString("utf8")) > limit, complete: captured.complete };
294
294
  }
295
295
 
296
+ // src/serverless.ts
297
+ var CONTEXTS = [/* @__PURE__ */ Symbol.for("@vercel/request-context"), /* @__PURE__ */ Symbol.for("@next/request-context")];
298
+ function isServerless(env = process.env) {
299
+ return Boolean(env.VERCEL || env.AWS_LAMBDA_FUNCTION_NAME || env.K_SERVICE);
300
+ }
301
+ function keepAlive(promise) {
302
+ try {
303
+ const globals = globalThis;
304
+ for (const symbol of CONTEXTS) {
305
+ const waitUntil = globals[symbol]?.get?.()?.waitUntil;
306
+ if (typeof waitUntil === "function") {
307
+ waitUntil(promise.catch(() => {
308
+ }));
309
+ return;
310
+ }
311
+ }
312
+ } catch {
313
+ }
314
+ }
315
+
296
316
  // src/api.ts
297
- var VERSION = "7.2.0";
317
+ var VERSION = "7.3.0";
298
318
  var MAX_HEALS_IN_FLIGHT = 8;
299
319
  var warn = (message) => process.emitWarning(message, { code: "MNFST" });
300
320
  var HealApi = class {
@@ -452,6 +472,7 @@ var HealApi = class {
452
472
  const promise = this.send(id, outcome);
453
473
  this.pending.add(promise);
454
474
  void promise.then(() => this.pending.delete(promise));
475
+ keepAlive(promise);
455
476
  }
456
477
  async send(id, outcome) {
457
478
  const controller = new AbortController();
@@ -492,6 +513,8 @@ export {
492
513
  REQUEST_LIMIT,
493
514
  captureRequest,
494
515
  captureResponse,
516
+ isServerless,
517
+ keepAlive,
495
518
  VERSION,
496
519
  warn,
497
520
  HealApi
package/dist/index.cjs CHANGED
@@ -340,8 +340,28 @@ async function captureResponse(original, limit = RESPONSE_LIMIT, timeoutMs = CAP
340
340
  // src/runtime.ts
341
341
  var import_node_crypto = require("crypto");
342
342
 
343
+ // src/serverless.ts
344
+ var CONTEXTS = [/* @__PURE__ */ Symbol.for("@vercel/request-context"), /* @__PURE__ */ Symbol.for("@next/request-context")];
345
+ function isServerless(env = process.env) {
346
+ return Boolean(env.VERCEL || env.AWS_LAMBDA_FUNCTION_NAME || env.K_SERVICE);
347
+ }
348
+ function keepAlive(promise) {
349
+ try {
350
+ const globals2 = globalThis;
351
+ for (const symbol of CONTEXTS) {
352
+ const waitUntil = globals2[symbol]?.get?.()?.waitUntil;
353
+ if (typeof waitUntil === "function") {
354
+ waitUntil(promise.catch(() => {
355
+ }));
356
+ return;
357
+ }
358
+ }
359
+ } catch {
360
+ }
361
+ }
362
+
343
363
  // src/api.ts
344
- var VERSION = "7.2.0";
364
+ var VERSION = "7.3.0";
345
365
  var MAX_HEALS_IN_FLIGHT = 8;
346
366
  var warn = (message) => process.emitWarning(message, { code: "MNFST" });
347
367
  var HealApi = class {
@@ -499,6 +519,7 @@ var HealApi = class {
499
519
  const promise = this.send(id, outcome);
500
520
  this.pending.add(promise);
501
521
  void promise.then(() => this.pending.delete(promise));
522
+ keepAlive(promise);
502
523
  }
503
524
  async send(id, outcome) {
504
525
  const controller = new AbortController();
@@ -534,6 +555,8 @@ var CallBuffer = class {
534
555
  this.send = send;
535
556
  this.flushAt = options.flushAt ?? 500;
536
557
  this.minGapMs = options.minGapMs ?? 1e3;
558
+ this.immediate = options.immediate ?? false;
559
+ this.keepAlive = options.keepAlive ?? keepAlive;
537
560
  this.timer = setInterval(() => void this.kick(), options.intervalMs ?? 5e3);
538
561
  this.timer.unref();
539
562
  }
@@ -547,10 +570,14 @@ var CallBuffer = class {
547
570
  timer;
548
571
  flushAt;
549
572
  minGapMs;
573
+ immediate;
574
+ keepAlive;
575
+ draining = null;
550
576
  record(call) {
551
577
  if (this.queue.length >= MAX_BUFFER) return;
552
578
  this.queue.push(call);
553
- if (this.queue.length >= this.flushAt) void this.kick();
579
+ if (this.immediate) this.drain();
580
+ else if (this.queue.length >= this.flushAt) void this.kick();
554
581
  }
555
582
  size() {
556
583
  return this.queue.length;
@@ -581,6 +608,21 @@ var CallBuffer = class {
581
608
  stop() {
582
609
  clearInterval(this.timer);
583
610
  }
611
+ /**
612
+ * Serverless: the function may freeze as soon as its response is sent, before
613
+ * any timer fires. So send now, through `flush()` (same gap, same single send
614
+ * in flight), and let the platform wait for it. Calls recorded meanwhile ride
615
+ * the same drain; one that lands as it settles starts the next.
616
+ */
617
+ drain() {
618
+ if (this.draining) return;
619
+ const run = this.flush().finally(() => {
620
+ this.draining = null;
621
+ if (this.queue.length > 0) this.drain();
622
+ });
623
+ this.draining = run;
624
+ this.keepAlive(run);
625
+ }
584
626
  kick() {
585
627
  if (this.inFlight || this.queue.length === 0) return;
586
628
  if (performance.now() - this.lastSentAt < this.minGapMs) return;
@@ -628,7 +670,10 @@ var Runtime = class {
628
670
  this.options = options;
629
671
  this.original = original;
630
672
  this.api = api ?? new HealApi(original, options.key, options.url);
631
- this.tracker = new CallBuffer((batch, signal) => this.api.sendRequests(batch, signal));
673
+ this.tracker = new CallBuffer(
674
+ (batch, signal) => this.api.sendRequests(batch, signal),
675
+ { immediate: isServerless() }
676
+ );
632
677
  }
633
678
  options;
634
679
  original;
package/dist/index.d.cts CHANGED
@@ -12,7 +12,7 @@ interface HealEvent {
12
12
  operations?: unknown[];
13
13
  }
14
14
 
15
- declare const VERSION = "7.2.0";
15
+ declare const VERSION = "7.3.0";
16
16
 
17
17
  /** Install once, before libraries capture their own reference to global fetch. */
18
18
  declare function manifest(options?: ManifestOptions): void;
package/dist/index.d.ts CHANGED
@@ -12,7 +12,7 @@ interface HealEvent {
12
12
  operations?: unknown[];
13
13
  }
14
14
 
15
- declare const VERSION = "7.2.0";
15
+ declare const VERSION = "7.3.0";
16
16
 
17
17
  /** Install once, before libraries capture their own reference to global fetch. */
18
18
  declare function manifest(options?: ManifestOptions): void;
package/dist/index.js CHANGED
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  manifest
3
- } from "./chunk-GC5H22R2.js";
3
+ } from "./chunk-KIHONWHK.js";
4
4
  import {
5
5
  VERSION
6
- } from "./chunk-NHEF7GUP.js";
6
+ } from "./chunk-VEIUJBK7.js";
7
7
  export {
8
8
  VERSION,
9
9
  manifest
package/dist/register.cjs CHANGED
@@ -327,8 +327,28 @@ async function captureResponse(original, limit = RESPONSE_LIMIT, timeoutMs = CAP
327
327
  // src/runtime.ts
328
328
  var import_node_crypto = require("crypto");
329
329
 
330
+ // src/serverless.ts
331
+ var CONTEXTS = [/* @__PURE__ */ Symbol.for("@vercel/request-context"), /* @__PURE__ */ Symbol.for("@next/request-context")];
332
+ function isServerless(env = process.env) {
333
+ return Boolean(env.VERCEL || env.AWS_LAMBDA_FUNCTION_NAME || env.K_SERVICE);
334
+ }
335
+ function keepAlive(promise) {
336
+ try {
337
+ const globals2 = globalThis;
338
+ for (const symbol of CONTEXTS) {
339
+ const waitUntil = globals2[symbol]?.get?.()?.waitUntil;
340
+ if (typeof waitUntil === "function") {
341
+ waitUntil(promise.catch(() => {
342
+ }));
343
+ return;
344
+ }
345
+ }
346
+ } catch {
347
+ }
348
+ }
349
+
330
350
  // src/api.ts
331
- var VERSION = "7.2.0";
351
+ var VERSION = "7.3.0";
332
352
  var MAX_HEALS_IN_FLIGHT = 8;
333
353
  var warn = (message) => process.emitWarning(message, { code: "MNFST" });
334
354
  var HealApi = class {
@@ -486,6 +506,7 @@ var HealApi = class {
486
506
  const promise = this.send(id, outcome);
487
507
  this.pending.add(promise);
488
508
  void promise.then(() => this.pending.delete(promise));
509
+ keepAlive(promise);
489
510
  }
490
511
  async send(id, outcome) {
491
512
  const controller = new AbortController();
@@ -521,6 +542,8 @@ var CallBuffer = class {
521
542
  this.send = send;
522
543
  this.flushAt = options.flushAt ?? 500;
523
544
  this.minGapMs = options.minGapMs ?? 1e3;
545
+ this.immediate = options.immediate ?? false;
546
+ this.keepAlive = options.keepAlive ?? keepAlive;
524
547
  this.timer = setInterval(() => void this.kick(), options.intervalMs ?? 5e3);
525
548
  this.timer.unref();
526
549
  }
@@ -534,10 +557,14 @@ var CallBuffer = class {
534
557
  timer;
535
558
  flushAt;
536
559
  minGapMs;
560
+ immediate;
561
+ keepAlive;
562
+ draining = null;
537
563
  record(call) {
538
564
  if (this.queue.length >= MAX_BUFFER) return;
539
565
  this.queue.push(call);
540
- if (this.queue.length >= this.flushAt) void this.kick();
566
+ if (this.immediate) this.drain();
567
+ else if (this.queue.length >= this.flushAt) void this.kick();
541
568
  }
542
569
  size() {
543
570
  return this.queue.length;
@@ -568,6 +595,21 @@ var CallBuffer = class {
568
595
  stop() {
569
596
  clearInterval(this.timer);
570
597
  }
598
+ /**
599
+ * Serverless: the function may freeze as soon as its response is sent, before
600
+ * any timer fires. So send now, through `flush()` (same gap, same single send
601
+ * in flight), and let the platform wait for it. Calls recorded meanwhile ride
602
+ * the same drain; one that lands as it settles starts the next.
603
+ */
604
+ drain() {
605
+ if (this.draining) return;
606
+ const run = this.flush().finally(() => {
607
+ this.draining = null;
608
+ if (this.queue.length > 0) this.drain();
609
+ });
610
+ this.draining = run;
611
+ this.keepAlive(run);
612
+ }
571
613
  kick() {
572
614
  if (this.inFlight || this.queue.length === 0) return;
573
615
  if (performance.now() - this.lastSentAt < this.minGapMs) return;
@@ -615,7 +657,10 @@ var Runtime = class {
615
657
  this.options = options;
616
658
  this.original = original;
617
659
  this.api = api ?? new HealApi(original, options.key, options.url);
618
- this.tracker = new CallBuffer((batch, signal) => this.api.sendRequests(batch, signal));
660
+ this.tracker = new CallBuffer(
661
+ (batch, signal) => this.api.sendRequests(batch, signal),
662
+ { immediate: isServerless() }
663
+ );
619
664
  }
620
665
  options;
621
666
  original;
package/dist/register.js CHANGED
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  manifest
3
- } from "./chunk-GC5H22R2.js";
4
- import "./chunk-NHEF7GUP.js";
3
+ } from "./chunk-KIHONWHK.js";
4
+ import "./chunk-VEIUJBK7.js";
5
5
 
6
6
  // src/register.ts
7
7
  manifest();
package/docs/guide.md CHANGED
@@ -124,7 +124,7 @@ Outcome reports are best effort, limited to 64 concurrent requests with five-sec
124
124
 
125
125
  ## Data sent to Manifest
126
126
 
127
- **Every call (metadata only).** For each call that is not healed, whatever its status, the SDK sends its method, URL without the query string, userinfo or fragment, status code, response time and time of the call. No headers and no bodies. Calls are batched and sent in the background, at most once per second; recording one never slows the call. Calls still buffered when a serverless runtime freezes the process can be lost.
127
+ **Every call (metadata only).** For each call that is not healed, whatever its status, the SDK sends its method, URL without the query string, userinfo or fragment, status code, response time and time of the call. No headers and no bodies. Calls are batched and sent in the background, at most once per second; recording one never slows the call. On Vercel, AWS Lambda and Cloud Run, each call is sent as soon as it is recorded, and the function is kept alive until it is delivered.
128
128
 
129
129
  **Healable failures (full capture).** Failed URLs, request headers, JSON or form-urlencoded bodies, and raw error responses go to the configured server. Known credential names in query parameters and headers are masked; credential-named top-level request body fields are withheld and restored on retry. Exception prose is not sent for transport failures.
130
130
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "manifest",
3
- "version": "7.2.0",
3
+ "version": "7.3.0",
4
4
  "description": "Repair eligible failed API calls made by Node HTTP clients.",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",