mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
This commit instruments the embed runtime to forward structured logs and lifecycle events (Nostr, relay, pointer resolution, playback decision, WebTorrent) to the parent window via `postMessage` when the `embed_debug=1` query parameter is present. It also adds a defensive guard to `resetTorrentStats` in `js/app.js` to prevent TypeErrors. Changes: - Added `js/embedDiagnostics.js` module. - Modified `js/embed.js` to initialize diagnostics and instrument startup. - Modified `js/app.js` to instrument playback fallback and patch `resetTorrentStats`. - Modified `js/webtorrent.js` to instrument peer probing and streaming.
178 lines
4.3 KiB
JavaScript
178 lines
4.3 KiB
JavaScript
// js/embedDiagnostics.js
|
|
|
|
let activeEmitter = null;
|
|
|
|
export function initEmbedDiagnostics({ enabled = true } = {}) {
|
|
if (!enabled) {
|
|
return { emit: () => {} };
|
|
}
|
|
|
|
function postToParent(type, payload) {
|
|
try {
|
|
// NOTE: using "*" so tester receives messages; in a production build you may restrict origin.
|
|
if (window.parent && window.parent !== window) {
|
|
window.parent.postMessage({ __bitvid_debug: true, type, payload }, "*");
|
|
}
|
|
} catch (e) {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
function safeStringify(obj, max = 2000) {
|
|
try {
|
|
const s = JSON.stringify(
|
|
obj,
|
|
(k, v) => {
|
|
if (typeof v === "string" && v.length > 1000)
|
|
return v.slice(0, 1000) + "…";
|
|
// redact likely sensitive fields
|
|
if (k && /key|secret|sk|priv|pass|token/i.test(k)) return "[REDACTED]";
|
|
return v;
|
|
},
|
|
2
|
|
);
|
|
return s.length > max ? s.slice(0, max) + "…" : s;
|
|
} catch (e) {
|
|
try {
|
|
return String(obj);
|
|
} catch (e2) {
|
|
return "[unserializable]";
|
|
}
|
|
}
|
|
}
|
|
|
|
// console wrappers
|
|
["log", "info", "warn", "error", "debug"].forEach((lvl) => {
|
|
// eslint-disable-next-line no-console
|
|
const orig = console[lvl] ? console[lvl].bind(console) : null;
|
|
if (orig) {
|
|
// eslint-disable-next-line no-console
|
|
console[lvl] = (...args) => {
|
|
try {
|
|
postToParent("console", {
|
|
level: lvl,
|
|
args: args.map((a) =>
|
|
typeof a === "string" ? a : safeStringify(a, 1000)
|
|
),
|
|
});
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
try {
|
|
orig(...args);
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
};
|
|
}
|
|
});
|
|
|
|
// global errors
|
|
window.addEventListener(
|
|
"error",
|
|
(ev) => {
|
|
try {
|
|
const payload = {
|
|
message: ev.message,
|
|
filename: ev.filename,
|
|
lineno: ev.lineno,
|
|
colno: ev.colno,
|
|
stack: ev.error && ev.error.stack ? ev.error.stack : null,
|
|
};
|
|
postToParent("error", payload);
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
},
|
|
true
|
|
);
|
|
|
|
window.addEventListener("unhandledrejection", (ev) => {
|
|
try {
|
|
const reason =
|
|
ev && ev.reason
|
|
? ev.reason && ev.reason.stack
|
|
? ev.reason.stack
|
|
: safeStringify(ev.reason)
|
|
: "unknown";
|
|
postToParent("unhandledrejection", { reason });
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
});
|
|
|
|
// light fetch/XHR monitoring (failures only)
|
|
(function wrapFetch() {
|
|
if (!window.fetch) return;
|
|
const orig = window.fetch.bind(window);
|
|
window.fetch = async (...args) => {
|
|
try {
|
|
const res = await orig(...args);
|
|
if (!res.ok) {
|
|
postToParent("fetch-error", {
|
|
url: args[0],
|
|
status: res.status,
|
|
statusText: res.statusText,
|
|
});
|
|
}
|
|
return res;
|
|
} catch (err) {
|
|
postToParent("fetch-exception", { url: args[0], error: String(err) });
|
|
throw err;
|
|
}
|
|
};
|
|
})();
|
|
|
|
(function wrapXhr() {
|
|
try {
|
|
const origOpen = XMLHttpRequest.prototype.open;
|
|
const origSend = XMLHttpRequest.prototype.send;
|
|
XMLHttpRequest.prototype.open = function (...args) {
|
|
this.__embed_diag_url = args[1];
|
|
return origOpen.apply(this, args);
|
|
};
|
|
XMLHttpRequest.prototype.send = function (...args) {
|
|
try {
|
|
this.addEventListener("error", () =>
|
|
postToParent("xhr-error", { url: this.__embed_diag_url })
|
|
);
|
|
this.addEventListener("load", () => {
|
|
if (this.status >= 400)
|
|
postToParent("xhr-status", {
|
|
url: this.__embed_diag_url,
|
|
status: this.status,
|
|
});
|
|
});
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
return origSend.apply(this, args);
|
|
};
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
})();
|
|
|
|
function emitEmbedEvent(name, payload = {}) {
|
|
try {
|
|
postToParent("embed-event", { name, payload });
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
}
|
|
|
|
activeEmitter = emitEmbedEvent;
|
|
|
|
return { emit: emitEmbedEvent };
|
|
}
|
|
|
|
export function emit(name, payload) {
|
|
if (activeEmitter) {
|
|
try {
|
|
activeEmitter(name, payload);
|
|
} catch (e) {
|
|
/* no-op */
|
|
}
|
|
}
|
|
}
|