@aryanduntley/pwa-debug 0.1.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,267 @@
1
+ (function (exports) {
2
+ 'use strict';
3
+
4
+ const PAGE_BRIDGE_NS = 'pwa-debug';
5
+ const encodeRequest = (input) => {
6
+ const base = {
7
+ ns: PAGE_BRIDGE_NS,
8
+ dir: 'cs->page',
9
+ requestId: input.requestId,
10
+ tool: input.tool,
11
+ };
12
+ return Object.freeze(input.payload === undefined ? base : { ...base, payload: input.payload });
13
+ };
14
+ const isPageBridgeNs = (v) => v === PAGE_BRIDGE_NS;
15
+ const isInboundPageToCs = (event) => {
16
+ if (event.source !== window)
17
+ return false;
18
+ const data = event.data;
19
+ if (data === null || typeof data !== 'object')
20
+ return false;
21
+ const r = data;
22
+ return (isPageBridgeNs(r['ns']) &&
23
+ r['dir'] === 'page->cs' &&
24
+ typeof r['requestId'] === 'string');
25
+ };
26
+ const isInboundPageEvent = (event) => {
27
+ if (event.source !== window)
28
+ return false;
29
+ const data = event.data;
30
+ if (data === null || typeof data !== 'object')
31
+ return false;
32
+ const r = data;
33
+ return (isPageBridgeNs(r['ns']) &&
34
+ r['dir'] === 'page-event' &&
35
+ 'event' in r);
36
+ };
37
+
38
+ // Single source of truth for opaque correlation-id generation.
39
+ //
40
+ // crypto.randomUUID() is unavailable on insecure origins (e.g.
41
+ // http://<LAN-IP> debug targets) and old runtimes — a real pwa-debug use
42
+ // case. Every id generator must therefore guard the call; this collapses
43
+ // the four hand-rolled guards (capture_fetch/xhr/websocket defaultIdGen +
44
+ // frame_meta cross-origin fallback) and the one UNGUARDED site
45
+ // (cs_dispatcher's default generateRequestId, which threw on such origins).
46
+ const cryptoRandomUUID = () => {
47
+ const c = globalThis.crypto;
48
+ return typeof c?.randomUUID === 'function' ? c.randomUUID() : undefined;
49
+ };
50
+ const fallback = (prefix) => `${prefix}${Date.now().toString(36)}_${Math.random().toString(36).slice(2, 10)}`;
51
+ // crypto.randomUUID() when available, else `${fallbackPrefix}<ts36>_<rand36>`.
52
+ // fallbackPrefix namespaces ONLY the fallback path, exactly preserving the
53
+ // prior per-producer f_/x_/w_ discriminators.
54
+ const safeRandomId = (fallbackPrefix = '') => cryptoRandomUUID() ?? fallback(fallbackPrefix);
55
+ // No-prefix convenience: the crypto-absent-safe replacement for a bare
56
+ // `crypto.randomUUID()` call.
57
+ const safeUuid = () => safeRandomId();
58
+
59
+ const PAGE_EVENT_SW_TAG = 'pwa-debug-page-event';
60
+ const DEFAULT_TIMEOUT_MS = 4000;
61
+ const defaultForwardEventToSw = (message) => {
62
+ try {
63
+ chrome.runtime.sendMessage(message);
64
+ }
65
+ catch {
66
+ // chrome.runtime missing (test env) or messaging port closed; events are
67
+ // fire-and-forget so dropping is acceptable.
68
+ }
69
+ };
70
+ const isCsToolRequest = (m) => {
71
+ if (m === null || typeof m !== 'object')
72
+ return false;
73
+ const r = m;
74
+ return typeof r['tool'] === 'string';
75
+ };
76
+ const createCsDispatcher = (input = {}) => {
77
+ const timeoutMs = input.timeoutMs ?? DEFAULT_TIMEOUT_MS;
78
+ const generateRequestId = input.generateRequestId ?? safeUuid;
79
+ const forwardEventToSw = input.forwardEventToSw ?? defaultForwardEventToSw;
80
+ const pending = new Map();
81
+ const finish = (requestId, response) => {
82
+ const entry = pending.get(requestId);
83
+ if (!entry)
84
+ return;
85
+ pending.delete(requestId);
86
+ clearTimeout(entry.timeoutHandle);
87
+ try {
88
+ entry.sendResponse(response);
89
+ }
90
+ catch {
91
+ // sendResponse throws if the SW message channel was closed; safe to ignore.
92
+ }
93
+ };
94
+ const handleSwRequest = (req, sendResponse) => {
95
+ const requestId = generateRequestId();
96
+ const envelope = encodeRequest({
97
+ requestId,
98
+ tool: req.tool,
99
+ payload: req.payload,
100
+ });
101
+ const timeoutHandle = setTimeout(() => {
102
+ finish(requestId, {
103
+ error: {
104
+ message: `page-bridge timeout after ${timeoutMs}ms (tool=${req.tool})`,
105
+ },
106
+ });
107
+ }, timeoutMs);
108
+ pending.set(requestId, { sendResponse, timeoutHandle });
109
+ window.postMessage(envelope, window.location.origin);
110
+ };
111
+ const handlePageMessage = (event) => {
112
+ if (isInboundPageToCs(event)) {
113
+ const env = event.data;
114
+ const response = {};
115
+ if (env.payload !== undefined) {
116
+ response.payload = env.payload;
117
+ }
118
+ if (env.error !== undefined) {
119
+ response.error = env.error;
120
+ }
121
+ finish(env.requestId, response);
122
+ return;
123
+ }
124
+ if (isInboundPageEvent(event)) {
125
+ const env = event.data;
126
+ forwardEventToSw({ tag: PAGE_EVENT_SW_TAG, event: env.event });
127
+ }
128
+ };
129
+ const dispose = () => {
130
+ for (const entry of pending.values()) {
131
+ clearTimeout(entry.timeoutHandle);
132
+ }
133
+ pending.clear();
134
+ };
135
+ return Object.freeze({ handleSwRequest, handlePageMessage, dispose });
136
+ };
137
+
138
+ const NOOP_DISPOSER = () => { };
139
+ const installCsLifecycleCapture = (input) => {
140
+ if (typeof window === 'undefined') {
141
+ return NOOP_DISPOSER;
142
+ }
143
+ const { frame, send, opts } = input;
144
+ if (opts?.enabled?.pagehide === false) {
145
+ return NOOP_DISPOSER;
146
+ }
147
+ let disposed = false;
148
+ const onPagehide = (e) => {
149
+ if (disposed)
150
+ return;
151
+ const persisted = e.persisted ?? false;
152
+ const event = Object.freeze({
153
+ kind: 'lifecycle',
154
+ source: 'cs',
155
+ subkind: 'pagehide',
156
+ persisted,
157
+ ts: Date.now(),
158
+ frameUrl: frame.frameUrl,
159
+ frameKey: frame.frameKey,
160
+ ...(frame.isCrossOrigin !== undefined ? { isCrossOrigin: frame.isCrossOrigin } : {}),
161
+ });
162
+ try {
163
+ send(event);
164
+ }
165
+ catch {
166
+ // CS-side send failures must never break the page.
167
+ }
168
+ };
169
+ window.addEventListener('pagehide', onPagehide);
170
+ return () => {
171
+ if (disposed)
172
+ return;
173
+ disposed = true;
174
+ window.removeEventListener('pagehide', onPagehide);
175
+ };
176
+ };
177
+
178
+ const TOP_KEY = 'top';
179
+ const indexInParent = (win, parent) => {
180
+ const len = parent.frames.length;
181
+ for (let i = 0; i < len; i++) {
182
+ if (parent.frames[i] === win)
183
+ return i;
184
+ }
185
+ return -1;
186
+ };
187
+ // Always namespaced with `cross_origin/` so a cross-origin frame key can
188
+ // never collide with a structural `top/...` key — the uuid source is the
189
+ // shared guarded generator.
190
+ const defaultFallback = () => `cross_origin/${safeUuid()}`;
191
+ const deriveFrameKey = (win, fallback = defaultFallback) => {
192
+ if (win === win.top)
193
+ return TOP_KEY;
194
+ const indices = [];
195
+ let memoizedFallback;
196
+ const cachedFallback = () => {
197
+ if (memoizedFallback === undefined)
198
+ memoizedFallback = fallback();
199
+ return memoizedFallback;
200
+ };
201
+ let current = win;
202
+ try {
203
+ while (current !== current.parent) {
204
+ const parent = current.parent;
205
+ const idx = indexInParent(current, parent);
206
+ if (idx < 0)
207
+ return cachedFallback();
208
+ indices.push(idx);
209
+ current = parent;
210
+ }
211
+ }
212
+ catch {
213
+ return cachedFallback();
214
+ }
215
+ indices.reverse();
216
+ return `${TOP_KEY}/${indices.join('/')}`;
217
+ };
218
+
219
+ const detectCrossOrigin = (win) => {
220
+ if (win === win.top)
221
+ return false;
222
+ try {
223
+ void win.parent.location.href;
224
+ return false;
225
+ }
226
+ catch {
227
+ return true;
228
+ }
229
+ };
230
+ const computeFrameMeta = (win = window) => ({
231
+ frameUrl: win.location.href,
232
+ frameKey: deriveFrameKey(win),
233
+ isCrossOrigin: detectCrossOrigin(win),
234
+ });
235
+
236
+ const bootstrap = () => {
237
+ const dispatcher = createCsDispatcher();
238
+ chrome.runtime.onMessage.addListener((msg, _sender, sendResponse) => {
239
+ if (!isCsToolRequest(msg))
240
+ return false;
241
+ dispatcher.handleSwRequest(msg, sendResponse);
242
+ return true;
243
+ });
244
+ window.addEventListener('message', (event) => {
245
+ dispatcher.handlePageMessage(event);
246
+ });
247
+ const frame = computeFrameMeta();
248
+ const sendLifecycle = (event) => {
249
+ try {
250
+ chrome.runtime.sendMessage({ tag: PAGE_EVENT_SW_TAG, event });
251
+ }
252
+ catch {
253
+ // Page may be tearing down; sendMessage failure is expected on the
254
+ // very last tick. The event is already best-effort.
255
+ }
256
+ };
257
+ installCsLifecycleCapture({ frame, send: sendLifecycle });
258
+ console.log('[pwa-debug/cs] attached at', location.href);
259
+ };
260
+ bootstrap();
261
+
262
+ exports.bootstrap = bootstrap;
263
+
264
+ return exports;
265
+
266
+ })({});
267
+ //# sourceMappingURL=content-script.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"content-script.js","sources":["../src/page_bridge/protocol.ts","../src/ids/safe_random_id.ts","../src/page_bridge/cs_dispatcher.ts","../src/captures/capture_cs_lifecycle.ts","../src/frame_meta/derive_frame_key.ts","../src/frame_meta/frame_meta.ts","../src/content-script.ts"],"sourcesContent":[null,null,null,null,null,null,null],"names":[],"mappings":"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"}
@@ -0,0 +1,30 @@
1
+ {
2
+ "manifest_version": 3,
3
+ "name": "PWA Debug Layer",
4
+ "version": "0.0.0",
5
+ "key": "MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAqORD1iZOB89zzCoA/bffPsUqxFXaeDCtN7U898HfmCvswf8UmSUTnUNkqtP8xNRY5Hl4MairGQHlMg295rRl+Z53XjjfFBGsoYT/l3DfrDcZPF2/hCRecxovaQSjF2O+lR2w/ysIqSpxANiHZNiVkHxNfqbsXOvOcc5RoU9drdMcOPNthogRO6lII7Cwss6tbq07LBW4drSmvGF09Xcj2G5xvlQNyJRjWVJm0RXMVrAo1kr49ELXdmnMTUv2zNijvX4u7ZYFnakoKYXBLNi3XW4df2bT04v32jCmwMhuKWHBzz2nKhVYmN6EycJCXP951zYfTgf2fmtXtkXxR9M2hwIDAQAB",
6
+ "description": "Browser-side debug layer that exposes live PWA state to AI agents via MCP. Stub build (M1).",
7
+ "minimum_chrome_version": "111",
8
+ "background": {
9
+ "service_worker": "service-worker.js",
10
+ "type": "module"
11
+ },
12
+ "content_scripts": [
13
+ {
14
+ "matches": ["<all_urls>"],
15
+ "js": ["content-script.js"],
16
+ "run_at": "document_start",
17
+ "world": "ISOLATED",
18
+ "all_frames": true
19
+ },
20
+ {
21
+ "matches": ["<all_urls>"],
22
+ "js": ["page-world.js"],
23
+ "run_at": "document_start",
24
+ "world": "MAIN",
25
+ "all_frames": true
26
+ }
27
+ ],
28
+ "permissions": ["scripting", "storage", "nativeMessaging", "webNavigation", "tabs"],
29
+ "host_permissions": ["<all_urls>"]
30
+ }