personal-agent-benchmark 0.0.0-stage → 0.2.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.
Files changed (81) hide show
  1. package/README.md +128 -2
  2. package/bin/pab.js +5 -0
  3. package/dist/src/browser.d.ts +29 -0
  4. package/dist/src/browser.js +37 -0
  5. package/dist/src/browser.js.map +1 -0
  6. package/dist/src/cli.d.ts +20 -0
  7. package/dist/src/cli.js +331 -0
  8. package/dist/src/cli.js.map +1 -0
  9. package/dist/src/core/archive.d.ts +49 -0
  10. package/dist/src/core/archive.js +213 -0
  11. package/dist/src/core/archive.js.map +1 -0
  12. package/dist/src/core/audit.d.ts +15 -0
  13. package/dist/src/core/audit.js +85 -0
  14. package/dist/src/core/audit.js.map +1 -0
  15. package/dist/src/core/bundle.d.ts +42 -0
  16. package/dist/src/core/bundle.js +80 -0
  17. package/dist/src/core/bundle.js.map +1 -0
  18. package/dist/src/core/lookup.d.ts +15 -0
  19. package/dist/src/core/lookup.js +82 -0
  20. package/dist/src/core/lookup.js.map +1 -0
  21. package/dist/src/core/normalize.d.ts +45 -0
  22. package/dist/src/core/normalize.js +143 -0
  23. package/dist/src/core/normalize.js.map +1 -0
  24. package/dist/src/core/rules.d.ts +38 -0
  25. package/dist/src/core/rules.js +187 -0
  26. package/dist/src/core/rules.js.map +1 -0
  27. package/dist/src/core/store.d.ts +26 -0
  28. package/dist/src/core/store.js +78 -0
  29. package/dist/src/core/store.js.map +1 -0
  30. package/dist/src/core/types.d.ts +125 -0
  31. package/dist/src/core/types.js +3 -0
  32. package/dist/src/core/types.js.map +1 -0
  33. package/dist/src/core/util.d.ts +21 -0
  34. package/dist/src/core/util.js +150 -0
  35. package/dist/src/core/util.js.map +1 -0
  36. package/dist/src/core/warc.d.ts +55 -0
  37. package/dist/src/core/warc.js +258 -0
  38. package/dist/src/core/warc.js.map +1 -0
  39. package/dist/src/core/writer.d.ts +26 -0
  40. package/dist/src/core/writer.js +119 -0
  41. package/dist/src/core/writer.js.map +1 -0
  42. package/dist/src/grading.d.ts +63 -0
  43. package/dist/src/grading.js +173 -0
  44. package/dist/src/grading.js.map +1 -0
  45. package/dist/src/judge.d.ts +25 -0
  46. package/dist/src/judge.js +119 -0
  47. package/dist/src/judge.js.map +1 -0
  48. package/dist/src/paths.d.ts +2 -0
  49. package/dist/src/paths.js +40 -0
  50. package/dist/src/paths.js.map +1 -0
  51. package/dist/src/replay/clock.d.ts +19 -0
  52. package/dist/src/replay/clock.js +60 -0
  53. package/dist/src/replay/clock.js.map +1 -0
  54. package/dist/src/replay/engine.d.ts +53 -0
  55. package/dist/src/replay/engine.js +280 -0
  56. package/dist/src/replay/engine.js.map +1 -0
  57. package/dist/src/replay/launcher.d.ts +36 -0
  58. package/dist/src/replay/launcher.js +163 -0
  59. package/dist/src/replay/launcher.js.map +1 -0
  60. package/dist/src/replay/whistle-plugin.d.ts +24 -0
  61. package/dist/src/replay/whistle-plugin.js +82 -0
  62. package/dist/src/replay/whistle-plugin.js.map +1 -0
  63. package/dist/src/report.d.ts +3 -0
  64. package/dist/src/report.js +143 -0
  65. package/dist/src/report.js.map +1 -0
  66. package/dist/src/scoring.d.ts +87 -0
  67. package/dist/src/scoring.js +232 -0
  68. package/dist/src/scoring.js.map +1 -0
  69. package/dist/src/tasks.d.ts +61 -0
  70. package/dist/src/tasks.js +152 -0
  71. package/dist/src/tasks.js.map +1 -0
  72. package/docs/bundle-format.md +114 -0
  73. package/docs/deploy.md +78 -0
  74. package/docs/grading.md +81 -0
  75. package/docs/site-rules.md +114 -0
  76. package/docs/tasks.md +63 -0
  77. package/package.json +121 -4
  78. package/plugins/whistle.bench-replay/index.js +1 -0
  79. package/plugins/whistle.bench-replay/package.json +7 -0
  80. package/sites/_default.yaml +80 -0
  81. package/sites/amazon.com.yaml +125 -0
