@intentproof/sdk 0.1.0 → 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
@@ -1,16 +1,39 @@
1
- # @intentproof/sdk
1
+ ## **Logs narrate; IntentProof gives you proof.**
2
2
 
3
- **IntentProof** turns function calls into **verifiable records** of what your system **meant** to do and what **actually happened**—**intent**, **action**, and **outcome** on the same wire. That is not another log stream: logs narrate; **IntentProof** gives you **proof** you can reconcile, attest to, or feed a verifier, because every record is tied to a real invocation with structured inputs, a stable label pair, and a completed result or error snapshot.
3
+ **IntentProof** is **auditable execution records** for actions that must be defensible—**intent** tied to what actually ran.
4
4
 
5
- This package is the Node.js / TypeScript SDK: **`IntentProofClient.wrap`** is the bridge from your code to those records. You keep your functions; each call through the wrapper emits one canonical **`ExecutionEvent`** for export.
5
+ **Wrap** the calls that matter; each invocation emits one **verifiable** **`ExecutionEvent`**, structured so intent and outcome can be **reconciled** with reality—not only observed.
6
6
 
7
- ## What this SDK does
7
+ Observability captures what happened. **IntentProof** tells you whether it matched what was **meant to happen**.
8
8
 
9
- Each such invocation produces one **`ExecutionEvent`**: **`intent`** / **`action`** (what you declared this call represents), JSON-safe **`inputs`** and **`output`** (or an **`error`** snapshot for what occurred), **`startedAt`** / **`completedAt`**, **`durationMs`**, a unique **`id`**, optional **`correlationId`** (async context or wrap options), and merged **`attributes`**. Serialization is configurable (`snapshot`, redaction, custom capture hooks) so the proof stays bounded and policy-aware.
9
+ Every **`ExecutionEvent`** contains:
10
10
 
11
- Events are delivered to every configured **`Exporter`** (`export(event)`). Built-ins cover an in-memory ring buffer, HTTP ingest, and a bounded async queue. If an exporter throws or rejects, **`onExporterError`** is notified; the wrapped function’s return value or thrown error is unchanged—your runtime behavior stays authoritative; the record is best-effort delivery.
11
+ - **`intent`**: what this invocation was meant to prove
12
+ - **`action`**: the stable operation id for this step
13
+ - **`status`**: success or error
14
+ - **`inputs`** and **`output`**: what the runtime saw going in and coming out
12
15
 
13
- The wire shape stays small and canonical so verifiers and ingest paths reason about **intent / action / outcome**, not ad hoc log lines or internal object graphs.
16
+ ## Why this matters
17
+
18
+ Modern systems—especially AI agents—do not only compute; they act:
19
+ issuing refunds, sending emails, updating databases.
20
+
21
+ When something goes wrong, logs tell you what ran.
22
+ They don't tell you:
23
+
24
+ - what was supposed to happen
25
+ - whether all steps completed
26
+ - whether systems ended up in a consistent state
27
+
28
+ **IntentProof** exists to bridge that gap.
29
+
30
+ It records intent alongside execution so systems can be verified, not just observed.
31
+
32
+ ### Picture this:
33
+
34
+ It's 4:47 on a Friday. A customer insists the critical action never happened. Support sees scattered traces; engineering sees green checks; finance asks for **one** clean chain: what was **supposed** to occur, what **did** occur, and whether the outcome is **complete**.
35
+
36
+ Ordinary telemetry shows that *something ran*. It rarely ships an **auditable story** you can hand to someone who doesn't read your codebase. **IntentProof** exists for when the question stops being "what was logged?" and starts being **"prove it."**
14
37
 
15
38
  ## Requirements
16
39
 
@@ -18,130 +41,117 @@ The wire shape stays small and canonical so verifiers and ingest paths reason ab
18
41
 
19
42
  ## Install
20
43
 
