@alwaysmeticulous/backend-recorder-workerd 2.327.0 → 2.329.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +36 -0
- package/dist/context.js +2 -2
- package/dist/context.js.map +1 -1
- package/dist/coverage/coverage.types.d.ts +32 -0
- package/dist/coverage/replay-coverage.js +84 -0
- package/dist/coverage/replay-coverage.js.map +1 -0
- package/dist/coverage/runtime.d.ts +70 -0
- package/dist/coverage/runtime.js +138 -0
- package/dist/coverage/runtime.js.map +1 -0
- package/dist/index.d.ts +5 -2
- package/dist/index.js +6 -4
- package/dist/index.js.map +1 -1
- package/dist/protocol.d.ts +36 -1
- package/dist/protocol.js +19 -3
- package/dist/protocol.js.map +1 -1
- package/dist/publish-shim-version.js +37 -0
- package/dist/publish-shim-version.js.map +1 -0
- package/dist/replay-log-tagging.js +57 -0
- package/dist/replay-log-tagging.js.map +1 -0
- package/dist/sidecar-client.js +45 -4
- package/dist/sidecar-client.js.map +1 -1
- package/dist/version.d.ts +14 -0
- package/dist/version.js +18 -0
- package/dist/version.js.map +1 -0
- package/dist/vite/index.d.ts +62 -0
- package/dist/vite/index.js +6764 -0
- package/dist/vite/index.js.map +1 -0
- package/dist/with-meticulous.js +0 -0
- package/dist/with-meticulous.js.map +1 -1
- package/package.json +5 -2
package/README.md
CHANGED
|
@@ -155,8 +155,44 @@ Replay is **hermetic**: a call the recording does not cover fails with a `[backe
|
|
|
155
155
|
await fetch(url, { headers: { "meticulous-passthrough": "true" } });
|
|
156
156
|
```
|
|
157
157
|
|
|
158
|
+
While serving a replay, the shim prefixes request-scoped `console.debug`, `console.log`,
|
|
159
|
+
`console.info`, `console.warn`, `console.error`, and `console.trace` output with the active replay
|
|
160
|
+
ID. Each request reads its own ID from `AsyncLocalStorage`, so logs stay correctly attributed when
|
|
161
|
+
one Worker isolate serves concurrent replays. Startup and other work outside a replay request stays
|
|
162
|
+
untagged.
|
|
163
|
+
|
|
158
164
|
Calls through bindings and KV namespaces are not served from the recording (see Limitations) and are never failed — they always reach the real binding.
|
|
159
165
|
|
|
166
|
+
## Code coverage
|
|
167
|
+
|
|
168
|
+
Meticulous can report which of your server lines each replayed session executed. Workerd exposes no usable V8 coverage — its inspector never dispatches `Profiler.enable`, so `Profiler.startPreciseCoverage` is unreachable, and the one coverage call it does forward reports binary counts that never reset, which cannot be split per request. So the lines are marked at build time instead.
|
|
169
|
+
|
|
170
|
+
Add the plugin to the build you **upload for testing**, not the one you deploy:
|
|
171
|
+
|
|
172
|
+
```ts
|
|
173
|
+
import { defineConfig } from "vite";
|
|
174
|
+
import { meticulousCoverage } from "@alwaysmeticulous/backend-recorder-workerd/vite";
|
|
175
|
+
|
|
176
|
+
export default defineConfig({
|
|
177
|
+
plugins: [meticulousCoverage()],
|
|
178
|
+
});
|
|
179
|
+
```
|
|
180
|
+
|
|
181
|
+
Then replays report coverage automatically — the wrapper posts the lines each request ran to the Meticulous replay sidecar, which attributes them to that session.
|
|
182
|
+
|
|
183
|
+
- Only **server** modules are instrumented; the client build is untouched unless you pass `includeClient: true`.
|
|
184
|
+
- `node_modules` and virtual modules are always skipped. `exclude: [/pattern/]` skips more.
|
|
185
|
+
- The instrumented bundle is safe to run with coverage off: every marker is a no-op when nothing is collecting, so the same image still works for ordinary replays and for local development.
|
|
186
|
+
- A module the plugin cannot parse is passed through unchanged. Coverage is never worth failing your build for.
|
|
187
|
+
- Some lines are deliberately not marked, because marking them would mean rewriting code rather than adding to it: statements at module top level (they run at isolate startup, outside any request), class `static` blocks, the body of a braceless single statement such as `if (x) return;`, and the condition of an `else if` (only the first `if` of a chain gets a marker, though every branch body still gets its own). Those lines therefore read as uncovered even in a run that executed them.
|
|
188
|
+
|
|
189
|
+
Reported line numbers are lines in your source, not in the bundle. The plugin runs after your build's TypeScript/JSX pass, which re-prints each module and drops comments and blank lines — so it resolves every line back through that pass's source map. Two consequences worth knowing:
|
|
190
|
+
|
|
191
|
+
- A module whose source map your build does not produce is still instrumented, but its lines are reported as the build printed them. The plugin says how many modules this affected at the end of the build.
|
|
192
|
+
- A module whose source map covers some other file is skipped entirely rather than reported against the wrong lines.
|
|
193
|
+
|
|
194
|
+
Because each function re-reads the current request's sink, a callback that outlives the request that created it is credited to the request that actually runs it, not the one that built it.
|
|
195
|
+
|
|
160
196
|
## Limitations
|
|
161
197
|
|
|
162
198
|
- Streamed responses are captured truncated: the inbound request is reported once the handler returns, which for a streamed response is before the stream ends, and outbound bodies cap at 256 KB. An app whose main endpoints are SSE will not record them faithfully.
|
package/dist/context.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="fd65e097-c18e-51ca-8f2b-59427a88d125")}catch(e){}}();
|
|
3
3
|
import { transportOrigin } from "./sidecar-transport.js";
|
|
4
4
|
import { AsyncLocalStorage } from "node:async_hooks";
|
|
5
5
|
//#region src/context.ts
|
|
@@ -10,4 +10,4 @@ const sidecarOriginOf = (ctx) => ctx.mode === "replay" ? ctx.sidecarUrl : transp
|
|
|
10
10
|
export { requestCaptureContext, sidecarOriginOf };
|
|
11
11
|
|
|
12
12
|
//# sourceMappingURL=context.js.map
|
|
13
|
-
//# debugId=
|
|
13
|
+
//# debugId=fd65e097-c18e-51ca-8f2b-59427a88d125
|
package/dist/context.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"context.js","sources":["../src/context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CaptureBuffer } from \"./capture-buffer\";\nimport { type SidecarTransport, transportOrigin } from \"./sidecar-transport\";\n\n/**\n * Per-inbound-request context, entered by the withMeticulous wrapper and read by the fetch\n * patch. Requires the `nodejs_als` (or `nodejs_compat`) compatibility flag in the worker's\n * wrangler configuration.\n */\ninterface BaseRequestContext {\n requestId: string;\n /** The inbound request's ctx.waitUntil, for post-response capture work. */\n waitUntil: (promise: Promise<unknown>) => void;\n}\n\n/** Recording: capture events are reported to the sidecar, which stays out of the request path. */\nexport interface RequestCaptureContext extends BaseRequestContext {\n mode: \"record\";\n frontendSessionId: string | undefined;\n /**\n * Set only when we minted {@link frontendSessionId} ourselves for a document navigation the\n * browser could not tag, rather than reading it off the request. Recorded on the inbound\n * event so ingestion can tell an id the page may never have adopted from one it sent us.\n * See provisional-session-id.ts.\n */\n sessionIdOrigin?: \"backend\";\n transport: SidecarTransport;\n /** Batches this request's events into one report. */\n buffer: CaptureBuffer;\n /**\n * Trace this request's spans belong to, and the id of its SERVER span. Minted here rather than\n * by the sidecar so span assembly needs no cross-batch memory — see `CorrelatedEvent`.\n */\n traceId: string;\n serverSpanId: string;\n}\n\n/**\n * Replaying: outbound calls are looked up against the sidecar's mock store before they leave the\n * worker.\n *\n * Both ids are required here, unlike recording. Mocks are indexed by session and their\n * consume-once state is isolated by replay, so omitting either would make deterministic\n * lookup impossible. Making both non-optional keeps that state unrepresentable.\n *\n * Replay is URL-only, deliberately: the sidecar URL arrives on a request header the replay runner\n * injects, validated down to a loopback / docker-gateway / private-network origin. There is no\n * binding transport here because a replay sidecar is a Node process holding the mock store, never\n * a Worker.\n */\nexport interface RequestReplayContext extends BaseRequestContext {\n mode: \"replay\";\n frontendSessionId: string;\n replayId: string;\n /** Normalized origin of the sidecar, e.g. \"http://127.0.0.1:9670\". No trailing slash. */\n sidecarUrl: string;\n /**\n * Instant to freeze the worker's clock at while serving this session, or undefined to leave the\n * real clock alone.\n */\n clockAnchorMs: number | undefined;\n}\n\nexport type RequestContext = RequestCaptureContext | RequestReplayContext;\n\nexport const requestCaptureContext = new AsyncLocalStorage<RequestContext>();\n\n/** The origin the shim's own sidecar traffic goes to, for the self-capture guards. */\nexport const sidecarOriginOf = (ctx: RequestContext): string =>\n ctx.mode === \"replay\" ? ctx.sidecarUrl : transportOrigin(ctx.transport);\n"],"names":[],"mappings":";;;;;
|
|
1
|
+
{"version":3,"file":"context.js","sources":["../src/context.ts"],"sourcesContent":["import { AsyncLocalStorage } from \"node:async_hooks\";\nimport type { CaptureBuffer } from \"./capture-buffer\";\nimport { type SidecarTransport, transportOrigin } from \"./sidecar-transport\";\n\n/**\n * Per-inbound-request context, entered by the withMeticulous wrapper and read by the fetch\n * patch. Requires the `nodejs_als` (or `nodejs_compat`) compatibility flag in the worker's\n * wrangler configuration.\n */\ninterface BaseRequestContext {\n requestId: string;\n /** The inbound request's ctx.waitUntil, for post-response capture work. */\n waitUntil: (promise: Promise<unknown>) => void;\n /**\n * Per-request line-coverage sink, indexed by the global line id the build\n * plugin assigned. Present only when the bundle is instrumented and the\n * request is being replayed.\n *\n * Lives here rather than in a module-scope global because workerd interleaves\n * concurrent requests in one isolate — a shared sink would merge sessions'\n * coverage together.\n */\n coverage?: Uint8Array;\n}\n\n/** Recording: capture events are reported to the sidecar, which stays out of the request path. */\nexport interface RequestCaptureContext extends BaseRequestContext {\n mode: \"record\";\n frontendSessionId: string | undefined;\n /**\n * Set only when we minted {@link frontendSessionId} ourselves for a document navigation the\n * browser could not tag, rather than reading it off the request. Recorded on the inbound\n * event so ingestion can tell an id the page may never have adopted from one it sent us.\n * See provisional-session-id.ts.\n */\n sessionIdOrigin?: \"backend\";\n transport: SidecarTransport;\n /** Batches this request's events into one report. */\n buffer: CaptureBuffer;\n /**\n * Trace this request's spans belong to, and the id of its SERVER span. Minted here rather than\n * by the sidecar so span assembly needs no cross-batch memory — see `CorrelatedEvent`.\n */\n traceId: string;\n serverSpanId: string;\n}\n\n/**\n * Replaying: outbound calls are looked up against the sidecar's mock store before they leave the\n * worker.\n *\n * Both ids are required here, unlike recording. Mocks are indexed by session and their\n * consume-once state is isolated by replay, so omitting either would make deterministic\n * lookup impossible. Making both non-optional keeps that state unrepresentable.\n *\n * Replay is URL-only, deliberately: the sidecar URL arrives on a request header the replay runner\n * injects, validated down to a loopback / docker-gateway / private-network origin. There is no\n * binding transport here because a replay sidecar is a Node process holding the mock store, never\n * a Worker.\n */\nexport interface RequestReplayContext extends BaseRequestContext {\n mode: \"replay\";\n frontendSessionId: string;\n replayId: string;\n /** Normalized origin of the sidecar, e.g. \"http://127.0.0.1:9670\". No trailing slash. */\n sidecarUrl: string;\n /**\n * Instant to freeze the worker's clock at while serving this session, or undefined to leave the\n * real clock alone.\n */\n clockAnchorMs: number | undefined;\n}\n\nexport type RequestContext = RequestCaptureContext | RequestReplayContext;\n\nexport const requestCaptureContext = new AsyncLocalStorage<RequestContext>();\n\n/** The origin the shim's own sidecar traffic goes to, for the self-capture guards. */\nexport const sidecarOriginOf = (ctx: RequestContext): string =>\n ctx.mode === \"replay\" ? ctx.sidecarUrl : transportOrigin(ctx.transport);\n"],"names":[],"mappings":";;;;;AA2EA,MAAa,wBAAwB,IAAI,mBAAmC;;AAG5E,MAAa,mBAAmB,QAC9B,IAAI,SAAS,WAAW,IAAI,aAAa,gBAAgB,IAAI,UAAU","debugId":"fd65e097-c18e-51ca-8f2b-59427a88d125"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
//#region src/coverage/coverage.types.d.ts
|
|
2
|
+
/**
|
|
3
|
+
* Build-time line coverage contract, shared by the Vite plugin (which produces
|
|
4
|
+
* the ids), the in-worker runtime (which reports hits against them) and the
|
|
5
|
+
* sidecar (which turns hits back into file/line ranges).
|
|
6
|
+
*/
|
|
7
|
+
/** One instrumented source file's slice of the global id space. */
|
|
8
|
+
interface CoverageMapFile {
|
|
9
|
+
/** Source path as the build saw it, project-root-relative where possible. */
|
|
10
|
+
path: string;
|
|
11
|
+
/** First global id assigned to this file. */
|
|
12
|
+
firstId: number;
|
|
13
|
+
/**
|
|
14
|
+
* Inclusive 1-based line ranges, flattened as `[s1, e1, s2, e2, ...]` — the
|
|
15
|
+
* range at pair index `i` belongs to global id `firstId + i`. Flat rather
|
|
16
|
+
* than nested because this ships inside the customer's bundle, and it matches
|
|
17
|
+
* the `[start, end]` flattening the V8 chunk format already uses.
|
|
18
|
+
*
|
|
19
|
+
* A range covers only the lines the marked statement occupies itself: nested
|
|
20
|
+
* statements and function bodies carry their own ids, so an enclosing `if`
|
|
21
|
+
* never credits its untaken branch.
|
|
22
|
+
*/
|
|
23
|
+
lineRanges: number[];
|
|
24
|
+
}
|
|
25
|
+
interface CoverageMap {
|
|
26
|
+
/** Size of the global id space, and therefore of a request's sink. */
|
|
27
|
+
totalIds: number;
|
|
28
|
+
files: CoverageMapFile[];
|
|
29
|
+
}
|
|
30
|
+
//#endregion
|
|
31
|
+
export { CoverageMap, CoverageMapFile };
|
|
32
|
+
//# sourceMappingURL=coverage.types.d.ts.map
|
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="7dccd8d2-bdd2-5af1-ab64-d5b05a22f58e")}catch(e){}}();
|
|
3
|
+
import { requestCaptureContext } from "../context.js";
|
|
4
|
+
import { warnOnce } from "../log.js";
|
|
5
|
+
import { getOriginalFetch } from "../original-fetch.js";
|
|
6
|
+
import { postCoverageReport } from "../sidecar-client.js";
|
|
7
|
+
import { collectHitIds, createCoverageSink, getUnreportedCoverageFiles, markCoverageFilesReported } from "./runtime.js";
|
|
8
|
+
//#region src/coverage/replay-coverage.ts
|
|
9
|
+
/**
|
|
10
|
+
* The replay-mode half of line coverage: giving a request a sink, and reporting
|
|
11
|
+
* what it marked. The marking itself is `runtime.ts`, which the instrumented
|
|
12
|
+
* bundle calls directly.
|
|
13
|
+
*/
|
|
14
|
+
/**
|
|
15
|
+
* Whether the sidecar has told us it will never take coverage (404 on the route: an older
|
|
16
|
+
* sidecar, or one started without coverage enabled). Latched per isolate so a replay against
|
|
17
|
+
* such a sidecar stops allocating sinks and serialising hits after the first report.
|
|
18
|
+
*/
|
|
19
|
+
let coverageDisabled = false;
|
|
20
|
+
/**
|
|
21
|
+
* Runs the handler with a per-request coverage sink, reporting what it marked once the response
|
|
22
|
+
* exists.
|
|
23
|
+
*
|
|
24
|
+
* The sink is per-request rather than per-isolate because workerd interleaves concurrent
|
|
25
|
+
* requests, and every replayed request belongs to a different session — a shared sink would
|
|
26
|
+
* merge their coverage. Reporting goes through `waitUntil` so serialising the hits never delays
|
|
27
|
+
* the response, and every failure path leaves the response untouched: coverage is strictly
|
|
28
|
+
* best-effort.
|
|
29
|
+
*/
|
|
30
|
+
const runReplayWithCoverage = async (replayContext, invokeHandler) => {
|
|
31
|
+
if (coverageDisabled) return requestCaptureContext.run(replayContext, invokeHandler);
|
|
32
|
+
let sink;
|
|
33
|
+
try {
|
|
34
|
+
sink = createCoverageSink();
|
|
35
|
+
} catch (error) {
|
|
36
|
+
warnOnce("coverage-sink", "Could not allocate a coverage sink.", error);
|
|
37
|
+
}
|
|
38
|
+
if (sink === void 0) return requestCaptureContext.run(replayContext, invokeHandler);
|
|
39
|
+
const contextWithCoverage = {
|
|
40
|
+
...replayContext,
|
|
41
|
+
coverage: sink
|
|
42
|
+
};
|
|
43
|
+
try {
|
|
44
|
+
return await requestCaptureContext.run(contextWithCoverage, invokeHandler);
|
|
45
|
+
} finally {
|
|
46
|
+
reportCoverage(contextWithCoverage);
|
|
47
|
+
}
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Sends the hits, plus any id→line map the sidecar has not acknowledged yet.
|
|
51
|
+
*
|
|
52
|
+
* The map goes out incrementally rather than once per isolate because a
|
|
53
|
+
* code-split app registers a module only when its chunk is first imported: a
|
|
54
|
+
* route's server module usually registers on the request that first calls it,
|
|
55
|
+
* after earlier requests have already reported. Without the delta its hits would
|
|
56
|
+
* arrive against ids no file describes, and be dropped by the post-process.
|
|
57
|
+
*/
|
|
58
|
+
const reportCoverage = (context) => {
|
|
59
|
+
try {
|
|
60
|
+
const sink = context.coverage;
|
|
61
|
+
if (sink === void 0) return;
|
|
62
|
+
const hitIds = collectHitIds(sink);
|
|
63
|
+
const files = getUnreportedCoverageFiles();
|
|
64
|
+
if (hitIds.length === 0 && files.length === 0) return;
|
|
65
|
+
context.waitUntil(postCoverageReport(getOriginalFetch(), context.sidecarUrl, {
|
|
66
|
+
frontendSessionId: context.frontendSessionId,
|
|
67
|
+
hitIds,
|
|
68
|
+
...files.length > 0 ? { files } : {}
|
|
69
|
+
}).then((outcome) => {
|
|
70
|
+
if (outcome === "unsupported") {
|
|
71
|
+
coverageDisabled = true;
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
if (outcome === "accepted") markCoverageFilesReported(files);
|
|
75
|
+
}));
|
|
76
|
+
} catch (error) {
|
|
77
|
+
warnOnce("coverage-report", "Failed to report line coverage.", error);
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
//#endregion
|
|
81
|
+
export { runReplayWithCoverage };
|
|
82
|
+
|
|
83
|
+
//# sourceMappingURL=replay-coverage.js.map
|
|
84
|
+
//# debugId=7dccd8d2-bdd2-5af1-ab64-d5b05a22f58e
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"replay-coverage.js","sources":["../../src/coverage/replay-coverage.ts"],"sourcesContent":["import { type RequestReplayContext, requestCaptureContext } from \"../context\";\nimport { warnOnce } from \"../log\";\nimport { getOriginalFetch } from \"../original-fetch\";\nimport { postCoverageReport } from \"../sidecar-client\";\nimport {\n collectHitIds,\n createCoverageSink,\n getUnreportedCoverageFiles,\n markCoverageFilesReported,\n} from \"./runtime\";\n\n/**\n * The replay-mode half of line coverage: giving a request a sink, and reporting\n * what it marked. The marking itself is `runtime.ts`, which the instrumented\n * bundle calls directly.\n */\n\n/**\n * Whether the sidecar has told us it will never take coverage (404 on the route: an older\n * sidecar, or one started without coverage enabled). Latched per isolate so a replay against\n * such a sidecar stops allocating sinks and serialising hits after the first report.\n */\nlet coverageDisabled = false;\n\n/**\n * Runs the handler with a per-request coverage sink, reporting what it marked once the response\n * exists.\n *\n * The sink is per-request rather than per-isolate because workerd interleaves concurrent\n * requests, and every replayed request belongs to a different session — a shared sink would\n * merge their coverage. Reporting goes through `waitUntil` so serialising the hits never delays\n * the response, and every failure path leaves the response untouched: coverage is strictly\n * best-effort.\n */\nexport const runReplayWithCoverage = async (\n replayContext: RequestReplayContext,\n invokeHandler: () => Response | Promise<Response>,\n): Promise<Response> => {\n if (coverageDisabled) {\n return requestCaptureContext.run(replayContext, invokeHandler);\n }\n\n let sink: Uint8Array | undefined;\n try {\n sink = createCoverageSink();\n } catch (error) {\n warnOnce(\"coverage-sink\", \"Could not allocate a coverage sink.\", error);\n }\n if (sink === undefined) {\n // Allocation threw — run the request uncovered rather than failing it.\n return requestCaptureContext.run(replayContext, invokeHandler);\n }\n\n const contextWithCoverage: RequestReplayContext = {\n ...replayContext,\n coverage: sink,\n };\n try {\n return await requestCaptureContext.run(contextWithCoverage, invokeHandler);\n } finally {\n reportCoverage(contextWithCoverage);\n }\n};\n\n/**\n * Sends the hits, plus any id→line map the sidecar has not acknowledged yet.\n *\n * The map goes out incrementally rather than once per isolate because a\n * code-split app registers a module only when its chunk is first imported: a\n * route's server module usually registers on the request that first calls it,\n * after earlier requests have already reported. Without the delta its hits would\n * arrive against ids no file describes, and be dropped by the post-process.\n */\nconst reportCoverage = (context: RequestReplayContext): void => {\n try {\n // Read the sink off the context rather than closing over the one allocated at\n // request start: a module imported while the request ran will have grown it.\n const sink = context.coverage;\n if (sink === undefined) {\n return;\n }\n const hitIds = collectHitIds(sink);\n const files = getUnreportedCoverageFiles();\n if (hitIds.length === 0 && files.length === 0) {\n return;\n }\n context.waitUntil(\n postCoverageReport(getOriginalFetch(), context.sidecarUrl, {\n frontendSessionId: context.frontendSessionId,\n hitIds,\n ...(files.length > 0 ? { files } : {}),\n }).then((outcome) => {\n if (outcome === \"unsupported\") {\n coverageDisabled = true;\n return;\n }\n if (outcome === \"accepted\") {\n markCoverageFilesReported(files);\n }\n }),\n );\n } catch (error) {\n warnOnce(\"coverage-report\", \"Failed to report line coverage.\", error);\n }\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;AAsBA,IAAI,mBAAmB;;;;;;;;;;;AAYvB,MAAa,wBAAwB,OACnC,eACA,kBACsB;AACtB,KAAI,iBACF,QAAO,sBAAsB,IAAI,eAAe,cAAc;CAGhE,IAAI;AACJ,KAAI;AACF,SAAO,oBAAoB;UACpB,OAAO;AACd,WAAS,iBAAiB,uCAAuC,MAAM;;AAEzE,KAAI,SAAS,KAAA,EAEX,QAAO,sBAAsB,IAAI,eAAe,cAAc;CAGhE,MAAM,sBAA4C;EAChD,GAAG;EACH,UAAU;EACX;AACD,KAAI;AACF,SAAO,MAAM,sBAAsB,IAAI,qBAAqB,cAAc;WAClE;AACR,iBAAe,oBAAoB;;;;;;;;;;;;AAavC,MAAM,kBAAkB,YAAwC;AAC9D,KAAI;EAGF,MAAM,OAAO,QAAQ;AACrB,MAAI,SAAS,KAAA,EACX;EAEF,MAAM,SAAS,cAAc,KAAK;EAClC,MAAM,QAAQ,4BAA4B;AAC1C,MAAI,OAAO,WAAW,KAAK,MAAM,WAAW,EAC1C;AAEF,UAAQ,UACN,mBAAmB,kBAAkB,EAAE,QAAQ,YAAY;GACzD,mBAAmB,QAAQ;GAC3B;GACA,GAAI,MAAM,SAAS,IAAI,EAAE,OAAO,GAAG,EAAE;GACtC,CAAC,CAAC,MAAM,YAAY;AACnB,OAAI,YAAY,eAAe;AAC7B,uBAAmB;AACnB;;AAEF,OAAI,YAAY,WACd,2BAA0B,MAAM;IAElC,CACH;UACM,OAAO;AACd,WAAS,mBAAmB,mCAAmC,MAAM","debugId":"7dccd8d2-bdd2-5af1-ab64-d5b05a22f58e"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { CoverageMap, CoverageMapFile } from "./coverage.types.js";
|
|
2
|
+
|
|
3
|
+
//#region src/coverage/runtime.d.ts
|
|
4
|
+
/**
|
|
5
|
+
* Registers one module's slice of the id space, as a side effect of that module
|
|
6
|
+
* being evaluated.
|
|
7
|
+
*
|
|
8
|
+
* Per-module rather than one generated manifest because the full map is not
|
|
9
|
+
* known until every module has been transformed, and a manifest module would be
|
|
10
|
+
* loaded by the bundler as soon as the *first* instrumented module imported it.
|
|
11
|
+
* Self-registration sidesteps that ordering entirely.
|
|
12
|
+
*
|
|
13
|
+
* Deduplicated by path+id so a bundler that evaluates a module twice cannot
|
|
14
|
+
* inflate the id space.
|
|
15
|
+
*/
|
|
16
|
+
declare const registerCoverageFile: (file: CoverageMapFile) => void;
|
|
17
|
+
/** The whole registered id space. Exposed for debugging an instrumented build. */
|
|
18
|
+
declare const getCoverageMap: () => CoverageMap;
|
|
19
|
+
/**
|
|
20
|
+
* The registered files the sidecar has not acknowledged yet.
|
|
21
|
+
*
|
|
22
|
+
* Reported per request rather than once per isolate because a code-split app
|
|
23
|
+
* registers modules as their chunks are first imported — a route's server module
|
|
24
|
+
* typically registers on the request that first calls into it, long after the
|
|
25
|
+
* isolate's first report. Sending the map only once would leave every one of
|
|
26
|
+
* that module's hits unresolvable, which is coverage silently lost rather than
|
|
27
|
+
* coverage reported as missing.
|
|
28
|
+
*/
|
|
29
|
+
declare const getUnreportedCoverageFiles: () => CoverageMapFile[];
|
|
30
|
+
/**
|
|
31
|
+
* Marks files as delivered. Called only once the sidecar has accepted them, so a
|
|
32
|
+
* report lost to a timeout or a 5xx goes out again with the next one — the
|
|
33
|
+
* sidecar keeps the first map it sees for an id block, so a dropped map is
|
|
34
|
+
* permanent otherwise.
|
|
35
|
+
*/
|
|
36
|
+
declare const markCoverageFilesReported: (reported: readonly CoverageMapFile[]) => void;
|
|
37
|
+
/**
|
|
38
|
+
* Resolves the current request's sink. Called once per function invocation by
|
|
39
|
+
* instrumented code, which then stores into the returned array directly.
|
|
40
|
+
*/
|
|
41
|
+
declare const __mcEnter: () => Uint8Array | undefined;
|
|
42
|
+
/**
|
|
43
|
+
* Marks one line hit. Used only for concise arrow bodies (`() => expr`), which
|
|
44
|
+
* have no block in which to hoist the sink lookup.
|
|
45
|
+
*/
|
|
46
|
+
declare const __mcHit: (id: number) => void;
|
|
47
|
+
/**
|
|
48
|
+
* Allocates a request's sink, sized to the id space registered so far — which on
|
|
49
|
+
* a cold isolate is empty, since a code-split app registers nothing until its
|
|
50
|
+
* chunks are imported. An empty sink is deliberately not the same as "no
|
|
51
|
+
* instrumentation": {@link registerCoverageFile} grows it as modules arrive, so a
|
|
52
|
+
* request that starts with nothing registered still collects what it loads.
|
|
53
|
+
*
|
|
54
|
+
* Never undefined, so an uninstrumented bundle costs one zero-length allocation
|
|
55
|
+
* per request and reports nothing, rather than needing a per-isolate latch that
|
|
56
|
+
* cannot tell "no instrumentation" from "not loaded yet".
|
|
57
|
+
*/
|
|
58
|
+
declare const createCoverageSink: () => Uint8Array;
|
|
59
|
+
/**
|
|
60
|
+
* The ids marked during a request.
|
|
61
|
+
*
|
|
62
|
+
* Scanning the whole sink costs one pass over the id space per request — for a
|
|
63
|
+
* large app a few hundred thousand array reads, well under a millisecond, and
|
|
64
|
+
* paid once rather than on every line hit. The alternative (a push-list beside
|
|
65
|
+
* the bitmap) would add a branch to the hot path to save that single pass.
|
|
66
|
+
*/
|
|
67
|
+
declare const collectHitIds: (sink: Uint8Array) => number[];
|
|
68
|
+
//#endregion
|
|
69
|
+
export { __mcEnter, __mcHit, collectHitIds, createCoverageSink, getCoverageMap, getUnreportedCoverageFiles, markCoverageFilesReported, registerCoverageFile };
|
|
70
|
+
//# sourceMappingURL=runtime.d.ts.map
|
|
@@ -0,0 +1,138 @@
|
|
|
1
|
+
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="a559d75e-b978-551b-aaf6-c1a5a06e7cfd")}catch(e){}}();
|
|
3
|
+
import { requestCaptureContext } from "../context.js";
|
|
4
|
+
//#region src/coverage/runtime.ts
|
|
5
|
+
/**
|
|
6
|
+
* The in-worker half of build-time line coverage.
|
|
7
|
+
*
|
|
8
|
+
* The Meticulous Vite plugin rewrites the app's modules so each line marks
|
|
9
|
+
* itself against a sink, and injects a manifest module that calls
|
|
10
|
+
* {@link registerCoverageMap} once per isolate. Everything else here exists to
|
|
11
|
+
* keep the hot path to a single array store.
|
|
12
|
+
*
|
|
13
|
+
* The sink lives on the per-request AsyncLocalStorage store rather than in a
|
|
14
|
+
* module-scope global, which is the whole reason this can attribute coverage at
|
|
15
|
+
* all: workerd interleaves concurrent requests in one isolate, so a shared
|
|
16
|
+
* global would mix sessions together — the same over-attribution that makes
|
|
17
|
+
* workerd's `getBestEffortCoverage` useless for this.
|
|
18
|
+
*
|
|
19
|
+
* Both entry points are no-ops when no sink is present (recording, an
|
|
20
|
+
* uninstrumented request, module-level code running at isolate init), so an
|
|
21
|
+
* instrumented bundle is safe to run with coverage off.
|
|
22
|
+
*/
|
|
23
|
+
const files = [];
|
|
24
|
+
const registeredKeys = /* @__PURE__ */ new Set();
|
|
25
|
+
const reportedKeys = /* @__PURE__ */ new Set();
|
|
26
|
+
let totalIds = 0;
|
|
27
|
+
const fileKey = (file) => `${file.path}#${file.firstId}`;
|
|
28
|
+
/**
|
|
29
|
+
* Registers one module's slice of the id space, as a side effect of that module
|
|
30
|
+
* being evaluated.
|
|
31
|
+
*
|
|
32
|
+
* Per-module rather than one generated manifest because the full map is not
|
|
33
|
+
* known until every module has been transformed, and a manifest module would be
|
|
34
|
+
* loaded by the bundler as soon as the *first* instrumented module imported it.
|
|
35
|
+
* Self-registration sidesteps that ordering entirely.
|
|
36
|
+
*
|
|
37
|
+
* Deduplicated by path+id so a bundler that evaluates a module twice cannot
|
|
38
|
+
* inflate the id space.
|
|
39
|
+
*/
|
|
40
|
+
const registerCoverageFile = (file) => {
|
|
41
|
+
const key = fileKey(file);
|
|
42
|
+
if (registeredKeys.has(key)) return;
|
|
43
|
+
registeredKeys.add(key);
|
|
44
|
+
files.push(file);
|
|
45
|
+
const idsInFile = file.lineRanges.length / 2;
|
|
46
|
+
totalIds = Math.max(totalIds, file.firstId + idsInFile);
|
|
47
|
+
growCurrentRequestSink();
|
|
48
|
+
};
|
|
49
|
+
/**
|
|
50
|
+
* Extends the in-flight request's sink to cover the ids just registered.
|
|
51
|
+
*
|
|
52
|
+
* Registration happens as a module is evaluated, which for a code-split app is
|
|
53
|
+
* inside whichever request first imported its chunk — usually the one about to
|
|
54
|
+
* execute it. The sink was sized before that, so without this the request that
|
|
55
|
+
* brings a module in is the one request whose coverage of it is lost, and on a
|
|
56
|
+
* cold isolate that is the session's very first render.
|
|
57
|
+
*
|
|
58
|
+
* Replacing the array is safe because instrumented code re-reads the sink at
|
|
59
|
+
* every function entry: only a function already executing keeps the old one, and
|
|
60
|
+
* module evaluation itself carries no markers.
|
|
61
|
+
*/
|
|
62
|
+
const growCurrentRequestSink = () => {
|
|
63
|
+
const store = requestCaptureContext.getStore();
|
|
64
|
+
if (store === void 0) return;
|
|
65
|
+
const sink = store.coverage;
|
|
66
|
+
if (sink === void 0 || sink.length >= totalIds) return;
|
|
67
|
+
const grown = new Uint8Array(totalIds);
|
|
68
|
+
grown.set(sink);
|
|
69
|
+
store.coverage = grown;
|
|
70
|
+
};
|
|
71
|
+
/** The whole registered id space. Exposed for debugging an instrumented build. */
|
|
72
|
+
const getCoverageMap = () => ({
|
|
73
|
+
totalIds,
|
|
74
|
+
files
|
|
75
|
+
});
|
|
76
|
+
/**
|
|
77
|
+
* The registered files the sidecar has not acknowledged yet.
|
|
78
|
+
*
|
|
79
|
+
* Reported per request rather than once per isolate because a code-split app
|
|
80
|
+
* registers modules as their chunks are first imported — a route's server module
|
|
81
|
+
* typically registers on the request that first calls into it, long after the
|
|
82
|
+
* isolate's first report. Sending the map only once would leave every one of
|
|
83
|
+
* that module's hits unresolvable, which is coverage silently lost rather than
|
|
84
|
+
* coverage reported as missing.
|
|
85
|
+
*/
|
|
86
|
+
const getUnreportedCoverageFiles = () => files.filter((file) => !reportedKeys.has(fileKey(file)));
|
|
87
|
+
/**
|
|
88
|
+
* Marks files as delivered. Called only once the sidecar has accepted them, so a
|
|
89
|
+
* report lost to a timeout or a 5xx goes out again with the next one — the
|
|
90
|
+
* sidecar keeps the first map it sees for an id block, so a dropped map is
|
|
91
|
+
* permanent otherwise.
|
|
92
|
+
*/
|
|
93
|
+
const markCoverageFilesReported = (reported) => {
|
|
94
|
+
for (const file of reported) reportedKeys.add(fileKey(file));
|
|
95
|
+
};
|
|
96
|
+
/**
|
|
97
|
+
* Resolves the current request's sink. Called once per function invocation by
|
|
98
|
+
* instrumented code, which then stores into the returned array directly.
|
|
99
|
+
*/
|
|
100
|
+
const __mcEnter = () => requestCaptureContext.getStore()?.coverage;
|
|
101
|
+
/**
|
|
102
|
+
* Marks one line hit. Used only for concise arrow bodies (`() => expr`), which
|
|
103
|
+
* have no block in which to hoist the sink lookup.
|
|
104
|
+
*/
|
|
105
|
+
const __mcHit = (id) => {
|
|
106
|
+
const sink = requestCaptureContext.getStore()?.coverage;
|
|
107
|
+
if (sink !== void 0 && id < sink.length) sink[id] = 1;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Allocates a request's sink, sized to the id space registered so far — which on
|
|
111
|
+
* a cold isolate is empty, since a code-split app registers nothing until its
|
|
112
|
+
* chunks are imported. An empty sink is deliberately not the same as "no
|
|
113
|
+
* instrumentation": {@link registerCoverageFile} grows it as modules arrive, so a
|
|
114
|
+
* request that starts with nothing registered still collects what it loads.
|
|
115
|
+
*
|
|
116
|
+
* Never undefined, so an uninstrumented bundle costs one zero-length allocation
|
|
117
|
+
* per request and reports nothing, rather than needing a per-isolate latch that
|
|
118
|
+
* cannot tell "no instrumentation" from "not loaded yet".
|
|
119
|
+
*/
|
|
120
|
+
const createCoverageSink = () => new Uint8Array(totalIds);
|
|
121
|
+
/**
|
|
122
|
+
* The ids marked during a request.
|
|
123
|
+
*
|
|
124
|
+
* Scanning the whole sink costs one pass over the id space per request — for a
|
|
125
|
+
* large app a few hundred thousand array reads, well under a millisecond, and
|
|
126
|
+
* paid once rather than on every line hit. The alternative (a push-list beside
|
|
127
|
+
* the bitmap) would add a branch to the hot path to save that single pass.
|
|
128
|
+
*/
|
|
129
|
+
const collectHitIds = (sink) => {
|
|
130
|
+
const hits = [];
|
|
131
|
+
for (let id = 0; id < sink.length; id++) if (sink[id] !== 0) hits.push(id);
|
|
132
|
+
return hits;
|
|
133
|
+
};
|
|
134
|
+
//#endregion
|
|
135
|
+
export { __mcEnter, __mcHit, collectHitIds, createCoverageSink, getCoverageMap, getUnreportedCoverageFiles, markCoverageFilesReported, registerCoverageFile };
|
|
136
|
+
|
|
137
|
+
//# sourceMappingURL=runtime.js.map
|
|
138
|
+
//# debugId=a559d75e-b978-551b-aaf6-c1a5a06e7cfd
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"runtime.js","sources":["../../src/coverage/runtime.ts"],"sourcesContent":["import { requestCaptureContext } from \"../context\";\nimport type { CoverageMap, CoverageMapFile } from \"./coverage.types\";\n\n/**\n * The in-worker half of build-time line coverage.\n *\n * The Meticulous Vite plugin rewrites the app's modules so each line marks\n * itself against a sink, and injects a manifest module that calls\n * {@link registerCoverageMap} once per isolate. Everything else here exists to\n * keep the hot path to a single array store.\n *\n * The sink lives on the per-request AsyncLocalStorage store rather than in a\n * module-scope global, which is the whole reason this can attribute coverage at\n * all: workerd interleaves concurrent requests in one isolate, so a shared\n * global would mix sessions together — the same over-attribution that makes\n * workerd's `getBestEffortCoverage` useless for this.\n *\n * Both entry points are no-ops when no sink is present (recording, an\n * uninstrumented request, module-level code running at isolate init), so an\n * instrumented bundle is safe to run with coverage off.\n */\n\nconst files: CoverageMapFile[] = [];\nconst registeredKeys = new Set<string>();\nconst reportedKeys = new Set<string>();\nlet totalIds = 0;\n\nconst fileKey = (file: CoverageMapFile): string =>\n `${file.path}#${file.firstId}`;\n\n/**\n * Registers one module's slice of the id space, as a side effect of that module\n * being evaluated.\n *\n * Per-module rather than one generated manifest because the full map is not\n * known until every module has been transformed, and a manifest module would be\n * loaded by the bundler as soon as the *first* instrumented module imported it.\n * Self-registration sidesteps that ordering entirely.\n *\n * Deduplicated by path+id so a bundler that evaluates a module twice cannot\n * inflate the id space.\n */\nexport const registerCoverageFile = (file: CoverageMapFile): void => {\n const key = fileKey(file);\n if (registeredKeys.has(key)) {\n return;\n }\n registeredKeys.add(key);\n files.push(file);\n const idsInFile = file.lineRanges.length / 2;\n totalIds = Math.max(totalIds, file.firstId + idsInFile);\n growCurrentRequestSink();\n};\n\n/**\n * Extends the in-flight request's sink to cover the ids just registered.\n *\n * Registration happens as a module is evaluated, which for a code-split app is\n * inside whichever request first imported its chunk — usually the one about to\n * execute it. The sink was sized before that, so without this the request that\n * brings a module in is the one request whose coverage of it is lost, and on a\n * cold isolate that is the session's very first render.\n *\n * Replacing the array is safe because instrumented code re-reads the sink at\n * every function entry: only a function already executing keeps the old one, and\n * module evaluation itself carries no markers.\n */\nconst growCurrentRequestSink = (): void => {\n const store = requestCaptureContext.getStore();\n if (store === undefined) {\n return;\n }\n const sink = store.coverage;\n if (sink === undefined || sink.length >= totalIds) {\n return;\n }\n const grown = new Uint8Array(totalIds);\n grown.set(sink);\n store.coverage = grown;\n};\n\n/** The whole registered id space. Exposed for debugging an instrumented build. */\nexport const getCoverageMap = (): CoverageMap => ({ totalIds, files });\n\n/**\n * The registered files the sidecar has not acknowledged yet.\n *\n * Reported per request rather than once per isolate because a code-split app\n * registers modules as their chunks are first imported — a route's server module\n * typically registers on the request that first calls into it, long after the\n * isolate's first report. Sending the map only once would leave every one of\n * that module's hits unresolvable, which is coverage silently lost rather than\n * coverage reported as missing.\n */\nexport const getUnreportedCoverageFiles = (): CoverageMapFile[] =>\n files.filter((file) => !reportedKeys.has(fileKey(file)));\n\n/**\n * Marks files as delivered. Called only once the sidecar has accepted them, so a\n * report lost to a timeout or a 5xx goes out again with the next one — the\n * sidecar keeps the first map it sees for an id block, so a dropped map is\n * permanent otherwise.\n */\nexport const markCoverageFilesReported = (\n reported: readonly CoverageMapFile[],\n): void => {\n for (const file of reported) {\n reportedKeys.add(fileKey(file));\n }\n};\n\n/**\n * Resolves the current request's sink. Called once per function invocation by\n * instrumented code, which then stores into the returned array directly.\n */\nexport const __mcEnter = (): Uint8Array | undefined =>\n requestCaptureContext.getStore()?.coverage;\n\n/**\n * Marks one line hit. Used only for concise arrow bodies (`() => expr`), which\n * have no block in which to hoist the sink lookup.\n */\nexport const __mcHit = (id: number): void => {\n const sink = requestCaptureContext.getStore()?.coverage;\n if (sink !== undefined && id < sink.length) {\n sink[id] = 1;\n }\n};\n\n/**\n * Allocates a request's sink, sized to the id space registered so far — which on\n * a cold isolate is empty, since a code-split app registers nothing until its\n * chunks are imported. An empty sink is deliberately not the same as \"no\n * instrumentation\": {@link registerCoverageFile} grows it as modules arrive, so a\n * request that starts with nothing registered still collects what it loads.\n *\n * Never undefined, so an uninstrumented bundle costs one zero-length allocation\n * per request and reports nothing, rather than needing a per-isolate latch that\n * cannot tell \"no instrumentation\" from \"not loaded yet\".\n */\nexport const createCoverageSink = (): Uint8Array => new Uint8Array(totalIds);\n\n/**\n * The ids marked during a request.\n *\n * Scanning the whole sink costs one pass over the id space per request — for a\n * large app a few hundred thousand array reads, well under a millisecond, and\n * paid once rather than on every line hit. The alternative (a push-list beside\n * the bitmap) would add a branch to the hot path to save that single pass.\n */\nexport const collectHitIds = (sink: Uint8Array): number[] => {\n const hits: number[] = [];\n for (let id = 0; id < sink.length; id++) {\n if (sink[id] !== 0) {\n hits.push(id);\n }\n }\n return hits;\n};\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;AAsBA,MAAM,QAA2B,EAAE;AACnC,MAAM,iCAAiB,IAAI,KAAa;AACxC,MAAM,+BAAe,IAAI,KAAa;AACtC,IAAI,WAAW;AAEf,MAAM,WAAW,SACf,GAAG,KAAK,KAAK,GAAG,KAAK;;;;;;;;;;;;;AAcvB,MAAa,wBAAwB,SAAgC;CACnE,MAAM,MAAM,QAAQ,KAAK;AACzB,KAAI,eAAe,IAAI,IAAI,CACzB;AAEF,gBAAe,IAAI,IAAI;AACvB,OAAM,KAAK,KAAK;CAChB,MAAM,YAAY,KAAK,WAAW,SAAS;AAC3C,YAAW,KAAK,IAAI,UAAU,KAAK,UAAU,UAAU;AACvD,yBAAwB;;;;;;;;;;;;;;;AAgB1B,MAAM,+BAAqC;CACzC,MAAM,QAAQ,sBAAsB,UAAU;AAC9C,KAAI,UAAU,KAAA,EACZ;CAEF,MAAM,OAAO,MAAM;AACnB,KAAI,SAAS,KAAA,KAAa,KAAK,UAAU,SACvC;CAEF,MAAM,QAAQ,IAAI,WAAW,SAAS;AACtC,OAAM,IAAI,KAAK;AACf,OAAM,WAAW;;;AAInB,MAAa,wBAAqC;CAAE;CAAU;CAAO;;;;;;;;;;;AAYrE,MAAa,mCACX,MAAM,QAAQ,SAAS,CAAC,aAAa,IAAI,QAAQ,KAAK,CAAC,CAAC;;;;;;;AAQ1D,MAAa,6BACX,aACS;AACT,MAAK,MAAM,QAAQ,SACjB,cAAa,IAAI,QAAQ,KAAK,CAAC;;;;;;AAQnC,MAAa,kBACX,sBAAsB,UAAU,EAAE;;;;;AAMpC,MAAa,WAAW,OAAqB;CAC3C,MAAM,OAAO,sBAAsB,UAAU,EAAE;AAC/C,KAAI,SAAS,KAAA,KAAa,KAAK,KAAK,OAClC,MAAK,MAAM;;;;;;;;;;;;;AAef,MAAa,2BAAuC,IAAI,WAAW,SAAS;;;;;;;;;AAU5E,MAAa,iBAAiB,SAA+B;CAC3D,MAAM,OAAiB,EAAE;AACzB,MAAK,IAAI,KAAK,GAAG,KAAK,KAAK,QAAQ,KACjC,KAAI,KAAK,QAAQ,EACf,MAAK,KAAK,GAAG;AAGjB,QAAO","debugId":"a559d75e-b978-551b-aaf6-c1a5a06e7cfd"}
|
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import { SIDECAR_BINDING_ENV_KEY, SIDECAR_BINDING_ORIGIN, SIDECAR_URL_ENV_KEY, SidecarFetcher, SidecarTransport } from "./sidecar-transport.js";
|
|
2
2
|
import { MeticulousExecutionContext, WithMeticulousOptions } from "./with-meticulous.js";
|
|
3
|
-
import { BindingRequestEvent, CAPTURED_HEADERS, CaptureEvent, CaptureEventsPayload, CapturedBody, FRONTEND_SESSION_ID_HEADER, InboundRequestEvent, KvOmittedReason, KvOperation, KvOperationEvent, METICULOUS_PASSTHROUGH_HEADER, OutboundFetchLookupRequest, OutboundFetchLookupResponse, OutboundRequestEvent, PostgresQueryEvent, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, ReplaySessionInfoResponse, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH } from "./protocol.js";
|
|
3
|
+
import { BindingRequestEvent, CAPTURED_HEADERS, CaptureEvent, CaptureEventsPayload, CapturedBody, CoverageReportRequest, FRONTEND_SESSION_ID_HEADER, InboundRequestEvent, KvOmittedReason, KvOperation, KvOperationEvent, METICULOUS_PASSTHROUGH_HEADER, OutboundFetchLookupRequest, OutboundFetchLookupResponse, OutboundRequestEvent, PostgresQueryEvent, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, ReplaySessionInfoResponse, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_COVERAGE_PATH, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, WORKERD_SHIM_VERSION_HEADER } from "./protocol.js";
|
|
4
|
+
import { WORKERD_SHIM_VERSION } from "./version.js";
|
|
4
5
|
import { MAX_BODY_CAPTURE_SIZE, readBodyWithCap, readRequestBodyWithCap } from "./body-capture.js";
|
|
5
6
|
import { headersToRecord } from "./outbound-capture.js";
|
|
6
7
|
import { STR_REDACTED, redactRequestBody } from "./redact-body.js";
|
|
8
|
+
import { CoverageMap, CoverageMapFile } from "./coverage/coverage.types.js";
|
|
9
|
+
import { __mcEnter, __mcHit, collectHitIds, createCoverageSink, getCoverageMap, getUnreportedCoverageFiles, markCoverageFilesReported, registerCoverageFile } from "./coverage/runtime.js";
|
|
7
10
|
import { MeticulousPagesFunction, MeticulousPagesFunctionContext, withMeticulousPagesFunction } from "./pages-function.js";
|
|
8
11
|
import { KvCaptureFields, KvCaptureOutcome, serializeKvArgs, serializeKvCaptureFields } from "./kv-capture.js";
|
|
9
12
|
import { deserializeCapturedError, serializeCapturedError } from "./error-capture.js";
|
|
@@ -82,5 +85,5 @@ declare const withMeticulous: <H extends MeticulousWorkerHandler<never>>(handler
|
|
|
82
85
|
*/
|
|
83
86
|
declare const getMeticulousSessionId: () => string | undefined;
|
|
84
87
|
//#endregion
|
|
85
|
-
export { type BindingRequestEvent, CAPTURED_HEADERS, CLIENT_TECHNOLOGY_ATTR, CLIENT_TECHNOLOGY_POSTGRES_JS, CLIENT_TECHNOLOGY_WORKERD_BINDING, CLIENT_TECHNOLOGY_WORKERD_FETCH, CLIENT_TECHNOLOGY_WORKERD_KV, type CaptureEvent, type CaptureEventsPayload, type CapturedBody, FRONTEND_SESSION_ID_ATTR, FRONTEND_SESSION_ID_HEADER, type HeaderReader, type HrTime, type InboundRequestEvent, type KvCaptureFields, type KvCaptureOutcome, type KvOmittedReason, type KvOperation, type KvOperationEvent, MAX_BODY_CAPTURE_SIZE, MAX_POSTGRES_JS_RESULT_SIZE, METICULOUS_PASSTHROUGH_HEADER, type MeticulousExecutionContext, type MeticulousPagesFunction, type MeticulousPagesFunctionContext, MeticulousWorkerHandler, type OutboundFetchLookupRequest, type OutboundFetchLookupResponse, type OutboundRequestEvent, POSTGRES_JS_ERROR_ATTR, POSTGRES_JS_QUERY_PARAMS_ATTR, POSTGRES_JS_QUERY_TEXT_ATTR, POSTGRES_JS_RESULT_ATTR, POSTGRES_JS_RESULT_TRUNCATED_ATTR, POSTGRES_JS_ROW_MODE_ATTR, type PostgresJsQueryLike, type PostgresJsRowMode, type PostgresQueryEvent, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, type ReadableSpan, type ReplaySessionInfoResponse, SERVER_TIMING_HEADER, SERVER_TIMING_SESSION_METRIC, SESSION_ID_ORIGIN_ATTR, SESSION_ID_ORIGIN_BACKEND, SIDECAR_BINDING_ENV_KEY, SIDECAR_BINDING_ORIGIN, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, SIDECAR_URL_ENV_KEY, SPAN_KIND_CLIENT, SPAN_KIND_INTERNAL, SPAN_KIND_SERVER, SPAN_STATUS_ERROR, SPAN_STATUS_OK, SPAN_STATUS_UNSET, STR_REDACTED, type SerializedSpanBase, type SidecarFetcher, type SidecarTransport, SpanBuilder, type SpanStatus, WORKERD_BINDING_NAME_ATTR, WORKERD_KV_ARGS_ATTR, WORKERD_KV_ARGS_TRUNCATED_ATTR, WORKERD_KV_KEY_ATTR, WORKERD_KV_OMITTED_ATTR, WORKERD_KV_OPERATION_ATTR, WORKERD_KV_RESULT_ATTR, WORKERD_KV_RESULT_TRUNCATED_ATTR, WORKERD_KV_VALUE_ATTR, WORKERD_KV_VALUE_TRUNCATED_ATTR, type WithMeticulousOptions, buildServerTimingSessionEntry, deserializeCapturedError, getMeticulousSessionId, headersToRecord, hrTimeToMs, isProvisionalSessionIdCandidate, isSupportedPostgresJsQuery, mintProvisionalSessionId, msToHrTime, postgresJsCommandOf, randomHex, readBodyWithCap, readRequestBodyWithCap, reconstructQueryText, redactRequestBody, redactUrlCredentials, resolveRowMode, serializeCapturedError, serializeKvArgs, serializeKvCaptureFields, serializePostgresJsArgs, serializePostgresJsError, serializePostgresJsResult, serializeSpan, withMeticulous, withMeticulousPagesFunction, withMeticulousPostgres };
|
|
88
|
+
export { type BindingRequestEvent, CAPTURED_HEADERS, CLIENT_TECHNOLOGY_ATTR, CLIENT_TECHNOLOGY_POSTGRES_JS, CLIENT_TECHNOLOGY_WORKERD_BINDING, CLIENT_TECHNOLOGY_WORKERD_FETCH, CLIENT_TECHNOLOGY_WORKERD_KV, type CaptureEvent, type CaptureEventsPayload, type CapturedBody, type CoverageMap, type CoverageMapFile, type CoverageReportRequest, FRONTEND_SESSION_ID_ATTR, FRONTEND_SESSION_ID_HEADER, type HeaderReader, type HrTime, type InboundRequestEvent, type KvCaptureFields, type KvCaptureOutcome, type KvOmittedReason, type KvOperation, type KvOperationEvent, MAX_BODY_CAPTURE_SIZE, MAX_POSTGRES_JS_RESULT_SIZE, METICULOUS_PASSTHROUGH_HEADER, type MeticulousExecutionContext, type MeticulousPagesFunction, type MeticulousPagesFunctionContext, MeticulousWorkerHandler, type OutboundFetchLookupRequest, type OutboundFetchLookupResponse, type OutboundRequestEvent, POSTGRES_JS_ERROR_ATTR, POSTGRES_JS_QUERY_PARAMS_ATTR, POSTGRES_JS_QUERY_TEXT_ATTR, POSTGRES_JS_RESULT_ATTR, POSTGRES_JS_RESULT_TRUNCATED_ATTR, POSTGRES_JS_ROW_MODE_ATTR, type PostgresJsQueryLike, type PostgresJsRowMode, type PostgresQueryEvent, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, type ReadableSpan, type ReplaySessionInfoResponse, SERVER_TIMING_HEADER, SERVER_TIMING_SESSION_METRIC, SESSION_ID_ORIGIN_ATTR, SESSION_ID_ORIGIN_BACKEND, SIDECAR_BINDING_ENV_KEY, SIDECAR_BINDING_ORIGIN, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_COVERAGE_PATH, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, SIDECAR_URL_ENV_KEY, SPAN_KIND_CLIENT, SPAN_KIND_INTERNAL, SPAN_KIND_SERVER, SPAN_STATUS_ERROR, SPAN_STATUS_OK, SPAN_STATUS_UNSET, STR_REDACTED, type SerializedSpanBase, type SidecarFetcher, type SidecarTransport, SpanBuilder, type SpanStatus, WORKERD_BINDING_NAME_ATTR, WORKERD_KV_ARGS_ATTR, WORKERD_KV_ARGS_TRUNCATED_ATTR, WORKERD_KV_KEY_ATTR, WORKERD_KV_OMITTED_ATTR, WORKERD_KV_OPERATION_ATTR, WORKERD_KV_RESULT_ATTR, WORKERD_KV_RESULT_TRUNCATED_ATTR, WORKERD_KV_VALUE_ATTR, WORKERD_KV_VALUE_TRUNCATED_ATTR, WORKERD_SHIM_VERSION, WORKERD_SHIM_VERSION_HEADER, type WithMeticulousOptions, __mcEnter, __mcHit, buildServerTimingSessionEntry, collectHitIds, createCoverageSink, deserializeCapturedError, getCoverageMap, getMeticulousSessionId, getUnreportedCoverageFiles, headersToRecord, hrTimeToMs, isProvisionalSessionIdCandidate, isSupportedPostgresJsQuery, markCoverageFilesReported, mintProvisionalSessionId, msToHrTime, postgresJsCommandOf, randomHex, readBodyWithCap, readRequestBodyWithCap, reconstructQueryText, redactRequestBody, redactUrlCredentials, registerCoverageFile, resolveRowMode, serializeCapturedError, serializeKvArgs, serializeKvCaptureFields, serializePostgresJsArgs, serializePostgresJsError, serializePostgresJsResult, serializeSpan, withMeticulous, withMeticulousPagesFunction, withMeticulousPostgres };
|
|
86
89
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.js
CHANGED
|
@@ -1,13 +1,15 @@
|
|
|
1
1
|
|
|
2
|
-
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="
|
|
2
|
+
!function(){try{var e="undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof globalThis?globalThis:"undefined"!=typeof self?self:{},n=(new e.Error).stack;n&&(e._sentryDebugIds=e._sentryDebugIds||{},e._sentryDebugIds[n]="22e3bcf8-6298-5815-a54c-39716473b677")}catch(e){}}();
|
|
3
3
|
import { SIDECAR_BINDING_ENV_KEY, SIDECAR_BINDING_ORIGIN, SIDECAR_URL_ENV_KEY } from "./sidecar-transport.js";
|
|
4
4
|
import { requestCaptureContext } from "./context.js";
|
|
5
5
|
import { STR_REDACTED, redactRequestBody } from "./redact-body.js";
|
|
6
6
|
import { MAX_BODY_CAPTURE_SIZE, readBodyWithCap, readRequestBodyWithCap } from "./body-capture.js";
|
|
7
|
-
import { CAPTURED_HEADERS, FRONTEND_SESSION_ID_HEADER, METICULOUS_PASSTHROUGH_HEADER, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH } from "./protocol.js";
|
|
7
|
+
import { CAPTURED_HEADERS, FRONTEND_SESSION_ID_HEADER, METICULOUS_PASSTHROUGH_HEADER, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_COVERAGE_PATH, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, WORKERD_SHIM_VERSION_HEADER } from "./protocol.js";
|
|
8
8
|
import { headersToRecord } from "./outbound-capture.js";
|
|
9
|
+
import { __mcEnter, __mcHit, collectHitIds, createCoverageSink, getCoverageMap, getUnreportedCoverageFiles, markCoverageFilesReported, registerCoverageFile } from "./coverage/runtime.js";
|
|
9
10
|
import { serializeKvArgs, serializeKvCaptureFields } from "./kv-capture.js";
|
|
10
11
|
import { SERVER_TIMING_HEADER, SERVER_TIMING_SESSION_METRIC, buildServerTimingSessionEntry, isProvisionalSessionIdCandidate, mintProvisionalSessionId } from "./provisional-session-id.js";
|
|
12
|
+
import { WORKERD_SHIM_VERSION } from "./version.js";
|
|
11
13
|
import { deserializeCapturedError, serializeCapturedError } from "./error-capture.js";
|
|
12
14
|
import { MAX_POSTGRES_JS_RESULT_SIZE, POSTGRES_JS_ERROR_ATTR, POSTGRES_JS_QUERY_PARAMS_ATTR, POSTGRES_JS_QUERY_TEXT_ATTR, POSTGRES_JS_RESULT_ATTR, POSTGRES_JS_RESULT_TRUNCATED_ATTR, POSTGRES_JS_ROW_MODE_ATTR, isSupportedPostgresJsQuery, postgresJsCommandOf, reconstructQueryText, resolveRowMode, serializePostgresJsArgs, serializePostgresJsError, serializePostgresJsResult } from "./postgres/capture.js";
|
|
13
15
|
import { CLIENT_TECHNOLOGY_ATTR, CLIENT_TECHNOLOGY_POSTGRES_JS, CLIENT_TECHNOLOGY_WORKERD_BINDING, CLIENT_TECHNOLOGY_WORKERD_FETCH, CLIENT_TECHNOLOGY_WORKERD_KV, FRONTEND_SESSION_ID_ATTR, SESSION_ID_ORIGIN_ATTR, SESSION_ID_ORIGIN_BACKEND, WORKERD_BINDING_NAME_ATTR, WORKERD_KV_ARGS_ATTR, WORKERD_KV_ARGS_TRUNCATED_ATTR, WORKERD_KV_KEY_ATTR, WORKERD_KV_OMITTED_ATTR, WORKERD_KV_OPERATION_ATTR, WORKERD_KV_RESULT_ATTR, WORKERD_KV_RESULT_TRUNCATED_ATTR, WORKERD_KV_VALUE_ATTR, WORKERD_KV_VALUE_TRUNCATED_ATTR } from "./spans/attributes.js";
|
|
@@ -91,7 +93,7 @@ const withMeticulous = (handler, options) => {
|
|
|
91
93
|
*/
|
|
92
94
|
const getMeticulousSessionId = () => requestCaptureContext.getStore()?.frontendSessionId;
|
|
93
95
|
//#endregion
|
|
94
|
-
export { CAPTURED_HEADERS, CLIENT_TECHNOLOGY_ATTR, CLIENT_TECHNOLOGY_POSTGRES_JS, CLIENT_TECHNOLOGY_WORKERD_BINDING, CLIENT_TECHNOLOGY_WORKERD_FETCH, CLIENT_TECHNOLOGY_WORKERD_KV, FRONTEND_SESSION_ID_ATTR, FRONTEND_SESSION_ID_HEADER, MAX_BODY_CAPTURE_SIZE, MAX_POSTGRES_JS_RESULT_SIZE, METICULOUS_PASSTHROUGH_HEADER, POSTGRES_JS_ERROR_ATTR, POSTGRES_JS_QUERY_PARAMS_ATTR, POSTGRES_JS_QUERY_TEXT_ATTR, POSTGRES_JS_RESULT_ATTR, POSTGRES_JS_RESULT_TRUNCATED_ATTR, POSTGRES_JS_ROW_MODE_ATTR, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, SERVER_TIMING_HEADER, SERVER_TIMING_SESSION_METRIC, SESSION_ID_ORIGIN_ATTR, SESSION_ID_ORIGIN_BACKEND, SIDECAR_BINDING_ENV_KEY, SIDECAR_BINDING_ORIGIN, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, SIDECAR_URL_ENV_KEY, SPAN_KIND_CLIENT, SPAN_KIND_INTERNAL, SPAN_KIND_SERVER, SPAN_STATUS_ERROR, SPAN_STATUS_OK, SPAN_STATUS_UNSET, STR_REDACTED, SpanBuilder, WORKERD_BINDING_NAME_ATTR, WORKERD_KV_ARGS_ATTR, WORKERD_KV_ARGS_TRUNCATED_ATTR, WORKERD_KV_KEY_ATTR, WORKERD_KV_OMITTED_ATTR, WORKERD_KV_OPERATION_ATTR, WORKERD_KV_RESULT_ATTR, WORKERD_KV_RESULT_TRUNCATED_ATTR, WORKERD_KV_VALUE_ATTR, WORKERD_KV_VALUE_TRUNCATED_ATTR, buildServerTimingSessionEntry, deserializeCapturedError, getMeticulousSessionId, headersToRecord, hrTimeToMs, isProvisionalSessionIdCandidate, isSupportedPostgresJsQuery, mintProvisionalSessionId, msToHrTime, postgresJsCommandOf, randomHex, readBodyWithCap, readRequestBodyWithCap, reconstructQueryText, redactRequestBody, redactUrlCredentials, resolveRowMode, serializeCapturedError, serializeKvArgs, serializeKvCaptureFields, serializePostgresJsArgs, serializePostgresJsError, serializePostgresJsResult, serializeSpan, withMeticulous, withMeticulousPagesFunction, withMeticulousPostgres };
|
|
96
|
+
export { CAPTURED_HEADERS, CLIENT_TECHNOLOGY_ATTR, CLIENT_TECHNOLOGY_POSTGRES_JS, CLIENT_TECHNOLOGY_WORKERD_BINDING, CLIENT_TECHNOLOGY_WORKERD_FETCH, CLIENT_TECHNOLOGY_WORKERD_KV, FRONTEND_SESSION_ID_ATTR, FRONTEND_SESSION_ID_HEADER, MAX_BODY_CAPTURE_SIZE, MAX_POSTGRES_JS_RESULT_SIZE, METICULOUS_PASSTHROUGH_HEADER, POSTGRES_JS_ERROR_ATTR, POSTGRES_JS_QUERY_PARAMS_ATTR, POSTGRES_JS_QUERY_TEXT_ATTR, POSTGRES_JS_RESULT_ATTR, POSTGRES_JS_RESULT_TRUNCATED_ATTR, POSTGRES_JS_ROW_MODE_ATTR, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, SERVER_TIMING_HEADER, SERVER_TIMING_SESSION_METRIC, SESSION_ID_ORIGIN_ATTR, SESSION_ID_ORIGIN_BACKEND, SIDECAR_BINDING_ENV_KEY, SIDECAR_BINDING_ORIGIN, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_COVERAGE_PATH, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, SIDECAR_URL_ENV_KEY, SPAN_KIND_CLIENT, SPAN_KIND_INTERNAL, SPAN_KIND_SERVER, SPAN_STATUS_ERROR, SPAN_STATUS_OK, SPAN_STATUS_UNSET, STR_REDACTED, SpanBuilder, WORKERD_BINDING_NAME_ATTR, WORKERD_KV_ARGS_ATTR, WORKERD_KV_ARGS_TRUNCATED_ATTR, WORKERD_KV_KEY_ATTR, WORKERD_KV_OMITTED_ATTR, WORKERD_KV_OPERATION_ATTR, WORKERD_KV_RESULT_ATTR, WORKERD_KV_RESULT_TRUNCATED_ATTR, WORKERD_KV_VALUE_ATTR, WORKERD_KV_VALUE_TRUNCATED_ATTR, WORKERD_SHIM_VERSION, WORKERD_SHIM_VERSION_HEADER, __mcEnter, __mcHit, buildServerTimingSessionEntry, collectHitIds, createCoverageSink, deserializeCapturedError, getCoverageMap, getMeticulousSessionId, getUnreportedCoverageFiles, headersToRecord, hrTimeToMs, isProvisionalSessionIdCandidate, isSupportedPostgresJsQuery, markCoverageFilesReported, mintProvisionalSessionId, msToHrTime, postgresJsCommandOf, randomHex, readBodyWithCap, readRequestBodyWithCap, reconstructQueryText, redactRequestBody, redactUrlCredentials, registerCoverageFile, resolveRowMode, serializeCapturedError, serializeKvArgs, serializeKvCaptureFields, serializePostgresJsArgs, serializePostgresJsError, serializePostgresJsResult, serializeSpan, withMeticulous, withMeticulousPagesFunction, withMeticulousPostgres };
|
|
95
97
|
|
|
96
98
|
//# sourceMappingURL=index.js.map
|
|
97
|
-
//# debugId=
|
|
99
|
+
//# debugId=22e3bcf8-6298-5815-a54c-39716473b677
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { requestCaptureContext } from \"./context\";\nimport {\n type MeticulousExecutionContext,\n runWithMeticulous,\n type WithMeticulousOptions,\n} from \"./with-meticulous\";\n\nexport type {\n BindingRequestEvent,\n CaptureEvent,\n CapturedBody,\n CaptureEventsPayload,\n InboundRequestEvent,\n KvOmittedReason,\n KvOperation,\n KvOperationEvent,\n OutboundFetchLookupRequest,\n OutboundFetchLookupResponse,\n OutboundRequestEvent,\n PostgresQueryEvent,\n ReplaySessionInfoResponse,\n} from \"./protocol\";\nexport {\n CAPTURED_HEADERS,\n FRONTEND_SESSION_ID_HEADER,\n METICULOUS_PASSTHROUGH_HEADER,\n REPLAY_ID_HEADER,\n REPLAY_SIDECAR_URL_HEADER,\n SIDECAR_EVENTS_PATH,\n SIDECAR_PROTOCOL_VERSION,\n SIDECAR_PROTOCOL_VERSION_HEADER,\n SIDECAR_REPLAY_OUTBOUND_FETCH_PATH,\n SIDECAR_REPLAY_SESSION_PATH,\n} from \"./protocol\";\nexport {\n MAX_BODY_CAPTURE_SIZE,\n readBodyWithCap,\n readRequestBodyWithCap,\n} from \"./body-capture\";\nexport { headersToRecord } from \"./outbound-capture\";\nexport { redactRequestBody, STR_REDACTED } from \"./redact-body\";\nexport type { MeticulousExecutionContext, WithMeticulousOptions };\nexport {\n type MeticulousPagesFunction,\n type MeticulousPagesFunctionContext,\n withMeticulousPagesFunction,\n} from \"./pages-function\";\nexport {\n SIDECAR_BINDING_ENV_KEY,\n SIDECAR_BINDING_ORIGIN,\n SIDECAR_URL_ENV_KEY,\n type SidecarFetcher,\n type SidecarTransport,\n} from \"./sidecar-transport\";\n/**\n * Exported for the Node recorder's `withMeticulousCloudflareEnv`, which records the same KV\n * operations from a process whose bindings come from wrangler's `getPlatformProxy`. Both surfaces\n * must produce identical fields, so the contract has exactly one implementation.\n */\nexport {\n type KvCaptureFields,\n type KvCaptureOutcome,\n serializeKvArgs,\n serializeKvCaptureFields,\n} from \"./kv-capture\";\n/**\n * Exported for the same reason: the Node recorder re-exports these so a postgres.js query, a\n * captured error and a built span are byte-identical whichever surface produced them. A\n * Worker-hosted sidecar needs them too, and cannot load the Node bundle.\n */\nexport {\n deserializeCapturedError,\n serializeCapturedError,\n} from \"./error-capture\";\nexport {\n isSupportedPostgresJsQuery,\n MAX_POSTGRES_JS_RESULT_SIZE,\n POSTGRES_JS_ERROR_ATTR,\n POSTGRES_JS_QUERY_PARAMS_ATTR,\n POSTGRES_JS_QUERY_TEXT_ATTR,\n POSTGRES_JS_RESULT_ATTR,\n POSTGRES_JS_RESULT_TRUNCATED_ATTR,\n POSTGRES_JS_ROW_MODE_ATTR,\n postgresJsCommandOf,\n type PostgresJsQueryLike,\n type PostgresJsRowMode,\n reconstructQueryText,\n resolveRowMode,\n serializePostgresJsArgs,\n serializePostgresJsError,\n serializePostgresJsResult,\n} from \"./postgres/capture\";\nexport { withMeticulousPostgres } from \"./postgres/with-meticulous-postgres\";\nexport * from \"./spans/attributes\";\nexport {\n hrTimeToMs,\n msToHrTime,\n type HrTime,\n type ReadableSpan,\n type SerializedSpanBase,\n SPAN_KIND_CLIENT,\n SPAN_KIND_INTERNAL,\n SPAN_KIND_SERVER,\n SPAN_STATUS_ERROR,\n SPAN_STATUS_OK,\n SPAN_STATUS_UNSET,\n type SpanStatus,\n} from \"./spans/readable-span\";\nexport { serializeSpan } from \"./spans/serialize-span\";\nexport { randomHex, SpanBuilder } from \"./spans/span-builder\";\nexport { redactUrlCredentials } from \"./spans/url-redaction\";\n/**\n * Exported for the Node recorder, whose own `provisional-session-id.ts` adapts these to\n * `http.IncomingMessage` / `http.ServerResponse`. The mint format, the rule for which requests\n * get an id and the `Server-Timing` metric are all wire contracts with the page, so — as with\n * the KV capture fields above — they have exactly one implementation.\n */\nexport {\n type HeaderReader,\n SERVER_TIMING_HEADER,\n SERVER_TIMING_SESSION_METRIC,\n buildServerTimingSessionEntry,\n isProvisionalSessionIdCandidate,\n mintProvisionalSessionId,\n} from \"./provisional-session-id\";\n\n/** Structural subset of an ES-module Worker handler (`export default {...}`). */\nexport interface MeticulousWorkerHandler<Env = never> {\n fetch(\n request: Request,\n env: Env,\n ctx: MeticulousExecutionContext,\n ): Response | Promise<Response>;\n}\n\n/**\n * Wraps an ES-module Worker handler so Meticulous can record, or replay, the app's HTTP\n * behaviour:\n *\n * export default withMeticulous({\n * async fetch(request, env, ctx) { ... },\n * });\n *\n * For a Cloudflare Pages project, whose worker exports `onRequest` instead, use\n * {@link withMeticulousPagesFunction} — same behaviour, different handler shape.\n *\n * **Recording** activates on either a `METICULOUS_SIDECAR` service binding (how a **deployed**\n * Worker records: the binding points at a Meticulous recorder sidecar Worker in the same account)\n * or a `METICULOUS_SIDECAR_URL` var (how `wrangler dev` records against a local sidecar process),\n * or the matching `options`. Inbound requests, outgoing `fetch` calls, calls through\n * `fetch`-shaped bindings, KV namespace operations and — with `withMeticulousPostgres` — postgres.js\n * queries are reported to the sidecar, batched into one report per request, without affecting the\n * app. A binding beats a var if both are configured: only the binding can have been added to\n * *this* deployment's wrangler configuration deliberately, whereas a stale `.dev.vars` travels\n * with an image.\n *\n * **Replay** activates on the `x-meticulous-backend-replay-sidecar-url` header, injected by the\n * Meticulous replay runner on requests to the app under test. Outgoing `fetch` calls are then\n * served from the recording instead of reaching the real service — and a call the recording does\n * not cover fails, rather than quietly becoming live traffic; put a `meticulous-passthrough: true`\n * header on a request that must stay real. The clock is frozen at the recorded session's end so\n * recorded credentials are still valid, and `Math.random` / `crypto.randomUUID` /\n * `crypto.getRandomValues` are seeded so ids the app mints are the same in every replay of that\n * session. Workerd cannot read container environment variables, which is why per-replay config\n * arrives as a request header; the shim validates it and only honours a loopback /\n * docker-gateway / private-network `http:` origin.\n *\n * Replay takes precedence over recording when both are configured. A stale sidecar var baked into\n * an image is far more likely than a spurious replay header (nothing but the replay runner emits\n * one), and letting the env win would silently record a replay instead of mocking it.\n *\n * With neither configured the wrapper is a complete pass-through, so it is safe to keep in\n * deployed code. Requires the `nodejs_als` (or `nodejs_compat`) compatibility flag. A capture\n * failure or unreachable sidecar never affects the app.\n */\nexport const withMeticulous = <H extends MeticulousWorkerHandler<never>>(\n handler: H,\n options?: WithMeticulousOptions,\n): H => {\n const wrappedFetch = (\n request: Request,\n env: unknown,\n ctx: MeticulousExecutionContext,\n ): Promise<Response> =>\n runWithMeticulous(\n {\n request,\n env,\n ctx,\n invokeHandler: () => handler.fetch(request, env as never, ctx),\n },\n options,\n );\n\n // The wrapper only replaces `fetch` (same call signature), but TypeScript cannot verify a\n // spread against the bare generic H.\n return { ...handler, fetch: wrappedFetch } as H;\n};\n\n/**\n * The Meticulous session id of the request currently being served, or `undefined` if this\n * call cannot be tied to one — including whenever the wrapper is a pass-through.\n *\n * Exposed so a server-rendering worker can put the id into the HTML it is about to return,\n * typically as `data-session-id` on the recorder's own `<script>` tag. That is the exact,\n * cache-proof alternative to the `Server-Timing` header the shim publishes automatically;\n * doing both is fine, since the recorder prefers the rendered value. It is also how the id\n * reaches another process — a document navigation has no inbound header for the app to\n * forward, so a worker that fans out to its own services has to pass this on as\n * `x-meticulous-session-id` itself.\n *\n * During a replay this returns the replayed session's id, which is the same value the render\n * being replayed was given when it was recorded (the page adopted the minted id, so that is\n * what the recording is stored under, and it is what the replay runner injects back). An app\n * that renders the id therefore renders the same bytes both times, rather than the id turning\n * every server-rendered page into a diff.\n */\nexport const getMeticulousSessionId = (): string | undefined =>\n requestCaptureContext.getStore()?.frontendSessionId;\n"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":["../src/index.ts"],"sourcesContent":["import { requestCaptureContext } from \"./context\";\nimport {\n type MeticulousExecutionContext,\n runWithMeticulous,\n type WithMeticulousOptions,\n} from \"./with-meticulous\";\n\nexport type {\n BindingRequestEvent,\n CaptureEvent,\n CapturedBody,\n CaptureEventsPayload,\n CoverageReportRequest,\n InboundRequestEvent,\n KvOmittedReason,\n KvOperation,\n KvOperationEvent,\n OutboundFetchLookupRequest,\n OutboundFetchLookupResponse,\n OutboundRequestEvent,\n PostgresQueryEvent,\n ReplaySessionInfoResponse,\n} from \"./protocol\";\nexport {\n CAPTURED_HEADERS,\n FRONTEND_SESSION_ID_HEADER,\n METICULOUS_PASSTHROUGH_HEADER,\n REPLAY_ID_HEADER,\n REPLAY_SIDECAR_URL_HEADER,\n SIDECAR_EVENTS_PATH,\n SIDECAR_PROTOCOL_VERSION,\n SIDECAR_PROTOCOL_VERSION_HEADER,\n SIDECAR_REPLAY_COVERAGE_PATH,\n SIDECAR_REPLAY_OUTBOUND_FETCH_PATH,\n SIDECAR_REPLAY_SESSION_PATH,\n WORKERD_SHIM_VERSION_HEADER,\n} from \"./protocol\";\nexport { WORKERD_SHIM_VERSION } from \"./version\";\nexport {\n MAX_BODY_CAPTURE_SIZE,\n readBodyWithCap,\n readRequestBodyWithCap,\n} from \"./body-capture\";\nexport { headersToRecord } from \"./outbound-capture\";\nexport { redactRequestBody, STR_REDACTED } from \"./redact-body\";\nexport type { CoverageMap, CoverageMapFile } from \"./coverage/coverage.types\";\n// __mcEnter / __mcHit are the entry points the Vite plugin's injected imports\n// bind to, so they are part of the package's public surface even though no\n// human writes a call to them.\nexport {\n __mcEnter,\n __mcHit,\n collectHitIds,\n createCoverageSink,\n getCoverageMap,\n getUnreportedCoverageFiles,\n markCoverageFilesReported,\n registerCoverageFile,\n} from \"./coverage/runtime\";\nexport type { MeticulousExecutionContext, WithMeticulousOptions };\nexport {\n type MeticulousPagesFunction,\n type MeticulousPagesFunctionContext,\n withMeticulousPagesFunction,\n} from \"./pages-function\";\nexport {\n SIDECAR_BINDING_ENV_KEY,\n SIDECAR_BINDING_ORIGIN,\n SIDECAR_URL_ENV_KEY,\n type SidecarFetcher,\n type SidecarTransport,\n} from \"./sidecar-transport\";\n/**\n * Exported for the Node recorder's `withMeticulousCloudflareEnv`, which records the same KV\n * operations from a process whose bindings come from wrangler's `getPlatformProxy`. Both surfaces\n * must produce identical fields, so the contract has exactly one implementation.\n */\nexport {\n type KvCaptureFields,\n type KvCaptureOutcome,\n serializeKvArgs,\n serializeKvCaptureFields,\n} from \"./kv-capture\";\n/**\n * Exported for the same reason: the Node recorder re-exports these so a postgres.js query, a\n * captured error and a built span are byte-identical whichever surface produced them. A\n * Worker-hosted sidecar needs them too, and cannot load the Node bundle.\n */\nexport {\n deserializeCapturedError,\n serializeCapturedError,\n} from \"./error-capture\";\nexport {\n isSupportedPostgresJsQuery,\n MAX_POSTGRES_JS_RESULT_SIZE,\n POSTGRES_JS_ERROR_ATTR,\n POSTGRES_JS_QUERY_PARAMS_ATTR,\n POSTGRES_JS_QUERY_TEXT_ATTR,\n POSTGRES_JS_RESULT_ATTR,\n POSTGRES_JS_RESULT_TRUNCATED_ATTR,\n POSTGRES_JS_ROW_MODE_ATTR,\n postgresJsCommandOf,\n type PostgresJsQueryLike,\n type PostgresJsRowMode,\n reconstructQueryText,\n resolveRowMode,\n serializePostgresJsArgs,\n serializePostgresJsError,\n serializePostgresJsResult,\n} from \"./postgres/capture\";\nexport { withMeticulousPostgres } from \"./postgres/with-meticulous-postgres\";\nexport * from \"./spans/attributes\";\nexport {\n hrTimeToMs,\n msToHrTime,\n type HrTime,\n type ReadableSpan,\n type SerializedSpanBase,\n SPAN_KIND_CLIENT,\n SPAN_KIND_INTERNAL,\n SPAN_KIND_SERVER,\n SPAN_STATUS_ERROR,\n SPAN_STATUS_OK,\n SPAN_STATUS_UNSET,\n type SpanStatus,\n} from \"./spans/readable-span\";\nexport { serializeSpan } from \"./spans/serialize-span\";\nexport { randomHex, SpanBuilder } from \"./spans/span-builder\";\nexport { redactUrlCredentials } from \"./spans/url-redaction\";\n/**\n * Exported for the Node recorder, whose own `provisional-session-id.ts` adapts these to\n * `http.IncomingMessage` / `http.ServerResponse`. The mint format, the rule for which requests\n * get an id and the `Server-Timing` metric are all wire contracts with the page, so — as with\n * the KV capture fields above — they have exactly one implementation.\n */\nexport {\n type HeaderReader,\n SERVER_TIMING_HEADER,\n SERVER_TIMING_SESSION_METRIC,\n buildServerTimingSessionEntry,\n isProvisionalSessionIdCandidate,\n mintProvisionalSessionId,\n} from \"./provisional-session-id\";\n\n/** Structural subset of an ES-module Worker handler (`export default {...}`). */\nexport interface MeticulousWorkerHandler<Env = never> {\n fetch(\n request: Request,\n env: Env,\n ctx: MeticulousExecutionContext,\n ): Response | Promise<Response>;\n}\n\n/**\n * Wraps an ES-module Worker handler so Meticulous can record, or replay, the app's HTTP\n * behaviour:\n *\n * export default withMeticulous({\n * async fetch(request, env, ctx) { ... },\n * });\n *\n * For a Cloudflare Pages project, whose worker exports `onRequest` instead, use\n * {@link withMeticulousPagesFunction} — same behaviour, different handler shape.\n *\n * **Recording** activates on either a `METICULOUS_SIDECAR` service binding (how a **deployed**\n * Worker records: the binding points at a Meticulous recorder sidecar Worker in the same account)\n * or a `METICULOUS_SIDECAR_URL` var (how `wrangler dev` records against a local sidecar process),\n * or the matching `options`. Inbound requests, outgoing `fetch` calls, calls through\n * `fetch`-shaped bindings, KV namespace operations and — with `withMeticulousPostgres` — postgres.js\n * queries are reported to the sidecar, batched into one report per request, without affecting the\n * app. A binding beats a var if both are configured: only the binding can have been added to\n * *this* deployment's wrangler configuration deliberately, whereas a stale `.dev.vars` travels\n * with an image.\n *\n * **Replay** activates on the `x-meticulous-backend-replay-sidecar-url` header, injected by the\n * Meticulous replay runner on requests to the app under test. Outgoing `fetch` calls are then\n * served from the recording instead of reaching the real service — and a call the recording does\n * not cover fails, rather than quietly becoming live traffic; put a `meticulous-passthrough: true`\n * header on a request that must stay real. The clock is frozen at the recorded session's end so\n * recorded credentials are still valid, and `Math.random` / `crypto.randomUUID` /\n * `crypto.getRandomValues` are seeded so ids the app mints are the same in every replay of that\n * session. Workerd cannot read container environment variables, which is why per-replay config\n * arrives as a request header; the shim validates it and only honours a loopback /\n * docker-gateway / private-network `http:` origin.\n *\n * Replay takes precedence over recording when both are configured. A stale sidecar var baked into\n * an image is far more likely than a spurious replay header (nothing but the replay runner emits\n * one), and letting the env win would silently record a replay instead of mocking it.\n *\n * With neither configured the wrapper is a complete pass-through, so it is safe to keep in\n * deployed code. Requires the `nodejs_als` (or `nodejs_compat`) compatibility flag. A capture\n * failure or unreachable sidecar never affects the app.\n */\nexport const withMeticulous = <H extends MeticulousWorkerHandler<never>>(\n handler: H,\n options?: WithMeticulousOptions,\n): H => {\n const wrappedFetch = (\n request: Request,\n env: unknown,\n ctx: MeticulousExecutionContext,\n ): Promise<Response> =>\n runWithMeticulous(\n {\n request,\n env,\n ctx,\n invokeHandler: () => handler.fetch(request, env as never, ctx),\n },\n options,\n );\n\n // The wrapper only replaces `fetch` (same call signature), but TypeScript cannot verify a\n // spread against the bare generic H.\n return { ...handler, fetch: wrappedFetch } as H;\n};\n\n/**\n * The Meticulous session id of the request currently being served, or `undefined` if this\n * call cannot be tied to one — including whenever the wrapper is a pass-through.\n *\n * Exposed so a server-rendering worker can put the id into the HTML it is about to return,\n * typically as `data-session-id` on the recorder's own `<script>` tag. That is the exact,\n * cache-proof alternative to the `Server-Timing` header the shim publishes automatically;\n * doing both is fine, since the recorder prefers the rendered value. It is also how the id\n * reaches another process — a document navigation has no inbound header for the app to\n * forward, so a worker that fans out to its own services has to pass this on as\n * `x-meticulous-session-id` itself.\n *\n * During a replay this returns the replayed session's id, which is the same value the render\n * being replayed was given when it was recorded (the page adopted the minted id, so that is\n * what the recording is stored under, and it is what the replay runner injects back). An app\n * that renders the id therefore renders the same bytes both times, rather than the id turning\n * every server-rendered page into a diff.\n */\nexport const getMeticulousSessionId = (): string | undefined =>\n requestCaptureContext.getStore()?.frontendSessionId;\n"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiMA,MAAa,kBACX,SACA,YACM;CACN,MAAM,gBACJ,SACA,KACA,QAEA,kBACE;EACE;EACA;EACA;EACA,qBAAqB,QAAQ,MAAM,SAAS,KAAc,IAAI;EAC/D,EACD,QACD;AAIH,QAAO;EAAE,GAAG;EAAS,OAAO;EAAc;;;;;;;;;;;;;;;;;;;;AAqB5C,MAAa,+BACX,sBAAsB,UAAU,EAAE","debugId":"22e3bcf8-6298-5815-a54c-39716473b677"}
|
package/dist/protocol.d.ts
CHANGED
|
@@ -32,6 +32,14 @@ declare const SIDECAR_EVENTS_PATH = "/v1/events";
|
|
|
32
32
|
*/
|
|
33
33
|
declare const SIDECAR_REPLAY_SESSION_PATH = "/v1/replay/session";
|
|
34
34
|
declare const SIDECAR_REPLAY_OUTBOUND_FETCH_PATH = "/v1/replay/outbound-fetch";
|
|
35
|
+
/**
|
|
36
|
+
* Line-coverage reporting. Additive: an older sidecar answers 404, which the
|
|
37
|
+
* shim treats as "coverage not collected here" and stops reporting for the life
|
|
38
|
+
* of the isolate. Deliberately NOT guarded by a
|
|
39
|
+
* {@link SIDECAR_PROTOCOL_VERSION} bump — that check is exact equality, so a
|
|
40
|
+
* bump would stop every already-built customer image from mocking at all.
|
|
41
|
+
*/
|
|
42
|
+
declare const SIDECAR_REPLAY_COVERAGE_PATH = "/v1/replay/coverage";
|
|
35
43
|
/**
|
|
36
44
|
* Header carrying the replay sidecar's origin, injected by the Meticulous replay runner
|
|
37
45
|
* on requests to the app under test. Workerd cannot see container environment variables,
|
|
@@ -41,6 +49,14 @@ declare const SIDECAR_REPLAY_OUTBOUND_FETCH_PATH = "/v1/replay/outbound-fetch";
|
|
|
41
49
|
* `host.docker.internal` / private-network `http:` origin — see `replay-sidecar-url.ts`.
|
|
42
50
|
*/
|
|
43
51
|
declare const REPLAY_SIDECAR_URL_HEADER = "x-meticulous-backend-replay-sidecar-url";
|
|
52
|
+
/**
|
|
53
|
+
* Header the in-worker shim stamps on every app response (record and replay)
|
|
54
|
+
* carrying the shim's npm package version. The replay runner reads this from
|
|
55
|
+
* Puppeteer — workerd cannot see container env, and the execute pod cannot
|
|
56
|
+
* reach the in-pod sidecar, so a response header is the only channel that
|
|
57
|
+
* reports which bundled shim produced a replay's After screenshots.
|
|
58
|
+
*/
|
|
59
|
+
declare const WORKERD_SHIM_VERSION_HEADER = "x-meticulous-workerd-shim-version";
|
|
44
60
|
/**
|
|
45
61
|
* The only headers persisted on capture events. Everything else — notably
|
|
46
62
|
* authorization, cookie/set-cookie, and API-key headers — is dropped at
|
|
@@ -244,6 +260,25 @@ interface ReplaySessionInfoResponse {
|
|
|
244
260
|
*/
|
|
245
261
|
clockAnchorMs?: number;
|
|
246
262
|
}
|
|
263
|
+
/**
|
|
264
|
+
* One request's line coverage, sent to {@link SIDECAR_REPLAY_COVERAGE_PATH}
|
|
265
|
+
* after the response has been produced.
|
|
266
|
+
*
|
|
267
|
+
* `files` carries the build-time id→line map and is sent only on the first
|
|
268
|
+
* report of an isolate: it is the same for every request the isolate serves and
|
|
269
|
+
* is far larger than the hits themselves.
|
|
270
|
+
*/
|
|
271
|
+
interface CoverageReportRequest {
|
|
272
|
+
frontendSessionId: string;
|
|
273
|
+
/** Global line ids marked during this request, ascending. */
|
|
274
|
+
hitIds: number[];
|
|
275
|
+
/** Present on an isolate's first report only. */
|
|
276
|
+
files?: Array<{
|
|
277
|
+
path: string;
|
|
278
|
+
firstId: number; /** Inclusive 1-based line ranges, flattened as `[s1, e1, s2, e2, ...]`. */
|
|
279
|
+
lineRanges: number[];
|
|
280
|
+
}>;
|
|
281
|
+
}
|
|
247
282
|
/** Lookup for a single outbound `fetch`, sent to {@link SIDECAR_REPLAY_OUTBOUND_FETCH_PATH}. */
|
|
248
283
|
interface OutboundFetchLookupRequest {
|
|
249
284
|
frontendSessionId: string;
|
|
@@ -281,5 +316,5 @@ type OutboundFetchLookupResponse = {
|
|
|
281
316
|
outcome: "no-mock";
|
|
282
317
|
};
|
|
283
318
|
//#endregion
|
|
284
|
-
export { BindingRequestEvent, CAPTURED_HEADERS, CaptureEvent, CaptureEventsPayload, CapturedBody, FRONTEND_SESSION_ID_HEADER, InboundRequestEvent, KvOmittedReason, KvOperation, KvOperationEvent, METICULOUS_PASSTHROUGH_HEADER, OutboundFetchLookupRequest, OutboundFetchLookupResponse, OutboundRequestEvent, PostgresQueryEvent, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, ReplaySessionInfoResponse, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH };
|
|
319
|
+
export { BindingRequestEvent, CAPTURED_HEADERS, CaptureEvent, CaptureEventsPayload, CapturedBody, CoverageReportRequest, FRONTEND_SESSION_ID_HEADER, InboundRequestEvent, KvOmittedReason, KvOperation, KvOperationEvent, METICULOUS_PASSTHROUGH_HEADER, OutboundFetchLookupRequest, OutboundFetchLookupResponse, OutboundRequestEvent, PostgresQueryEvent, REPLAY_ID_HEADER, REPLAY_SIDECAR_URL_HEADER, ReplaySessionInfoResponse, SIDECAR_EVENTS_PATH, SIDECAR_PROTOCOL_VERSION, SIDECAR_PROTOCOL_VERSION_HEADER, SIDECAR_REPLAY_COVERAGE_PATH, SIDECAR_REPLAY_OUTBOUND_FETCH_PATH, SIDECAR_REPLAY_SESSION_PATH, WORKERD_SHIM_VERSION_HEADER };
|
|
285
320
|
//# sourceMappingURL=protocol.d.ts.map
|