@@ -0,0 +1,143 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.normalizeText = normalizeText;
4
+ exports.normalizeRequest = normalizeRequest;
5
+ exports.parseBody = parseBody;
6
+ exports.getPath = getPath;
7
+ exports.readField = readField;
8
+ const rules_1 = require("./rules");
9
+ const util_1 = require("./util");
10
+ const STATIC_EXT = /\.(js|mjs|css|png|jpe?g|gif|webp|avif|svg|ico|woff2?|ttf|otf|eot|mp4|webm|mp3|wav|map)$/i;
11
+ function normalizeText(value) {
12
+ return value.replace(/\+/g, ' ').toLowerCase().replace(/\s+/g, ' ').trim();
13
+ }
14
+ function normalizeRequest(input, rules) {
15
+ const method = input.method.toUpperCase();
16
+ const url = new URL(input.url);
17
+ const host = url.hostname.toLowerCase() + (url.port && !isDefaultPort(url) ? ':' + url.port : '');
18
+ let pathname = url.pathname.replace(/\/{2,}/g, '/');
19
+ if (pathname.length > 1 && pathname.endsWith('/'))
20
+ pathname = pathname.slice(0, -1);
21
+ const site = rules.siteFor(url.hostname.toLowerCase());
22
+ const match = rules.matchEndpoint(site, method, url.hostname.toLowerCase(), pathname);
23
+ const endpoint = match?.endpoint;
24
+ const captures = match?.captures ?? {};
25
+ const path = endpoint?.key ? (0, rules_1.fillTemplate)(endpoint.key, captures) : pathname;
26
+ let kind = endpoint?.kind ?? (STATIC_EXT.test(pathname) ? 'static' : 'browse');
27
+ if (rules.isBlocked(url.hostname.toLowerCase(), pathname, site))
28
+ kind = 'block';
29
+ const textParam = endpoint?.text_param;
30
+ let text;
31
+ const drop = rules.dropParams(site, endpoint);
32
+ const params = [];
33
+ for (const [k, v] of url.searchParams) {
34
+ if (endpoint?.keep_params ? !endpoint.keep_params.includes(k) : (0, util_1.matchesAny)(k, drop))
35
+ continue;
36
+ if (textParam && k === textParam) {
37
+ text = normalizeText(v);
38
+ params.push([k, text]);
39
+ }
40
+ else {
41
+ params.push([k, v]);
42
+ }
43
+ }
44
+ params.sort((a, b) => (a[0] === b[0] ? a[1].localeCompare(b[1]) : a[0].localeCompare(b[0])));
45
+ const body = parseBody(input.contentType, input.body);
46
+ let bodyKey = '';
47
+ if (body.kind === 'fields') {
48
+ const kept = filterFields(body.fields, endpoint?.body_keep, rules.bodyDrop(site, endpoint));
49
+ if (textParam && typeof kept[textParam] === 'string') {
50
+ text = normalizeText(kept[textParam]);
51
+ kept[textParam] = text;
52
+ }
53
+ bodyKey = Object.keys(kept).length ? (0, util_1.stableStringify)(kept) : '';
54
+ }
55
+ else if (body.kind === 'raw') {
56
+ bodyKey = 'sha256:' + (0, util_1.sha256)(body.raw).slice(0, 16);
57
+ }
58
+ const query = params.map(([k, v]) => `${k}=${v}`).join('&');
59
+ const pathKey = `${method} ${host}${path}`;
60
+ const key = pathKey + (query ? '?' + query : '') + (bodyKey ? ' #body:' + bodyKey : '');
61
+ const latest = rules.prefersLatest(url.hostname.toLowerCase(), pathname, site);
62
+ return { method, host, path, params, bodyKey, key, pathKey, kind, site, endpoint, captures, text, latest };
63
+ }
64
+ function isDefaultPort(url) {
65
+ return (url.protocol === 'https:' && url.port === '443') || (url.protocol === 'http:' && url.port === '80');
66
+ }
67
+ function parseBody(contentType, body) {
68
+ if (!body || body.length === 0)
69
+ return { kind: 'none' };
70
+ const ct = (contentType ?? '').toLowerCase();
71
+ const text = body.toString('utf8');
72
+ if (ct.includes('json') || /^\s*[{[]/.test(text)) {
73
+ try {
74
+ const parsed = JSON.parse(text);
75
+ if (parsed && typeof parsed === 'object' && !Array.isArray(parsed))
76
+ return { kind: 'fields', fields: parsed };
77
+ return { kind: 'fields', fields: { _: parsed } };
78
+ }
79
+ catch {
80
+ // not JSON after all
81
+ }
82
+ }
83
+ if (ct.includes('x-www-form-urlencoded') || (!ct && /^[\w.%[\]-]+=/.test(text))) {
84
+ const fields = {};
85
+ for (const [k, v] of new URLSearchParams(text)) {
86
+ const prev = fields[k];
87
+ fields[k] = prev === undefined ? v : Array.isArray(prev) ? [...prev, v] : [prev, v];
88
+ }
89
+ return { kind: 'fields', fields };
90
+ }
91
+ return { kind: 'raw', raw: body };
92
+ }
93
+ /** Keep listed top-level fields (dot paths allowed) or drop volatile ones recursively. */
94
+ function filterFields(fields, keep, drop) {
95
+ if (keep && keep.length) {
96
+ const out = {};
97
+ for (const p of keep) {
98
+ const v = getPath(fields, p);
99
+ if (v !== undefined)
100
+ out[p] = v;
101
+ }
102
+ return out;
103
+ }
104
+ const strip = (value) => {
105
+ if (Array.isArray(value))
106
+ return value.map(strip);
107
+ if (value && typeof value === 'object') {
108
+ const out = {};
109
+ for (const [k, v] of Object.entries(value)) {
110
+ if (!(0, util_1.matchesAny)(k, drop))
111
+ out[k] = strip(v);
112
+ }
113
+ return out;
114
+ }
115
+ return value;
116
+ };
117
+ return strip(fields);
118
+ }
119
+ function getPath(obj, dotted) {
120
+ if (obj && typeof obj === 'object' && dotted in obj) {
121
+ return obj[dotted];
122
+ }
123
+ let cur = obj;
124
+ for (const part of dotted.split('.')) {
125
+ if (cur === null || typeof cur !== 'object')
126
+ return undefined;
127
+ cur = cur[part];
128
+ }
129
+ return cur;
130
+ }
131
+ /** Read a field from the query string or a parsed body. */
132
+ function readField(input, from, field) {
133
+ if (from === 'query')
134
+ return new URL(input.url).searchParams.get(field) ?? undefined;
135
+ const body = parseBody(input.contentType, input.body);
136
+ if (body.kind !== 'fields')
137
+ return undefined;
138
+ const v = getPath(body.fields, field);
139
+ if (Array.isArray(v))
140
+ return v.length ? String(v[0]) : undefined;
141
+ return v === undefined || v === null ? undefined : String(v);
142
+ }
143
+ //# sourceMappingURL=normalize.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"normalize.js","sourceRoot":"","sources":["../../../src/core/normalize.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ import type { EndpointRule, SiteRules } from './types';
2
+ export interface EndpointMatch {
3
+ endpoint: EndpointRule;
4
+ captures: Record<string, string>;
5
+ }
6
+ /** Site rules for one bundle: `_default.yaml` plus one file per site. */
7
+ export declare class RuleSet {
8
+ readonly defaults: SiteRules;
9
+ readonly sites: SiteRules[];
10
+ constructor(sites: SiteRules[]);
11
+ /**
12
+ * Files for the same site are merged. Hand-written files (`<site>.yaml`) take precedence over
13
+ * generated ones (`<site>.auto.yaml`) from any directory; among files of the same kind, later
14
+ * directories win. Winning files' endpoints are tried first and their scalar settings kept;
15
+ * lists are combined.
16
+ */
17
+ static load(dirs: string[]): RuleSet;
18
+ siteFor(host: string): SiteRules | undefined;
19
+ dropParams(site?: SiteRules, endpoint?: EndpointRule): string[];
20
+ bodyDrop(site?: SiteRules, endpoint?: EndpointRule): string[];
21
+ isBlocked(host: string, pathname: string, site?: SiteRules): boolean;
22
+ /** True for URLs that must never be stored or replayed, such as bot-check pages. */
23
+ isExcluded(url: string): boolean;
24
+ /** True for pages answered with their last recording (see SiteRules.latest). */
25
+ prefersLatest(host: string, pathname: string, site?: SiteRules): boolean;
26
+ matchEndpoint(site: SiteRules | undefined, method: string, host: string, pathname: string): EndpointMatch | undefined;
27
+ allEndpoints(): {
28
+ site: SiteRules;
29
+ endpoint: EndpointRule;
30
+ }[];
31
+ }
32
+ export declare function parseMatch(match: string): {
33
+ method?: string;
34
+ pattern: string;
35
+ };
36
+ /** Match a path against a pattern; returns captured `{name}` segments or undefined. */
37
+ export declare function matchPath(pattern: string, pathname: string): Record<string, string> | undefined;
38
+ export declare function fillTemplate(template: string, captures: Record<string, string>): string;
@@ -0,0 +1,187 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ var __importDefault = (this && this.__importDefault) || function (mod) {
36
+ return (mod && mod.__esModule) ? mod : { "default": mod };
37
+ };
38
+ Object.defineProperty(exports, "__esModule", { value: true });
39
+ exports.RuleSet = void 0;
40
+ exports.parseMatch = parseMatch;
41
+ exports.matchPath = matchPath;
42
+ exports.fillTemplate = fillTemplate;
43
+ const fs = __importStar(require("node:fs"));
44
+ const path = __importStar(require("node:path"));
45
+ const yaml_1 = __importDefault(require("yaml"));
46
+ const util_1 = require("./util");
47
+ const DEFAULT_SITE = '_default';
48
+ /** Site rules for one bundle: `_default.yaml` plus one file per site. */
49
+ class RuleSet {
50
+ defaults;
51
+ sites;
52
+ constructor(sites) {
53
+ this.defaults = sites.find((s) => s.site === DEFAULT_SITE) ?? { site: DEFAULT_SITE, hosts: [] };
54
+ this.sites = sites.filter((s) => s.site !== DEFAULT_SITE);
55
+ }
56
+ /**
57
+ * Files for the same site are merged. Hand-written files (`<site>.yaml`) take precedence over
58
+ * generated ones (`<site>.auto.yaml`) from any directory; among files of the same kind, later
59
+ * directories win. Winning files' endpoints are tried first and their scalar settings kept;
60
+ * lists are combined.
61
+ */
62
+ static load(dirs) {
63
+ const files = [];
64
+ dirs.forEach((dir, d) => {
65
+ if (!dir || !fs.existsSync(dir))
66
+ return;
67
+ for (const name of fs.readdirSync(dir).sort()) {
68
+ if (!/\.ya?ml$/.test(name) || name.includes('.draft.'))
69
+ continue;
70
+ files.push({ file: path.join(dir, name), rank: (/\.auto\.ya?ml$/.test(name) ? 0 : dirs.length) + d });
71
+ }
72
+ });
73
+ files.sort((a, b) => b.rank - a.rank);
74
+ const bySite = new Map();
75
+ for (const { file } of files) {
76
+ const parsed = yaml_1.default.parse(fs.readFileSync(file, 'utf8'));
77
+ if (!parsed || !parsed.site)
78
+ throw new Error(`rules file without "site": ${file}`);
79
+ parsed.hosts = parsed.hosts ?? [];
80
+ const prev = bySite.get(parsed.site);
81
+ bySite.set(parsed.site, prev ? mergeSite(prev, parsed) : parsed);
82
+ }
83
+ return new RuleSet([...bySite.values()]);
84
+ }
85
+ siteFor(host) {
86
+ return this.sites.find((s) => (0, util_1.matchesAny)(host, s.hosts));
87
+ }
88
+ dropParams(site, endpoint) {
89
+ return [...(this.defaults.drop_params ?? []), ...(site?.drop_params ?? []), ...(endpoint?.drop_params ?? [])];
90
+ }
91
+ bodyDrop(site, endpoint) {
92
+ return [...(this.defaults.body_drop ?? []), ...(site?.body_drop ?? []), ...(endpoint?.body_drop ?? [])];
93
+ }
94
+ isBlocked(host, pathname, site) {
95
+ const patterns = [...(this.defaults.block ?? []), ...(site?.block ?? [])];
96
+ return patterns.some((p) => (p.includes('/') ? (0, util_1.globToRegExp)(p).test(host + pathname) : (0, util_1.globToRegExp)(p).test(host)));
97
+ }
98
+ /** True for URLs that must never be stored or replayed, such as bot-check pages. */
99
+ isExcluded(url) {
100
+ let u;
101
+ try {
102
+ u = new URL(url);
103
+ }
104
+ catch {
105
+ return false;
106
+ }
107
+ const host = u.hostname.toLowerCase();
108
+ const patterns = [...(this.defaults.exclude ?? []), ...(this.siteFor(host)?.exclude ?? [])];
109
+ return patterns.some((p) => (p.includes('/') ? (0, util_1.globToRegExp)(p).test(host + u.pathname) : (0, util_1.globToRegExp)(p).test(host)));
110
+ }
111
+ /** True for pages answered with their last recording (see SiteRules.latest). */
112
+ prefersLatest(host, pathname, site) {
113
+ const patterns = [...(this.defaults.latest ?? []), ...(site?.latest ?? [])];
114
+ return patterns.some((p) => (p.includes('/') ? (0, util_1.globToRegExp)(p).test(host + pathname) : (0, util_1.globToRegExp)(p).test(host)));
115
+ }
116
+ matchEndpoint(site, method, host, pathname) {
117
+ for (const endpoint of site?.endpoints ?? []) {
118
+ if (endpoint.host && !(0, util_1.globToRegExp)(endpoint.host).test(host))
119
+ continue;
120
+ const { method: m, pattern } = parseMatch(endpoint.match);
121
+ if (m && m !== method)
122
+ continue;
123
+ const captures = matchPath(pattern, pathname);
124
+ if (captures)
125
+ return { endpoint, captures };
126
+ }
127
+ return undefined;
128
+ }
129
+ allEndpoints() {
130
+ return this.sites.flatMap((site) => (site.endpoints ?? []).map((endpoint) => ({ site, endpoint })));
131
+ }
132
+ }
133
+ exports.RuleSet = RuleSet;
134
+ /** `high` wins: its endpoints are tried first and its single values are kept; lists are unioned. */
135
+ function mergeSite(high, low) {
136
+ const union = (a, b) => (a || b ? [...new Set([...(a ?? []), ...(b ?? [])])] : undefined);
137
+ const names = new Set((high.endpoints ?? []).map((e) => e.name));
138
+ return {
139
+ ...low,
140
+ ...high,
141
+ hosts: union(high.hosts, low.hosts) ?? [],
142
+ drop_params: union(high.drop_params, low.drop_params),
143
+ body_drop: union(high.body_drop, low.body_drop),
144
+ block: union(high.block, low.block),
145
+ exclude: union(high.exclude, low.exclude),
146
+ latest: union(high.latest, low.latest),
147
+ endpoints: [...(high.endpoints ?? []), ...(low.endpoints ?? []).filter((e) => !names.has(e.name))],
148
+ };
149
+ }
150
+ function parseMatch(match) {
151
+ const parts = match.trim().split(/\s+/);
152
+ if (parts.length === 2)
153
+ return { method: parts[0].toUpperCase(), pattern: parts[1] };
154
+ return { pattern: parts[0] };
155
+ }
156
+ /** Match a path against a pattern; returns captured `{name}` segments or undefined. */
157
+ function matchPath(pattern, pathname) {
158
+ const pat = pattern.split('/').filter(Boolean);
159
+ const segs = pathname.split('/').filter(Boolean);
160
+ const captures = {};
161
+ const walk = (i, j) => {
162
+ if (i === pat.length)
163
+ return j === segs.length;
164
+ const p = pat[i];
165
+ if (p === '**') {
166
+ for (let k = j; k <= segs.length; k++)
167
+ if (walk(i + 1, k))
168
+ return true;
169
+ return false;
170
+ }
171
+ if (j >= segs.length)
172
+ return false;
173
+ const capture = /^\{(\w+)\}$/.exec(p);
174
+ if (capture) {
175
+ captures[capture[1]] = decodeURIComponent(segs[j]);
176
+ return walk(i + 1, j + 1);
177
+ }
178
+ if (p === '*' || (0, util_1.globToRegExp)(p).test(segs[j]))
179
+ return walk(i + 1, j + 1);
180
+ return false;
181
+ };
182
+ return walk(0, 0) ? captures : undefined;
183
+ }
184
+ function fillTemplate(template, captures) {
185
+ return template.replace(/\{(\w+)\}/g, (_, name) => captures[name] ?? '');
186
+ }
187
+ //# sourceMappingURL=rules.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"rules.js","sourceRoot":"","sources":["../../../src/core/rules.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ import type { Bundle } from './bundle';
2
+ import { type NormalizedRequest } from './normalize';
3
+ import type { RuleSet } from './rules';
4
+ import type { Entry, StoredResponse } from './types';
5
+ export interface IndexedEntry {
6
+ entry: Entry;
7
+ norm: NormalizedRequest;
8
+ order: number;
9
+ }
10
+ /** In-memory index over a bundle. Keys are recomputed from the current rules at load time. */
11
+ export declare class RecordStore {
12
+ readonly bundle: Bundle;
13
+ readonly rules: RuleSet;
14
+ readonly byKey: Map<string, IndexedEntry[]>;
15
+ readonly byPathKey: Map<string, IndexedEntry[]>;
16
+ readonly byId: Map<string, IndexedEntry>;
17
+ readonly all: IndexedEntry[];
18
+ private readonly cache;
19
+ private cacheBytes;
20
+ constructor(bundle: Bundle, rules: RuleSet);
21
+ normalizeEntry(entry: Entry): NormalizedRequest;
22
+ /** Earliest recorded exchange for a URL (exact string match), optionally by method. */
23
+ findByUrl(url: string, method?: string): IndexedEntry | undefined;
24
+ response(ix: IndexedEntry): Promise<StoredResponse>;
25
+ private remember;
26
+ }
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.RecordStore = void 0;
4
+ const normalize_1 = require("./normalize");
5
+ const warc_1 = require("./warc");
6
+ const CACHE_LIMIT_BYTES = 256 * 1024 * 1024;
7
+ /** In-memory index over a bundle. Keys are recomputed from the current rules at load time. */
8
+ class RecordStore {
9
+ bundle;
10
+ rules;
11
+ byKey = new Map();
12
+ byPathKey = new Map();
13
+ byId = new Map();
14
+ all = [];
15
+ cache = new Map();
16
+ cacheBytes = 0;
17
+ constructor(bundle, rules) {
18
+ this.bundle = bundle;
19
+ this.rules = rules;
20
+ const entries = bundle.entries().map((entry, i) => ({ entry, i }));
21
+ entries.sort((a, b) => (a.entry.ts === b.entry.ts ? a.i - b.i : a.entry.ts < b.entry.ts ? -1 : 1));
22
+ entries.forEach(({ entry }, order) => {
23
+ const norm = this.normalizeEntry(entry);
24
+ const ix = { entry, norm, order };
25
+ this.all.push(ix);
26
+ this.byId.set(entry.id, ix);
27
+ push(this.byKey, norm.key, ix);
28
+ push(this.byPathKey, norm.pathKey, ix);
29
+ });
30
+ }
31
+ normalizeEntry(entry) {
32
+ return (0, normalize_1.normalizeRequest)({
33
+ method: entry.method,
34
+ url: entry.url,
35
+ contentType: entry.reqContentType,
36
+ body: entry.reqBody ? Buffer.from(entry.reqBody, 'base64') : undefined,
37
+ }, this.rules);
38
+ }
39
+ /** Earliest recorded exchange for a URL (exact string match), optionally by method. */
40
+ findByUrl(url, method = 'GET') {
41
+ return this.all.find((ix) => ix.entry.url === url && ix.entry.method === method);
42
+ }
43
+ async response(ix) {
44
+ const cached = this.cache.get(ix.entry.id);
45
+ if (cached)
46
+ return cached;
47
+ const own = await (0, warc_1.readResponseAt)(this.bundle.archivePath, { offset: ix.entry.respOffset, length: ix.entry.respLength });
48
+ let body = own.body;
49
+ if (ix.entry.revisitOf) {
50
+ const original = this.byId.get(ix.entry.revisitOf);
51
+ if (!original)
52
+ throw new Error(`revisit target missing: ${ix.entry.revisitOf}`);
53
+ body = (await this.response(original)).body;
54
+ }
55
+ const resp = { status: own.status, statusText: own.statusText, headers: own.headers, body };
56
+ this.remember(ix.entry.id, resp);
57
+ return resp;
58
+ }
59
+ remember(id, resp) {
60
+ this.cache.set(id, resp);
61
+ this.cacheBytes += resp.body.length;
62
+ for (const [k, v] of this.cache) {
63
+ if (this.cacheBytes <= CACHE_LIMIT_BYTES)
64
+ break;
65
+ this.cache.delete(k);
66
+ this.cacheBytes -= v.body.length;
67
+ }
68
+ }
69
+ }
70
+ exports.RecordStore = RecordStore;
71
+ function push(map, key, value) {
72
+ const list = map.get(key);
73
+ if (list)
74
+ list.push(value);
75
+ else
76
+ map.set(key, [value]);
77
+ }
78
+ //# sourceMappingURL=store.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"store.js","sourceRoot":"","sources":["../../../src/core/store.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,125 @@
1
+ export type HeaderList = [string, string][];
2
+ /** One HTTP request/response pair as captured from a real site. */
3
+ export interface Exchange {
4
+ id: string;
5
+ ts: string;
6
+ method: string;
7
+ url: string;
8
+ httpVersion: string;
9
+ reqHeaders: HeaderList;
10
+ reqBody?: Buffer;
11
+ status: number;
12
+ statusText: string;
13
+ respHeaders: HeaderList;
14
+ respBody: Buffer;
15
+ /** Content-Encoding the site used on the wire; the stored body is already decoded. */
16
+ originalContentEncoding?: string;
17
+ resourceType?: string;
18
+ /** Read from a WARC: stored header lines of the request and response that are not headers (see parseHeaderLines). */
19
+ malformedHeaderLines?: number;
20
+ }
21
+ /** Index row for one exchange inside a bundle (indexes/entries.jsonl). */
22
+ export interface Entry {
23
+ id: string;
24
+ ts: string;
25
+ method: string;
26
+ url: string;
27
+ status: number;
28
+ mime: string;
29
+ resourceType?: string;
30
+ reqContentType?: string;
31
+ /** Request body, base64, kept inline so keys can be recomputed without reading the WARC. */
32
+ reqBody?: string;
33
+ digest: string;
34
+ size: number;
35
+ reqOffset: number;
36
+ reqLength: number;
37
+ respOffset: number;
38
+ respLength: number;
39
+ /** Set when this response was stored as a revisit of an identical earlier payload. */
40
+ revisitOf?: string;
41
+ }
42
+ export type Kind = 'browse' | 'search' | 'promo' | 'stateful' | 'block' | 'static';
43
+ export interface EndpointRule {
44
+ name: string;
45
+ /** "METHOD /path/pattern" or "/path/pattern"; `*` one segment, `**` any segments, `{x}` captures one segment. */
46
+ match: string;
47
+ /** Host glob this endpoint is limited to; defaults to any host of the site. */
48
+ host?: string;
49
+ /** Template for the normalized path, e.g. "/dp/{asin}". */
50
+ key?: string;
51
+ kind?: Kind;
52
+ keep_params?: string[];
53
+ drop_params?: string[];
54
+ body_keep?: string[];
55
+ body_drop?: string[];
56
+ /** Query or body field holding free text (search) or a code (promo). */
57
+ text_param?: string;
58
+ /** Minimum token similarity for search matching (0-1). */
59
+ similarity?: number;
60
+ /** Allow same-path matching when the exact key is missing. GET defaults to true, bodies to false. */
61
+ fuzzy?: boolean;
62
+ /** Minimum share of query parameters that must agree for a fuzzy match. */
63
+ fuzzy_min?: number;
64
+ /** For promo endpoints: a code recorded as invalid, whose response answers unknown codes. */
65
+ invalid_code?: string;
66
+ }
67
+ export interface SiteRules {
68
+ site: string;
69
+ hosts: string[];
70
+ drop_params?: string[];
71
+ body_drop?: string[];
72
+ block?: string[];
73
+ /** Never stored: bot checks and other pages that must not be replayed ("host/path" globs). */
74
+ exclude?: string[];
75
+ /**
76
+ * Pages whose content follows what was done before them, such as the cart ("host/path" globs):
77
+ * replay answers them with the last recording instead of the first.
78
+ */
79
+ latest?: string[];
80
+ endpoints?: EndpointRule[];
81
+ /** URL of this site's own 404 page recorded during capture. */
82
+ not_found?: string;
83
+ /** Body returned for missed API requests of this site. */
84
+ xhr_not_found?: {
85
+ content_type: string;
86
+ body: string;
87
+ };
88
+ }
89
+ /** manifest.json: only what replay and import read. */
90
+ export interface Manifest {
91
+ /** Benchmark task this recording belongs to (tasks/<task_id>/). */
92
+ task_id: string;
93
+ /** Page clocks start here during replay. */
94
+ captured_from: string;
95
+ captured_to: string;
96
+ /** Each site's own 404 page, answered for documents replay cannot find. */
97
+ not_found: Record<string, string>;
98
+ /** Replay browsers use the recording's language and time zone. */
99
+ locale?: string;
100
+ timezone?: string;
101
+ /** Layout version of a recording published in a task (RECORDING_FORMAT); absent elsewhere. */
102
+ format?: number;
103
+ }
104
+ export interface StoredResponse {
105
+ status: number;
106
+ statusText: string;
107
+ headers: HeaderList;
108
+ body: Buffer;
109
+ }
110
+ export type Source = 'exact' | 'fuzzy' | 'search' | 'promo' | 'blocked' | 'preflight' | 'control' | 'miss';
111
+ export type ResourceClass = 'document' | 'xhr' | 'static' | 'tracker';
112
+ export interface ReplayRequest {
113
+ method: string;
114
+ url: string;
115
+ headers: Record<string, string | string[] | undefined>;
116
+ body?: Buffer;
117
+ }
118
+ export interface ReplayResponse extends StoredResponse {
119
+ source: Source;
120
+ key: string;
121
+ kind: Kind;
122
+ resourceClass: ResourceClass;
123
+ entryId?: string;
124
+ detail?: string;
125
+ }
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/core/types.ts"],"names":[],"mappings":""}