44
+ **Package:** `@intentproof/sdk`.
45
+
46
+ - [npm — `@intentproof/sdk`](https://www.npmjs.com/package/@intentproof/sdk)
47
+ - [GitHub Releases — IntentProof Node SDK](https://github.com/IntentProof/intentproof-sdk-node/releases)
48
+
49
+ Pin the **version** you want from npm or from GitHub Releases. Replace **`x.y.z`** below with that version.
50
+
21
51
  ```bash
22
- npm install @intentproof/sdk
52
+ npm install @intentproof/sdk@x.y.z
23
53
  ```
24
54
 
25
55
  ## Quick start
26
56
 
27
- Below, the object printed from **`getEvents()`** is the **proof artifact** for a single call: intent and action you chose at wrap time, inputs and output the runtime saw, plus timing and id.
28
-
29
- Use a **`MemoryExporter`** so you can inspect that record immediately (the default singleton client also uses memory, but you need your own instance to call **`getEvents()`**).
30
-
31
57
  ```ts
32
- import { createIntentProofClient, MemoryExporter } from "@intentproof/sdk";
33
-
34
- const memory = new MemoryExporter({ maxEvents: 50 });
35
- const client = createIntentProofClient({ exporters: [memory] });
58
+ import { client } from "@intentproof/sdk";
36
59
 
37
- const add = client.wrap(
38
- { intent: "demo", action: "math.add" },
39
- (a: number, b: number) => a + b,
60
+ const refund = client.wrap(
61
+ { intent: "Initiate refund", action: "stripe.refunds.create" },
62
+ async (input) => stripe.refunds.create(input),
40
63
  );
41
-
42
- const sum = add(2, 3);
43
- console.assert(sum === 5);
44
-
45
- const [event] = memory.getEvents();
46
- console.log(event);
47
64
  ```
48
65
 
49
- Calling **`add(2, 3)`** runs your original function and, after it returns, emits one event per exporter. A typical emitted object looks like this (values vary at runtime):
66
+ Each refund call emits one **`ExecutionEvent`** with the **`intent`** and **`action`** you chose, the **`inputs`** and **`output`** (or **`error`** + **`status: "error"`**), and timing fields—an execution record you can inspect, export, or verify later.
50
67
 
51
- ```json
52
- {
53
- "id": "f47ac10b-58cc-4372-a567-0e02b2c3d479",
54
- "intent": "demo",
55
- "action": "math.add",
56
- "inputs": [2, 3],
57
- "status": "ok",
58
- "output": 5,
59
- "startedAt": "2026-05-02T12:00:00.000Z",
60
- "completedAt": "2026-05-02T12:00:00.003Z",
61
- "durationMs": 3
62
- }
63
- ```
68
+ ## Reference
64
69
 
65
- - **`id`** Random UUID for this invocation.
66
- - **`inputs` / `output`** — Produced via **`snapshot()`** (see `SerializeOptions` / `WrapOptions`) unless you override with **`captureInput`** / **`captureOutput`**.
67
- - **`correlationId`** — Omitted here; present when async context or wrap options supply one (see examples below).
68
- - **`attributes`** — Omitted when empty; otherwise merged from client **`defaultAttributes`** and per-wrap **`attributes`**.
70
+ Detailed tables for the client API, emitted events, configuration, and related exports.
69
71
 
70
- ## `IntentProofClient` API
72
+ ### `IntentProofClient` API
71
73
 
72
- | Member | Description |
73
- | ----------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
74
- | **`constructor(config?)`** | Creates a client. Default exporters: a single **`MemoryExporter`** if you omit **`config.exporters`**. |
75
- | **`configure(config)`** | Re-applies **`IntentProofConfig`** fields (exporters, error hook, defaults, stack policy). |
76
- | **`wrap(options, fn)`** | Returns a function that records one **`ExecutionEvent`** per call (sync or async). **`options`** must satisfy **`assertWrapOptionsShape`** (`intent` / `action` non-empty strings, etc.). |
77
- | **`flush()`** | Awaits optional **`Exporter.flush`** on all exporters in parallel. |
78
- | **`shutdown()`** | Awaits **`Exporter.shutdown`** when defined, otherwise **`flush`**. |
79
- | **`getCorrelationId()`** | Returns the correlation id from **`AsyncLocalStorage`**, if any. |
80
- | **`withCorrelation(fn)`** | Runs **`fn`** with a **fresh UUID** as correlation id for nested wraps. |
81
- | **`withCorrelation(id, fn)`** | Runs **`fn`** with **`id`** trimmed; blank / whitespace-only **`id`** falls back to a UUID. |
74
+ | Member | Description |
75
+ | ------ | ----------- |
76
+ | **`constructor(config?)`** | Creates a client. Default exporters: a single **`MemoryExporter`** if you omit **`config.exporters`**. |
77
+ | **`configure(config)`** | Re-applies **`IntentProofConfig`** fields (exporters, error hook, defaults, stack policy). |
78
+ | **`wrap(options, fn)`** | Returns a function that records one **`ExecutionEvent`** per call (sync or async). **`options`** must satisfy **`assertWrapOptionsShape`** (`intent` / `action` non-empty strings, etc.). |
79
+ | **`flush()`** | Awaits **`flush()`** on every **`Exporter`** that implements it, in parallel. |
80
+ | **`shutdown()`** | For each **`Exporter`**, awaits **`shutdown()`** if implemented, otherwise **`flush()`** if implemented. |
81
+ | **`getCorrelationId()`** | Returns the correlation ID from **`AsyncLocalStorage`**, if any. |
82
+ | **`withCorrelation(fn)`** | Runs **`fn`** with a **fresh UUID** as correlation ID for nested wraps. |
83
+ | **`withCorrelation(id, fn)`** | Runs **`fn`** with **`id`** trimmed; blank / whitespace-only **`id`** falls back to a UUID. |
82
84
 
83
- ### Module-level helpers (same module as the client)
85
+ #### Module-level helpers (same module as the client)
84
86
 
85
87
  These use the same async correlation store as **`IntentProofClient`** instances:
86
88
 
87
- | Export | Description |
88
- | -------------------------------------- | ---------------------------------------------------------------------- |
89
- | **`createIntentProofClient(config?)`** | New isolated client (tests, workers, multi-tenant). |
90
- | **`getIntentProofClient()`** | Lazy singleton used by **`client`**. |
91
- | **`client`** | Default singleton instance. |
92
- | **`getCorrelationId()`** | Same behavior as the instance method. |
93
- | **`runWithCorrelationId(id, fn)`** | Requires a **non-empty** correlation id after trim; throws if invalid. |
94
- | **`assertCorrelationId(id)`** | Runtime assertion for correlation id shape. |
95
- | **`assertWrapOptionsShape(options)`** | Runtime validation for **`WrapOptions`**. |
96
-
97
- ## `ExecutionEvent` fields
98
-
99
- | Field | Type | When present | Meaning |
100
- | ------------------- | ------------------------ | ------------ | -------------------------------------------------------------------------------------------------------------------------------- |
101
- | **`id`** | `string` | always | Unique event id (UUID). |
102
- | **`correlationId`** | `string` | optional | Request / trace id from context or wrap options. |
103
- | **`intent`** | `string` | always | Human-readable label for what this invocation is meant to prove (outcome, policy goal, or domain). |
104
- | **`action`** | `string` | always | Stable operation id for this step (often dotted or namespaced). |
105
- | **`inputs`** | `unknown` | always | JSON-safe snapshot of call arguments (default) or **`captureInput`** result. |
106
- | **`output`** | `unknown` | success | JSON-safe return value or **`captureOutput`** result. On **`status: "error"`**, set only if **`captureError`** returned a value. |
107
- | **`error`** | `ExecutionErrorSnapshot` | failure | **`name`**, **`message`**, optional **`stack`** (see **`includeErrorStack`**). |
108
- | **`status`** | `"ok" \| "error"` | always | Outcome of the wrapped invocation. |
109
- | **`startedAt`** | ISO string | always | Start timestamp. |
110
- | **`completedAt`** | ISO string | always | Completion timestamp. |
111
- | **`durationMs`** | `number` | always | Wall time between start and completion. |
112
- | **`attributes`** | plain record | optional | String / number / boolean values only; merged from client defaults and wrap options. |
113
-
114
- ## `WrapOptions` and `IntentProofConfig`
115
-
116
- ### `WrapOptions` (passed to **`wrap`**)
117
-
118
- | Field | Description |
119
- | ---------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- |
120
- | **`intent`**, **`action`** | Required, non-empty after trim. |
121
- | **`correlationId`** | Optional; when set, non-empty after trim. Otherwise the active context id is used if any. |
122
- | **`attributes`** | Per-invocation dimensions merged over **`defaultAttributes`**. |
123
- | **`captureInput`**, **`captureOutput`**, **`captureError`** | Optional hooks to replace default **`snapshot`** behavior for inputs, success output, or error-side extra **`output`**. |
124
- | **`includeErrorStack`** | When `false`, omit **`error.stack`** for this wrap (overrides client default). |
125
- | **`maxDepth`**, **`maxKeys`**, **`redactKeys`**, **`maxStringLength`** | Forwarded to **`snapshot`** for inputs and outputs (see **`SerializeOptions`** in types). |
126
-
127
- ### `IntentProofConfig` (constructor / **`configure`**)
128
-
129
- | Field | Description |
130
- | ----------------------- | ----------------------------------------------------------------------------------------------- |
131
- | **`exporters`** | Ordered list of **`Exporter`** instances; each receives every event. |
132
- | **`onExporterError`** | Called when **`export`** throws or returns a rejected promise. Defaults to **`console.error`**. |
133
- | **`defaultAttributes`** | Merged into every event’s **`attributes`** (wrap-specific attributes win on key collision). |
134
- | **`includeErrorStack`** | Default `true`; set `false` in production if stacks must not leave the trust zone. |
89
+ | Export | Description |
90
+ | ------ | ----------- |
91
+ | **`createIntentProofClient(config?)`** | New isolated client (tests, workers, multi-tenant). |
92
+ | **`getIntentProofClient()`** | Lazy singleton used by **`client`**. |
93
+ | **`client`** | Default singleton instance. |
94
+ | **`getCorrelationId()`** | Same behavior as the instance method. |
95
+ | **`runWithCorrelationId(id, fn)`** | Requires a **non-empty** correlation ID after trim; throws if invalid. |
96
+ | **`assertCorrelationId(id)`** | Runtime assertion for correlation ID shape. |
97
+ | **`assertWrapOptionsShape(options)`** | Runtime validation for **`WrapOptions`**. |
98
+
99
+ ### `ExecutionEvent` fields
100
+
101
+ | Field | Description |
102
+ | ----- | ----------- |
103
+ | **`id`** | Unique event id (UUID). |
104
+ | **`correlationId`** | Request or trace correlation ID when present—usually from context or **`WrapOptions`**. |
105
+ | **`intent`** | Human-readable label for what this invocation is meant to prove (outcome, policy goal, or domain). |
106
+ | **`action`** | Stable operation id for this step (often dotted or namespaced). |
107
+ | **`inputs`** | JSON-safe snapshot of call arguments (default) or **`captureInput`** result. |
108
+ | **`output`** | JSON-safe return value or **`captureOutput`** result on success. When **`status`** is **`"error"`**, set only if **`captureError`** returned a value. |
109
+ | **`error`** | On failure: **`name`**, **`message`**, and optional **`stack`** (see **`includeErrorStack`**). |
110
+ | **`status`** | **`"ok"`** if the wrapped call completed normally; **`"error"`** if it threw. |
111
+ | **`startedAt`** | Start time (ISO 8601). |
112
+ | **`completedAt`** | Completion time (ISO 8601). |
113
+ | **`durationMs`** | Wall time between start and completion, in milliseconds. |
114
+ | **`attributes`** | Optional plain record (string / number / boolean values only), merged from client defaults and wrap options. |
115
+
116
+ ### `WrapOptions` and `IntentProofConfig`
117
+
118
+ #### `WrapOptions` (passed to **`wrap`**)
119
+
120
+ | Field | Description |
121
+ | ----- | ----------- |
122
+ | **`intent`**, **`action`** | Required, non-empty after trim. |
123
+ | **`correlationId`** | Optional; when set, non-empty after trim. Otherwise the active correlation ID from context is used, if any. |
124
+ | **`attributes`** | Per-invocation dimensions merged over **`defaultAttributes`**. |
125
+ | **`captureInput`**, **`captureOutput`**, **`captureError`** | Optional hooks to replace default **`snapshot`** behavior for inputs, success output, or error-side extra **`output`**. |
126
+ | **`includeErrorStack`** | When `false`, omit **`error.stack`** for this wrap (overrides client default). |
127
+ | **`maxDepth`**, **`maxKeys`**, **`redactKeys`**, **`maxStringLength`** | Forwarded to **`snapshot`** for inputs and outputs (see **`SerializeOptions`** in types). |
128
+
129
+ #### `IntentProofConfig` (constructor / **`configure`**)
130
+
131
+ | Field | Description |
132
+ | ----- | ----------- |
133
+ | **`exporters`** | Ordered list of **`Exporter`** instances; each receives every **`ExecutionEvent`**. |
134
+ | **`onExporterError`** | Called when any exporter’s **`export()`** throws or returns a rejected promise. Defaults to **`console.error`**. |
135
+ | **`defaultAttributes`** | Merged into every event’s **`attributes`** (wrap-specific attributes win on key collision). |
136
+ | **`includeErrorStack`** | Default `true`; set `false` in production if stacks must not leave the trust zone. |
137
+
138
+ ### Related exports
139
+
140
+ - **`MemoryExporter`**, **`HttpExporter`**, **`BoundedQueueExporter`** — Delivery implementations; each implements **`Exporter`**.
141
+ - **`snapshot`** — Same JSON-safe serializer the client uses internally, if you build custom tooling.
142
+ - **`VERSION`** — Package version string injected at build time.
135
143
 
136
144
  ---
137
145
 
138
146
  ## Examples
139
147
 
140
- ### 1 — Refund saga: money back, customer notified, ops alerted (one correlation id)
148
+ ### 1 — Refund and customer receipt
141
149
 
142
- Support approves **order `ORD-1042`**. Your service runs one cohesive workflow: create the **Stripe refund**, email the customer a receipt, post to **Slack** so billing ops see it. **`runWithCorrelationId`** ties all three calls to **`req_refund_ord_1042`**. Each wrap has its own **`intent`** (the outcome you are proving for that step) and **`action`** (how it is done); **`correlationId`** is what stitches the saga together.
150
+ Support approves **order `ORD-1042`**. Your service creates the **Stripe refund**, then emails the customer a receipt. **`runWithCorrelationId`** ties both calls to **`req_refund_ord_1042`**. Each **`wrap`** defines its own **`intent`** (the outcome you are proving for that step) and **`action`** (how it is done); **`correlationId`** is what stitches them together.
143
151
 
144
- **`captureInput` / `captureOutput`** trim each record to the fields you want in proof (refund id, amounts, message id, Slack metadata)—not full vendor payloads.
152
+ **`captureInput`** / **`captureOutput`** trim each record to the fields you want in proof (refund id, amounts, message id)—not full vendor payloads.
153
+
154
+ JSON on the wire uses **camelCase**; TypeScript **`WrapOptions`** use the same camelCase names (e.g. **`captureInput`**).
145
155
 
146
156
  ```ts
147
157
  const createRefund = client.wrap(
@@ -221,35 +231,6 @@ const sendRefundReceipt = client.wrap(
221
231
  }) => ({ messageId: "msg_49401_sample", status: "queued" as const }),
222
232
  );
223
233
 
224
- const notifyOpsRefund = client.wrap(
225
- {
226
- intent: "Surface the completed refund to billing operations for review",
227
- action: "slack.operations.refund_posted",
228
- attributes: { channel: "slack", step: "notify_ops" },
229
- captureInput: (args) => {
230
- const [p] = args as [{ refundId: string; orderId: string; amountCents: number }];
231
- return {
232
- refundId: p.refundId,
233
- orderId: p.orderId,
234
- amountCents: p.amountCents,
235
- };
236
- },
237
- captureOutput: (result) => {
238
- const r = result as {
239
- ok: boolean;
240
- channel: string;
241
- ts: string;
242
- };
243
- return { ok: r.ok, channel: r.channel, ts: r.ts };
244
- },
245
- },
246
- (p: { refundId: string; orderId: string; amountCents: number }) => ({
247
- ok: true,
248
- channel: "#billing-alerts",
249
- ts: "1714648800.000100",
250
- }),
251
- );
252
-
253
234
  await runWithCorrelationId("req_refund_ord_1042", async () => {
254
235
  const refund = createRefund({
255
236
  paymentIntentId: "pi_3SAMPLEabcdefghijklmnop",
@@ -264,17 +245,10 @@ await runWithCorrelationId("req_refund_ord_1042", async () => {
264
245
  amountCents: refund.amountCents,
265
246
  }),
266
247
  );
267
- await Promise.resolve(
268
- notifyOpsRefund({
269
- refundId: refund.id,
270
- orderId: "ORD-1042",
271
- amountCents: refund.amountCents,
272
- }),
273
- );
274
248
  });
275
249
  ```
276
250
 
277
- Emitted events (same **`correlationId`** on each; distinct **`intent`** per step; **`id`** / timestamps omitted):
251
+ Emitted **`ExecutionEvent`** values (same **`correlationId`** on each; distinct **`intent`** per step; **`id`** / timestamps omitted):
278
252
 
279
253
  ```json
280
254
  [
@@ -318,28 +292,6 @@ Emitted events (same **`correlationId`** on each; distinct **`intent`** per step
318
292
  "channel": "email",
319
293
  "step": "notify_customer"
320
294
  }
321
- },
322
- {
323
- "correlationId": "req_refund_ord_1042",
324
- "intent": "Surface the completed refund to billing operations for review",
325
- "action": "slack.operations.refund_posted",
326
- "inputs": {
327
- "refundId": "re_3SAMPLEabcdefghijklmnop",
328
- "orderId": "ORD-1042",
329
- "amountCents": 4999
330
- },
331
- "status": "ok",
332
- "output": {
333
- "ok": true,
334
- "channel": "#billing-alerts",
335
- "ts": "1714648800.000100"
336
- },
337
- "attributes": {
338
- "service": "billing-api",
339
- "env": "test",
340
- "channel": "slack",
341
- "step": "notify_ops"
342
- }
343
295
  }
344
296
  ]
345
297
  ```
@@ -385,9 +337,9 @@ try {
385
337
  }
386
338
  ```
387
339
 
388
- ### 3 — Proof delivery over HTTP (same event shape)
340
+ ### 3 — Proof delivery over HTTP (same **`ExecutionEvent`** shape)
389
341
 
390
- **`HttpExporter`** POSTs the same **`ExecutionEvent`** your verifiers see in memory—here alongside **`MemoryExporter`** so tests can assert the wire without a real collector. The request uses **`credentials: "omit"`**; the body is **`{ intentproof: "1", event: … }`** (see exporter implementation). For authenticated collectors, pass **`headers`** (e.g. **`Authorization`**, API keys) — see [Security](#security).
342
+ **`HttpExporter`** POSTs the same **`ExecutionEvent`** your verifiers see in memory—here alongside **`MemoryExporter`** so tests can assert the wire without a real collector. The request omits ambient credentials; the body is **`{ "intentproof": "1", "event": … }`** (see exporter implementation). For authenticated collectors, pass **`headers`** (e.g. **`Authorization`**, API keys) — see [Security](#security).
391
343
 
392
344
  ```ts
393
345
  const runProbe = client.wrap({ intent: "HTTP test", action: "test.http" }, () => 42);
@@ -408,30 +360,39 @@ runProbe();
408
360
 
409
361
  ## Security
410
362
 
411
- **IntentProof events are data you ship off-process.** Treat **`ExecutionEvent`** like structured logs or audit payloads: they can include PII, secrets, stack traces, and business identifiers depending on your **`snapshot`** / **`capture*`** hooks.
363
+ For **vulnerability reporting**, use this repository’s [**Security**](https://github.com/IntentProof/intentproof-sdk-node/security) tab (private advisories).
412
364
 
413
- - **Minimize payload:** Use **`redactKeys`**, **`maxDepth` / `maxKeys` / `maxStringLength`**, and narrow **`captureInput` / `captureOutput` / `captureError`** so proof records contain only what verifiers need.
365
+ Every **`ExecutionEvent`** you emit is data you may ship off-process. Treat them like audit-grade execution records: they can include PII, secrets, stack traces, and business identifiers depending on your **`snapshot`** / **`capture*`** hooks.
366
+
367
+ - **Minimize payload:** Use **`redactKeys`**, **`maxDepth`** / **`maxKeys`** / **`maxStringLength`**, and narrow **`captureInput`** / **`captureOutput`** / **`captureError`** so proof records contain only what verifiers need.
414
368
  - **Stacks:** Set **`includeErrorStack: false`** on the client (or per wrap) when traces must not leave your trust zone.
415
369
  - **HTTP ingest:** Keep collector **`url`** and any redirect behavior under **trusted configuration** (avoid SSRF if URLs were ever influenced by untrusted input). Prefer **HTTPS** and **short-lived credentials** end-to-end.
416
370
  - **`HttpExporter` auth:** Pass credentials in **`headers`** (for example **`Authorization: Bearer …`**, **`x-api-key`**, or whatever your collector expects). The SDK does **not** log header values; use short-lived tokens and scope them to ingest only.
417
- - **Browser vs server:** This package targets **Node**; if you wrap code in a browser, treat the ingest endpoint and headers as you would any cross-origin credential (CORS, CSP, token storage policies are your app’s responsibility).
371
+ - **Runtime surface:** This package targets **Node**; if you wrap code in a browser, treat the ingest endpoint and headers as you would any cross-origin credential (CORS, CSP, token storage policies are your app’s responsibility).
418
372
  - **Delivery semantics:** Exporter failures invoke **`onExporterError`** and do **not** roll back the wrapped function’s side effects—design compensating controls if you need strict “delivered exactly once” guarantees.
419
373
 
420
374
  Custom **`body`** serializers: if **`body(event)`** throws, **`HttpExporter`** notifies **`onError`** and falls back to the same **JSON envelope** path as the default serializer (full event, then a partial envelope, then a minimal `eventSerializeFailed` payload) so **`export()`** still completes and **`fetch`** runs when possible.
421
375
 
422
376
  ---
423
377
 
424
- ## Related exports
378
+ ## Canonical specification (`intentproof-spec`)
425
379
 
426
- - **`MemoryExporter`**, **`HttpExporter`**, **`BoundedQueueExporter`** Delivery implementations; each implements **`Exporter`**.
427
- - **`snapshot`** — Same JSON-safe serializer the client uses internally, if you build custom tooling.
428
- - **`VERSION`** — Package version string injected at build time.
380
+ Schemas, golden oracles, and the **Vitest conformance oracle** live in the **[IntentProof specification repository (`intentproof-spec`)](https://github.com/intentproof/intentproof-spec)**.
429
381
 
430
- ## Monorepo development
382
+ - **CI:** every push/PR runs `scripts/run-conformance.sh` from that repo (see `.github/workflows/ci.yml`).
383
+ - **Local:** clone `intentproof-spec` **next to** this repository (`../intentproof-spec`), then:
384
+
385
+ ```bash
386
+ npm run spec:conformance
387
+ ```
388
+
389
+ Or set `INTENTPROOF_SPEC_ROOT` to your spec checkout and run `bash scripts/spec-conformance.sh`.
390
+
391
+ ---
431
392
 
432
- This repository is an npm workspace; the publishable package is [`packages/sdk`](packages/sdk).
393
+ ## Project development
433
394
 
434
- Requires **Node.js 22+** (see `.nvmrc` and workspace `engines`).
395
+ Layout: **npm workspace** (`package.json` **`workspaces`**, publishable package [`packages/sdk`](packages/sdk)). Requires **Node.js** 22 or newer (see `.nvmrc` and workspace **`engines`**). Release history: [`CHANGELOG.md`](CHANGELOG.md).
435
396
 
436
397
  ```bash
437
398
  npm ci
@@ -440,4 +401,4 @@ npm run ci
440
401
 
441
402
  ## License
442
403
 
443
- Apache-2.0 (see `LICENSE` at the repository root and in the published npm package).
404
+ Apache-2.0 (see `LICENSE` at the repository root and in the published npm package when released).
package/dist/index.cjs CHANGED
@@ -132,32 +132,30 @@ function snapshot(value, options = {}) {
132
132
  if (depth >= maxDepth) return "[Array]";
133
133
  return v.slice(0, maxKeys).map((item) => walk(item, depth + 1));
134
134
  }
135
- if (t === "object") {
136
- const o = v;
137
- if (seen.has(o)) return "[Circular]";
138
- seen.add(o);
139
- if (depth >= maxDepth) return "[Object]";
140
- const out = {};
141
- const keys = Object.keys(o);
142
- let n = 0;
143
- for (const k of keys) {
144
- if (n >= maxKeys) {
145
- out["\u2026"] = `${keys.length - maxKeys} more keys`;
146
- break;
147
- }
148
- try {
149
- if (shouldRedactKey(k, redact)) {
150
- out[k] = "[REDACTED]";
151
- } else {
152
- out[k] = walk(o[k], depth + 1);
153
- }
154
- } catch {
155
- out[k] = "[Unserializable]";
135
+ const o = v;
136
+ if (seen.has(o)) return "[Circular]";
137
+ seen.add(o);
138
+ if (depth >= maxDepth) return "[Object]";
139
+ const out = {};
140
+ const keys = Object.keys(o);
141
+ let n = 0;
142
+ for (const k of keys) {
143
+ if (n >= maxKeys) {
144
+ out["\u2026"] = `${keys.length - maxKeys} more keys`;
145
+ break;
146
+ }
147
+ try {
148
+ if (shouldRedactKey(k, redact)) {
149
+ out[k] = "[REDACTED]";
150
+ } else {
151
+ out[k] = walk(o[k], depth + 1);
156
152
  }
157
- n += 1;
153
+ } catch {
154
+ out[k] = "[Unserializable]";
158
155
  }
159
- return out;
156
+ n += 1;
160
157
  }
158
+ return out;
161
159
  }
162
160
  try {
163
161
  return walk(value, 0);
@@ -702,7 +700,7 @@ var BoundedQueueExporter = class {
702
700
  if (this.queue.length >= cap) {
703
701
  if (this.strategy === "drop-oldest") {
704
702
  const dropped = this.queue.shift();
705
- if (dropped) this.onDrop?.(dropped, "queue-overflow-drop-oldest");
703
+ this.onDrop?.(dropped, "queue-overflow-drop-oldest");
706
704
  this.queue.push(event);
707
705
  } else {
708
706
  this.onDrop?.(event, "queue-overflow-drop-newest");
@@ -759,7 +757,7 @@ var BoundedQueueExporter = class {
759
757
  };
760
758
 
761
759
  // src/index.ts
762
- var VERSION = "0.1.0";
760
+ var VERSION = "0.1.2";
763
761
  var client = getIntentProofClient();
764
762
  function createIntentProofClient(config) {
765
763
  return new IntentProofClient(config);
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/exporters/memory.ts","../src/runtime.ts","../src/snapshot.ts","../src/exporters/http.ts","../src/exporters/queue.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Structured `ExecutionEvent` emission for verification / ingest pipelines.\n */\n\nimport { IntentProofClient, getIntentProofClient } from \"./client.js\";\nimport type { IntentProofConfig } from \"./types.js\";\n\n/** Injected at build (`tsup`) and test (`vitest`) time from `package.json` — single source of truth. */\ndeclare const __INTENTPROOF_SDK_VERSION__: string;\n\nexport const VERSION = __INTENTPROOF_SDK_VERSION__;\n\nexport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nexport { snapshot } from \"./snapshot.js\";\n\nexport { MemoryExporter } from \"./exporters/memory.js\";\nexport type { MemoryExporterOptions } from \"./exporters/memory.js\";\n\nexport { HttpExporter } from \"./exporters/http.js\";\nexport type { HttpExporterOptions } from \"./exporters/http.js\";\n\nexport { BoundedQueueExporter } from \"./exporters/queue.js\";\nexport type {\n BoundedQueueExporterOptions,\n QueueOverflowStrategy,\n} from \"./exporters/queue.js\";\n\nexport {\n IntentProofClient,\n assertCorrelationId,\n assertWrapOptionsShape,\n getCorrelationId,\n getIntentProofClient,\n runWithCorrelationId,\n} from \"./client.js\";\n\n/** Default singleton — same instance as `getIntentProofClient()`. */\nexport const client = getIntentProofClient();\n\n/** Isolated client instance (tests, workers, per-tenant configuration). */\nexport function createIntentProofClient(config?: IntentProofConfig): IntentProofClient {\n return new IntentProofClient(config);\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { randomUUID } from \"crypto\";\nimport { MemoryExporter } from \"./exporters/memory.js\";\nimport { describeValueType, isPromiseLike } from \"./runtime.js\";\nimport { snapshot } from \"./snapshot.js\";\nimport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nconst correlationStore = new AsyncLocalStorage<string>();\n\n/**\n * Validates a correlation id: non-empty string after trim (same as `WrapOptions.correlationId` /\n * {@link assertWrapOptionsShape}). Used by {@link runWithCorrelationId}.\n */\nexport function assertCorrelationId(id: unknown): asserts id is string {\n if (typeof id !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string, got ${describeValueType(id)}`,\n );\n }\n if (id.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n}\n\n/** Active correlation id from async context, if any. */\nexport function getCorrelationId(): string | undefined {\n return correlationStore.getStore();\n}\n\n/**\n * Run `fn` with an explicit `correlationId` in async context. The id must be a non-empty string\n * after trim ({@link assertCorrelationId}) — the parameter name implies a caller-supplied id.\n */\nexport function runWithCorrelationId<T>(correlationId: string, fn: () => T): T {\n if (typeof fn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected runWithCorrelationId(correlationId, fn)\",\n );\n }\n assertCorrelationId(correlationId);\n return correlationStore.run(correlationId, fn);\n}\n\nfunction defaultOnExporterError(error: unknown, _event: ExecutionEvent): void {\n console.error(\"[intentproof] exporter error\", error);\n}\n\nfunction toErrorSnapshot(e: unknown, includeStack: boolean): ExecutionErrorSnapshot {\n if (e instanceof Error) {\n return includeStack\n ? { name: e.name, message: e.message, stack: e.stack }\n : { name: e.name, message: e.message };\n }\n return { name: \"Error\", message: String(e) };\n}\n\nfunction assertExporterAtIndex(ex: unknown, index: number): void {\n if (\n ex == null ||\n typeof ex !== \"object\" ||\n typeof (ex as Exporter).export !== \"function\"\n ) {\n throw new TypeError(\n `IntentProofClient: exporters[${index}] must be an object with an export() method`,\n );\n }\n}\n\nfunction assertAttributesRecord(label: string, value: unknown): void {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(\n `IntentProofClient: ${label} must be a plain object, got ${describeValueType(value)}`,\n );\n }\n const o = value as Record<string, unknown>;\n for (const key of Object.keys(o)) {\n const v = o[key];\n const t = typeof v;\n if (t !== \"string\" && t !== \"number\" && t !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: ${label}[${JSON.stringify(key)}] must be a string, number, or boolean, got ${describeValueType(v)}`,\n );\n }\n }\n}\n\n/** Runtime validation for {@link IntentProofClient.wrap} options. */\nexport function assertWrapOptionsShape(options: WrapOptions): void {\n if (typeof options.intent !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a string, got ${describeValueType(options.intent)}`,\n );\n }\n if (options.intent.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (typeof options.action !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a string, got ${describeValueType(options.action)}`,\n );\n }\n if (options.action.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (\n options.correlationId !== undefined &&\n typeof options.correlationId !== \"string\"\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string when provided, got ${describeValueType(options.correlationId)}`,\n );\n }\n if (\n options.correlationId !== undefined &&\n options.correlationId.trim().length === 0\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string when provided (trimmed length is 0)`,\n );\n }\n if (options.attributes !== undefined) {\n assertAttributesRecord(\"WrapOptions.attributes\", options.attributes);\n }\n if (options.includeErrorStack !== undefined) {\n if (typeof options.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: \"includeErrorStack\" must be a boolean when provided, got ${describeValueType(options.includeErrorStack)}`,\n );\n }\n }\n}\n\nexport class IntentProofClient {\n private exporters: Exporter[] = [new MemoryExporter()];\n private onExporterError: (error: unknown, event: ExecutionEvent) => void =\n defaultOnExporterError;\n private defaultAttributes: Readonly<Record<string, string | number | boolean>> = {};\n private includeErrorStack = true;\n\n constructor(config: IntentProofConfig = {}) {\n this.configure(config);\n }\n\n configure(config: IntentProofConfig): void {\n if (config.exporters !== undefined) {\n for (let i = 0; i < config.exporters.length; i++) {\n assertExporterAtIndex(config.exporters[i], i);\n }\n this.exporters = [...config.exporters];\n }\n if (config.onExporterError !== undefined) {\n if (typeof config.onExporterError !== \"function\") {\n throw new TypeError(\n `IntentProofClient: onExporterError must be a function, got ${describeValueType(config.onExporterError)}`,\n );\n }\n this.onExporterError = config.onExporterError;\n }\n if (config.defaultAttributes !== undefined) {\n assertAttributesRecord(\"defaultAttributes\", config.defaultAttributes);\n this.defaultAttributes = config.defaultAttributes;\n }\n if (config.includeErrorStack !== undefined) {\n if (typeof config.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: includeErrorStack must be a boolean when provided, got ${describeValueType(config.includeErrorStack)}`,\n );\n }\n this.includeErrorStack = config.includeErrorStack;\n }\n }\n\n /**\n * Await optional {@link Exporter.flush} on each exporter (parallel).\n * Used for graceful shutdown or tests.\n */\n flush(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) =>\n typeof ex.flush === \"function\"\n ? Promise.resolve(ex.flush())\n : Promise.resolve(),\n ),\n ).then(() => {});\n }\n\n /**\n * {@link Exporter.shutdown} when present, otherwise {@link Exporter.flush}.\n */\n shutdown(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) => {\n if (typeof ex.shutdown === \"function\") {\n return Promise.resolve(ex.shutdown());\n }\n if (typeof ex.flush === \"function\") {\n return Promise.resolve(ex.flush());\n }\n return Promise.resolve();\n }),\n ).then(() => {});\n }\n\n /** Read active correlation id (AsyncLocalStorage). */\n getCorrelationId(): string | undefined {\n return getCorrelationId();\n }\n\n /**\n * Run `fn` with a generated correlation id for nested `wrap` calls (callers do not supply an id).\n */\n withCorrelation<T>(fn: () => T): T;\n /**\n * Run `fn` under an optional inbound `correlationId`. Non-empty after trim uses that id;\n * empty or whitespace-only values generate a UUID instead (e.g. missing request header).\n * To require a validated, non-blank id, use {@link runWithCorrelationId}.\n */\n withCorrelation<T>(correlationId: string, fn: () => T): T;\n withCorrelation<T>(correlationIdOrFn: string | (() => T), maybeFn?: () => T): T {\n if (typeof correlationIdOrFn === \"function\") {\n return runWithCorrelationId(randomUUID(), correlationIdOrFn);\n }\n if (typeof correlationIdOrFn !== \"string\") {\n throw new TypeError(\n \"IntentProofClient: withCorrelation: correlation id must be a string\",\n );\n }\n if (typeof maybeFn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected withCorrelation(fn) or withCorrelation(correlationId, fn)\",\n );\n }\n const fn = maybeFn;\n const id = correlationIdOrFn;\n if (id.trim().length === 0) {\n return runWithCorrelationId(randomUUID(), fn);\n }\n return runWithCorrelationId(id, fn);\n }\n\n /**\n * Wrap a function to emit one `ExecutionEvent` per invocation (sync or async).\n */\n wrap<A extends unknown[], R>(\n options: WrapOptions,\n fn: (...args: A) => R,\n ): (...args: A) => R {\n assertWrapOptionsShape(options);\n if (typeof fn !== \"function\") {\n throw new TypeError(\n `IntentProofClient: wrap() second argument must be a function, got ${describeValueType(fn)}`,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- `function` wrapper uses `fn.apply(this, …)`\n const self = this;\n const wrapped = function (this: unknown, ...args: A): R {\n const correlationId = options.correlationId ?? getCorrelationId() ?? undefined;\n const startedAt = new Date();\n const serOpts: SerializeOptions = {\n maxDepth: options.maxDepth,\n maxKeys: options.maxKeys,\n redactKeys: options.redactKeys,\n maxStringLength: options.maxStringLength,\n };\n let inputs: unknown;\n if (options.captureInput) {\n try {\n inputs = options.captureInput(args as unknown[]);\n } catch {\n inputs = snapshot(args as unknown[], serOpts);\n }\n } else {\n inputs = snapshot(args as unknown[], serOpts);\n }\n\n const base = {\n id: randomUUID(),\n correlationId,\n intent: options.intent,\n action: options.action,\n inputs,\n startedAt: startedAt.toISOString(),\n attributes: mergeAttrs(self.defaultAttributes, options.attributes),\n };\n\n try {\n const out = fn.apply(this, args as unknown as A);\n if (isPromiseLike(out)) {\n return self.handleAsync(out, base, options, serOpts, startedAt) as R;\n }\n self.emitComplete(\n base,\n \"ok\",\n out,\n undefined,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n return out;\n } catch (e) {\n self.emitComplete(\n base,\n \"error\",\n undefined,\n e,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n throw e;\n }\n };\n Object.defineProperty(wrapped, \"name\", {\n value: `intentproof(${fn.name || \"anonymous\"})`,\n configurable: true,\n });\n return wrapped as (...args: A) => R;\n }\n\n private handleAsync(\n p: PromiseLike<unknown>,\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n ): Promise<unknown> {\n const includeStack = this.includeErrorStack;\n return Promise.resolve(p).then(\n (value) => {\n this.emitComplete(\n base,\n \"ok\",\n value,\n undefined,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n return value;\n },\n (err) => {\n this.emitComplete(\n base,\n \"error\",\n undefined,\n err,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n throw err;\n },\n );\n }\n\n private emitComplete(\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n status: ExecutionStatus,\n result: unknown,\n error: unknown | undefined,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n defaultIncludeErrorStack: boolean,\n ): void {\n const completedAt = new Date();\n const durationMs = completedAt.getTime() - startedAt.getTime();\n let output: unknown | undefined;\n let errSnap: ExecutionErrorSnapshot | undefined;\n const includeStack = options.includeErrorStack ?? defaultIncludeErrorStack;\n\n if (status === \"ok\") {\n try {\n output = options.captureOutput\n ? options.captureOutput(result)\n : snapshot(result, serOpts);\n } catch {\n output = snapshot(result, serOpts);\n }\n } else {\n errSnap = toErrorSnapshot(error, includeStack);\n if (options.captureError) {\n try {\n output = options.captureError(error);\n } catch {\n output = undefined;\n }\n }\n }\n\n const event: ExecutionEvent =\n status === \"ok\"\n ? {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n output,\n }\n : {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n error: errSnap,\n ...(output !== undefined ? { output } : {}),\n };\n\n this.dispatch(event);\n }\n\n private dispatch(event: ExecutionEvent): void {\n for (const ex of this.exporters) {\n try {\n const r = ex.export(event);\n if (isPromiseLike(r)) {\n void r.catch((e) => this.onExporterError(e, event));\n }\n } catch (e) {\n this.onExporterError(e, event);\n }\n }\n }\n}\n\nfunction mergeAttrs(\n a: Readonly<Record<string, string | number | boolean>>,\n b: Readonly<Record<string, string | number | boolean>> | undefined,\n): Readonly<Record<string, string | number | boolean>> | undefined {\n if (!b || Object.keys(b).length === 0) {\n return Object.keys(a).length ? { ...a } : undefined;\n }\n return { ...a, ...b };\n}\n\nlet defaultClient: IntentProofClient | null = null;\n\nexport function getIntentProofClient(): IntentProofClient {\n if (!defaultClient) defaultClient = new IntentProofClient();\n return defaultClient;\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\n\nexport interface MemoryExporterOptions {\n /** Keep at most this many recent events (default 1000). Must be a finite number >= 1. */\n maxEvents?: number;\n}\n\n/**\n * Default exporter: ring buffer in memory for debugging and tests.\n */\nexport class MemoryExporter implements Exporter {\n private readonly maxEvents: number;\n private readonly events: ExecutionEvent[] = [];\n\n constructor(options: MemoryExporterOptions = {}) {\n const cap = options.maxEvents ?? 1000;\n if (!Number.isFinite(cap) || cap < 1) {\n throw new TypeError('MemoryExporter: \"maxEvents\" must be a finite number >= 1');\n }\n this.maxEvents = Math.trunc(cap);\n }\n\n export(event: ExecutionEvent): void {\n this.events.push(event);\n const overflow = this.events.length - this.maxEvents;\n if (overflow > 0) this.events.splice(0, overflow);\n }\n\n /** Mutable snapshot for inspection — newest last. */\n getEvents(): readonly ExecutionEvent[] {\n return this.events;\n }\n\n clear(): void {\n this.events.length = 0;\n }\n\n flush(): Promise<void> {\n return Promise.resolve();\n }\n}\n","export function describeValueType(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n return (\n x !== null &&\n typeof x === \"object\" &&\n typeof (x as PromiseLike<unknown>).then === \"function\"\n );\n}\n","import type { SerializeOptions } from \"./types.js\";\n\nconst DEFAULT_MAX_DEPTH = 6;\nconst DEFAULT_MAX_KEYS = 50;\n\nfunction snapshotLimit(n: number | undefined, fallback: number): number {\n if (n === undefined) return fallback;\n if (!Number.isFinite(n)) return fallback;\n const i = Math.trunc(n);\n return i < 0 ? fallback : i;\n}\n\nfunction snapshotStringLimit(n: number | undefined): number | undefined {\n if (n === undefined) return undefined;\n if (!Number.isFinite(n)) return undefined;\n const i = Math.trunc(n);\n return i < 0 ? undefined : i;\n}\n\nfunction normalizeRedactSet(redactKeys: string[] | undefined): Set<string> | undefined {\n if (!redactKeys?.length) return undefined;\n const set = new Set(\n redactKeys\n .filter((k): k is string => typeof k === \"string\" && k.length > 0)\n .map((k) => k.toLowerCase()),\n );\n return set.size > 0 ? set : undefined;\n}\n\nfunction shouldRedactKey(key: string, redact: Set<string> | undefined): boolean {\n if (!redact) return false;\n return redact.has(key.toLowerCase());\n}\n\nfunction truncateString(s: string, maxLen: number | undefined): string {\n if (maxLen === undefined || s.length <= maxLen) return s;\n return `${s.slice(0, maxLen)}…[truncated ${s.length - maxLen} chars]`;\n}\n\n/** JSON-safe value for `ExecutionEvent` inputs/output (depth/key limits, optional redaction). */\nexport function snapshot(value: unknown, options: SerializeOptions = {}): unknown {\n const maxDepth = snapshotLimit(options.maxDepth, DEFAULT_MAX_DEPTH);\n const maxKeys = snapshotLimit(options.maxKeys, DEFAULT_MAX_KEYS);\n const maxStringLength = snapshotStringLimit(options.maxStringLength);\n const redact = normalizeRedactSet(options.redactKeys);\n const seen = new WeakSet<object>();\n\n function walk(v: unknown, depth: number): unknown {\n if (v === null || v === undefined) return v;\n const t = typeof v;\n if (t === \"string\" || t === \"number\" || t === \"boolean\") {\n if (t === \"string\") return truncateString(v as string, maxStringLength);\n return v;\n }\n if (t === \"bigint\") return (v as bigint).toString();\n if (t === \"symbol\") return (v as symbol).toString();\n if (t === \"function\") {\n const fn = v as { name?: string };\n return `[Function ${fn.name || \"anonymous\"}]`;\n }\n if (v instanceof Date) return v.toISOString();\n if (Array.isArray(v)) {\n if (depth >= maxDepth) return \"[Array]\";\n return v.slice(0, maxKeys).map((item) => walk(item, depth + 1));\n }\n if (t === \"object\") {\n const o = v as object;\n if (seen.has(o)) return \"[Circular]\";\n seen.add(o);\n if (depth >= maxDepth) return \"[Object]\";\n const out: Record<string, unknown> = {};\n const keys = Object.keys(o);\n let n = 0;\n for (const k of keys) {\n if (n >= maxKeys) {\n out[\"…\"] = `${keys.length - maxKeys} more keys`;\n break;\n }\n try {\n if (shouldRedactKey(k, redact)) {\n out[k] = \"[REDACTED]\";\n } else {\n out[k] = walk((o as Record<string, unknown>)[k], depth + 1);\n }\n } catch {\n out[k] = \"[Unserializable]\";\n }\n n += 1;\n }\n return out;\n }\n }\n\n try {\n return walk(value, 0);\n } catch {\n return \"[SnapshotError]\";\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { describeValueType } from \"../runtime.js\";\n\n/** Last-resort wire body when custom `body` and `safeJsonEnvelope` both fail. */\nconst HTTP_EXPORTER_FALLBACK_BODY =\n '{\"intentproof\":\"1\",\"eventSerializeFailed\":true}' as const;\n\n/** JSON body for the default wire shape; never throws (last resort is a static envelope). */\nfunction safeJsonEnvelope(event: ExecutionEvent): string {\n try {\n return JSON.stringify({ intentproof: \"1\", event });\n } catch {\n try {\n return JSON.stringify({\n intentproof: \"1\",\n eventPartial: {\n id: event.id,\n action: event.action,\n intent: event.intent,\n status: event.status,\n correlationId: event.correlationId,\n startedAt: event.startedAt,\n completedAt: event.completedAt,\n durationMs: event.durationMs,\n },\n note: \"full event not JSON-serializable\",\n });\n } catch {\n return HTTP_EXPORTER_FALLBACK_BODY;\n }\n }\n}\n\nexport interface HttpExporterOptions {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n /** Serialize event for wire format (default JSON body). */\n body?: (event: ExecutionEvent) => string;\n /**\n * When true, await each request (blocks until HTTP completes). Default false.\n */\n awaitEach?: boolean;\n /** Abort the request after this many milliseconds (global `AbortSignal.timeout`). */\n timeoutMs?: number;\n onError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * POST execution events as JSON. Uses global `fetch` (Node 18+).\n * Fire-and-forget by default to avoid slowing callers.\n */\nexport class HttpExporter implements Exporter {\n private readonly url: string;\n private readonly method: string;\n private readonly headers: Record<string, string>;\n private readonly body: (event: ExecutionEvent) => string;\n private readonly awaitEach: boolean;\n private readonly timeoutMs?: number;\n private readonly onError?: (error: unknown, event: ExecutionEvent) => void;\n private readonly inFlight = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: HttpExporterOptions) {\n if (typeof options.url !== \"string\") {\n throw new TypeError(\n `HttpExporter: \"url\" must be a non-empty string, got ${describeValueType(options.url)}`,\n );\n }\n if (options.url.trim().length === 0) {\n throw new TypeError(\n 'HttpExporter: \"url\" must be a non-empty string (trimmed length is 0)',\n );\n }\n this.url = options.url;\n this.method = (options.method ?? \"POST\").trim() || \"POST\";\n const rawHeaders = options.headers;\n const extraHeaders =\n rawHeaders !== undefined &&\n rawHeaders !== null &&\n typeof rawHeaders === \"object\" &&\n !Array.isArray(rawHeaders)\n ? (rawHeaders as Record<string, string>)\n : {};\n this.headers = {\n \"content-type\": \"application/json\",\n ...extraHeaders,\n };\n this.body = options.body ?? ((event: ExecutionEvent) => safeJsonEnvelope(event));\n this.awaitEach = options.awaitEach ?? false;\n if (options.timeoutMs !== undefined) {\n const t = options.timeoutMs;\n if (!Number.isFinite(t) || t <= 0) {\n throw new TypeError(\n 'HttpExporter: \"timeoutMs\" must be a finite number > 0 when set',\n );\n }\n this.timeoutMs = Math.trunc(t);\n } else {\n this.timeoutMs = undefined;\n }\n this.onError = options.onError;\n }\n\n private track(p: Promise<void>): void {\n this.inFlight.add(p);\n void p.finally(() => this.inFlight.delete(p));\n }\n\n export(event: ExecutionEvent): void | Promise<void> {\n if (this.closed) {\n this.onError?.(new Error(\"HttpExporter has been shut down\"), event);\n return;\n }\n\n let payload: string;\n try {\n payload = this.body(event);\n } catch (e) {\n this.onError?.(e, event);\n payload = safeJsonEnvelope(event);\n }\n\n const run = async (): Promise<void> => {\n try {\n const res = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body: payload,\n credentials: \"omit\",\n signal:\n this.timeoutMs !== undefined\n ? AbortSignal.timeout(this.timeoutMs)\n : undefined,\n });\n if (!res.ok) {\n const err = new Error(`HTTP ${res.status}: ${res.statusText}`);\n this.onError?.(err, event);\n }\n } catch (e) {\n this.onError?.(e, event);\n }\n };\n\n const p = run();\n this.track(p);\n if (this.awaitEach) return p;\n void p;\n }\n\n /** Waits until every started request has settled (success or failure). */\n flush(): Promise<void> {\n if (this.inFlight.size === 0) return Promise.resolve();\n return Promise.all([...this.inFlight]).then(() => {});\n }\n\n /** Stops accepting new events and waits for in-flight requests to finish. */\n async shutdown(): Promise<void> {\n this.closed = true;\n await this.flush();\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { isPromiseLike } from \"../runtime.js\";\n\nexport type QueueOverflowStrategy = \"drop-newest\" | \"drop-oldest\";\n\nexport interface BoundedQueueExporterOptions {\n /** Downstream exporter (often {@link import(\"./http.js\").HttpExporter}). */\n exporter: Exporter;\n /** Maximum concurrent async exports to the inner exporter (default `4`). */\n maxConcurrent?: number;\n /**\n * Maximum **queued** events waiting for a worker slot (default `1000`).\n * Use `0` for unlimited backlog (not recommended under sustained overload).\n */\n maxQueue?: number;\n /** How to handle overflow when the queue is full (default `drop-newest`). */\n strategy?: QueueOverflowStrategy;\n onDrop?: (event: ExecutionEvent, reason: string) => void;\n onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * Bounded concurrency + backlog for async-heavy exporters.\n * Sync inner exporters run on the microtask queue and still respect {@link maxConcurrent}.\n */\nexport class BoundedQueueExporter implements Exporter {\n private readonly inner: Exporter;\n private readonly maxConcurrent: number;\n private readonly maxQueue: number;\n private readonly strategy: QueueOverflowStrategy;\n private readonly onDrop?: (event: ExecutionEvent, reason: string) => void;\n private readonly onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n\n private readonly queue: ExecutionEvent[] = [];\n private active = 0;\n /** When false, {@link export} drops events with reason `shutdown`; queued work still drains. */\n private accepting = true;\n private idleResolvers: Array<() => void> = [];\n\n constructor(options: BoundedQueueExporterOptions) {\n const inner = options.exporter;\n if (\n inner == null ||\n typeof inner !== \"object\" ||\n typeof inner.export !== \"function\"\n ) {\n throw new TypeError(\n 'BoundedQueueExporter: \"exporter\" must be an object with an export() method',\n );\n }\n this.inner = inner;\n const rawMc = options.maxConcurrent ?? 4;\n this.maxConcurrent = !Number.isFinite(rawMc) ? 4 : Math.max(1, Math.trunc(rawMc));\n const rawQ = options.maxQueue ?? 1000;\n if (!Number.isFinite(rawQ)) {\n this.maxQueue = 1000;\n } else {\n const q = Math.trunc(rawQ);\n if (q === 0) {\n this.maxQueue = 0;\n } else if (q < 0) {\n this.maxQueue = 1000;\n } else {\n this.maxQueue = q;\n }\n }\n const strategy = options.strategy ?? \"drop-newest\";\n if (strategy !== \"drop-newest\" && strategy !== \"drop-oldest\") {\n throw new TypeError(\n 'BoundedQueueExporter: \"strategy\" must be \"drop-newest\" or \"drop-oldest\"',\n );\n }\n this.strategy = strategy;\n this.onDrop = options.onDrop;\n this.onInnerError = options.onInnerError;\n }\n\n export(event: ExecutionEvent): void {\n if (!this.accepting) {\n this.onDrop?.(event, \"shutdown\");\n return;\n }\n\n const cap = this.maxQueue <= 0 ? Number.POSITIVE_INFINITY : this.maxQueue;\n\n if (this.queue.length >= cap) {\n if (this.strategy === \"drop-oldest\") {\n const dropped = this.queue.shift();\n if (dropped) this.onDrop?.(dropped, \"queue-overflow-drop-oldest\");\n this.queue.push(event);\n } else {\n this.onDrop?.(event, \"queue-overflow-drop-newest\");\n }\n this.pump();\n return;\n }\n\n this.queue.push(event);\n this.pump();\n }\n\n private pump(): void {\n while (this.active < this.maxConcurrent && this.queue.length > 0) {\n const next = this.queue.shift()!;\n this.active++;\n void this.runInner(next).finally(() => {\n this.active--;\n this.pump();\n this.resolveIdleWaitersIfNeeded();\n });\n }\n }\n\n private async runInner(event: ExecutionEvent): Promise<void> {\n try {\n const r = this.inner.export(event);\n if (isPromiseLike(r)) await r;\n } catch (e) {\n this.onInnerError?.(e, event);\n }\n }\n\n private resolveIdleWaitersIfNeeded(): void {\n if (this.queue.length === 0 && this.active === 0) {\n const waiters = this.idleResolvers;\n this.idleResolvers = [];\n for (const r of waiters) r();\n }\n }\n\n /** Resolves when the queue is empty and no inner export is in flight. */\n flush(): Promise<void> {\n if (this.queue.length === 0 && this.active === 0) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n\n /**\n * Stops accepting new events; does **not** drop items already in the queue—\n * {@link flush} waits until queued and in-flight work finishes.\n */\n async shutdown(): Promise<void> {\n this.accepting = false;\n await this.flush();\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/index.ts","../src/client.ts","../src/exporters/memory.ts","../src/runtime.ts","../src/snapshot.ts","../src/exporters/http.ts","../src/exporters/queue.ts"],"sourcesContent":["/**\n * @packageDocumentation\n * Structured `ExecutionEvent` emission for verification / ingest pipelines.\n */\n\nimport { IntentProofClient, getIntentProofClient } from \"./client.js\";\nimport type { IntentProofConfig } from \"./types.js\";\n\n/** Injected at build (`tsup`) and test (`vitest`) time from `package.json` — single source of truth. */\ndeclare const __INTENTPROOF_SDK_VERSION__: string;\n\nexport const VERSION = __INTENTPROOF_SDK_VERSION__;\n\nexport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nexport { snapshot } from \"./snapshot.js\";\n\nexport { MemoryExporter } from \"./exporters/memory.js\";\nexport type { MemoryExporterOptions } from \"./exporters/memory.js\";\n\nexport { HttpExporter } from \"./exporters/http.js\";\nexport type { HttpExporterOptions } from \"./exporters/http.js\";\n\nexport { BoundedQueueExporter } from \"./exporters/queue.js\";\nexport type {\n BoundedQueueExporterOptions,\n QueueOverflowStrategy,\n} from \"./exporters/queue.js\";\n\nexport {\n IntentProofClient,\n assertCorrelationId,\n assertWrapOptionsShape,\n getCorrelationId,\n getIntentProofClient,\n runWithCorrelationId,\n} from \"./client.js\";\n\n/** Default singleton — same instance as `getIntentProofClient()`. */\nexport const client = getIntentProofClient();\n\n/** Isolated client instance (tests, workers, per-tenant configuration). */\nexport function createIntentProofClient(config?: IntentProofConfig): IntentProofClient {\n return new IntentProofClient(config);\n}\n","import { AsyncLocalStorage } from \"async_hooks\";\nimport { randomUUID } from \"crypto\";\nimport { MemoryExporter } from \"./exporters/memory.js\";\nimport { describeValueType, isPromiseLike } from \"./runtime.js\";\nimport { snapshot } from \"./snapshot.js\";\nimport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nconst correlationStore = new AsyncLocalStorage<string>();\n\n/**\n * Validates a correlation id: non-empty string after trim (same as `WrapOptions.correlationId` /\n * {@link assertWrapOptionsShape}). Used by {@link runWithCorrelationId}.\n */\nexport function assertCorrelationId(id: unknown): asserts id is string {\n if (typeof id !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string, got ${describeValueType(id)}`,\n );\n }\n if (id.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n}\n\n/** Active correlation id from async context, if any. */\nexport function getCorrelationId(): string | undefined {\n return correlationStore.getStore();\n}\n\n/**\n * Run `fn` with an explicit `correlationId` in async context. The id must be a non-empty string\n * after trim ({@link assertCorrelationId}) — the parameter name implies a caller-supplied id.\n */\nexport function runWithCorrelationId<T>(correlationId: string, fn: () => T): T {\n if (typeof fn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected runWithCorrelationId(correlationId, fn)\",\n );\n }\n assertCorrelationId(correlationId);\n return correlationStore.run(correlationId, fn);\n}\n\nfunction defaultOnExporterError(error: unknown, _event: ExecutionEvent): void {\n console.error(\"[intentproof] exporter error\", error);\n}\n\nfunction toErrorSnapshot(e: unknown, includeStack: boolean): ExecutionErrorSnapshot {\n if (e instanceof Error) {\n return includeStack\n ? { name: e.name, message: e.message, stack: e.stack }\n : { name: e.name, message: e.message };\n }\n return { name: \"Error\", message: String(e) };\n}\n\nfunction assertExporterAtIndex(ex: unknown, index: number): void {\n if (\n ex == null ||\n typeof ex !== \"object\" ||\n typeof (ex as Exporter).export !== \"function\"\n ) {\n throw new TypeError(\n `IntentProofClient: exporters[${index}] must be an object with an export() method`,\n );\n }\n}\n\nfunction assertAttributesRecord(label: string, value: unknown): void {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(\n `IntentProofClient: ${label} must be a plain object, got ${describeValueType(value)}`,\n );\n }\n const o = value as Record<string, unknown>;\n for (const key of Object.keys(o)) {\n const v = o[key];\n const t = typeof v;\n if (t !== \"string\" && t !== \"number\" && t !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: ${label}[${JSON.stringify(key)}] must be a string, number, or boolean, got ${describeValueType(v)}`,\n );\n }\n }\n}\n\n/** Runtime validation for {@link IntentProofClient.wrap} options. */\nexport function assertWrapOptionsShape(options: WrapOptions): void {\n if (typeof options.intent !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a string, got ${describeValueType(options.intent)}`,\n );\n }\n if (options.intent.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (typeof options.action !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a string, got ${describeValueType(options.action)}`,\n );\n }\n if (options.action.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (\n options.correlationId !== undefined &&\n typeof options.correlationId !== \"string\"\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string when provided, got ${describeValueType(options.correlationId)}`,\n );\n }\n if (\n options.correlationId !== undefined &&\n options.correlationId.trim().length === 0\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string when provided (trimmed length is 0)`,\n );\n }\n if (options.attributes !== undefined) {\n assertAttributesRecord(\"WrapOptions.attributes\", options.attributes);\n }\n if (options.includeErrorStack !== undefined) {\n if (typeof options.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: \"includeErrorStack\" must be a boolean when provided, got ${describeValueType(options.includeErrorStack)}`,\n );\n }\n }\n}\n\nexport class IntentProofClient {\n private exporters: Exporter[] = [new MemoryExporter()];\n private onExporterError: (error: unknown, event: ExecutionEvent) => void =\n defaultOnExporterError;\n private defaultAttributes: Readonly<Record<string, string | number | boolean>> = {};\n private includeErrorStack = true;\n\n constructor(config: IntentProofConfig = {}) {\n this.configure(config);\n }\n\n configure(config: IntentProofConfig): void {\n if (config.exporters !== undefined) {\n for (let i = 0; i < config.exporters.length; i++) {\n assertExporterAtIndex(config.exporters[i], i);\n }\n this.exporters = [...config.exporters];\n }\n if (config.onExporterError !== undefined) {\n if (typeof config.onExporterError !== \"function\") {\n throw new TypeError(\n `IntentProofClient: onExporterError must be a function, got ${describeValueType(config.onExporterError)}`,\n );\n }\n this.onExporterError = config.onExporterError;\n }\n if (config.defaultAttributes !== undefined) {\n assertAttributesRecord(\"defaultAttributes\", config.defaultAttributes);\n this.defaultAttributes = config.defaultAttributes;\n }\n if (config.includeErrorStack !== undefined) {\n if (typeof config.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: includeErrorStack must be a boolean when provided, got ${describeValueType(config.includeErrorStack)}`,\n );\n }\n this.includeErrorStack = config.includeErrorStack;\n }\n }\n\n /**\n * Await optional {@link Exporter.flush} on each exporter (parallel).\n * Used for graceful shutdown or tests.\n */\n flush(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) =>\n typeof ex.flush === \"function\"\n ? Promise.resolve(ex.flush())\n : Promise.resolve(),\n ),\n ).then(() => {});\n }\n\n /**\n * {@link Exporter.shutdown} when present, otherwise {@link Exporter.flush}.\n */\n shutdown(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) => {\n if (typeof ex.shutdown === \"function\") {\n return Promise.resolve(ex.shutdown());\n }\n if (typeof ex.flush === \"function\") {\n return Promise.resolve(ex.flush());\n }\n return Promise.resolve();\n }),\n ).then(() => {});\n }\n\n /** Read active correlation id (AsyncLocalStorage). */\n getCorrelationId(): string | undefined {\n return getCorrelationId();\n }\n\n /**\n * Run `fn` with a generated correlation id for nested `wrap` calls (callers do not supply an id).\n */\n withCorrelation<T>(fn: () => T): T;\n /**\n * Run `fn` under an optional inbound `correlationId`. Non-empty after trim uses that id;\n * empty or whitespace-only values generate a UUID instead (e.g. missing request header).\n * To require a validated, non-blank id, use {@link runWithCorrelationId}.\n */\n withCorrelation<T>(correlationId: string, fn: () => T): T;\n withCorrelation<T>(correlationIdOrFn: string | (() => T), maybeFn?: () => T): T {\n if (typeof correlationIdOrFn === \"function\") {\n return runWithCorrelationId(randomUUID(), correlationIdOrFn);\n }\n if (typeof correlationIdOrFn !== \"string\") {\n throw new TypeError(\n \"IntentProofClient: withCorrelation: correlation id must be a string\",\n );\n }\n if (typeof maybeFn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected withCorrelation(fn) or withCorrelation(correlationId, fn)\",\n );\n }\n const fn = maybeFn;\n const id = correlationIdOrFn;\n if (id.trim().length === 0) {\n return runWithCorrelationId(randomUUID(), fn);\n }\n return runWithCorrelationId(id, fn);\n }\n\n /**\n * Wrap a function to emit one `ExecutionEvent` per invocation (sync or async).\n */\n wrap<A extends unknown[], R>(\n options: WrapOptions,\n fn: (...args: A) => R,\n ): (...args: A) => R {\n assertWrapOptionsShape(options);\n if (typeof fn !== \"function\") {\n throw new TypeError(\n `IntentProofClient: wrap() second argument must be a function, got ${describeValueType(fn)}`,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- `function` wrapper uses `fn.apply(this, …)`\n const self = this;\n const wrapped = function (this: unknown, ...args: A): R {\n const correlationId = options.correlationId ?? getCorrelationId() ?? undefined;\n const startedAt = new Date();\n const serOpts: SerializeOptions = {\n maxDepth: options.maxDepth,\n maxKeys: options.maxKeys,\n redactKeys: options.redactKeys,\n maxStringLength: options.maxStringLength,\n };\n let inputs: unknown;\n if (options.captureInput) {\n try {\n inputs = options.captureInput(args as unknown[]);\n } catch {\n inputs = snapshot(args as unknown[], serOpts);\n }\n } else {\n inputs = snapshot(args as unknown[], serOpts);\n }\n\n const base = {\n id: randomUUID(),\n correlationId,\n intent: options.intent,\n action: options.action,\n inputs,\n startedAt: startedAt.toISOString(),\n attributes: mergeAttrs(self.defaultAttributes, options.attributes),\n };\n\n try {\n const out = fn.apply(this, args as unknown as A);\n if (isPromiseLike(out)) {\n return self.handleAsync(out, base, options, serOpts, startedAt) as R;\n }\n self.emitComplete(\n base,\n \"ok\",\n out,\n undefined,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n return out;\n } catch (e) {\n self.emitComplete(\n base,\n \"error\",\n undefined,\n e,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n throw e;\n }\n };\n Object.defineProperty(wrapped, \"name\", {\n value: `intentproof(${fn.name || \"anonymous\"})`,\n configurable: true,\n });\n return wrapped as (...args: A) => R;\n }\n\n private handleAsync(\n p: PromiseLike<unknown>,\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n ): Promise<unknown> {\n const includeStack = this.includeErrorStack;\n return Promise.resolve(p).then(\n (value) => {\n this.emitComplete(\n base,\n \"ok\",\n value,\n undefined,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n return value;\n },\n (err) => {\n this.emitComplete(\n base,\n \"error\",\n undefined,\n err,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n throw err;\n },\n );\n }\n\n private emitComplete(\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n status: ExecutionStatus,\n result: unknown,\n error: unknown | undefined,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n defaultIncludeErrorStack: boolean,\n ): void {\n const completedAt = new Date();\n const durationMs = completedAt.getTime() - startedAt.getTime();\n let output: unknown | undefined;\n let errSnap: ExecutionErrorSnapshot | undefined;\n const includeStack = options.includeErrorStack ?? defaultIncludeErrorStack;\n\n if (status === \"ok\") {\n try {\n output = options.captureOutput\n ? options.captureOutput(result)\n : snapshot(result, serOpts);\n } catch {\n output = snapshot(result, serOpts);\n }\n } else {\n errSnap = toErrorSnapshot(error, includeStack);\n if (options.captureError) {\n try {\n output = options.captureError(error);\n } catch {\n output = undefined;\n }\n }\n }\n\n const event: ExecutionEvent =\n status === \"ok\"\n ? {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n output,\n }\n : {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n error: errSnap,\n ...(output !== undefined ? { output } : {}),\n };\n\n this.dispatch(event);\n }\n\n private dispatch(event: ExecutionEvent): void {\n for (const ex of this.exporters) {\n try {\n const r = ex.export(event);\n if (isPromiseLike(r)) {\n void r.catch((e) => this.onExporterError(e, event));\n }\n } catch (e) {\n this.onExporterError(e, event);\n }\n }\n }\n}\n\nfunction mergeAttrs(\n a: Readonly<Record<string, string | number | boolean>>,\n b: Readonly<Record<string, string | number | boolean>> | undefined,\n): Readonly<Record<string, string | number | boolean>> | undefined {\n if (!b || Object.keys(b).length === 0) {\n return Object.keys(a).length ? { ...a } : undefined;\n }\n return { ...a, ...b };\n}\n\nlet defaultClient: IntentProofClient | null = null;\n\nexport function getIntentProofClient(): IntentProofClient {\n if (!defaultClient) defaultClient = new IntentProofClient();\n return defaultClient;\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\n\nexport interface MemoryExporterOptions {\n /** Keep at most this many recent events (default 1000). Must be a finite number >= 1. */\n maxEvents?: number;\n}\n\n/**\n * Default exporter: ring buffer in memory for debugging and tests.\n */\nexport class MemoryExporter implements Exporter {\n private readonly maxEvents: number;\n private readonly events: ExecutionEvent[] = [];\n\n constructor(options: MemoryExporterOptions = {}) {\n const cap = options.maxEvents ?? 1000;\n if (!Number.isFinite(cap) || cap < 1) {\n throw new TypeError('MemoryExporter: \"maxEvents\" must be a finite number >= 1');\n }\n this.maxEvents = Math.trunc(cap);\n }\n\n export(event: ExecutionEvent): void {\n this.events.push(event);\n const overflow = this.events.length - this.maxEvents;\n if (overflow > 0) this.events.splice(0, overflow);\n }\n\n /** Mutable snapshot for inspection — newest last. */\n getEvents(): readonly ExecutionEvent[] {\n return this.events;\n }\n\n clear(): void {\n this.events.length = 0;\n }\n\n flush(): Promise<void> {\n return Promise.resolve();\n }\n}\n","export function describeValueType(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n return (\n x !== null &&\n typeof x === \"object\" &&\n typeof (x as PromiseLike<unknown>).then === \"function\"\n );\n}\n","import type { SerializeOptions } from \"./types.js\";\n\nconst DEFAULT_MAX_DEPTH = 6;\nconst DEFAULT_MAX_KEYS = 50;\n\nfunction snapshotLimit(n: number | undefined, fallback: number): number {\n if (n === undefined) return fallback;\n if (!Number.isFinite(n)) return fallback;\n const i = Math.trunc(n);\n return i < 0 ? fallback : i;\n}\n\nfunction snapshotStringLimit(n: number | undefined): number | undefined {\n if (n === undefined) return undefined;\n if (!Number.isFinite(n)) return undefined;\n const i = Math.trunc(n);\n return i < 0 ? undefined : i;\n}\n\nfunction normalizeRedactSet(redactKeys: string[] | undefined): Set<string> | undefined {\n if (!redactKeys?.length) return undefined;\n const set = new Set(\n redactKeys\n .filter((k): k is string => typeof k === \"string\" && k.length > 0)\n .map((k) => k.toLowerCase()),\n );\n return set.size > 0 ? set : undefined;\n}\n\nfunction shouldRedactKey(key: string, redact: Set<string> | undefined): boolean {\n if (!redact) return false;\n return redact.has(key.toLowerCase());\n}\n\nfunction truncateString(s: string, maxLen: number | undefined): string {\n if (maxLen === undefined || s.length <= maxLen) return s;\n return `${s.slice(0, maxLen)}…[truncated ${s.length - maxLen} chars]`;\n}\n\n/** JSON-safe value for `ExecutionEvent` inputs/output (depth/key limits, optional redaction). */\nexport function snapshot(value: unknown, options: SerializeOptions = {}): unknown {\n const maxDepth = snapshotLimit(options.maxDepth, DEFAULT_MAX_DEPTH);\n const maxKeys = snapshotLimit(options.maxKeys, DEFAULT_MAX_KEYS);\n const maxStringLength = snapshotStringLimit(options.maxStringLength);\n const redact = normalizeRedactSet(options.redactKeys);\n const seen = new WeakSet<object>();\n\n function walk(v: unknown, depth: number): unknown {\n if (v === null || v === undefined) return v;\n const t = typeof v;\n if (t === \"string\" || t === \"number\" || t === \"boolean\") {\n if (t === \"string\") return truncateString(v as string, maxStringLength);\n return v;\n }\n if (t === \"bigint\") return (v as bigint).toString();\n if (t === \"symbol\") return (v as symbol).toString();\n if (t === \"function\") {\n const fn = v as { name?: string };\n return `[Function ${fn.name || \"anonymous\"}]`;\n }\n if (v instanceof Date) return v.toISOString();\n if (Array.isArray(v)) {\n if (depth >= maxDepth) return \"[Array]\";\n return v.slice(0, maxKeys).map((item) => walk(item, depth + 1));\n }\n // Remaining `typeof v === \"object\"` values (plain objects, Map-like POJOs, etc.).\n const o = v as object;\n if (seen.has(o)) return \"[Circular]\";\n seen.add(o);\n if (depth >= maxDepth) return \"[Object]\";\n const out: Record<string, unknown> = {};\n const keys = Object.keys(o);\n let n = 0;\n for (const k of keys) {\n if (n >= maxKeys) {\n out[\"…\"] = `${keys.length - maxKeys} more keys`;\n break;\n }\n try {\n if (shouldRedactKey(k, redact)) {\n out[k] = \"[REDACTED]\";\n } else {\n out[k] = walk((o as Record<string, unknown>)[k], depth + 1);\n }\n } catch {\n out[k] = \"[Unserializable]\";\n }\n n += 1;\n }\n return out;\n }\n\n try {\n return walk(value, 0);\n } catch {\n return \"[SnapshotError]\";\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { describeValueType } from \"../runtime.js\";\n\n/** Last-resort wire body when custom `body` and `safeJsonEnvelope` both fail. */\nconst HTTP_EXPORTER_FALLBACK_BODY =\n '{\"intentproof\":\"1\",\"eventSerializeFailed\":true}' as const;\n\n/** JSON body for the default wire shape; never throws (last resort is a static envelope). */\nfunction safeJsonEnvelope(event: ExecutionEvent): string {\n try {\n return JSON.stringify({ intentproof: \"1\", event });\n } catch {\n try {\n return JSON.stringify({\n intentproof: \"1\",\n eventPartial: {\n id: event.id,\n action: event.action,\n intent: event.intent,\n status: event.status,\n correlationId: event.correlationId,\n startedAt: event.startedAt,\n completedAt: event.completedAt,\n durationMs: event.durationMs,\n },\n note: \"full event not JSON-serializable\",\n });\n } catch {\n return HTTP_EXPORTER_FALLBACK_BODY;\n }\n }\n}\n\nexport interface HttpExporterOptions {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n /** Serialize event for wire format (default JSON body). */\n body?: (event: ExecutionEvent) => string;\n /**\n * When true, await each request (blocks until HTTP completes). Default false.\n */\n awaitEach?: boolean;\n /** Abort the request after this many milliseconds (global `AbortSignal.timeout`). */\n timeoutMs?: number;\n onError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * POST execution events as JSON. Uses global `fetch` (Node 18+).\n * Fire-and-forget by default to avoid slowing callers.\n */\nexport class HttpExporter implements Exporter {\n private readonly url: string;\n private readonly method: string;\n private readonly headers: Record<string, string>;\n private readonly body: (event: ExecutionEvent) => string;\n private readonly awaitEach: boolean;\n private readonly timeoutMs?: number;\n private readonly onError?: (error: unknown, event: ExecutionEvent) => void;\n private readonly inFlight = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: HttpExporterOptions) {\n if (typeof options.url !== \"string\") {\n throw new TypeError(\n `HttpExporter: \"url\" must be a non-empty string, got ${describeValueType(options.url)}`,\n );\n }\n if (options.url.trim().length === 0) {\n throw new TypeError(\n 'HttpExporter: \"url\" must be a non-empty string (trimmed length is 0)',\n );\n }\n this.url = options.url;\n this.method = (options.method ?? \"POST\").trim() || \"POST\";\n const rawHeaders = options.headers;\n const extraHeaders =\n rawHeaders !== undefined &&\n rawHeaders !== null &&\n typeof rawHeaders === \"object\" &&\n !Array.isArray(rawHeaders)\n ? (rawHeaders as Record<string, string>)\n : {};\n this.headers = {\n \"content-type\": \"application/json\",\n ...extraHeaders,\n };\n this.body = options.body ?? ((event: ExecutionEvent) => safeJsonEnvelope(event));\n this.awaitEach = options.awaitEach ?? false;\n if (options.timeoutMs !== undefined) {\n const t = options.timeoutMs;\n if (!Number.isFinite(t) || t <= 0) {\n throw new TypeError(\n 'HttpExporter: \"timeoutMs\" must be a finite number > 0 when set',\n );\n }\n this.timeoutMs = Math.trunc(t);\n } else {\n this.timeoutMs = undefined;\n }\n this.onError = options.onError;\n }\n\n private track(p: Promise<void>): void {\n this.inFlight.add(p);\n void p.finally(() => this.inFlight.delete(p));\n }\n\n export(event: ExecutionEvent): void | Promise<void> {\n if (this.closed) {\n this.onError?.(new Error(\"HttpExporter has been shut down\"), event);\n return;\n }\n\n let payload: string;\n try {\n payload = this.body(event);\n } catch (e) {\n this.onError?.(e, event);\n payload = safeJsonEnvelope(event);\n }\n\n const run = async (): Promise<void> => {\n try {\n const res = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body: payload,\n credentials: \"omit\",\n signal:\n this.timeoutMs !== undefined\n ? AbortSignal.timeout(this.timeoutMs)\n : undefined,\n });\n if (!res.ok) {\n const err = new Error(`HTTP ${res.status}: ${res.statusText}`);\n this.onError?.(err, event);\n }\n } catch (e) {\n this.onError?.(e, event);\n }\n };\n\n const p = run();\n this.track(p);\n if (this.awaitEach) return p;\n void p;\n }\n\n /** Waits until every started request has settled (success or failure). */\n flush(): Promise<void> {\n if (this.inFlight.size === 0) return Promise.resolve();\n return Promise.all([...this.inFlight]).then(() => {});\n }\n\n /** Stops accepting new events and waits for in-flight requests to finish. */\n async shutdown(): Promise<void> {\n this.closed = true;\n await this.flush();\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { isPromiseLike } from \"../runtime.js\";\n\nexport type QueueOverflowStrategy = \"drop-newest\" | \"drop-oldest\";\n\nexport interface BoundedQueueExporterOptions {\n /** Downstream exporter (often {@link import(\"./http.js\").HttpExporter}). */\n exporter: Exporter;\n /** Maximum concurrent async exports to the inner exporter (default `4`). */\n maxConcurrent?: number;\n /**\n * Maximum **queued** events waiting for a worker slot (default `1000`).\n * Use `0` for unlimited backlog (not recommended under sustained overload).\n */\n maxQueue?: number;\n /** How to handle overflow when the queue is full (default `drop-newest`). */\n strategy?: QueueOverflowStrategy;\n onDrop?: (event: ExecutionEvent, reason: string) => void;\n onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * Bounded concurrency + backlog for async-heavy exporters.\n * Sync inner exporters run on the microtask queue and still respect {@link maxConcurrent}.\n */\nexport class BoundedQueueExporter implements Exporter {\n private readonly inner: Exporter;\n private readonly maxConcurrent: number;\n private readonly maxQueue: number;\n private readonly strategy: QueueOverflowStrategy;\n private readonly onDrop?: (event: ExecutionEvent, reason: string) => void;\n private readonly onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n\n private readonly queue: ExecutionEvent[] = [];\n private active = 0;\n /** When false, {@link export} drops events with reason `shutdown`; queued work still drains. */\n private accepting = true;\n private idleResolvers: Array<() => void> = [];\n\n constructor(options: BoundedQueueExporterOptions) {\n const inner = options.exporter;\n if (\n inner == null ||\n typeof inner !== \"object\" ||\n typeof inner.export !== \"function\"\n ) {\n throw new TypeError(\n 'BoundedQueueExporter: \"exporter\" must be an object with an export() method',\n );\n }\n this.inner = inner;\n const rawMc = options.maxConcurrent ?? 4;\n this.maxConcurrent = !Number.isFinite(rawMc) ? 4 : Math.max(1, Math.trunc(rawMc));\n const rawQ = options.maxQueue ?? 1000;\n if (!Number.isFinite(rawQ)) {\n this.maxQueue = 1000;\n } else {\n const q = Math.trunc(rawQ);\n if (q === 0) {\n this.maxQueue = 0;\n } else if (q < 0) {\n this.maxQueue = 1000;\n } else {\n this.maxQueue = q;\n }\n }\n const strategy = options.strategy ?? \"drop-newest\";\n if (strategy !== \"drop-newest\" && strategy !== \"drop-oldest\") {\n throw new TypeError(\n 'BoundedQueueExporter: \"strategy\" must be \"drop-newest\" or \"drop-oldest\"',\n );\n }\n this.strategy = strategy;\n this.onDrop = options.onDrop;\n this.onInnerError = options.onInnerError;\n }\n\n export(event: ExecutionEvent): void {\n if (!this.accepting) {\n this.onDrop?.(event, \"shutdown\");\n return;\n }\n\n const cap = this.maxQueue <= 0 ? Number.POSITIVE_INFINITY : this.maxQueue;\n\n if (this.queue.length >= cap) {\n if (this.strategy === \"drop-oldest\") {\n // `length >= cap` and finite cap imply a non-empty queue before push.\n const dropped = this.queue.shift()!;\n this.onDrop?.(dropped, \"queue-overflow-drop-oldest\");\n this.queue.push(event);\n } else {\n this.onDrop?.(event, \"queue-overflow-drop-newest\");\n }\n this.pump();\n return;\n }\n\n this.queue.push(event);\n this.pump();\n }\n\n private pump(): void {\n while (this.active < this.maxConcurrent && this.queue.length > 0) {\n const next = this.queue.shift()!;\n this.active++;\n void this.runInner(next).finally(() => {\n this.active--;\n this.pump();\n this.resolveIdleWaitersIfNeeded();\n });\n }\n }\n\n private async runInner(event: ExecutionEvent): Promise<void> {\n try {\n const r = this.inner.export(event);\n if (isPromiseLike(r)) await r;\n } catch (e) {\n this.onInnerError?.(e, event);\n }\n }\n\n private resolveIdleWaitersIfNeeded(): void {\n if (this.queue.length === 0 && this.active === 0) {\n const waiters = this.idleResolvers;\n this.idleResolvers = [];\n for (const r of waiters) r();\n }\n }\n\n /** Resolves when the queue is empty and no inner export is in flight. */\n flush(): Promise<void> {\n if (this.queue.length === 0 && this.active === 0) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n\n /**\n * Stops accepting new events; does **not** drop items already in the queue—\n * {@link flush} waits until queued and in-flight work finishes.\n */\n async shutdown(): Promise<void> {\n this.accepting = false;\n await this.flush();\n }\n}\n"],"mappings":"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","names":[]}
package/dist/index.js CHANGED
@@ -94,32 +94,30 @@ function snapshot(value, options = {}) {
94
94
  if (depth >= maxDepth) return "[Array]";
95
95
  return v.slice(0, maxKeys).map((item) => walk(item, depth + 1));
96
96
  }
97
- if (t === "object") {
98
- const o = v;
99
- if (seen.has(o)) return "[Circular]";
100
- seen.add(o);
101
- if (depth >= maxDepth) return "[Object]";
102
- const out = {};
103
- const keys = Object.keys(o);
104
- let n = 0;
105
- for (const k of keys) {
106
- if (n >= maxKeys) {
107
- out["\u2026"] = `${keys.length - maxKeys} more keys`;
108
- break;
109
- }
110
- try {
111
- if (shouldRedactKey(k, redact)) {
112
- out[k] = "[REDACTED]";
113
- } else {
114
- out[k] = walk(o[k], depth + 1);
115
- }
116
- } catch {
117
- out[k] = "[Unserializable]";
97
+ const o = v;
98
+ if (seen.has(o)) return "[Circular]";
99
+ seen.add(o);
100
+ if (depth >= maxDepth) return "[Object]";
101
+ const out = {};
102
+ const keys = Object.keys(o);
103
+ let n = 0;
104
+ for (const k of keys) {
105
+ if (n >= maxKeys) {
106
+ out["\u2026"] = `${keys.length - maxKeys} more keys`;
107
+ break;
108
+ }
109
+ try {
110
+ if (shouldRedactKey(k, redact)) {
111
+ out[k] = "[REDACTED]";
112
+ } else {
113
+ out[k] = walk(o[k], depth + 1);
118
114
  }
119
- n += 1;
115
+ } catch {
116
+ out[k] = "[Unserializable]";
120
117
  }
121
- return out;
118
+ n += 1;
122
119
  }
120
+ return out;
123
121
  }
124
122
  try {
125
123
  return walk(value, 0);
@@ -664,7 +662,7 @@ var BoundedQueueExporter = class {
664
662
  if (this.queue.length >= cap) {
665
663
  if (this.strategy === "drop-oldest") {
666
664
  const dropped = this.queue.shift();
667
- if (dropped) this.onDrop?.(dropped, "queue-overflow-drop-oldest");
665
+ this.onDrop?.(dropped, "queue-overflow-drop-oldest");
668
666
  this.queue.push(event);
669
667
  } else {
670
668
  this.onDrop?.(event, "queue-overflow-drop-newest");
@@ -721,7 +719,7 @@ var BoundedQueueExporter = class {
721
719
  };
722
720
 
723
721
  // src/index.ts
724
- var VERSION = "0.1.0";
722
+ var VERSION = "0.1.2";
725
723
  var client = getIntentProofClient();
726
724
  function createIntentProofClient(config) {
727
725
  return new IntentProofClient(config);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/client.ts","../src/exporters/memory.ts","../src/runtime.ts","../src/snapshot.ts","../src/exporters/http.ts","../src/exporters/queue.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\nimport { randomUUID } from \"crypto\";\nimport { MemoryExporter } from \"./exporters/memory.js\";\nimport { describeValueType, isPromiseLike } from \"./runtime.js\";\nimport { snapshot } from \"./snapshot.js\";\nimport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nconst correlationStore = new AsyncLocalStorage<string>();\n\n/**\n * Validates a correlation id: non-empty string after trim (same as `WrapOptions.correlationId` /\n * {@link assertWrapOptionsShape}). Used by {@link runWithCorrelationId}.\n */\nexport function assertCorrelationId(id: unknown): asserts id is string {\n if (typeof id !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string, got ${describeValueType(id)}`,\n );\n }\n if (id.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n}\n\n/** Active correlation id from async context, if any. */\nexport function getCorrelationId(): string | undefined {\n return correlationStore.getStore();\n}\n\n/**\n * Run `fn` with an explicit `correlationId` in async context. The id must be a non-empty string\n * after trim ({@link assertCorrelationId}) — the parameter name implies a caller-supplied id.\n */\nexport function runWithCorrelationId<T>(correlationId: string, fn: () => T): T {\n if (typeof fn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected runWithCorrelationId(correlationId, fn)\",\n );\n }\n assertCorrelationId(correlationId);\n return correlationStore.run(correlationId, fn);\n}\n\nfunction defaultOnExporterError(error: unknown, _event: ExecutionEvent): void {\n console.error(\"[intentproof] exporter error\", error);\n}\n\nfunction toErrorSnapshot(e: unknown, includeStack: boolean): ExecutionErrorSnapshot {\n if (e instanceof Error) {\n return includeStack\n ? { name: e.name, message: e.message, stack: e.stack }\n : { name: e.name, message: e.message };\n }\n return { name: \"Error\", message: String(e) };\n}\n\nfunction assertExporterAtIndex(ex: unknown, index: number): void {\n if (\n ex == null ||\n typeof ex !== \"object\" ||\n typeof (ex as Exporter).export !== \"function\"\n ) {\n throw new TypeError(\n `IntentProofClient: exporters[${index}] must be an object with an export() method`,\n );\n }\n}\n\nfunction assertAttributesRecord(label: string, value: unknown): void {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(\n `IntentProofClient: ${label} must be a plain object, got ${describeValueType(value)}`,\n );\n }\n const o = value as Record<string, unknown>;\n for (const key of Object.keys(o)) {\n const v = o[key];\n const t = typeof v;\n if (t !== \"string\" && t !== \"number\" && t !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: ${label}[${JSON.stringify(key)}] must be a string, number, or boolean, got ${describeValueType(v)}`,\n );\n }\n }\n}\n\n/** Runtime validation for {@link IntentProofClient.wrap} options. */\nexport function assertWrapOptionsShape(options: WrapOptions): void {\n if (typeof options.intent !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a string, got ${describeValueType(options.intent)}`,\n );\n }\n if (options.intent.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (typeof options.action !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a string, got ${describeValueType(options.action)}`,\n );\n }\n if (options.action.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (\n options.correlationId !== undefined &&\n typeof options.correlationId !== \"string\"\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string when provided, got ${describeValueType(options.correlationId)}`,\n );\n }\n if (\n options.correlationId !== undefined &&\n options.correlationId.trim().length === 0\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string when provided (trimmed length is 0)`,\n );\n }\n if (options.attributes !== undefined) {\n assertAttributesRecord(\"WrapOptions.attributes\", options.attributes);\n }\n if (options.includeErrorStack !== undefined) {\n if (typeof options.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: \"includeErrorStack\" must be a boolean when provided, got ${describeValueType(options.includeErrorStack)}`,\n );\n }\n }\n}\n\nexport class IntentProofClient {\n private exporters: Exporter[] = [new MemoryExporter()];\n private onExporterError: (error: unknown, event: ExecutionEvent) => void =\n defaultOnExporterError;\n private defaultAttributes: Readonly<Record<string, string | number | boolean>> = {};\n private includeErrorStack = true;\n\n constructor(config: IntentProofConfig = {}) {\n this.configure(config);\n }\n\n configure(config: IntentProofConfig): void {\n if (config.exporters !== undefined) {\n for (let i = 0; i < config.exporters.length; i++) {\n assertExporterAtIndex(config.exporters[i], i);\n }\n this.exporters = [...config.exporters];\n }\n if (config.onExporterError !== undefined) {\n if (typeof config.onExporterError !== \"function\") {\n throw new TypeError(\n `IntentProofClient: onExporterError must be a function, got ${describeValueType(config.onExporterError)}`,\n );\n }\n this.onExporterError = config.onExporterError;\n }\n if (config.defaultAttributes !== undefined) {\n assertAttributesRecord(\"defaultAttributes\", config.defaultAttributes);\n this.defaultAttributes = config.defaultAttributes;\n }\n if (config.includeErrorStack !== undefined) {\n if (typeof config.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: includeErrorStack must be a boolean when provided, got ${describeValueType(config.includeErrorStack)}`,\n );\n }\n this.includeErrorStack = config.includeErrorStack;\n }\n }\n\n /**\n * Await optional {@link Exporter.flush} on each exporter (parallel).\n * Used for graceful shutdown or tests.\n */\n flush(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) =>\n typeof ex.flush === \"function\"\n ? Promise.resolve(ex.flush())\n : Promise.resolve(),\n ),\n ).then(() => {});\n }\n\n /**\n * {@link Exporter.shutdown} when present, otherwise {@link Exporter.flush}.\n */\n shutdown(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) => {\n if (typeof ex.shutdown === \"function\") {\n return Promise.resolve(ex.shutdown());\n }\n if (typeof ex.flush === \"function\") {\n return Promise.resolve(ex.flush());\n }\n return Promise.resolve();\n }),\n ).then(() => {});\n }\n\n /** Read active correlation id (AsyncLocalStorage). */\n getCorrelationId(): string | undefined {\n return getCorrelationId();\n }\n\n /**\n * Run `fn` with a generated correlation id for nested `wrap` calls (callers do not supply an id).\n */\n withCorrelation<T>(fn: () => T): T;\n /**\n * Run `fn` under an optional inbound `correlationId`. Non-empty after trim uses that id;\n * empty or whitespace-only values generate a UUID instead (e.g. missing request header).\n * To require a validated, non-blank id, use {@link runWithCorrelationId}.\n */\n withCorrelation<T>(correlationId: string, fn: () => T): T;\n withCorrelation<T>(correlationIdOrFn: string | (() => T), maybeFn?: () => T): T {\n if (typeof correlationIdOrFn === \"function\") {\n return runWithCorrelationId(randomUUID(), correlationIdOrFn);\n }\n if (typeof correlationIdOrFn !== \"string\") {\n throw new TypeError(\n \"IntentProofClient: withCorrelation: correlation id must be a string\",\n );\n }\n if (typeof maybeFn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected withCorrelation(fn) or withCorrelation(correlationId, fn)\",\n );\n }\n const fn = maybeFn;\n const id = correlationIdOrFn;\n if (id.trim().length === 0) {\n return runWithCorrelationId(randomUUID(), fn);\n }\n return runWithCorrelationId(id, fn);\n }\n\n /**\n * Wrap a function to emit one `ExecutionEvent` per invocation (sync or async).\n */\n wrap<A extends unknown[], R>(\n options: WrapOptions,\n fn: (...args: A) => R,\n ): (...args: A) => R {\n assertWrapOptionsShape(options);\n if (typeof fn !== \"function\") {\n throw new TypeError(\n `IntentProofClient: wrap() second argument must be a function, got ${describeValueType(fn)}`,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- `function` wrapper uses `fn.apply(this, …)`\n const self = this;\n const wrapped = function (this: unknown, ...args: A): R {\n const correlationId = options.correlationId ?? getCorrelationId() ?? undefined;\n const startedAt = new Date();\n const serOpts: SerializeOptions = {\n maxDepth: options.maxDepth,\n maxKeys: options.maxKeys,\n redactKeys: options.redactKeys,\n maxStringLength: options.maxStringLength,\n };\n let inputs: unknown;\n if (options.captureInput) {\n try {\n inputs = options.captureInput(args as unknown[]);\n } catch {\n inputs = snapshot(args as unknown[], serOpts);\n }\n } else {\n inputs = snapshot(args as unknown[], serOpts);\n }\n\n const base = {\n id: randomUUID(),\n correlationId,\n intent: options.intent,\n action: options.action,\n inputs,\n startedAt: startedAt.toISOString(),\n attributes: mergeAttrs(self.defaultAttributes, options.attributes),\n };\n\n try {\n const out = fn.apply(this, args as unknown as A);\n if (isPromiseLike(out)) {\n return self.handleAsync(out, base, options, serOpts, startedAt) as R;\n }\n self.emitComplete(\n base,\n \"ok\",\n out,\n undefined,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n return out;\n } catch (e) {\n self.emitComplete(\n base,\n \"error\",\n undefined,\n e,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n throw e;\n }\n };\n Object.defineProperty(wrapped, \"name\", {\n value: `intentproof(${fn.name || \"anonymous\"})`,\n configurable: true,\n });\n return wrapped as (...args: A) => R;\n }\n\n private handleAsync(\n p: PromiseLike<unknown>,\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n ): Promise<unknown> {\n const includeStack = this.includeErrorStack;\n return Promise.resolve(p).then(\n (value) => {\n this.emitComplete(\n base,\n \"ok\",\n value,\n undefined,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n return value;\n },\n (err) => {\n this.emitComplete(\n base,\n \"error\",\n undefined,\n err,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n throw err;\n },\n );\n }\n\n private emitComplete(\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n status: ExecutionStatus,\n result: unknown,\n error: unknown | undefined,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n defaultIncludeErrorStack: boolean,\n ): void {\n const completedAt = new Date();\n const durationMs = completedAt.getTime() - startedAt.getTime();\n let output: unknown | undefined;\n let errSnap: ExecutionErrorSnapshot | undefined;\n const includeStack = options.includeErrorStack ?? defaultIncludeErrorStack;\n\n if (status === \"ok\") {\n try {\n output = options.captureOutput\n ? options.captureOutput(result)\n : snapshot(result, serOpts);\n } catch {\n output = snapshot(result, serOpts);\n }\n } else {\n errSnap = toErrorSnapshot(error, includeStack);\n if (options.captureError) {\n try {\n output = options.captureError(error);\n } catch {\n output = undefined;\n }\n }\n }\n\n const event: ExecutionEvent =\n status === \"ok\"\n ? {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n output,\n }\n : {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n error: errSnap,\n ...(output !== undefined ? { output } : {}),\n };\n\n this.dispatch(event);\n }\n\n private dispatch(event: ExecutionEvent): void {\n for (const ex of this.exporters) {\n try {\n const r = ex.export(event);\n if (isPromiseLike(r)) {\n void r.catch((e) => this.onExporterError(e, event));\n }\n } catch (e) {\n this.onExporterError(e, event);\n }\n }\n }\n}\n\nfunction mergeAttrs(\n a: Readonly<Record<string, string | number | boolean>>,\n b: Readonly<Record<string, string | number | boolean>> | undefined,\n): Readonly<Record<string, string | number | boolean>> | undefined {\n if (!b || Object.keys(b).length === 0) {\n return Object.keys(a).length ? { ...a } : undefined;\n }\n return { ...a, ...b };\n}\n\nlet defaultClient: IntentProofClient | null = null;\n\nexport function getIntentProofClient(): IntentProofClient {\n if (!defaultClient) defaultClient = new IntentProofClient();\n return defaultClient;\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\n\nexport interface MemoryExporterOptions {\n /** Keep at most this many recent events (default 1000). Must be a finite number >= 1. */\n maxEvents?: number;\n}\n\n/**\n * Default exporter: ring buffer in memory for debugging and tests.\n */\nexport class MemoryExporter implements Exporter {\n private readonly maxEvents: number;\n private readonly events: ExecutionEvent[] = [];\n\n constructor(options: MemoryExporterOptions = {}) {\n const cap = options.maxEvents ?? 1000;\n if (!Number.isFinite(cap) || cap < 1) {\n throw new TypeError('MemoryExporter: \"maxEvents\" must be a finite number >= 1');\n }\n this.maxEvents = Math.trunc(cap);\n }\n\n export(event: ExecutionEvent): void {\n this.events.push(event);\n const overflow = this.events.length - this.maxEvents;\n if (overflow > 0) this.events.splice(0, overflow);\n }\n\n /** Mutable snapshot for inspection — newest last. */\n getEvents(): readonly ExecutionEvent[] {\n return this.events;\n }\n\n clear(): void {\n this.events.length = 0;\n }\n\n flush(): Promise<void> {\n return Promise.resolve();\n }\n}\n","export function describeValueType(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n return (\n x !== null &&\n typeof x === \"object\" &&\n typeof (x as PromiseLike<unknown>).then === \"function\"\n );\n}\n","import type { SerializeOptions } from \"./types.js\";\n\nconst DEFAULT_MAX_DEPTH = 6;\nconst DEFAULT_MAX_KEYS = 50;\n\nfunction snapshotLimit(n: number | undefined, fallback: number): number {\n if (n === undefined) return fallback;\n if (!Number.isFinite(n)) return fallback;\n const i = Math.trunc(n);\n return i < 0 ? fallback : i;\n}\n\nfunction snapshotStringLimit(n: number | undefined): number | undefined {\n if (n === undefined) return undefined;\n if (!Number.isFinite(n)) return undefined;\n const i = Math.trunc(n);\n return i < 0 ? undefined : i;\n}\n\nfunction normalizeRedactSet(redactKeys: string[] | undefined): Set<string> | undefined {\n if (!redactKeys?.length) return undefined;\n const set = new Set(\n redactKeys\n .filter((k): k is string => typeof k === \"string\" && k.length > 0)\n .map((k) => k.toLowerCase()),\n );\n return set.size > 0 ? set : undefined;\n}\n\nfunction shouldRedactKey(key: string, redact: Set<string> | undefined): boolean {\n if (!redact) return false;\n return redact.has(key.toLowerCase());\n}\n\nfunction truncateString(s: string, maxLen: number | undefined): string {\n if (maxLen === undefined || s.length <= maxLen) return s;\n return `${s.slice(0, maxLen)}…[truncated ${s.length - maxLen} chars]`;\n}\n\n/** JSON-safe value for `ExecutionEvent` inputs/output (depth/key limits, optional redaction). */\nexport function snapshot(value: unknown, options: SerializeOptions = {}): unknown {\n const maxDepth = snapshotLimit(options.maxDepth, DEFAULT_MAX_DEPTH);\n const maxKeys = snapshotLimit(options.maxKeys, DEFAULT_MAX_KEYS);\n const maxStringLength = snapshotStringLimit(options.maxStringLength);\n const redact = normalizeRedactSet(options.redactKeys);\n const seen = new WeakSet<object>();\n\n function walk(v: unknown, depth: number): unknown {\n if (v === null || v === undefined) return v;\n const t = typeof v;\n if (t === \"string\" || t === \"number\" || t === \"boolean\") {\n if (t === \"string\") return truncateString(v as string, maxStringLength);\n return v;\n }\n if (t === \"bigint\") return (v as bigint).toString();\n if (t === \"symbol\") return (v as symbol).toString();\n if (t === \"function\") {\n const fn = v as { name?: string };\n return `[Function ${fn.name || \"anonymous\"}]`;\n }\n if (v instanceof Date) return v.toISOString();\n if (Array.isArray(v)) {\n if (depth >= maxDepth) return \"[Array]\";\n return v.slice(0, maxKeys).map((item) => walk(item, depth + 1));\n }\n if (t === \"object\") {\n const o = v as object;\n if (seen.has(o)) return \"[Circular]\";\n seen.add(o);\n if (depth >= maxDepth) return \"[Object]\";\n const out: Record<string, unknown> = {};\n const keys = Object.keys(o);\n let n = 0;\n for (const k of keys) {\n if (n >= maxKeys) {\n out[\"…\"] = `${keys.length - maxKeys} more keys`;\n break;\n }\n try {\n if (shouldRedactKey(k, redact)) {\n out[k] = \"[REDACTED]\";\n } else {\n out[k] = walk((o as Record<string, unknown>)[k], depth + 1);\n }\n } catch {\n out[k] = \"[Unserializable]\";\n }\n n += 1;\n }\n return out;\n }\n }\n\n try {\n return walk(value, 0);\n } catch {\n return \"[SnapshotError]\";\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { describeValueType } from \"../runtime.js\";\n\n/** Last-resort wire body when custom `body` and `safeJsonEnvelope` both fail. */\nconst HTTP_EXPORTER_FALLBACK_BODY =\n '{\"intentproof\":\"1\",\"eventSerializeFailed\":true}' as const;\n\n/** JSON body for the default wire shape; never throws (last resort is a static envelope). */\nfunction safeJsonEnvelope(event: ExecutionEvent): string {\n try {\n return JSON.stringify({ intentproof: \"1\", event });\n } catch {\n try {\n return JSON.stringify({\n intentproof: \"1\",\n eventPartial: {\n id: event.id,\n action: event.action,\n intent: event.intent,\n status: event.status,\n correlationId: event.correlationId,\n startedAt: event.startedAt,\n completedAt: event.completedAt,\n durationMs: event.durationMs,\n },\n note: \"full event not JSON-serializable\",\n });\n } catch {\n return HTTP_EXPORTER_FALLBACK_BODY;\n }\n }\n}\n\nexport interface HttpExporterOptions {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n /** Serialize event for wire format (default JSON body). */\n body?: (event: ExecutionEvent) => string;\n /**\n * When true, await each request (blocks until HTTP completes). Default false.\n */\n awaitEach?: boolean;\n /** Abort the request after this many milliseconds (global `AbortSignal.timeout`). */\n timeoutMs?: number;\n onError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * POST execution events as JSON. Uses global `fetch` (Node 18+).\n * Fire-and-forget by default to avoid slowing callers.\n */\nexport class HttpExporter implements Exporter {\n private readonly url: string;\n private readonly method: string;\n private readonly headers: Record<string, string>;\n private readonly body: (event: ExecutionEvent) => string;\n private readonly awaitEach: boolean;\n private readonly timeoutMs?: number;\n private readonly onError?: (error: unknown, event: ExecutionEvent) => void;\n private readonly inFlight = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: HttpExporterOptions) {\n if (typeof options.url !== \"string\") {\n throw new TypeError(\n `HttpExporter: \"url\" must be a non-empty string, got ${describeValueType(options.url)}`,\n );\n }\n if (options.url.trim().length === 0) {\n throw new TypeError(\n 'HttpExporter: \"url\" must be a non-empty string (trimmed length is 0)',\n );\n }\n this.url = options.url;\n this.method = (options.method ?? \"POST\").trim() || \"POST\";\n const rawHeaders = options.headers;\n const extraHeaders =\n rawHeaders !== undefined &&\n rawHeaders !== null &&\n typeof rawHeaders === \"object\" &&\n !Array.isArray(rawHeaders)\n ? (rawHeaders as Record<string, string>)\n : {};\n this.headers = {\n \"content-type\": \"application/json\",\n ...extraHeaders,\n };\n this.body = options.body ?? ((event: ExecutionEvent) => safeJsonEnvelope(event));\n this.awaitEach = options.awaitEach ?? false;\n if (options.timeoutMs !== undefined) {\n const t = options.timeoutMs;\n if (!Number.isFinite(t) || t <= 0) {\n throw new TypeError(\n 'HttpExporter: \"timeoutMs\" must be a finite number > 0 when set',\n );\n }\n this.timeoutMs = Math.trunc(t);\n } else {\n this.timeoutMs = undefined;\n }\n this.onError = options.onError;\n }\n\n private track(p: Promise<void>): void {\n this.inFlight.add(p);\n void p.finally(() => this.inFlight.delete(p));\n }\n\n export(event: ExecutionEvent): void | Promise<void> {\n if (this.closed) {\n this.onError?.(new Error(\"HttpExporter has been shut down\"), event);\n return;\n }\n\n let payload: string;\n try {\n payload = this.body(event);\n } catch (e) {\n this.onError?.(e, event);\n payload = safeJsonEnvelope(event);\n }\n\n const run = async (): Promise<void> => {\n try {\n const res = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body: payload,\n credentials: \"omit\",\n signal:\n this.timeoutMs !== undefined\n ? AbortSignal.timeout(this.timeoutMs)\n : undefined,\n });\n if (!res.ok) {\n const err = new Error(`HTTP ${res.status}: ${res.statusText}`);\n this.onError?.(err, event);\n }\n } catch (e) {\n this.onError?.(e, event);\n }\n };\n\n const p = run();\n this.track(p);\n if (this.awaitEach) return p;\n void p;\n }\n\n /** Waits until every started request has settled (success or failure). */\n flush(): Promise<void> {\n if (this.inFlight.size === 0) return Promise.resolve();\n return Promise.all([...this.inFlight]).then(() => {});\n }\n\n /** Stops accepting new events and waits for in-flight requests to finish. */\n async shutdown(): Promise<void> {\n this.closed = true;\n await this.flush();\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { isPromiseLike } from \"../runtime.js\";\n\nexport type QueueOverflowStrategy = \"drop-newest\" | \"drop-oldest\";\n\nexport interface BoundedQueueExporterOptions {\n /** Downstream exporter (often {@link import(\"./http.js\").HttpExporter}). */\n exporter: Exporter;\n /** Maximum concurrent async exports to the inner exporter (default `4`). */\n maxConcurrent?: number;\n /**\n * Maximum **queued** events waiting for a worker slot (default `1000`).\n * Use `0` for unlimited backlog (not recommended under sustained overload).\n */\n maxQueue?: number;\n /** How to handle overflow when the queue is full (default `drop-newest`). */\n strategy?: QueueOverflowStrategy;\n onDrop?: (event: ExecutionEvent, reason: string) => void;\n onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * Bounded concurrency + backlog for async-heavy exporters.\n * Sync inner exporters run on the microtask queue and still respect {@link maxConcurrent}.\n */\nexport class BoundedQueueExporter implements Exporter {\n private readonly inner: Exporter;\n private readonly maxConcurrent: number;\n private readonly maxQueue: number;\n private readonly strategy: QueueOverflowStrategy;\n private readonly onDrop?: (event: ExecutionEvent, reason: string) => void;\n private readonly onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n\n private readonly queue: ExecutionEvent[] = [];\n private active = 0;\n /** When false, {@link export} drops events with reason `shutdown`; queued work still drains. */\n private accepting = true;\n private idleResolvers: Array<() => void> = [];\n\n constructor(options: BoundedQueueExporterOptions) {\n const inner = options.exporter;\n if (\n inner == null ||\n typeof inner !== \"object\" ||\n typeof inner.export !== \"function\"\n ) {\n throw new TypeError(\n 'BoundedQueueExporter: \"exporter\" must be an object with an export() method',\n );\n }\n this.inner = inner;\n const rawMc = options.maxConcurrent ?? 4;\n this.maxConcurrent = !Number.isFinite(rawMc) ? 4 : Math.max(1, Math.trunc(rawMc));\n const rawQ = options.maxQueue ?? 1000;\n if (!Number.isFinite(rawQ)) {\n this.maxQueue = 1000;\n } else {\n const q = Math.trunc(rawQ);\n if (q === 0) {\n this.maxQueue = 0;\n } else if (q < 0) {\n this.maxQueue = 1000;\n } else {\n this.maxQueue = q;\n }\n }\n const strategy = options.strategy ?? \"drop-newest\";\n if (strategy !== \"drop-newest\" && strategy !== \"drop-oldest\") {\n throw new TypeError(\n 'BoundedQueueExporter: \"strategy\" must be \"drop-newest\" or \"drop-oldest\"',\n );\n }\n this.strategy = strategy;\n this.onDrop = options.onDrop;\n this.onInnerError = options.onInnerError;\n }\n\n export(event: ExecutionEvent): void {\n if (!this.accepting) {\n this.onDrop?.(event, \"shutdown\");\n return;\n }\n\n const cap = this.maxQueue <= 0 ? Number.POSITIVE_INFINITY : this.maxQueue;\n\n if (this.queue.length >= cap) {\n if (this.strategy === \"drop-oldest\") {\n const dropped = this.queue.shift();\n if (dropped) this.onDrop?.(dropped, \"queue-overflow-drop-oldest\");\n this.queue.push(event);\n } else {\n this.onDrop?.(event, \"queue-overflow-drop-newest\");\n }\n this.pump();\n return;\n }\n\n this.queue.push(event);\n this.pump();\n }\n\n private pump(): void {\n while (this.active < this.maxConcurrent && this.queue.length > 0) {\n const next = this.queue.shift()!;\n this.active++;\n void this.runInner(next).finally(() => {\n this.active--;\n this.pump();\n this.resolveIdleWaitersIfNeeded();\n });\n }\n }\n\n private async runInner(event: ExecutionEvent): Promise<void> {\n try {\n const r = this.inner.export(event);\n if (isPromiseLike(r)) await r;\n } catch (e) {\n this.onInnerError?.(e, event);\n }\n }\n\n private resolveIdleWaitersIfNeeded(): void {\n if (this.queue.length === 0 && this.active === 0) {\n const waiters = this.idleResolvers;\n this.idleResolvers = [];\n for (const r of waiters) r();\n }\n }\n\n /** Resolves when the queue is empty and no inner export is in flight. */\n flush(): Promise<void> {\n if (this.queue.length === 0 && this.active === 0) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n\n /**\n * Stops accepting new events; does **not** drop items already in the queue—\n * {@link flush} waits until queued and in-flight work finishes.\n */\n async shutdown(): Promise<void> {\n this.accepting = false;\n await this.flush();\n }\n}\n","/**\n * @packageDocumentation\n * Structured `ExecutionEvent` emission for verification / ingest pipelines.\n */\n\nimport { IntentProofClient, getIntentProofClient } from \"./client.js\";\nimport type { IntentProofConfig } from \"./types.js\";\n\n/** Injected at build (`tsup`) and test (`vitest`) time from `package.json` — single source of truth. */\ndeclare const __INTENTPROOF_SDK_VERSION__: string;\n\nexport const VERSION = __INTENTPROOF_SDK_VERSION__;\n\nexport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nexport { snapshot } from \"./snapshot.js\";\n\nexport { MemoryExporter } from \"./exporters/memory.js\";\nexport type { MemoryExporterOptions } from \"./exporters/memory.js\";\n\nexport { HttpExporter } from \"./exporters/http.js\";\nexport type { HttpExporterOptions } from \"./exporters/http.js\";\n\nexport { BoundedQueueExporter } from \"./exporters/queue.js\";\nexport type {\n BoundedQueueExporterOptions,\n QueueOverflowStrategy,\n} from \"./exporters/queue.js\";\n\nexport {\n IntentProofClient,\n assertCorrelationId,\n assertWrapOptionsShape,\n getCorrelationId,\n getIntentProofClient,\n runWithCorrelationId,\n} from \"./client.js\";\n\n/** Default singleton — same instance as `getIntentProofClient()`. */\nexport const client = getIntentProofClient();\n\n/** Isolated client instance (tests, workers, per-tenant configuration). */\nexport function createIntentProofClient(config?: IntentProofConfig): IntentProofClient {\n return new IntentProofClient(config);\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/client.ts","../src/exporters/memory.ts","../src/runtime.ts","../src/snapshot.ts","../src/exporters/http.ts","../src/exporters/queue.ts","../src/index.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"async_hooks\";\nimport { randomUUID } from \"crypto\";\nimport { MemoryExporter } from \"./exporters/memory.js\";\nimport { describeValueType, isPromiseLike } from \"./runtime.js\";\nimport { snapshot } from \"./snapshot.js\";\nimport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nconst correlationStore = new AsyncLocalStorage<string>();\n\n/**\n * Validates a correlation id: non-empty string after trim (same as `WrapOptions.correlationId` /\n * {@link assertWrapOptionsShape}). Used by {@link runWithCorrelationId}.\n */\nexport function assertCorrelationId(id: unknown): asserts id is string {\n if (typeof id !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string, got ${describeValueType(id)}`,\n );\n }\n if (id.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n}\n\n/** Active correlation id from async context, if any. */\nexport function getCorrelationId(): string | undefined {\n return correlationStore.getStore();\n}\n\n/**\n * Run `fn` with an explicit `correlationId` in async context. The id must be a non-empty string\n * after trim ({@link assertCorrelationId}) — the parameter name implies a caller-supplied id.\n */\nexport function runWithCorrelationId<T>(correlationId: string, fn: () => T): T {\n if (typeof fn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected runWithCorrelationId(correlationId, fn)\",\n );\n }\n assertCorrelationId(correlationId);\n return correlationStore.run(correlationId, fn);\n}\n\nfunction defaultOnExporterError(error: unknown, _event: ExecutionEvent): void {\n console.error(\"[intentproof] exporter error\", error);\n}\n\nfunction toErrorSnapshot(e: unknown, includeStack: boolean): ExecutionErrorSnapshot {\n if (e instanceof Error) {\n return includeStack\n ? { name: e.name, message: e.message, stack: e.stack }\n : { name: e.name, message: e.message };\n }\n return { name: \"Error\", message: String(e) };\n}\n\nfunction assertExporterAtIndex(ex: unknown, index: number): void {\n if (\n ex == null ||\n typeof ex !== \"object\" ||\n typeof (ex as Exporter).export !== \"function\"\n ) {\n throw new TypeError(\n `IntentProofClient: exporters[${index}] must be an object with an export() method`,\n );\n }\n}\n\nfunction assertAttributesRecord(label: string, value: unknown): void {\n if (value === null || typeof value !== \"object\" || Array.isArray(value)) {\n throw new TypeError(\n `IntentProofClient: ${label} must be a plain object, got ${describeValueType(value)}`,\n );\n }\n const o = value as Record<string, unknown>;\n for (const key of Object.keys(o)) {\n const v = o[key];\n const t = typeof v;\n if (t !== \"string\" && t !== \"number\" && t !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: ${label}[${JSON.stringify(key)}] must be a string, number, or boolean, got ${describeValueType(v)}`,\n );\n }\n }\n}\n\n/** Runtime validation for {@link IntentProofClient.wrap} options. */\nexport function assertWrapOptionsShape(options: WrapOptions): void {\n if (typeof options.intent !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a string, got ${describeValueType(options.intent)}`,\n );\n }\n if (options.intent.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"intent\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (typeof options.action !== \"string\") {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a string, got ${describeValueType(options.action)}`,\n );\n }\n if (options.action.trim().length === 0) {\n throw new TypeError(\n `IntentProofClient: \"action\" must be a non-empty string (trimmed length is 0)`,\n );\n }\n if (\n options.correlationId !== undefined &&\n typeof options.correlationId !== \"string\"\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a string when provided, got ${describeValueType(options.correlationId)}`,\n );\n }\n if (\n options.correlationId !== undefined &&\n options.correlationId.trim().length === 0\n ) {\n throw new TypeError(\n `IntentProofClient: \"correlationId\" must be a non-empty string when provided (trimmed length is 0)`,\n );\n }\n if (options.attributes !== undefined) {\n assertAttributesRecord(\"WrapOptions.attributes\", options.attributes);\n }\n if (options.includeErrorStack !== undefined) {\n if (typeof options.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: \"includeErrorStack\" must be a boolean when provided, got ${describeValueType(options.includeErrorStack)}`,\n );\n }\n }\n}\n\nexport class IntentProofClient {\n private exporters: Exporter[] = [new MemoryExporter()];\n private onExporterError: (error: unknown, event: ExecutionEvent) => void =\n defaultOnExporterError;\n private defaultAttributes: Readonly<Record<string, string | number | boolean>> = {};\n private includeErrorStack = true;\n\n constructor(config: IntentProofConfig = {}) {\n this.configure(config);\n }\n\n configure(config: IntentProofConfig): void {\n if (config.exporters !== undefined) {\n for (let i = 0; i < config.exporters.length; i++) {\n assertExporterAtIndex(config.exporters[i], i);\n }\n this.exporters = [...config.exporters];\n }\n if (config.onExporterError !== undefined) {\n if (typeof config.onExporterError !== \"function\") {\n throw new TypeError(\n `IntentProofClient: onExporterError must be a function, got ${describeValueType(config.onExporterError)}`,\n );\n }\n this.onExporterError = config.onExporterError;\n }\n if (config.defaultAttributes !== undefined) {\n assertAttributesRecord(\"defaultAttributes\", config.defaultAttributes);\n this.defaultAttributes = config.defaultAttributes;\n }\n if (config.includeErrorStack !== undefined) {\n if (typeof config.includeErrorStack !== \"boolean\") {\n throw new TypeError(\n `IntentProofClient: includeErrorStack must be a boolean when provided, got ${describeValueType(config.includeErrorStack)}`,\n );\n }\n this.includeErrorStack = config.includeErrorStack;\n }\n }\n\n /**\n * Await optional {@link Exporter.flush} on each exporter (parallel).\n * Used for graceful shutdown or tests.\n */\n flush(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) =>\n typeof ex.flush === \"function\"\n ? Promise.resolve(ex.flush())\n : Promise.resolve(),\n ),\n ).then(() => {});\n }\n\n /**\n * {@link Exporter.shutdown} when present, otherwise {@link Exporter.flush}.\n */\n shutdown(): Promise<void> {\n return Promise.all(\n this.exporters.map((ex) => {\n if (typeof ex.shutdown === \"function\") {\n return Promise.resolve(ex.shutdown());\n }\n if (typeof ex.flush === \"function\") {\n return Promise.resolve(ex.flush());\n }\n return Promise.resolve();\n }),\n ).then(() => {});\n }\n\n /** Read active correlation id (AsyncLocalStorage). */\n getCorrelationId(): string | undefined {\n return getCorrelationId();\n }\n\n /**\n * Run `fn` with a generated correlation id for nested `wrap` calls (callers do not supply an id).\n */\n withCorrelation<T>(fn: () => T): T;\n /**\n * Run `fn` under an optional inbound `correlationId`. Non-empty after trim uses that id;\n * empty or whitespace-only values generate a UUID instead (e.g. missing request header).\n * To require a validated, non-blank id, use {@link runWithCorrelationId}.\n */\n withCorrelation<T>(correlationId: string, fn: () => T): T;\n withCorrelation<T>(correlationIdOrFn: string | (() => T), maybeFn?: () => T): T {\n if (typeof correlationIdOrFn === \"function\") {\n return runWithCorrelationId(randomUUID(), correlationIdOrFn);\n }\n if (typeof correlationIdOrFn !== \"string\") {\n throw new TypeError(\n \"IntentProofClient: withCorrelation: correlation id must be a string\",\n );\n }\n if (typeof maybeFn !== \"function\") {\n throw new TypeError(\n \"IntentProofClient: expected withCorrelation(fn) or withCorrelation(correlationId, fn)\",\n );\n }\n const fn = maybeFn;\n const id = correlationIdOrFn;\n if (id.trim().length === 0) {\n return runWithCorrelationId(randomUUID(), fn);\n }\n return runWithCorrelationId(id, fn);\n }\n\n /**\n * Wrap a function to emit one `ExecutionEvent` per invocation (sync or async).\n */\n wrap<A extends unknown[], R>(\n options: WrapOptions,\n fn: (...args: A) => R,\n ): (...args: A) => R {\n assertWrapOptionsShape(options);\n if (typeof fn !== \"function\") {\n throw new TypeError(\n `IntentProofClient: wrap() second argument must be a function, got ${describeValueType(fn)}`,\n );\n }\n // eslint-disable-next-line @typescript-eslint/no-this-alias -- `function` wrapper uses `fn.apply(this, …)`\n const self = this;\n const wrapped = function (this: unknown, ...args: A): R {\n const correlationId = options.correlationId ?? getCorrelationId() ?? undefined;\n const startedAt = new Date();\n const serOpts: SerializeOptions = {\n maxDepth: options.maxDepth,\n maxKeys: options.maxKeys,\n redactKeys: options.redactKeys,\n maxStringLength: options.maxStringLength,\n };\n let inputs: unknown;\n if (options.captureInput) {\n try {\n inputs = options.captureInput(args as unknown[]);\n } catch {\n inputs = snapshot(args as unknown[], serOpts);\n }\n } else {\n inputs = snapshot(args as unknown[], serOpts);\n }\n\n const base = {\n id: randomUUID(),\n correlationId,\n intent: options.intent,\n action: options.action,\n inputs,\n startedAt: startedAt.toISOString(),\n attributes: mergeAttrs(self.defaultAttributes, options.attributes),\n };\n\n try {\n const out = fn.apply(this, args as unknown as A);\n if (isPromiseLike(out)) {\n return self.handleAsync(out, base, options, serOpts, startedAt) as R;\n }\n self.emitComplete(\n base,\n \"ok\",\n out,\n undefined,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n return out;\n } catch (e) {\n self.emitComplete(\n base,\n \"error\",\n undefined,\n e,\n options,\n serOpts,\n startedAt,\n self.includeErrorStack,\n );\n throw e;\n }\n };\n Object.defineProperty(wrapped, \"name\", {\n value: `intentproof(${fn.name || \"anonymous\"})`,\n configurable: true,\n });\n return wrapped as (...args: A) => R;\n }\n\n private handleAsync(\n p: PromiseLike<unknown>,\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n ): Promise<unknown> {\n const includeStack = this.includeErrorStack;\n return Promise.resolve(p).then(\n (value) => {\n this.emitComplete(\n base,\n \"ok\",\n value,\n undefined,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n return value;\n },\n (err) => {\n this.emitComplete(\n base,\n \"error\",\n undefined,\n err,\n options,\n serOpts,\n startedAt,\n includeStack,\n );\n throw err;\n },\n );\n }\n\n private emitComplete(\n base: Omit<\n ExecutionEvent,\n \"status\" | \"completedAt\" | \"durationMs\" | \"output\" | \"error\"\n >,\n status: ExecutionStatus,\n result: unknown,\n error: unknown | undefined,\n options: WrapOptions,\n serOpts: SerializeOptions,\n startedAt: Date,\n defaultIncludeErrorStack: boolean,\n ): void {\n const completedAt = new Date();\n const durationMs = completedAt.getTime() - startedAt.getTime();\n let output: unknown | undefined;\n let errSnap: ExecutionErrorSnapshot | undefined;\n const includeStack = options.includeErrorStack ?? defaultIncludeErrorStack;\n\n if (status === \"ok\") {\n try {\n output = options.captureOutput\n ? options.captureOutput(result)\n : snapshot(result, serOpts);\n } catch {\n output = snapshot(result, serOpts);\n }\n } else {\n errSnap = toErrorSnapshot(error, includeStack);\n if (options.captureError) {\n try {\n output = options.captureError(error);\n } catch {\n output = undefined;\n }\n }\n }\n\n const event: ExecutionEvent =\n status === \"ok\"\n ? {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n output,\n }\n : {\n ...base,\n status,\n completedAt: completedAt.toISOString(),\n durationMs,\n error: errSnap,\n ...(output !== undefined ? { output } : {}),\n };\n\n this.dispatch(event);\n }\n\n private dispatch(event: ExecutionEvent): void {\n for (const ex of this.exporters) {\n try {\n const r = ex.export(event);\n if (isPromiseLike(r)) {\n void r.catch((e) => this.onExporterError(e, event));\n }\n } catch (e) {\n this.onExporterError(e, event);\n }\n }\n }\n}\n\nfunction mergeAttrs(\n a: Readonly<Record<string, string | number | boolean>>,\n b: Readonly<Record<string, string | number | boolean>> | undefined,\n): Readonly<Record<string, string | number | boolean>> | undefined {\n if (!b || Object.keys(b).length === 0) {\n return Object.keys(a).length ? { ...a } : undefined;\n }\n return { ...a, ...b };\n}\n\nlet defaultClient: IntentProofClient | null = null;\n\nexport function getIntentProofClient(): IntentProofClient {\n if (!defaultClient) defaultClient = new IntentProofClient();\n return defaultClient;\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\n\nexport interface MemoryExporterOptions {\n /** Keep at most this many recent events (default 1000). Must be a finite number >= 1. */\n maxEvents?: number;\n}\n\n/**\n * Default exporter: ring buffer in memory for debugging and tests.\n */\nexport class MemoryExporter implements Exporter {\n private readonly maxEvents: number;\n private readonly events: ExecutionEvent[] = [];\n\n constructor(options: MemoryExporterOptions = {}) {\n const cap = options.maxEvents ?? 1000;\n if (!Number.isFinite(cap) || cap < 1) {\n throw new TypeError('MemoryExporter: \"maxEvents\" must be a finite number >= 1');\n }\n this.maxEvents = Math.trunc(cap);\n }\n\n export(event: ExecutionEvent): void {\n this.events.push(event);\n const overflow = this.events.length - this.maxEvents;\n if (overflow > 0) this.events.splice(0, overflow);\n }\n\n /** Mutable snapshot for inspection — newest last. */\n getEvents(): readonly ExecutionEvent[] {\n return this.events;\n }\n\n clear(): void {\n this.events.length = 0;\n }\n\n flush(): Promise<void> {\n return Promise.resolve();\n }\n}\n","export function describeValueType(value: unknown): string {\n if (value === null) return \"null\";\n if (Array.isArray(value)) return \"array\";\n return typeof value;\n}\n\nexport function isPromiseLike(x: unknown): x is PromiseLike<unknown> {\n return (\n x !== null &&\n typeof x === \"object\" &&\n typeof (x as PromiseLike<unknown>).then === \"function\"\n );\n}\n","import type { SerializeOptions } from \"./types.js\";\n\nconst DEFAULT_MAX_DEPTH = 6;\nconst DEFAULT_MAX_KEYS = 50;\n\nfunction snapshotLimit(n: number | undefined, fallback: number): number {\n if (n === undefined) return fallback;\n if (!Number.isFinite(n)) return fallback;\n const i = Math.trunc(n);\n return i < 0 ? fallback : i;\n}\n\nfunction snapshotStringLimit(n: number | undefined): number | undefined {\n if (n === undefined) return undefined;\n if (!Number.isFinite(n)) return undefined;\n const i = Math.trunc(n);\n return i < 0 ? undefined : i;\n}\n\nfunction normalizeRedactSet(redactKeys: string[] | undefined): Set<string> | undefined {\n if (!redactKeys?.length) return undefined;\n const set = new Set(\n redactKeys\n .filter((k): k is string => typeof k === \"string\" && k.length > 0)\n .map((k) => k.toLowerCase()),\n );\n return set.size > 0 ? set : undefined;\n}\n\nfunction shouldRedactKey(key: string, redact: Set<string> | undefined): boolean {\n if (!redact) return false;\n return redact.has(key.toLowerCase());\n}\n\nfunction truncateString(s: string, maxLen: number | undefined): string {\n if (maxLen === undefined || s.length <= maxLen) return s;\n return `${s.slice(0, maxLen)}…[truncated ${s.length - maxLen} chars]`;\n}\n\n/** JSON-safe value for `ExecutionEvent` inputs/output (depth/key limits, optional redaction). */\nexport function snapshot(value: unknown, options: SerializeOptions = {}): unknown {\n const maxDepth = snapshotLimit(options.maxDepth, DEFAULT_MAX_DEPTH);\n const maxKeys = snapshotLimit(options.maxKeys, DEFAULT_MAX_KEYS);\n const maxStringLength = snapshotStringLimit(options.maxStringLength);\n const redact = normalizeRedactSet(options.redactKeys);\n const seen = new WeakSet<object>();\n\n function walk(v: unknown, depth: number): unknown {\n if (v === null || v === undefined) return v;\n const t = typeof v;\n if (t === \"string\" || t === \"number\" || t === \"boolean\") {\n if (t === \"string\") return truncateString(v as string, maxStringLength);\n return v;\n }\n if (t === \"bigint\") return (v as bigint).toString();\n if (t === \"symbol\") return (v as symbol).toString();\n if (t === \"function\") {\n const fn = v as { name?: string };\n return `[Function ${fn.name || \"anonymous\"}]`;\n }\n if (v instanceof Date) return v.toISOString();\n if (Array.isArray(v)) {\n if (depth >= maxDepth) return \"[Array]\";\n return v.slice(0, maxKeys).map((item) => walk(item, depth + 1));\n }\n // Remaining `typeof v === \"object\"` values (plain objects, Map-like POJOs, etc.).\n const o = v as object;\n if (seen.has(o)) return \"[Circular]\";\n seen.add(o);\n if (depth >= maxDepth) return \"[Object]\";\n const out: Record<string, unknown> = {};\n const keys = Object.keys(o);\n let n = 0;\n for (const k of keys) {\n if (n >= maxKeys) {\n out[\"…\"] = `${keys.length - maxKeys} more keys`;\n break;\n }\n try {\n if (shouldRedactKey(k, redact)) {\n out[k] = \"[REDACTED]\";\n } else {\n out[k] = walk((o as Record<string, unknown>)[k], depth + 1);\n }\n } catch {\n out[k] = \"[Unserializable]\";\n }\n n += 1;\n }\n return out;\n }\n\n try {\n return walk(value, 0);\n } catch {\n return \"[SnapshotError]\";\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { describeValueType } from \"../runtime.js\";\n\n/** Last-resort wire body when custom `body` and `safeJsonEnvelope` both fail. */\nconst HTTP_EXPORTER_FALLBACK_BODY =\n '{\"intentproof\":\"1\",\"eventSerializeFailed\":true}' as const;\n\n/** JSON body for the default wire shape; never throws (last resort is a static envelope). */\nfunction safeJsonEnvelope(event: ExecutionEvent): string {\n try {\n return JSON.stringify({ intentproof: \"1\", event });\n } catch {\n try {\n return JSON.stringify({\n intentproof: \"1\",\n eventPartial: {\n id: event.id,\n action: event.action,\n intent: event.intent,\n status: event.status,\n correlationId: event.correlationId,\n startedAt: event.startedAt,\n completedAt: event.completedAt,\n durationMs: event.durationMs,\n },\n note: \"full event not JSON-serializable\",\n });\n } catch {\n return HTTP_EXPORTER_FALLBACK_BODY;\n }\n }\n}\n\nexport interface HttpExporterOptions {\n url: string;\n method?: string;\n headers?: Record<string, string>;\n /** Serialize event for wire format (default JSON body). */\n body?: (event: ExecutionEvent) => string;\n /**\n * When true, await each request (blocks until HTTP completes). Default false.\n */\n awaitEach?: boolean;\n /** Abort the request after this many milliseconds (global `AbortSignal.timeout`). */\n timeoutMs?: number;\n onError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * POST execution events as JSON. Uses global `fetch` (Node 18+).\n * Fire-and-forget by default to avoid slowing callers.\n */\nexport class HttpExporter implements Exporter {\n private readonly url: string;\n private readonly method: string;\n private readonly headers: Record<string, string>;\n private readonly body: (event: ExecutionEvent) => string;\n private readonly awaitEach: boolean;\n private readonly timeoutMs?: number;\n private readonly onError?: (error: unknown, event: ExecutionEvent) => void;\n private readonly inFlight = new Set<Promise<void>>();\n private closed = false;\n\n constructor(options: HttpExporterOptions) {\n if (typeof options.url !== \"string\") {\n throw new TypeError(\n `HttpExporter: \"url\" must be a non-empty string, got ${describeValueType(options.url)}`,\n );\n }\n if (options.url.trim().length === 0) {\n throw new TypeError(\n 'HttpExporter: \"url\" must be a non-empty string (trimmed length is 0)',\n );\n }\n this.url = options.url;\n this.method = (options.method ?? \"POST\").trim() || \"POST\";\n const rawHeaders = options.headers;\n const extraHeaders =\n rawHeaders !== undefined &&\n rawHeaders !== null &&\n typeof rawHeaders === \"object\" &&\n !Array.isArray(rawHeaders)\n ? (rawHeaders as Record<string, string>)\n : {};\n this.headers = {\n \"content-type\": \"application/json\",\n ...extraHeaders,\n };\n this.body = options.body ?? ((event: ExecutionEvent) => safeJsonEnvelope(event));\n this.awaitEach = options.awaitEach ?? false;\n if (options.timeoutMs !== undefined) {\n const t = options.timeoutMs;\n if (!Number.isFinite(t) || t <= 0) {\n throw new TypeError(\n 'HttpExporter: \"timeoutMs\" must be a finite number > 0 when set',\n );\n }\n this.timeoutMs = Math.trunc(t);\n } else {\n this.timeoutMs = undefined;\n }\n this.onError = options.onError;\n }\n\n private track(p: Promise<void>): void {\n this.inFlight.add(p);\n void p.finally(() => this.inFlight.delete(p));\n }\n\n export(event: ExecutionEvent): void | Promise<void> {\n if (this.closed) {\n this.onError?.(new Error(\"HttpExporter has been shut down\"), event);\n return;\n }\n\n let payload: string;\n try {\n payload = this.body(event);\n } catch (e) {\n this.onError?.(e, event);\n payload = safeJsonEnvelope(event);\n }\n\n const run = async (): Promise<void> => {\n try {\n const res = await fetch(this.url, {\n method: this.method,\n headers: this.headers,\n body: payload,\n credentials: \"omit\",\n signal:\n this.timeoutMs !== undefined\n ? AbortSignal.timeout(this.timeoutMs)\n : undefined,\n });\n if (!res.ok) {\n const err = new Error(`HTTP ${res.status}: ${res.statusText}`);\n this.onError?.(err, event);\n }\n } catch (e) {\n this.onError?.(e, event);\n }\n };\n\n const p = run();\n this.track(p);\n if (this.awaitEach) return p;\n void p;\n }\n\n /** Waits until every started request has settled (success or failure). */\n flush(): Promise<void> {\n if (this.inFlight.size === 0) return Promise.resolve();\n return Promise.all([...this.inFlight]).then(() => {});\n }\n\n /** Stops accepting new events and waits for in-flight requests to finish. */\n async shutdown(): Promise<void> {\n this.closed = true;\n await this.flush();\n }\n}\n","import type { ExecutionEvent, Exporter } from \"../types.js\";\nimport { isPromiseLike } from \"../runtime.js\";\n\nexport type QueueOverflowStrategy = \"drop-newest\" | \"drop-oldest\";\n\nexport interface BoundedQueueExporterOptions {\n /** Downstream exporter (often {@link import(\"./http.js\").HttpExporter}). */\n exporter: Exporter;\n /** Maximum concurrent async exports to the inner exporter (default `4`). */\n maxConcurrent?: number;\n /**\n * Maximum **queued** events waiting for a worker slot (default `1000`).\n * Use `0` for unlimited backlog (not recommended under sustained overload).\n */\n maxQueue?: number;\n /** How to handle overflow when the queue is full (default `drop-newest`). */\n strategy?: QueueOverflowStrategy;\n onDrop?: (event: ExecutionEvent, reason: string) => void;\n onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n}\n\n/**\n * Bounded concurrency + backlog for async-heavy exporters.\n * Sync inner exporters run on the microtask queue and still respect {@link maxConcurrent}.\n */\nexport class BoundedQueueExporter implements Exporter {\n private readonly inner: Exporter;\n private readonly maxConcurrent: number;\n private readonly maxQueue: number;\n private readonly strategy: QueueOverflowStrategy;\n private readonly onDrop?: (event: ExecutionEvent, reason: string) => void;\n private readonly onInnerError?: (error: unknown, event: ExecutionEvent) => void;\n\n private readonly queue: ExecutionEvent[] = [];\n private active = 0;\n /** When false, {@link export} drops events with reason `shutdown`; queued work still drains. */\n private accepting = true;\n private idleResolvers: Array<() => void> = [];\n\n constructor(options: BoundedQueueExporterOptions) {\n const inner = options.exporter;\n if (\n inner == null ||\n typeof inner !== \"object\" ||\n typeof inner.export !== \"function\"\n ) {\n throw new TypeError(\n 'BoundedQueueExporter: \"exporter\" must be an object with an export() method',\n );\n }\n this.inner = inner;\n const rawMc = options.maxConcurrent ?? 4;\n this.maxConcurrent = !Number.isFinite(rawMc) ? 4 : Math.max(1, Math.trunc(rawMc));\n const rawQ = options.maxQueue ?? 1000;\n if (!Number.isFinite(rawQ)) {\n this.maxQueue = 1000;\n } else {\n const q = Math.trunc(rawQ);\n if (q === 0) {\n this.maxQueue = 0;\n } else if (q < 0) {\n this.maxQueue = 1000;\n } else {\n this.maxQueue = q;\n }\n }\n const strategy = options.strategy ?? \"drop-newest\";\n if (strategy !== \"drop-newest\" && strategy !== \"drop-oldest\") {\n throw new TypeError(\n 'BoundedQueueExporter: \"strategy\" must be \"drop-newest\" or \"drop-oldest\"',\n );\n }\n this.strategy = strategy;\n this.onDrop = options.onDrop;\n this.onInnerError = options.onInnerError;\n }\n\n export(event: ExecutionEvent): void {\n if (!this.accepting) {\n this.onDrop?.(event, \"shutdown\");\n return;\n }\n\n const cap = this.maxQueue <= 0 ? Number.POSITIVE_INFINITY : this.maxQueue;\n\n if (this.queue.length >= cap) {\n if (this.strategy === \"drop-oldest\") {\n // `length >= cap` and finite cap imply a non-empty queue before push.\n const dropped = this.queue.shift()!;\n this.onDrop?.(dropped, \"queue-overflow-drop-oldest\");\n this.queue.push(event);\n } else {\n this.onDrop?.(event, \"queue-overflow-drop-newest\");\n }\n this.pump();\n return;\n }\n\n this.queue.push(event);\n this.pump();\n }\n\n private pump(): void {\n while (this.active < this.maxConcurrent && this.queue.length > 0) {\n const next = this.queue.shift()!;\n this.active++;\n void this.runInner(next).finally(() => {\n this.active--;\n this.pump();\n this.resolveIdleWaitersIfNeeded();\n });\n }\n }\n\n private async runInner(event: ExecutionEvent): Promise<void> {\n try {\n const r = this.inner.export(event);\n if (isPromiseLike(r)) await r;\n } catch (e) {\n this.onInnerError?.(e, event);\n }\n }\n\n private resolveIdleWaitersIfNeeded(): void {\n if (this.queue.length === 0 && this.active === 0) {\n const waiters = this.idleResolvers;\n this.idleResolvers = [];\n for (const r of waiters) r();\n }\n }\n\n /** Resolves when the queue is empty and no inner export is in flight. */\n flush(): Promise<void> {\n if (this.queue.length === 0 && this.active === 0) {\n return Promise.resolve();\n }\n return new Promise((resolve) => {\n this.idleResolvers.push(resolve);\n });\n }\n\n /**\n * Stops accepting new events; does **not** drop items already in the queue—\n * {@link flush} waits until queued and in-flight work finishes.\n */\n async shutdown(): Promise<void> {\n this.accepting = false;\n await this.flush();\n }\n}\n","/**\n * @packageDocumentation\n * Structured `ExecutionEvent` emission for verification / ingest pipelines.\n */\n\nimport { IntentProofClient, getIntentProofClient } from \"./client.js\";\nimport type { IntentProofConfig } from \"./types.js\";\n\n/** Injected at build (`tsup`) and test (`vitest`) time from `package.json` — single source of truth. */\ndeclare const __INTENTPROOF_SDK_VERSION__: string;\n\nexport const VERSION = __INTENTPROOF_SDK_VERSION__;\n\nexport type {\n ExecutionErrorSnapshot,\n ExecutionEvent,\n ExecutionStatus,\n Exporter,\n SerializeOptions,\n IntentProofConfig,\n WrapOptions,\n} from \"./types.js\";\n\nexport { snapshot } from \"./snapshot.js\";\n\nexport { MemoryExporter } from \"./exporters/memory.js\";\nexport type { MemoryExporterOptions } from \"./exporters/memory.js\";\n\nexport { HttpExporter } from \"./exporters/http.js\";\nexport type { HttpExporterOptions } from \"./exporters/http.js\";\n\nexport { BoundedQueueExporter } from \"./exporters/queue.js\";\nexport type {\n BoundedQueueExporterOptions,\n QueueOverflowStrategy,\n} from \"./exporters/queue.js\";\n\nexport {\n IntentProofClient,\n assertCorrelationId,\n assertWrapOptionsShape,\n getCorrelationId,\n getIntentProofClient,\n runWithCorrelationId,\n} from \"./client.js\";\n\n/** Default singleton — same instance as `getIntentProofClient()`. */\nexport const client = getIntentProofClient();\n\n/** Isolated client instance (tests, workers, per-tenant configuration). */\nexport function createIntentProofClient(config?: IntentProofConfig): IntentProofClient {\n return new IntentProofClient(config);\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,14 +1,15 @@
1
1
  {
2
2
  "name": "@intentproof/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.2",
4
4
  "description": "TypeScript SDK for IntentProof",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
7
7
  "type": "git",
8
- "url": "git+https://github.com/IntentProof/intentproof-sdk-node.git",
8
+ "url": "https://github.com/IntentProof/intentproof-sdk-node",
9
9
  "directory": "packages/sdk"
10
10
  },
11
11
  "keywords": [
12
+ "IntentProof",
12
13
  "intentproof",
13
14
  "execution-events",
14
15
  "telemetry",
@@ -54,18 +55,18 @@
54
55
  "ci": "npm run sync-readme && npm run typecheck && npm run lint && npm run format:check && npm run test:coverage && npm run build && npm run publint"
55
56
  },
56
57
  "devDependencies": {
57
- "@eslint/js": "^9.39.4",
58
- "@types/node": "^22.10.0",
59
- "@vitest/coverage-v8": "^2.1.9",
60
- "eslint": "^9.39.4",
61
- "eslint-config-prettier": "^10.1.1",
62
- "globals": "^15.15.0",
63
- "prettier": "^3.5.3",
64
- "publint": "^0.3.12",
65
- "tsup": "^8.3.5",
66
- "typescript": "^5.7.2",
58
+ "@eslint/js": "^10.0.1",
59
+ "@types/node": "^25.6.0",
60
+ "@vitest/coverage-v8": "^4.1.5",
61
+ "eslint": "^10.3.0",
62
+ "eslint-config-prettier": "^10.1.8",
63
+ "globals": "^17.6.0",
64
+ "prettier": "^3.8.3",
65
+ "publint": "^0.3.18",
66
+ "tsup": "^8.5.1",
67
+ "typescript": "^6.0.3",
67
68
  "typescript-eslint": "^8.59.1",
68
- "vitest": "^2.1.6"
69
+ "vitest": "^4.1.5"
69
70
  },
70
71
  "engines": {
71
72
  "node": ">=22"