Files
bitvid/tests/nip71-mirror-sync.test.mjs
T
thePR0M3TH3ANandClaude Opus 4.8 685e52656b nip71: account-level "auto-share new public videos" toggle
Adds an opt-in account preference (off by default, per pubkey) that
auto-mirrors newly published eligible public videos to NIP-71
(kinds 34235/34236) so they surface on other Nostr video clients —
no per-video opt-in needed.

- nip71MirrorFlags: isAutoShareEnabled/setAutoShareEnabled (persisted
  per pubkey) + pure resolvePublishSync({featureOn,autoShare,eligible}).
- nip71MirrorSync: syncNip71MirrorAfterPublish + a videos:published
  subscription in initNip71MirrorSync; converts the canonical 30078
  event, checks eligibility (public + hosted URL + ALLOW_NSFW gate),
  publishes the mirror, and records the per-video flag so later
  edits/deletes stay in lockstep. All best-effort.
- My Videos pane: an "Auto-share new public videos to other Nostr apps"
  checkbox wired to setAutoShareEnabled, gated by FEATURE_NIP71_MIRROR.

Tests (mutation-verified): auto-share persistence, resolvePublishSync
(eligible+on=>publish; off/ineligible=>none), and videos:published
subscription wiring.

Co-Authored-By: Claude Opus 4.8 <[email protected]>
2026-06-22 14:06:19 -04:00

47 lines
1.8 KiB
JavaScript

// Auto-sync glue: keeps an opted-in NIP-71 mirror in lockstep on edit/delete,
// driven by nostrService's existing videos:edited/videos:deleted events (so the
// size-capped nostrService is untouched).
import "./test-helpers/setup-localstorage.mjs";
import assert from "node:assert/strict";
import test from "node:test";
import {
syncNip71MirrorAfterDelete,
initNip71MirrorSync,
} from "../js/services/nip71MirrorSync.js";
import { isMirrorEnabled, setMirrorEnabled } from "../js/services/nip71MirrorFlags.js";
const PK = "a".repeat(64);
test("deleting a SHARED video clears its opt-in flag (mirror torn down)", async () => {
localStorage.clear();
setMirrorEnabled(PK, "root-x", true);
await syncNip71MirrorAfterDelete({ videoRootId: "root-x", video: {}, pubkey: PK });
assert.equal(isMirrorEnabled(PK, "root-x"), false, "flag cleared after delete");
});
test("deleting a NON-shared video is a no-op (and never throws)", async () => {
localStorage.clear();
await syncNip71MirrorAfterDelete({ videoRootId: "root-y", video: {}, pubkey: PK });
assert.equal(isMirrorEnabled(PK, "root-y"), false);
});
test("initNip71MirrorSync subscribes to edit+delete events, idempotently", () => {
const events = {};
const svc = {
on(name, handler) {
(events[name] = events[name] || []).push(handler);
return () => {};
},
};
const off = initNip71MirrorSync(svc);
assert.equal(events["videos:edited"]?.length, 1, "subscribes to videos:edited");
assert.equal(events["videos:deleted"]?.length, 1, "subscribes to videos:deleted");
assert.equal(events["videos:published"]?.length, 1, "subscribes to videos:published");
initNip71MirrorSync(svc); // guard prevents double-registration
assert.equal(events["videos:edited"].length, 1, "no double-register");
off(); // resets the guard for other tests
});