@enricai/barnacle 1.6.12 → 1.6.14
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 +113 -9
- package/dist/api/schemas/submissions.d.ts +14 -0
- package/dist/api/schemas/submissions.d.ts.map +1 -1
- package/dist/api/schemas/submissions.js +1 -0
- package/dist/api/schemas/submissions.js.map +1 -1
- package/dist/config.d.ts +33 -0
- package/dist/config.d.ts.map +1 -1
- package/dist/config.js +4 -0
- package/dist/config.js.map +1 -1
- package/dist/lib/bedrock.d.ts +8 -5
- package/dist/lib/bedrock.d.ts.map +1 -1
- package/dist/lib/bedrock.js +8 -5
- package/dist/lib/bedrock.js.map +1 -1
- package/dist/lib/http.d.ts +4 -3
- package/dist/lib/http.d.ts.map +1 -1
- package/dist/lib/http.js +25 -3
- package/dist/lib/http.js.map +1 -1
- package/dist/lib/telemetry/beacon-capture.d.ts +45 -2
- package/dist/lib/telemetry/beacon-capture.d.ts.map +1 -1
- package/dist/lib/telemetry/beacon-capture.js +36 -0
- package/dist/lib/telemetry/beacon-capture.js.map +1 -1
- package/dist/lib/telemetry/reconciliation-record.d.ts +41 -1
- package/dist/lib/telemetry/reconciliation-record.d.ts.map +1 -1
- package/dist/lib/telemetry/reconciliation-record.js +29 -2
- package/dist/lib/telemetry/reconciliation-record.js.map +1 -1
- package/dist/lib/telemetry/reconciliation-source.d.ts +7 -1
- package/dist/lib/telemetry/reconciliation-source.d.ts.map +1 -1
- package/dist/lib/telemetry/reconciliation-source.js +21 -5
- package/dist/lib/telemetry/reconciliation-source.js.map +1 -1
- package/dist/lib/telemetry/run-telemetry.d.ts +67 -0
- package/dist/lib/telemetry/run-telemetry.d.ts.map +1 -0
- package/dist/lib/telemetry/run-telemetry.js +55 -0
- package/dist/lib/telemetry/run-telemetry.js.map +1 -0
- package/dist/lib/telemetry/submission-capture.d.ts +11 -4
- package/dist/lib/telemetry/submission-capture.d.ts.map +1 -1
- package/dist/lib/telemetry/submission-capture.js +1 -0
- package/dist/lib/telemetry/submission-capture.js.map +1 -1
- package/dist/lib/telemetry/submission-reader.d.ts +11 -3
- package/dist/lib/telemetry/submission-reader.d.ts.map +1 -1
- package/dist/lib/telemetry/submission-reader.js +32 -8
- package/dist/lib/telemetry/submission-reader.js.map +1 -1
- package/dist/lib/tracking-click.d.ts.map +1 -1
- package/dist/lib/tracking-click.js +19 -0
- package/dist/lib/tracking-click.js.map +1 -1
- package/dist/plugins/config-plugin.js +3 -3
- package/dist/plugins/loader.d.ts +20 -0
- package/dist/plugins/loader.d.ts.map +1 -1
- package/dist/plugins/loader.js +94 -17
- package/dist/plugins/loader.js.map +1 -1
- package/dist/scraper/deep-locator-actuate.d.ts +94 -0
- package/dist/scraper/deep-locator-actuate.d.ts.map +1 -0
- package/dist/scraper/deep-locator-actuate.js +216 -0
- package/dist/scraper/deep-locator-actuate.js.map +1 -0
- package/dist/scraper/deep-locator-candidates.d.ts +105 -18
- package/dist/scraper/deep-locator-candidates.d.ts.map +1 -1
- package/dist/scraper/deep-locator-candidates.js +238 -46
- package/dist/scraper/deep-locator-candidates.js.map +1 -1
- package/dist/scraper/deep-locator-click.d.ts +71 -0
- package/dist/scraper/deep-locator-click.d.ts.map +1 -0
- package/dist/scraper/deep-locator-click.js +71 -0
- package/dist/scraper/deep-locator-click.js.map +1 -0
- package/dist/scraper/deep-locator-fake.d.ts +344 -14
- package/dist/scraper/deep-locator-fake.d.ts.map +1 -1
- package/dist/scraper/deep-locator-fake.js +509 -7
- package/dist/scraper/deep-locator-fake.js.map +1 -1
- package/dist/scraper/deep-locator-scan.d.ts +220 -0
- package/dist/scraper/deep-locator-scan.d.ts.map +1 -0
- package/dist/scraper/deep-locator-scan.js +386 -0
- package/dist/scraper/deep-locator-scan.js.map +1 -0
- package/dist/scraper/fake-timer-advance.d.ts +47 -0
- package/dist/scraper/fake-timer-advance.d.ts.map +1 -0
- package/dist/scraper/fake-timer-advance.js +44 -0
- package/dist/scraper/fake-timer-advance.js.map +1 -0
- package/dist/scraper/flow-runner.d.ts +80 -9
- package/dist/scraper/flow-runner.d.ts.map +1 -1
- package/dist/scraper/flow-runner.js +417 -63
- package/dist/scraper/flow-runner.js.map +1 -1
- package/dist/scraper/frame-target.d.ts +28 -0
- package/dist/scraper/frame-target.d.ts.map +1 -1
- package/dist/scraper/frame-target.js +30 -0
- package/dist/scraper/frame-target.js.map +1 -1
- package/dist/scraper/session-browserbase.d.ts +13 -0
- package/dist/scraper/session-browserbase.d.ts.map +1 -1
- package/dist/scraper/session-browserbase.js +29 -0
- package/dist/scraper/session-browserbase.js.map +1 -1
- package/dist/scraper/session-ip.d.ts +69 -0
- package/dist/scraper/session-ip.d.ts.map +1 -0
- package/dist/scraper/session-ip.js +88 -0
- package/dist/scraper/session-ip.js.map +1 -0
- package/dist/scraper/session-shared.d.ts +9 -0
- package/dist/scraper/session-shared.d.ts.map +1 -1
- package/dist/scraper/session-shared.js.map +1 -1
- package/dist/scraper/submit-control.d.ts +14 -2
- package/dist/scraper/submit-control.d.ts.map +1 -1
- package/dist/scraper/submit-control.js +33 -2
- package/dist/scraper/submit-control.js.map +1 -1
- package/dist/scripts/recon-browser.d.ts +1 -1
- package/dist/scripts/recon-browser.d.ts.map +1 -1
- package/dist/scripts/recon-browser.js +48 -16
- package/dist/scripts/recon-browser.js.map +1 -1
- package/dist/scripts/recon-generate.js +3 -3
- package/dist/scripts/recon-generate.js.map +1 -1
- package/dist/site-plugin.d.ts +20 -0
- package/dist/site-plugin.d.ts.map +1 -1
- package/dist/testing/integration-runner.d.ts.map +1 -1
- package/dist/testing/integration-runner.js +6 -7
- package/dist/testing/integration-runner.js.map +1 -1
- package/package.json +3 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"beacon-capture.js","sourceRoot":"","sources":["../../../src/lib/telemetry/beacon-capture.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"beacon-capture.js","sourceRoot":"","sources":["../../../src/lib/telemetry/beacon-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;GAiBG;;;;AAEH,uCAAqC;AAGrC,qCAAkC;AAClC,2CAA0C;AAE1C,2EAA8E;AAE9E,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,0BAA0B,EAAE,CAAC,CAAC;AAE/D,MAAM,uBAAuB,GAAG,GAAG,CAAC;AAqBpC;;;;;;GAMG;AACI,KAAK,6BACV,KAAuB,EACvB,IAAI,GAA8B,EAAE;IAEpC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC;IACzE,MAAM,MAAM,GAAsB;QAChC,GAAG,KAAK;QACR,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,KAAK,CAAC,WAAW,EAAE,KAAK,CAAC,CAAC,EAAE,uBAAuB,CAAC,IAAI,IAAI;QACzE,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,IAAI;QAClC,EAAE,EAAE,IAAA,oBAAS,EAAC,IAAI,IAAI,EAAE,CAAC;KAC1B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;QAC3C,MAAM,IAAA,6CAAwB,EAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,0CAA0C,QAAQ,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IACrF,CAAC;AACH,CAAC;AA6BD;;;;;;;;;;;;GAYG;AACH,qCACE,OAAqC;IAErC,OAAO,KAAK,EAAE,KAAK,EAAE,IAAI,GAAG,EAAE,EAAE,EAAE;QAChC,IAAI,CAAC;YACH,MAAM,kBAAkB,CACtB;gBACE,SAAS,EAAE,OAAO,CAAC,SAAS;gBAC5B,MAAM,EAAE,OAAO,CAAC,MAAM;gBACtB,QAAQ,EAAE,KAAK,CAAC,QAAQ;gBACxB,YAAY,EAAE,KAAK,CAAC,YAAY;gBAChC,WAAW,EAAE,KAAK,CAAC,WAAW,IAAI,IAAI;gBACtC,UAAU,EAAE,KAAK,CAAC,UAAU,IAAI,CAAC;aAClC,EACD,IAAI,CACL,CAAC;QACJ,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,CAAC,KAAK,CAAC,gDAAgD,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAC9E,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
|
|
@@ -24,8 +24,30 @@
|
|
|
24
24
|
* top-level keys, and a plain `z.object()` silently drops unrecognized
|
|
25
25
|
* keys — reading an old line through the new schema would otherwise lose
|
|
26
26
|
* its join keys rather than surface them.
|
|
27
|
+
*
|
|
28
|
+
* `session` (on `submitRecordSchema`) and `sessionIp` (on `beaconEventSchema`)
|
|
29
|
+
* carry the Browserbase session's identity and outbound IP so it's durable
|
|
30
|
+
* per-run telemetry rather than only a log line — every plugin acquires its
|
|
31
|
+
* session the same engine-owned way, so this lands here rather than
|
|
32
|
+
* per-plugin. Both are nullable-with-default for the same reason `joinKeys`
|
|
33
|
+
* is: millions of already-shipped NDJSON lines (and their S3 mirror) never
|
|
34
|
+
* carried these fields and must keep parsing.
|
|
27
35
|
*/
|
|
28
36
|
import { z } from "zod/v4";
|
|
37
|
+
/**
|
|
38
|
+
* The Browserbase session identity and outbound IP a plugin's run used.
|
|
39
|
+
* `ip`/`ipCapturedAt` are nullable independently of `id`/`provider` because
|
|
40
|
+
* the IP is only known after a separate in-session IP-echo navigation, which
|
|
41
|
+
* may never resolve (a disabled capture, a provider with no IP accessor, a
|
|
42
|
+
* timeout) even when the session itself was acquired successfully.
|
|
43
|
+
*/
|
|
44
|
+
export declare const sessionTelemetrySchema: z.ZodObject<{
|
|
45
|
+
id: z.ZodString;
|
|
46
|
+
provider: z.ZodString;
|
|
47
|
+
ip: z.ZodNullable<z.ZodString>;
|
|
48
|
+
ipCapturedAt: z.ZodNullable<z.ZodString>;
|
|
49
|
+
}, z.core.$strip>;
|
|
50
|
+
export type SessionTelemetry = z.infer<typeof sessionTelemetrySchema>;
|
|
29
51
|
/**
|
|
30
52
|
* Submit-side record: the existing submission envelope shape plus an opaque
|
|
31
53
|
* `joinKeys` bag. Nullable-with-default so pre-existing lines that never
|
|
@@ -36,6 +58,12 @@ export declare const submitRecordSchema: z.ZodObject<{
|
|
|
36
58
|
siteId: z.ZodString;
|
|
37
59
|
requestId: z.ZodString;
|
|
38
60
|
joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
61
|
+
session: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
62
|
+
id: z.ZodString;
|
|
63
|
+
provider: z.ZodString;
|
|
64
|
+
ip: z.ZodNullable<z.ZodString>;
|
|
65
|
+
ipCapturedAt: z.ZodNullable<z.ZodString>;
|
|
66
|
+
}, z.core.$strip>>>;
|
|
39
67
|
inboundPayload: z.ZodUnknown;
|
|
40
68
|
status: z.ZodEnum<{
|
|
41
69
|
error: "error";
|
|
@@ -56,7 +84,11 @@ export type SubmitRecord = z.infer<typeof submitRecordSchema>;
|
|
|
56
84
|
* `dispatch()` in `src/plugins/loader.ts`) — distinct from `"not_fired"`
|
|
57
85
|
* (the reader's fold default for a submit row with no matching beacon line
|
|
58
86
|
* at all), so "submitted but the beacon did not fire" excludes runs that
|
|
59
|
-
* never had a beacon to fire.
|
|
87
|
+
* never had a beacon to fire. `"skipped"` is not necessarily terminal for a
|
|
88
|
+
* self-managing plugin: if that plugin later records its own real `fired`/
|
|
89
|
+
* `failed` line for the same `requestId`, `foldReconciliationRecords` in
|
|
90
|
+
* `submission-reader.ts` ranks the real outcome above `"skipped"` and folds
|
|
91
|
+
* to that outcome regardless of which line was written first.
|
|
60
92
|
*/
|
|
61
93
|
export declare const beaconEventSchema: z.ZodObject<{
|
|
62
94
|
kind: z.ZodLiteral<"beacon">;
|
|
@@ -71,6 +103,7 @@ export declare const beaconEventSchema: z.ZodObject<{
|
|
|
71
103
|
trackingUrl: z.ZodNullable<z.ZodString>;
|
|
72
104
|
durationMs: z.ZodNumber;
|
|
73
105
|
ts: z.ZodString;
|
|
106
|
+
sessionIp: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
74
107
|
}, z.core.$strip>;
|
|
75
108
|
export type BeaconEvent = z.infer<typeof beaconEventSchema>;
|
|
76
109
|
/**
|
|
@@ -86,6 +119,12 @@ export declare const reconciliationRecordSchema: z.ZodPipe<z.ZodTransform<unknow
|
|
|
86
119
|
siteId: z.ZodString;
|
|
87
120
|
requestId: z.ZodString;
|
|
88
121
|
joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
122
|
+
session: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
123
|
+
id: z.ZodString;
|
|
124
|
+
provider: z.ZodString;
|
|
125
|
+
ip: z.ZodNullable<z.ZodString>;
|
|
126
|
+
ipCapturedAt: z.ZodNullable<z.ZodString>;
|
|
127
|
+
}, z.core.$strip>>>;
|
|
89
128
|
inboundPayload: z.ZodUnknown;
|
|
90
129
|
status: z.ZodEnum<{
|
|
91
130
|
error: "error";
|
|
@@ -108,6 +147,7 @@ export declare const reconciliationRecordSchema: z.ZodPipe<z.ZodTransform<unknow
|
|
|
108
147
|
trackingUrl: z.ZodNullable<z.ZodString>;
|
|
109
148
|
durationMs: z.ZodNumber;
|
|
110
149
|
ts: z.ZodString;
|
|
150
|
+
sessionIp: z.ZodDefault<z.ZodNullable<z.ZodString>>;
|
|
111
151
|
}, z.core.$strip>]>>;
|
|
112
152
|
export type ReconciliationRecord = z.infer<typeof reconciliationRecordSchema>;
|
|
113
153
|
//# sourceMappingURL=reconciliation-record.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciliation-record.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-record.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reconciliation-record.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-record.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B;;;;;;GAMG;AACH,eAAO,MAAM,sBAAsB;;;;;iBAKjC,CAAC;AAEH,MAAM,MAAM,gBAAgB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,sBAAsB,CAAC,CAAC;AAEtE;;;;GAIG;AACH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;iBAY7B,CAAC;AAEH,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAE9D;;;;;;;;;;;;;;GAcG;AACH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;iBAU5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAsB5D;;;;;;;GAOG;AACH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;oBAOtC,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC"}
|
|
@@ -25,10 +25,31 @@
|
|
|
25
25
|
* top-level keys, and a plain `z.object()` silently drops unrecognized
|
|
26
26
|
* keys — reading an old line through the new schema would otherwise lose
|
|
27
27
|
* its join keys rather than surface them.
|
|
28
|
+
*
|
|
29
|
+
* `session` (on `submitRecordSchema`) and `sessionIp` (on `beaconEventSchema`)
|
|
30
|
+
* carry the Browserbase session's identity and outbound IP so it's durable
|
|
31
|
+
* per-run telemetry rather than only a log line — every plugin acquires its
|
|
32
|
+
* session the same engine-owned way, so this lands here rather than
|
|
33
|
+
* per-plugin. Both are nullable-with-default for the same reason `joinKeys`
|
|
34
|
+
* is: millions of already-shipped NDJSON lines (and their S3 mirror) never
|
|
35
|
+
* carried these fields and must keep parsing.
|
|
28
36
|
*/
|
|
29
37
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
30
|
-
exports.reconciliationRecordSchema = exports.beaconEventSchema = exports.submitRecordSchema = void 0;
|
|
38
|
+
exports.reconciliationRecordSchema = exports.beaconEventSchema = exports.submitRecordSchema = exports.sessionTelemetrySchema = void 0;
|
|
31
39
|
const v4_1 = require("zod/v4");
|
|
40
|
+
/**
|
|
41
|
+
* The Browserbase session identity and outbound IP a plugin's run used.
|
|
42
|
+
* `ip`/`ipCapturedAt` are nullable independently of `id`/`provider` because
|
|
43
|
+
* the IP is only known after a separate in-session IP-echo navigation, which
|
|
44
|
+
* may never resolve (a disabled capture, a provider with no IP accessor, a
|
|
45
|
+
* timeout) even when the session itself was acquired successfully.
|
|
46
|
+
*/
|
|
47
|
+
exports.sessionTelemetrySchema = v4_1.z.object({
|
|
48
|
+
id: v4_1.z.string(),
|
|
49
|
+
provider: v4_1.z.string(),
|
|
50
|
+
ip: v4_1.z.string().nullable(),
|
|
51
|
+
ipCapturedAt: v4_1.z.string().nullable(),
|
|
52
|
+
});
|
|
32
53
|
/**
|
|
33
54
|
* Submit-side record: the existing submission envelope shape plus an opaque
|
|
34
55
|
* `joinKeys` bag. Nullable-with-default so pre-existing lines that never
|
|
@@ -39,6 +60,7 @@ exports.submitRecordSchema = v4_1.z.object({
|
|
|
39
60
|
siteId: v4_1.z.string(),
|
|
40
61
|
requestId: v4_1.z.string(),
|
|
41
62
|
joinKeys: v4_1.z.record(v4_1.z.string(), v4_1.z.unknown()).nullable().default(null),
|
|
63
|
+
session: exports.sessionTelemetrySchema.nullable().default(null),
|
|
42
64
|
inboundPayload: v4_1.z.unknown(),
|
|
43
65
|
status: v4_1.z.enum(["submitted", "error"]),
|
|
44
66
|
auditPayload: v4_1.z.unknown(),
|
|
@@ -55,7 +77,11 @@ exports.submitRecordSchema = v4_1.z.object({
|
|
|
55
77
|
* `dispatch()` in `src/plugins/loader.ts`) — distinct from `"not_fired"`
|
|
56
78
|
* (the reader's fold default for a submit row with no matching beacon line
|
|
57
79
|
* at all), so "submitted but the beacon did not fire" excludes runs that
|
|
58
|
-
* never had a beacon to fire.
|
|
80
|
+
* never had a beacon to fire. `"skipped"` is not necessarily terminal for a
|
|
81
|
+
* self-managing plugin: if that plugin later records its own real `fired`/
|
|
82
|
+
* `failed` line for the same `requestId`, `foldReconciliationRecords` in
|
|
83
|
+
* `submission-reader.ts` ranks the real outcome above `"skipped"` and folds
|
|
84
|
+
* to that outcome regardless of which line was written first.
|
|
59
85
|
*/
|
|
60
86
|
exports.beaconEventSchema = v4_1.z.object({
|
|
61
87
|
kind: v4_1.z.literal("beacon"),
|
|
@@ -66,6 +92,7 @@ exports.beaconEventSchema = v4_1.z.object({
|
|
|
66
92
|
trackingUrl: v4_1.z.string().nullable(),
|
|
67
93
|
durationMs: v4_1.z.number(),
|
|
68
94
|
ts: v4_1.z.string(),
|
|
95
|
+
sessionIp: v4_1.z.string().nullable().default(null),
|
|
69
96
|
});
|
|
70
97
|
/**
|
|
71
98
|
* Folds a legacy top-level `vivclid`/`jobReference` shape into `joinKeys`
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciliation-record.js","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-record.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"reconciliation-record.js","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-record.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,7 +13,13 @@
|
|
|
13
13
|
* every event (`appendSubmissionSinkLine` writes to disk and buffers to S3
|
|
14
14
|
* in the same call), so an overlap between the two stores is an exact JSON
|
|
15
15
|
* duplicate, never a conflicting value — deduping on `kind:requestId:ts` is
|
|
16
|
-
*
|
|
16
|
+
* lossless for that mirror case. But `ts` is formatISO second-precision, so
|
|
17
|
+
* two *distinct* beacon lines for the same `requestId` (e.g. dispatch's
|
|
18
|
+
* automatic `skipped` line and a plugin's later self-recorded `fired` line)
|
|
19
|
+
* can land in the same wall-clock second — the dedupe key for beacon
|
|
20
|
+
* records also folds in `beaconStatus` and `trackingUrl` so non-identical
|
|
21
|
+
* beacon outcomes never collide, while submit records keep the plain
|
|
22
|
+
* `kind:requestId:ts` key.
|
|
17
23
|
*/
|
|
18
24
|
import { type ReconciliationRow } from "../../lib/telemetry/submission-reader";
|
|
19
25
|
import { type ListSubmissionsS3ObjectsOptions } from "../../lib/telemetry/submissions-s3-objects";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciliation-source.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-source.ts"],"names":[],"mappings":"AAAA
|
|
1
|
+
{"version":3,"file":"reconciliation-source.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-source.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AASH,OAAO,EAGL,KAAK,iBAAiB,EACvB,MAAM,mCAAmC,CAAC;AAC3C,OAAO,EACL,KAAK,+BAA+B,EAErC,MAAM,wCAAwC,CAAC;AAKhD,mDAAmD;AACnD,MAAM,WAAW,oCAAqC,SAAQ,+BAA+B;IAC3F,mFAAmF;IACnF,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAkED;;;;;;GAMG;AACH,wBAAsB,6BAA6B,CACjD,IAAI,GAAE,oCAAyC,GAC9C,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAS9B"}
|
|
@@ -14,7 +14,13 @@
|
|
|
14
14
|
* every event (`appendSubmissionSinkLine` writes to disk and buffers to S3
|
|
15
15
|
* in the same call), so an overlap between the two stores is an exact JSON
|
|
16
16
|
* duplicate, never a conflicting value — deduping on `kind:requestId:ts` is
|
|
17
|
-
*
|
|
17
|
+
* lossless for that mirror case. But `ts` is formatISO second-precision, so
|
|
18
|
+
* two *distinct* beacon lines for the same `requestId` (e.g. dispatch's
|
|
19
|
+
* automatic `skipped` line and a plugin's later self-recorded `fired` line)
|
|
20
|
+
* can land in the same wall-clock second — the dedupe key for beacon
|
|
21
|
+
* records also folds in `beaconStatus` and `trackingUrl` so non-identical
|
|
22
|
+
* beacon outcomes never collide, while submit records keep the plain
|
|
23
|
+
* `kind:requestId:ts` key.
|
|
18
24
|
*/
|
|
19
25
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
20
26
|
exports.readDurableReconciliationRows = readDurableReconciliationRows;
|
|
@@ -57,14 +63,24 @@ async function readS3Records(opts) {
|
|
|
57
63
|
return [];
|
|
58
64
|
}
|
|
59
65
|
}
|
|
60
|
-
/**
|
|
66
|
+
/**
|
|
67
|
+
* Dedupe key for a raw record: the same line written to both stores
|
|
68
|
+
* collapses to one. Beacon records also key on `beaconStatus` and
|
|
69
|
+
* `trackingUrl` — `ts` alone is second-precision, so a `skipped` line and a
|
|
70
|
+
* later `fired`/`failed` line for the same `requestId` can share a `ts` and
|
|
71
|
+
* must not be treated as the same line.
|
|
72
|
+
*/
|
|
61
73
|
function dedupeKey(record) {
|
|
74
|
+
if (record.kind === "beacon") {
|
|
75
|
+
return `${record.kind}:${record.requestId}:${record.ts}:${record.beaconStatus}:${record.trackingUrl ?? ""}`;
|
|
76
|
+
}
|
|
62
77
|
return `${record.kind}:${record.requestId}:${record.ts}`;
|
|
63
78
|
}
|
|
64
79
|
/**
|
|
65
|
-
* Unions the two record sets, local first, and dedupes
|
|
66
|
-
*
|
|
67
|
-
*
|
|
80
|
+
* Unions the two record sets, local first, and dedupes with `dedupeKey` —
|
|
81
|
+
* the same line written to both stores collapses to one entry, so
|
|
82
|
+
* `foldReconciliationRecords` sees it exactly once, while distinct beacon
|
|
83
|
+
* outcomes sharing a `requestId`/`ts` both survive.
|
|
68
84
|
*/
|
|
69
85
|
function mergeRecords(localRecords, s3Records) {
|
|
70
86
|
const deduped = new Map();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"reconciliation-source.js","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-source.ts"],"names":[],"mappings":";AAAA
|
|
1
|
+
{"version":3,"file":"reconciliation-source.js","sourceRoot":"","sources":["../../../src/lib/telemetry/reconciliation-source.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;;AAEH,qCAAqC;AACrC,+CAA4C;AAE5C,qCAAkC;AAClC,yCAA8C;AAC9C,2CAA0C;AAE1C,yEAI2C;AAC3C,mFAGgD;AAChD,iFAAkF;AAElF,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,iCAAiC,EAAE,CAAC,CAAC;AAQtE;;;;;GAKG;AACH,KAAK,UAAU,gBAAgB,CAAC,QAAgB;IAC9C,IAAI,CAAC,IAAA,oBAAU,EAAC,QAAQ,CAAC;QAAE,OAAO,EAAE,CAAC;IACrC,MAAM,OAAO,GAAG,MAAM,IAAA,mBAAQ,EAAC,QAAQ,EAAE,MAAM,CAAC,CAAC;IACjD,OAAO,IAAA,4CAAwB,EAAC,OAAO,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,KAAK,UAAU,aAAa,CAC1B,IAAqC;IAErC,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,MAAM,IAAA,iDAAwB,EAAC,IAAI,CAAC,CAAC;QAClD,IAAI,IAAI,CAAC,MAAM,KAAK,CAAC;YAAE,OAAO,EAAE,CAAC;QACjC,OAAO,MAAM,IAAA,iDAAyB,EAAC,IAAI,CAAC,CAAC;IAC/C,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,IAAI,CACT,2EAA2E,IAAA,uBAAc,EAAC,GAAG,CAAC,EAAE,CACjG,CAAC;QACF,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,SAAS,SAAS,CAAC,MAA4B;IAC7C,IAAI,MAAM,CAAC,IAAI,KAAK,QAAQ,EAAE,CAAC;QAC7B,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,EAAE,IAAI,MAAM,CAAC,YAAY,IAAI,MAAM,CAAC,WAAW,IAAI,EAAE,EAAE,CAAC;IAC9G,CAAC;IACD,OAAO,GAAG,MAAM,CAAC,IAAI,IAAI,MAAM,CAAC,SAAS,IAAI,MAAM,CAAC,EAAE,EAAE,CAAC;AAC3D,CAAC;AAED;;;;;GAKG;AACH,SAAS,YAAY,CACnB,YAAoC,EACpC,SAAiC;IAEjC,MAAM,OAAO,GAAG,IAAI,GAAG,EAAgC,CAAC;IACxD,KAAK,MAAM,MAAM,IAAI,CAAC,GAAG,YAAY,EAAE,GAAG,SAAS,CAAC,EAAE,CAAC;QACrD,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC,CAAC;IACzC,CAAC;IACD,OAAO,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC;AACtC,CAAC;AAED;;;;;;GAMG;AACI,KAAK,wCACV,IAAI,GAAyC,EAAE;IAE/C,MAAM,EAAE,QAAQ,GAAG,eAAM,CAAC,SAAS,CAAC,qBAAqB,EAAE,GAAG,UAAU,EAAE,GAAG,IAAI,CAAC;IAElF,MAAM,CAAC,YAAY,EAAE,SAAS,CAAC,GAAG,MAAM,OAAO,CAAC,GAAG,CAAC;QAClD,gBAAgB,CAAC,QAAQ,CAAC;QAC1B,aAAa,CAAC,UAAU,CAAC;KAC1B,CAAC,CAAC;IAEH,OAAO,IAAA,6CAAyB,EAAC,YAAY,CAAC,YAAY,EAAE,SAAS,CAAC,CAAC,CAAC;AAC1E,CAAC"}
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Run-scoped, mutable telemetry accumulator that a plugin can write
|
|
3
|
+
* discovered fields into at any point during execute()/executeHttp() —
|
|
4
|
+
* mirrors `MetricsCollector` (src/lib/dispatch-metrics.ts) as a per-request
|
|
5
|
+
* instance meant to be threaded through the plugin context, but for
|
|
6
|
+
* run-discovered data (join keys, session info) rather than step timings.
|
|
7
|
+
* Funnels everything a plugin discovers mid-run into the same opaque
|
|
8
|
+
* `joinKeys` bag already documented in `reconciliation-record.ts`, rather
|
|
9
|
+
* than inventing a second bag.
|
|
10
|
+
*/
|
|
11
|
+
/** Browserbase session identity/network facts recorded once per run. */
|
|
12
|
+
export interface SessionTelemetry {
|
|
13
|
+
sessionId: string;
|
|
14
|
+
provider: string;
|
|
15
|
+
ip: string | null;
|
|
16
|
+
ipCapturedAt: string | null;
|
|
17
|
+
}
|
|
18
|
+
/** Point-in-time view of everything accumulated on a `RunTelemetry` instance. */
|
|
19
|
+
export interface RunTelemetrySnapshot {
|
|
20
|
+
joinKeys: Record<string, unknown> | null;
|
|
21
|
+
session: SessionTelemetry | null;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Public surface `SitePluginContext.telemetry` exposes to plugins. Declared
|
|
25
|
+
* separately from the `RunTelemetry` class (rather than using the class
|
|
26
|
+
* itself as the field type) so consumers — including this repo's own test
|
|
27
|
+
* doubles — can satisfy the contract with a plain object; `RunTelemetry`'s
|
|
28
|
+
* private accumulator fields would otherwise make it structurally
|
|
29
|
+
* unsatisfiable by anything but the class itself.
|
|
30
|
+
*/
|
|
31
|
+
export interface RunTelemetryHandle {
|
|
32
|
+
addJoinKeys(fields: Record<string, unknown>): void;
|
|
33
|
+
recordSession(info: SessionTelemetry): void;
|
|
34
|
+
snapshot(): RunTelemetrySnapshot;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* Accumulates run-discovered join keys and session telemetry for a single
|
|
38
|
+
* dispatch invocation. Constructed per-request in `buildPluginContext`
|
|
39
|
+
* (`src/plugins/loader.ts`) and threaded through `SitePluginContext.telemetry`
|
|
40
|
+
* so a plugin can attach fields it only learns mid-run — a token minted
|
|
41
|
+
* mid-flow, a value read from the page after navigation — instead of being
|
|
42
|
+
* limited to `extractJoinKeys`'s inbound-payload-only view.
|
|
43
|
+
*/
|
|
44
|
+
export declare class RunTelemetry implements RunTelemetryHandle {
|
|
45
|
+
private joinKeys;
|
|
46
|
+
private session;
|
|
47
|
+
/**
|
|
48
|
+
* Merges `fields` into the accumulated join-key bag. Later calls win on
|
|
49
|
+
* key collision, so a plugin can refine an early guess as the run
|
|
50
|
+
* progresses without losing earlier keys it doesn't repeat.
|
|
51
|
+
*/
|
|
52
|
+
addJoinKeys(fields: Record<string, unknown>): void;
|
|
53
|
+
/**
|
|
54
|
+
* Records Browserbase session identity/network facts. Last-write-wins
|
|
55
|
+
* (whole-object replace) since a run has at most one active session at a
|
|
56
|
+
* time — unlike join keys, there's no reason to merge partial calls.
|
|
57
|
+
*/
|
|
58
|
+
recordSession(info: SessionTelemetry): void;
|
|
59
|
+
/**
|
|
60
|
+
* Returns a defensive copy of everything accumulated so far. `joinKeys`
|
|
61
|
+
* stays `null` (not `{}`) when nothing was ever added, so dispatch can
|
|
62
|
+
* keep emitting `joinKeys: null` unchanged until a plugin actually writes
|
|
63
|
+
* to this collector.
|
|
64
|
+
*/
|
|
65
|
+
snapshot(): RunTelemetrySnapshot;
|
|
66
|
+
}
|
|
67
|
+
//# sourceMappingURL=run-telemetry.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-telemetry.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/run-telemetry.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,wEAAwE;AACxE,MAAM,WAAW,gBAAgB;IAC/B,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC;IACjB,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB,YAAY,EAAE,MAAM,GAAG,IAAI,CAAC;CAC7B;AAED,iFAAiF;AACjF,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACzC,OAAO,EAAE,gBAAgB,GAAG,IAAI,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,MAAM,WAAW,kBAAkB;IACjC,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IACnD,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAAC;IAC5C,QAAQ,IAAI,oBAAoB,CAAC;CAClC;AAED;;;;;;;GAOG;AACH,qBAAa,YAAa,YAAW,kBAAkB;IACrD,OAAO,CAAC,QAAQ,CAAwC;IACxD,OAAO,CAAC,OAAO,CAAiC;IAEhD;;;;OAIG;IACH,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAEjD;IAED;;;;OAIG;IACH,aAAa,CAAC,IAAI,EAAE,gBAAgB,GAAG,IAAI,CAE1C;IAED;;;;;OAKG;IACH,QAAQ,IAAI,oBAAoB,CAK/B;CACF"}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Run-scoped, mutable telemetry accumulator that a plugin can write
|
|
4
|
+
* discovered fields into at any point during execute()/executeHttp() —
|
|
5
|
+
* mirrors `MetricsCollector` (src/lib/dispatch-metrics.ts) as a per-request
|
|
6
|
+
* instance meant to be threaded through the plugin context, but for
|
|
7
|
+
* run-discovered data (join keys, session info) rather than step timings.
|
|
8
|
+
* Funnels everything a plugin discovers mid-run into the same opaque
|
|
9
|
+
* `joinKeys` bag already documented in `reconciliation-record.ts`, rather
|
|
10
|
+
* than inventing a second bag.
|
|
11
|
+
*/
|
|
12
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
13
|
+
exports.RunTelemetry = void 0;
|
|
14
|
+
/**
|
|
15
|
+
* Accumulates run-discovered join keys and session telemetry for a single
|
|
16
|
+
* dispatch invocation. Constructed per-request in `buildPluginContext`
|
|
17
|
+
* (`src/plugins/loader.ts`) and threaded through `SitePluginContext.telemetry`
|
|
18
|
+
* so a plugin can attach fields it only learns mid-run — a token minted
|
|
19
|
+
* mid-flow, a value read from the page after navigation — instead of being
|
|
20
|
+
* limited to `extractJoinKeys`'s inbound-payload-only view.
|
|
21
|
+
*/
|
|
22
|
+
class RunTelemetry {
|
|
23
|
+
joinKeys = null;
|
|
24
|
+
session = null;
|
|
25
|
+
/**
|
|
26
|
+
* Merges `fields` into the accumulated join-key bag. Later calls win on
|
|
27
|
+
* key collision, so a plugin can refine an early guess as the run
|
|
28
|
+
* progresses without losing earlier keys it doesn't repeat.
|
|
29
|
+
*/
|
|
30
|
+
addJoinKeys(fields) {
|
|
31
|
+
this.joinKeys = { ...this.joinKeys, ...fields };
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Records Browserbase session identity/network facts. Last-write-wins
|
|
35
|
+
* (whole-object replace) since a run has at most one active session at a
|
|
36
|
+
* time — unlike join keys, there's no reason to merge partial calls.
|
|
37
|
+
*/
|
|
38
|
+
recordSession(info) {
|
|
39
|
+
this.session = info;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* Returns a defensive copy of everything accumulated so far. `joinKeys`
|
|
43
|
+
* stays `null` (not `{}`) when nothing was ever added, so dispatch can
|
|
44
|
+
* keep emitting `joinKeys: null` unchanged until a plugin actually writes
|
|
45
|
+
* to this collector.
|
|
46
|
+
*/
|
|
47
|
+
snapshot() {
|
|
48
|
+
return {
|
|
49
|
+
joinKeys: this.joinKeys ? { ...this.joinKeys } : null,
|
|
50
|
+
session: this.session ? { ...this.session } : null,
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
exports.RunTelemetry = RunTelemetry;
|
|
55
|
+
//# sourceMappingURL=run-telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"run-telemetry.js","sourceRoot":"","sources":["../../../src/lib/telemetry/run-telemetry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;GASG;;;AA8BH;;;;;;;GAOG;AACH;IACU,QAAQ,GAAmC,IAAI,CAAC;IAChD,OAAO,GAA4B,IAAI,CAAC;IAEhD;;;;OAIG;IACH,WAAW,CAAC,MAA+B;QACzC,IAAI,CAAC,QAAQ,GAAG,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,GAAG,MAAM,EAAE,CAAC;IAClD,CAAC;IAED;;;;OAIG;IACH,aAAa,CAAC,IAAsB;QAClC,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC;IACtB,CAAC;IAED;;;;;OAKG;IACH,QAAQ;QACN,OAAO;YACL,QAAQ,EAAE,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,QAAQ,EAAE,CAAC,CAAC,CAAC,IAAI;YACrD,OAAO,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,GAAG,IAAI,CAAC,OAAO,EAAE,CAAC,CAAC,CAAC,IAAI;SACnD,CAAC;IACJ,CAAC;CACF"}
|
|
@@ -24,6 +24,12 @@ export declare const submissionEnvelopeSampleSchema: z.ZodObject<{
|
|
|
24
24
|
siteId: z.ZodString;
|
|
25
25
|
requestId: z.ZodString;
|
|
26
26
|
joinKeys: z.ZodDefault<z.ZodNullable<z.ZodRecord<z.ZodString, z.ZodUnknown>>>;
|
|
27
|
+
session: z.ZodDefault<z.ZodNullable<z.ZodObject<{
|
|
28
|
+
id: z.ZodString;
|
|
29
|
+
provider: z.ZodString;
|
|
30
|
+
ip: z.ZodNullable<z.ZodString>;
|
|
31
|
+
ipCapturedAt: z.ZodNullable<z.ZodString>;
|
|
32
|
+
}, z.core.$strip>>>;
|
|
27
33
|
inboundPayload: z.ZodUnknown;
|
|
28
34
|
status: z.ZodEnum<{
|
|
29
35
|
error: "error";
|
|
@@ -37,12 +43,13 @@ export declare const submissionEnvelopeSampleSchema: z.ZodObject<{
|
|
|
37
43
|
export type SubmissionEnvelopeSample = z.infer<typeof submissionEnvelopeSampleSchema>;
|
|
38
44
|
/**
|
|
39
45
|
* Input to `captureSubmissionEnvelope` — `ts` and `kind` are derived
|
|
40
|
-
* internally so callers omit them. `joinKeys`
|
|
41
|
-
* sites that don't yet resolve
|
|
42
|
-
* omitted value is persisted as `null`, not left undefined.
|
|
46
|
+
* internally so callers omit them. `joinKeys`/`session` are optional so
|
|
47
|
+
* existing call sites that don't yet resolve them keep compiling unchanged;
|
|
48
|
+
* an omitted value is persisted as `null`, not left undefined.
|
|
43
49
|
*/
|
|
44
|
-
export type SubmissionEnvelopeInput = Omit<SubmissionEnvelopeSample, "ts" | "kind" | "joinKeys"> & {
|
|
50
|
+
export type SubmissionEnvelopeInput = Omit<SubmissionEnvelopeSample, "ts" | "kind" | "joinKeys" | "session"> & {
|
|
45
51
|
joinKeys?: Record<string, unknown> | null;
|
|
52
|
+
session?: SubmissionEnvelopeSample["session"];
|
|
46
53
|
};
|
|
47
54
|
/** Options for `captureSubmissionEnvelope`. */
|
|
48
55
|
export interface CaptureSubmissionOptions {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-capture.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAShC;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B
|
|
1
|
+
{"version":3,"file":"submission-capture.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-capture.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAMH,OAAO,KAAK,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAShC;;;;;;GAMG;AACH,eAAO,MAAM,8BAA8B;;;;;;;;;;;;;;;;;;;;iBAAqB,CAAC;AAEjE,MAAM,MAAM,wBAAwB,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,8BAA8B,CAAC,CAAC;AAEtF;;;;;GAKG;AACH,MAAM,MAAM,uBAAuB,GAAG,IAAI,CACxC,wBAAwB,EACxB,IAAI,GAAG,MAAM,GAAG,UAAU,GAAG,SAAS,CACvC,GAAG;IACF,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;IAC1C,OAAO,CAAC,EAAE,wBAAwB,CAAC,SAAS,CAAC,CAAC;CAC/C,CAAC;AAEF,+CAA+C;AAC/C,MAAM,WAAW,wBAAwB;IACvC,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED;;;;;;GAMG;AACH,wBAAsB,wBAAwB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAI5F;AAED;;;;GAIG;AACH,wBAAsB,yBAAyB,CAC7C,KAAK,EAAE,uBAAuB,EAC9B,IAAI,GAAE,wBAA6B,GAClC,OAAO,CAAC,IAAI,CAAC,CAgBf"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-capture.js","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;AAEH,+CAAqD;AACrD,yCAAoC;AAEpC,uCAAqC;AAGrC,qCAAkC;AAClC,2CAA0C;AAC1C,iFAA2E;AAC3E,qDAA+D;AAE/D,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAC,CAAC;AAEnE;;;;;;GAMG;AACU,QAAA,8BAA8B,GAAG,0CAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"submission-capture.js","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-capture.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;GAYG;;;;;AAEH,+CAAqD;AACrD,yCAAoC;AAEpC,uCAAqC;AAGrC,qCAAkC;AAClC,2CAA0C;AAC1C,iFAA2E;AAC3E,qDAA+D;AAE/D,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,8BAA8B,EAAE,CAAC,CAAC;AAEnE;;;;;;GAMG;AACU,QAAA,8BAA8B,GAAG,0CAAkB,CAAC;AAwBjE;;;;;;GAMG;AACI,KAAK,mCAAmC,QAAgB,EAAE,IAAY;IAC3E,MAAM,IAAA,gBAAK,EAAC,IAAA,mBAAO,EAAC,QAAQ,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IACpD,MAAM,IAAA,qBAAU,EAAC,QAAQ,EAAE,IAAI,EAAE,MAAM,CAAC,CAAC;IACzC,IAAA,8BAAoB,EAAC,IAAI,CAAC,CAAC;AAC7B,CAAC;AAED;;;;GAIG;AACI,KAAK,oCACV,KAA8B,EAC9B,IAAI,GAA6B,EAAE;IAEnC,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,IAAI,eAAM,CAAC,SAAS,CAAC,qBAAqB,CAAC;IACzE,MAAM,MAAM,GAA6B;QACvC,GAAG,KAAK;QACR,IAAI,EAAE,QAAQ;QACd,QAAQ,EAAE,KAAK,CAAC,QAAQ,IAAI,IAAI;QAChC,OAAO,EAAE,KAAK,CAAC,OAAO,IAAI,IAAI;QAC9B,EAAE,EAAE,IAAA,oBAAS,EAAC,IAAI,IAAI,EAAE,CAAC;KAC1B,CAAC;IAEF,IAAI,CAAC;QACH,MAAM,IAAI,GAAG,GAAG,IAAI,CAAC,SAAS,CAAC,MAAM,CAAC,IAAI,CAAC;QAC3C,MAAM,wBAAwB,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;IACjD,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,MAAM,CAAC,KAAK,CAAC,iDAAiD,QAAQ,KAAK,MAAM,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAC5F,CAAC;AACH,CAAC"}
|
|
@@ -14,13 +14,19 @@ import { type BeaconEvent, type ReconciliationRecord, type SubmitRecord } from "
|
|
|
14
14
|
* One reconciliation row per run: the submit record's fields plus the
|
|
15
15
|
* outcome of its beacon fire, distinct from submit status so "submitted but
|
|
16
16
|
* the beacon did not fire" is measurable. `beaconStatus` defaults to
|
|
17
|
-
* `"not_fired"` when no matching beacon line ever arrived.
|
|
17
|
+
* `"not_fired"` when no matching beacon line ever arrived. When a run has
|
|
18
|
+
* both a `"skipped"` line and a real `"fired"`/`"failed"` line, the real
|
|
19
|
+
* outcome wins the fold (see `foldReconciliationRecords`) regardless of
|
|
20
|
+
* which line was written first. `beaconSessionIp` is the tracking-click
|
|
21
|
+
* session's own outbound IP — distinct from the submit line's `session.ip`,
|
|
22
|
+
* since the two are separate Browserbase sessions per run.
|
|
18
23
|
*/
|
|
19
24
|
export interface ReconciliationRow extends Omit<SubmitRecord, "kind"> {
|
|
20
25
|
beaconStatus: BeaconEvent["beaconStatus"] | "not_fired";
|
|
21
26
|
beaconTrackingUrl: string | null;
|
|
22
27
|
beaconTs: string | null;
|
|
23
28
|
beaconDurationMs: number | null;
|
|
29
|
+
beaconSessionIp: string | null;
|
|
24
30
|
}
|
|
25
31
|
/** Options for `readReconciliationRows`. */
|
|
26
32
|
export interface ReadReconciliationRowsOptions {
|
|
@@ -38,8 +44,10 @@ export declare function parseReconciliationLines(ndjsonContent: string): Reconci
|
|
|
38
44
|
* Left-joins beacon events onto submit records by `requestId`. Submit rows
|
|
39
45
|
* are the base — a beacon may arrive strictly after its submit line (or
|
|
40
46
|
* never), so an orphan beacon with no matching submit row is dropped rather
|
|
41
|
-
* than synthesizing a phantom row.
|
|
42
|
-
*
|
|
47
|
+
* than synthesizing a phantom row. Among beacon lines for the same
|
|
48
|
+
* `requestId`, the highest-`beaconRank` line wins regardless of write
|
|
49
|
+
* order; ties (equal rank) fall back to a later line overwriting an
|
|
50
|
+
* earlier one, so a duplicate/retry still resolves deterministically.
|
|
43
51
|
*/
|
|
44
52
|
export declare function foldReconciliationRecords(records: ReconciliationRecord[]): ReconciliationRow[];
|
|
45
53
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-reader.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,oBAAoB,EAEzB,KAAK,YAAY,EAClB,MAAM,uCAAuC,CAAC;AAI/C
|
|
1
|
+
{"version":3,"file":"submission-reader.d.ts","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-reader.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAOH,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,oBAAoB,EAEzB,KAAK,YAAY,EAClB,MAAM,uCAAuC,CAAC;AAI/C;;;;;;;;;;GAUG;AACH,MAAM,WAAW,iBAAkB,SAAQ,IAAI,CAAC,YAAY,EAAE,MAAM,CAAC;IACnE,YAAY,EAAE,WAAW,CAAC,cAAc,CAAC,GAAG,WAAW,CAAC;IACxD,iBAAiB,EAAE,MAAM,GAAG,IAAI,CAAC;IACjC,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAC;IACxB,gBAAgB,EAAE,MAAM,GAAG,IAAI,CAAC;IAChC,eAAe,EAAE,MAAM,GAAG,IAAI,CAAC;CAChC;AAED,4CAA4C;AAC5C,MAAM,WAAW,6BAA6B;IAC5C,6EAA6E;IAC7E,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAcD;;;;;GAKG;AACH,wBAAgB,wBAAwB,CAAC,aAAa,EAAE,MAAM,GAAG,oBAAoB,EAAE,CA2BtF;AAcD;;;;;;;;GAQG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,oBAAoB,EAAE,GAAG,iBAAiB,EAAE,CA2C9F;AAED;;;;;GAKG;AACH,wBAAsB,sBAAsB,CAC1C,IAAI,GAAE,6BAAkC,GACvC,OAAO,CAAC,iBAAiB,EAAE,CAAC,CAM9B"}
|
|
@@ -58,12 +58,25 @@ function parseReconciliationLines(ndjsonContent) {
|
|
|
58
58
|
}
|
|
59
59
|
return records;
|
|
60
60
|
}
|
|
61
|
+
/**
|
|
62
|
+
* Rank of a beacon outcome for fold precedence: a real `fired`/`failed`
|
|
63
|
+
* outcome always outranks `skipped`, because `dispatch()` writes `skipped`
|
|
64
|
+
* synchronously for any self-managing plugin (`loader.ts`) before that
|
|
65
|
+
* plugin's own later-recorded real outcome can arrive — write order alone
|
|
66
|
+
* is not a safe proxy for which line reflects reality. Equal-rank lines
|
|
67
|
+
* (e.g. a retried `fired`) fall through to array order, i.e. last one wins.
|
|
68
|
+
*/
|
|
69
|
+
function beaconRank(beaconStatus) {
|
|
70
|
+
return beaconStatus === "skipped" ? 0 : 1;
|
|
71
|
+
}
|
|
61
72
|
/**
|
|
62
73
|
* Left-joins beacon events onto submit records by `requestId`. Submit rows
|
|
63
74
|
* are the base — a beacon may arrive strictly after its submit line (or
|
|
64
75
|
* never), so an orphan beacon with no matching submit row is dropped rather
|
|
65
|
-
* than synthesizing a phantom row.
|
|
66
|
-
*
|
|
76
|
+
* than synthesizing a phantom row. Among beacon lines for the same
|
|
77
|
+
* `requestId`, the highest-`beaconRank` line wins regardless of write
|
|
78
|
+
* order; ties (equal rank) fall back to a later line overwriting an
|
|
79
|
+
* earlier one, so a duplicate/retry still resolves deterministically.
|
|
67
80
|
*/
|
|
68
81
|
function foldReconciliationRecords(records) {
|
|
69
82
|
const rows = new Map();
|
|
@@ -77,20 +90,31 @@ function foldReconciliationRecords(records) {
|
|
|
77
90
|
beaconTrackingUrl: null,
|
|
78
91
|
beaconTs: null,
|
|
79
92
|
beaconDurationMs: null,
|
|
93
|
+
beaconSessionIp: null,
|
|
80
94
|
});
|
|
81
95
|
}
|
|
96
|
+
const winningBeacons = new Map();
|
|
82
97
|
for (const record of records) {
|
|
83
98
|
if (record.kind !== "beacon")
|
|
84
99
|
continue;
|
|
85
|
-
const
|
|
100
|
+
const current = winningBeacons.get(record.requestId);
|
|
101
|
+
if (current !== undefined &&
|
|
102
|
+
beaconRank(current.beaconStatus) > beaconRank(record.beaconStatus)) {
|
|
103
|
+
continue;
|
|
104
|
+
}
|
|
105
|
+
winningBeacons.set(record.requestId, record);
|
|
106
|
+
}
|
|
107
|
+
for (const [requestId, beacon] of winningBeacons) {
|
|
108
|
+
const row = rows.get(requestId);
|
|
86
109
|
if (row === undefined)
|
|
87
110
|
continue;
|
|
88
|
-
rows.set(
|
|
111
|
+
rows.set(requestId, {
|
|
89
112
|
...row,
|
|
90
|
-
beaconStatus:
|
|
91
|
-
beaconTrackingUrl:
|
|
92
|
-
beaconTs:
|
|
93
|
-
beaconDurationMs:
|
|
113
|
+
beaconStatus: beacon.beaconStatus,
|
|
114
|
+
beaconTrackingUrl: beacon.trackingUrl,
|
|
115
|
+
beaconTs: beacon.ts,
|
|
116
|
+
beaconDurationMs: beacon.durationMs,
|
|
117
|
+
beaconSessionIp: beacon.sessionIp,
|
|
94
118
|
});
|
|
95
119
|
}
|
|
96
120
|
return Array.from(rows.values());
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"submission-reader.js","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-reader.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;GAUG;;;;;AAEH,qCAAqC;AACrC,+CAA4C;AAE5C,qCAAkC;AAClC,2CAA0C;AAC1C,iFAK+C;AAE/C,MAAM,MAAM,GAAG,IAAA,mBAAS,EAAC,EAAE,IAAI,EAAE,6BAA6B,EAAE,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"submission-reader.js","sourceRoot":"","sources":["../../../src/lib/telemetry/submission-reader.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"tracking-click.d.ts","sourceRoot":"","sources":["../../src/lib/tracking-click.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqBH;;;;GAIG;AACH,MAAM,WAAW,kCAAkC;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;
|
|
1
|
+
{"version":3,"file":"tracking-click.d.ts","sourceRoot":"","sources":["../../src/lib/tracking-click.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAqBH;;;;GAIG;AACH,MAAM,WAAW,kCAAkC;IACjD,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI,CAAC;CAC1C;AAqGD;;;;;GAKG;AACH,wBAAgB,iBAAiB,CAC/B,WAAW,EAAE,MAAM,EACnB,MAAM,EAAE,MAAM,EACd,cAAc,CAAC,EAAE,kCAAkC,GAClD,IAAI,CAKN;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,SAAS,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CAO3E"}
|
|
@@ -38,6 +38,23 @@ async function captureBeaconOutcomeSafely(input) {
|
|
|
38
38
|
logger.warn(`beacon outcome capture failed: ${(0, errors_1.toErrorMessage)(err)}`);
|
|
39
39
|
}
|
|
40
40
|
}
|
|
41
|
+
/**
|
|
42
|
+
* Resolves the given session's outbound IP for the beacon record. Never
|
|
43
|
+
* throws — a resolution failure (or a session/provider without the
|
|
44
|
+
* accessor) yields `null` rather than blocking the beacon write, matching
|
|
45
|
+
* the same never-throw contract `getOutboundIp` itself already applies.
|
|
46
|
+
*/
|
|
47
|
+
async function resolveSessionIp(session) {
|
|
48
|
+
if (!session?.getOutboundIp)
|
|
49
|
+
return null;
|
|
50
|
+
try {
|
|
51
|
+
return await session.getOutboundIp();
|
|
52
|
+
}
|
|
53
|
+
catch (err) {
|
|
54
|
+
logger.warn(`tracking click session IP resolution failed: ${(0, errors_1.toErrorMessage)(err)}`);
|
|
55
|
+
return null;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
41
58
|
/**
|
|
42
59
|
* Navigates a Browserbase session to the tracking URL. Errors are logged
|
|
43
60
|
* and swallowed — the apply already succeeded, so a failed tracking click
|
|
@@ -65,6 +82,7 @@ async function executeTrackingClick(trackingUrl, siteId, reconciliation) {
|
|
|
65
82
|
beaconStatus: "fired",
|
|
66
83
|
trackingUrl,
|
|
67
84
|
durationMs: Date.now() - startedAt,
|
|
85
|
+
sessionIp: await resolveSessionIp(session),
|
|
68
86
|
});
|
|
69
87
|
}
|
|
70
88
|
}
|
|
@@ -79,6 +97,7 @@ async function executeTrackingClick(trackingUrl, siteId, reconciliation) {
|
|
|
79
97
|
beaconStatus: "failed",
|
|
80
98
|
trackingUrl,
|
|
81
99
|
durationMs: Date.now() - startedAt,
|
|
100
|
+
sessionIp: await resolveSessionIp(session),
|
|
82
101
|
});
|
|
83
102
|
}
|
|
84
103
|
}
|