mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-27 16:02:26 +00:00
File-size decomposition (no behavior change). Move the dependency-free encode/ decode helpers (sanitizeWatchHistoryMetadata, serializeWatchHistoryItems, bytesToHex, looksLikeJsonStructure, hexToBytesCompat) into a new js/nostr/watchHistoryCodec.js and import them back. watchHistory.js: 2512 -> 2435 lines (back under its 2438 limit). Build + full unit suite green. Co-Authored-By: Claude Opus 4.8 <[email protected]>
89 lines
2.5 KiB
JavaScript
89 lines
2.5 KiB
JavaScript
// js/nostr/watchHistoryCodec.js
|
|
//
|
|
// Pure, dependency-free encode/decode helpers extracted from watchHistory.js to
|
|
// keep that module under the file-size budget. No behavior change.
|
|
|
|
export function sanitizeWatchHistoryMetadata(metadata) {
|
|
return {};
|
|
}
|
|
|
|
export function serializeWatchHistoryItems(items) {
|
|
if (!Array.isArray(items) || items.length === 0) {
|
|
return "[]";
|
|
}
|
|
const normalized = items
|
|
.map((item) => {
|
|
const type = item?.type === "a" ? "a" : "e";
|
|
const value = typeof item?.value === "string" ? item.value : "";
|
|
if (!type || !value) {
|
|
return null;
|
|
}
|
|
const relay =
|
|
typeof item?.relay === "string" && item.relay.trim()
|
|
? item.relay.trim()
|
|
: undefined;
|
|
const watchedAt = Number.isFinite(item?.watchedAt)
|
|
? Math.max(0, Math.floor(item.watchedAt))
|
|
: undefined;
|
|
const payload = { type, value };
|
|
if (relay) {
|
|
payload.relay = relay;
|
|
}
|
|
if (watchedAt !== undefined) {
|
|
payload.watchedAt = watchedAt;
|
|
}
|
|
const resumeAt = Number.isFinite(item?.resumeAt)
|
|
? Math.max(0, Math.floor(item.resumeAt))
|
|
: undefined;
|
|
if (resumeAt !== undefined) {
|
|
payload.resumeAt = resumeAt;
|
|
}
|
|
if (item?.completed === true) {
|
|
payload.completed = true;
|
|
}
|
|
return payload;
|
|
})
|
|
.filter(Boolean);
|
|
return JSON.stringify(normalized);
|
|
}
|
|
|
|
export function bytesToHex(bytes) {
|
|
return Array.from(bytes)
|
|
.map((byte) => byte.toString(16).padStart(2, "0"))
|
|
.join("");
|
|
}
|
|
|
|
export function looksLikeJsonStructure(content) {
|
|
if (typeof content !== "string") {
|
|
return false;
|
|
}
|
|
const trimmed = content.trim();
|
|
if (!trimmed) {
|
|
return false;
|
|
}
|
|
const first = trimmed[0];
|
|
return first === "{" || first === "[";
|
|
}
|
|
|
|
export function hexToBytesCompat(hex, tools = null) {
|
|
if (typeof hex !== "string") {
|
|
throw new Error("Invalid hex input.");
|
|
}
|
|
const trimmed = hex.trim();
|
|
if (!trimmed || trimmed.length % 2 !== 0) {
|
|
throw new Error("Invalid hex input.");
|
|
}
|
|
if (tools?.utils && typeof tools.utils.hexToBytes === "function") {
|
|
return tools.utils.hexToBytes(trimmed);
|
|
}
|
|
const bytes = new Uint8Array(trimmed.length / 2);
|
|
for (let index = 0; index < trimmed.length; index += 2) {
|
|
const byte = Number.parseInt(trimmed.slice(index, index + 2), 16);
|
|
if (Number.isNaN(byte)) {
|
|
throw new Error("Invalid hex input.");
|
|
}
|
|
bytes[index / 2] = byte;
|
|
}
|
|
return bytes;
|
|
}
|