diff --git a/js/nostr.js b/js/nostr.js index c71fedec..e9ae089d 100644 --- a/js/nostr.js +++ b/js/nostr.js @@ -1,22 +1,33 @@ // js/nostr.js +// +// Compatibility shim that forwards legacy imports to the new domain-specific +// facades. Prefer importing from the facades directly in new modules so the +// wiring between the default client and helper layers stays explicit. -import { - nostrClient, - requestDefaultExtensionPermissions, -} from "./nostr/defaultClient.js"; - -export { nostrClient, requestDefaultExtensionPermissions }; +export { nostrClient, requestDefaultExtensionPermissions } from "./nostrClientFacade.js"; export { - recordVideoView, - listVideoViewEvents, - subscribeVideoViewEvents, - countVideoViewEvents, -} from "./nostr/viewEventBindings.js"; + recordVideoViewWithDefaultClient, + listVideoViewEventsWithDefaultClient, + subscribeVideoViewEventsWithDefaultClient, + countVideoViewEventsWithDefaultClient, +} from "./nostrViewEventsFacade.js"; export { - updateWatchHistoryList, - removeWatchHistoryItem, -} from "./nostr/watchHistoryBindings.js"; + updateWatchHistoryListWithDefaultClient, + removeWatchHistoryItemWithDefaultClient, +} from "./nostrWatchHistoryFacade.js"; + +export { + recordVideoViewWithDefaultClient as recordVideoView, + listVideoViewEventsWithDefaultClient as listVideoViewEvents, + subscribeVideoViewEventsWithDefaultClient as subscribeVideoViewEvents, + countVideoViewEventsWithDefaultClient as countVideoViewEvents, +} from "./nostrViewEventsFacade.js"; + +export { + updateWatchHistoryListWithDefaultClient as updateWatchHistoryList, + removeWatchHistoryItemWithDefaultClient as removeWatchHistoryItem, +} from "./nostrWatchHistoryFacade.js"; export * from "./nostr/index.js"; diff --git a/js/nostrClientFacade.js b/js/nostrClientFacade.js new file mode 100644 index 00000000..f05bd6b8 --- /dev/null +++ b/js/nostrClientFacade.js @@ -0,0 +1,11 @@ +// js/nostrClientFacade.js +// +// Compatibility-forwarding module that exposes the default Nostr client +// singleton alongside the convenience permission helper. +// Future modules should import from this facade instead of reaching into the +// nested default client implementation directly. + +export { + nostrClient, + requestDefaultExtensionPermissions, +} from "./nostr/defaultClient.js"; diff --git a/js/nostrViewEventsFacade.js b/js/nostrViewEventsFacade.js new file mode 100644 index 00000000..606e329e --- /dev/null +++ b/js/nostrViewEventsFacade.js @@ -0,0 +1,27 @@ +// js/nostrViewEventsFacade.js +// +// Central export for NIP-71 view event helpers. Consumers can choose between +// helpers that accept an explicit Nostr client and thin wrappers that call the +// default client instance configured by the app shell. + +export { + recordVideoView as recordVideoViewWithDefaultClient, + listVideoViewEvents as listVideoViewEventsWithDefaultClient, + subscribeVideoViewEvents as subscribeVideoViewEventsWithDefaultClient, + countVideoViewEvents as countVideoViewEventsWithDefaultClient, +} from "./nostr/viewEventBindings.js"; + +export { + VIEW_EVENT_KIND, + createVideoViewEventFilters, + deriveViewEventBucketIndex, + deriveViewEventPointerScope, + getViewEventGuardWindowMs, + hasRecentViewPublish, + rememberViewPublish, + publishViewEvent, + recordVideoView, + listVideoViewEvents, + subscribeVideoViewEvents, + countVideoViewEvents, +} from "./nostr/viewEvents.js"; diff --git a/js/nostrWatchHistoryFacade.js b/js/nostrWatchHistoryFacade.js new file mode 100644 index 00000000..0af147d7 --- /dev/null +++ b/js/nostrWatchHistoryFacade.js @@ -0,0 +1,10 @@ +// js/nostrWatchHistoryFacade.js +// +// Wrapper exports for watch history helpers that operate on the default Nostr +// client instance. Future consumers should import from this module rather than +// reaching into the binding layer directly. + +export { + updateWatchHistoryList as updateWatchHistoryListWithDefaultClient, + removeWatchHistoryItem as removeWatchHistoryItemWithDefaultClient, +} from "./nostr/watchHistoryBindings.js"; diff --git a/tests/nostr-view-event-bindings.test.mjs b/tests/nostr-view-event-bindings.test.mjs index 4ef68f0c..325c02fd 100644 --- a/tests/nostr-view-event-bindings.test.mjs +++ b/tests/nostr-view-event-bindings.test.mjs @@ -3,12 +3,12 @@ import "./test-helpers/setup-localstorage.mjs"; import assert from "node:assert/strict"; -const { nostrClient } = await import("../js/nostr.js"); +const { nostrClient } = await import("../js/nostrClientFacade.js"); const { - listVideoViewEvents, - subscribeVideoViewEvents, - countVideoViewEvents, -} = await import("../js/nostr/viewEventBindings.js"); + listVideoViewEventsWithDefaultClient, + subscribeVideoViewEventsWithDefaultClient, + countVideoViewEventsWithDefaultClient, +} = await import("../js/nostrViewEventsFacade.js"); function temporarilyUnset(client, methodName) { const original = client[methodName]; @@ -21,9 +21,12 @@ function temporarilyUnset(client, methodName) { async function testListBindingGuardsMissingMethod() { const restore = temporarilyUnset(nostrClient, "listVideoViewEvents"); try { - assert.throws(() => listVideoViewEvents({ type: "e", value: "guard" }), { - message: "Video view listing is unavailable in this build.", - }); + assert.throws( + () => listVideoViewEventsWithDefaultClient({ type: "e", value: "guard" }), + { + message: "Video view listing is unavailable in this build.", + } + ); } finally { restore(); } @@ -33,7 +36,8 @@ async function testSubscribeBindingGuardsMissingMethod() { const restore = temporarilyUnset(nostrClient, "subscribeVideoViewEvents"); try { assert.throws( - () => subscribeVideoViewEvents({ type: "e", value: "guard" }), + () => + subscribeVideoViewEventsWithDefaultClient({ type: "e", value: "guard" }), { message: "Video view subscriptions are unavailable in this build.", } @@ -46,9 +50,12 @@ async function testSubscribeBindingGuardsMissingMethod() { async function testCountBindingGuardsMissingMethod() { const restore = temporarilyUnset(nostrClient, "countVideoViewEvents"); try { - assert.throws(() => countVideoViewEvents({ type: "e", value: "guard" }), { - message: "Video view counting is unavailable in this build.", - }); + assert.throws( + () => countVideoViewEventsWithDefaultClient({ type: "e", value: "guard" }), + { + message: "Video view counting is unavailable in this build.", + } + ); } finally { restore(); } @@ -65,7 +72,7 @@ async function testListBindingPassesThroughWhenAvailable() { return sentinel; }; try { - const result = await listVideoViewEvents(pointer, options); + const result = await listVideoViewEventsWithDefaultClient(pointer, options); assert.equal(result, sentinel, "binding should return the client result"); assert.deepEqual( receivedArgs, @@ -89,7 +96,7 @@ async function testSubscribeBindingPassesThroughWhenAvailable() { return unsubscribe; }; try { - const result = subscribeVideoViewEvents(pointer, options); + const result = subscribeVideoViewEventsWithDefaultClient(pointer, options); assert.equal(result, unsubscribe, "binding should return unsubscribe value"); assert.deepEqual( receivedArgs, @@ -112,7 +119,7 @@ async function testCountBindingPassesThroughWhenAvailable() { return sentinel; }; try { - const result = await countVideoViewEvents(pointer, options); + const result = await countVideoViewEventsWithDefaultClient(pointer, options); assert.equal(result, sentinel, "binding should return the client result"); assert.deepEqual( receivedArgs, diff --git a/tests/nostr/nostrClientFacade.test.js b/tests/nostr/nostrClientFacade.test.js new file mode 100644 index 00000000..b9b74c19 --- /dev/null +++ b/tests/nostr/nostrClientFacade.test.js @@ -0,0 +1,27 @@ +import assert from "node:assert/strict"; +import test from "node:test"; + +import { + nostrClient as facadeClient, + requestDefaultExtensionPermissions as facadeRequest, +} from "../../js/nostrClientFacade.js"; +import { + nostrClient as directClient, + requestDefaultExtensionPermissions as directRequest, +} from "../../js/nostr/defaultClient.js"; + +test("nostrClientFacade forwards the default client instance", () => { + assert.equal( + facadeClient, + directClient, + "facade should expose the default client singleton", + ); +}); + +test("nostrClientFacade forwards the default permission helper", async () => { + assert.equal( + facadeRequest, + directRequest, + "facade should reuse the registered permission helper", + ); +}); diff --git a/tests/nostr/watchHistoryBindings.test.js b/tests/nostr/watchHistoryBindings.test.js index 5d6f95c2..3fbc0218 100644 --- a/tests/nostr/watchHistoryBindings.test.js +++ b/tests/nostr/watchHistoryBindings.test.js @@ -1,11 +1,11 @@ import assert from "node:assert/strict"; import test from "node:test"; -import { nostrClient } from "../../js/nostr/defaultClient.js"; +import { nostrClient } from "../../js/nostrClientFacade.js"; import { - updateWatchHistoryList, - removeWatchHistoryItem, -} from "../../js/nostr/watchHistoryBindings.js"; + updateWatchHistoryListWithDefaultClient as updateWatchHistoryList, + removeWatchHistoryItemWithDefaultClient as removeWatchHistoryItem, +} from "../../js/nostrWatchHistoryFacade.js"; const originalWatchHistory = nostrClient.watchHistory;