mirror of
https://github.com/PR0M3TH3AN/bitvid.git
synced 2026-10-29 08:52:25 +00:00
Merge pull request #795 from PR0M3TH3AN/codex/create-and-migrate-nostr-toolkit-module
Refactor nostr toolkit helpers
This commit is contained in:
6 files changed
+415
-229
No files matched your search
@@ -2,9 +2,9 @@
|
||||
|
||||
import {
|
||||
nostrClient,
|
||||
DEFAULT_RELAY_URLS,
|
||||
convertEventToVideo as sharedConvertEventToVideo
|
||||
convertEventToVideo as sharedConvertEventToVideo,
|
||||
} from "./nostr.js";
|
||||
import { DEFAULT_RELAY_URLS } from "./nostr/toolkit.js";
|
||||
import { subscriptions } from "./subscriptions.js";
|
||||
import { attachHealthBadges } from "./gridHealth.js";
|
||||
import { attachUrlHealthBadges } from "./urlHealthObserver.js";
|
||||
|
||||
+10
-225
@@ -44,23 +44,17 @@ import {
|
||||
assertAnyRelayAccepted,
|
||||
summarizePublishResults,
|
||||
} from "./nostrPublish.js";
|
||||
import { nostrToolsReady } from "./nostrToolsBootstrap.js";
|
||||
import {
|
||||
DEFAULT_RELAY_URLS,
|
||||
RELAY_URLS,
|
||||
ensureNostrTools,
|
||||
getCachedNostrTools,
|
||||
nostrToolsBootstrapFailure,
|
||||
readToolkitFromScope,
|
||||
resolveSimplePoolConstructor,
|
||||
} from "./nostr/toolkit.js";
|
||||
import { devLogger, userLogger } from "./utils/logger.js";
|
||||
|
||||
/**
|
||||
* The default relay set bitvid bootstraps with before loading a user's
|
||||
* preferences.
|
||||
*/
|
||||
export const DEFAULT_RELAY_URLS = Object.freeze([
|
||||
"wss://relay.damus.io",
|
||||
"wss://nos.lol",
|
||||
"wss://relay.snort.social",
|
||||
"wss://relay.primal.net",
|
||||
"wss://relay.nostr.band",
|
||||
]);
|
||||
|
||||
const RELAY_URLS = Array.from(DEFAULT_RELAY_URLS);
|
||||
|
||||
let activeSigner = null;
|
||||
|
||||
const EVENTS_CACHE_STORAGE_KEY = "bitvid:eventsCache:v1";
|
||||
@@ -413,215 +407,6 @@ const VIEW_EVENT_KIND = Number.isFinite(VIEW_EVENT_SCHEMA?.kind)
|
||||
? VIEW_EVENT_SCHEMA.kind
|
||||
: 30079;
|
||||
|
||||
const globalScope =
|
||||
typeof window !== "undefined"
|
||||
? window
|
||||
: typeof globalThis !== "undefined"
|
||||
? globalThis
|
||||
: null;
|
||||
|
||||
const nostrToolsReadySource =
|
||||
globalScope &&
|
||||
globalScope.nostrToolsReady &&
|
||||
typeof globalScope.nostrToolsReady.then === "function"
|
||||
? globalScope.nostrToolsReady
|
||||
: nostrToolsReady;
|
||||
|
||||
function normalizeToolkitCandidate(candidate) {
|
||||
if (
|
||||
candidate &&
|
||||
typeof candidate === "object" &&
|
||||
candidate.ok !== false &&
|
||||
typeof candidate.then !== "function"
|
||||
) {
|
||||
return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
function readToolkitFromScope(scope = globalScope) {
|
||||
if (!scope || typeof scope !== "object") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const candidates = [];
|
||||
|
||||
const canonical = scope.__BITVID_CANONICAL_NOSTR_TOOLS__;
|
||||
if (canonical) {
|
||||
candidates.push(canonical);
|
||||
}
|
||||
|
||||
const direct = scope.NostrTools;
|
||||
if (direct) {
|
||||
candidates.push(direct);
|
||||
}
|
||||
|
||||
const nestedWindow =
|
||||
scope.window && scope.window !== scope && typeof scope.window === "object"
|
||||
? scope.window
|
||||
: null;
|
||||
if (nestedWindow) {
|
||||
if (nestedWindow.__BITVID_CANONICAL_NOSTR_TOOLS__) {
|
||||
candidates.push(nestedWindow.__BITVID_CANONICAL_NOSTR_TOOLS__);
|
||||
}
|
||||
if (nestedWindow.NostrTools) {
|
||||
candidates.push(nestedWindow.NostrTools);
|
||||
}
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
const normalized = normalizeToolkitCandidate(candidate);
|
||||
if (normalized) {
|
||||
return normalized;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const __nostrToolsBootstrapResult = await (async () => {
|
||||
try {
|
||||
const result = await nostrToolsReadySource;
|
||||
if (result && typeof result === "object" && result.ok === false) {
|
||||
return {
|
||||
toolkit: normalizeToolkitCandidate(readToolkitFromScope()),
|
||||
failure: result,
|
||||
};
|
||||
}
|
||||
|
||||
const normalized = normalizeToolkitCandidate(result);
|
||||
if (normalized) {
|
||||
return { toolkit: normalized, failure: null };
|
||||
}
|
||||
|
||||
return {
|
||||
toolkit: normalizeToolkitCandidate(readToolkitFromScope()),
|
||||
failure: null,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
toolkit: normalizeToolkitCandidate(readToolkitFromScope()),
|
||||
failure: error,
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
let cachedNostrTools = __nostrToolsBootstrapResult.toolkit || null;
|
||||
const nostrToolsBootstrapFailure = __nostrToolsBootstrapResult.failure || null;
|
||||
|
||||
if (!cachedNostrTools && nostrToolsBootstrapFailure && isDevMode) {
|
||||
userLogger.warn(
|
||||
"[nostr] nostr-tools helpers unavailable after bootstrap.",
|
||||
nostrToolsBootstrapFailure
|
||||
);
|
||||
}
|
||||
|
||||
function rememberNostrTools(candidate) {
|
||||
const normalized = normalizeToolkitCandidate(candidate);
|
||||
if (normalized) {
|
||||
cachedNostrTools = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
function getCachedNostrTools() {
|
||||
const fallback = readToolkitFromScope();
|
||||
if (cachedNostrTools && fallback && fallback !== cachedNostrTools) {
|
||||
rememberNostrTools(fallback);
|
||||
} else if (!cachedNostrTools && fallback) {
|
||||
rememberNostrTools(fallback);
|
||||
}
|
||||
return cachedNostrTools || fallback || null;
|
||||
}
|
||||
|
||||
async function ensureNostrTools() {
|
||||
if (cachedNostrTools) {
|
||||
return cachedNostrTools;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await nostrToolsReadySource;
|
||||
rememberNostrTools(result);
|
||||
} catch (error) {
|
||||
devLogger.warn("[nostr] Failed to resolve nostr-tools helpers.", error);
|
||||
}
|
||||
|
||||
if (!cachedNostrTools) {
|
||||
rememberNostrTools(readToolkitFromScope());
|
||||
}
|
||||
|
||||
return cachedNostrTools || null;
|
||||
}
|
||||
|
||||
function isSimplePoolConstructor(candidate) {
|
||||
if (typeof candidate !== "function") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const prototype = candidate.prototype;
|
||||
if (!prototype || typeof prototype !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return typeof prototype.sub === "function" && typeof prototype.close === "function";
|
||||
}
|
||||
|
||||
function unwrapSimplePool(candidate) {
|
||||
if (!candidate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isSimplePoolConstructor(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
if (typeof candidate === "object") {
|
||||
if (isSimplePoolConstructor(candidate.SimplePool)) {
|
||||
return candidate.SimplePool;
|
||||
}
|
||||
if (isSimplePoolConstructor(candidate.default)) {
|
||||
return candidate.default;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
function resolveSimplePoolConstructor(tools, scope = globalScope) {
|
||||
const candidates = [
|
||||
tools?.SimplePool,
|
||||
tools?.pool?.SimplePool,
|
||||
tools?.pool,
|
||||
tools?.SimplePool?.SimplePool,
|
||||
tools?.SimplePool?.default,
|
||||
tools?.pool?.default,
|
||||
tools?.default?.SimplePool,
|
||||
tools?.default?.pool?.SimplePool,
|
||||
tools?.default?.pool,
|
||||
];
|
||||
|
||||
if (scope && typeof scope === "object") {
|
||||
candidates.push(scope?.SimplePool);
|
||||
candidates.push(scope?.pool?.SimplePool);
|
||||
candidates.push(scope?.pool);
|
||||
const scopedTools =
|
||||
scope?.NostrTools && scope.NostrTools !== tools ? scope.NostrTools : null;
|
||||
if (scopedTools) {
|
||||
candidates.push(scopedTools.SimplePool);
|
||||
candidates.push(scopedTools.pool?.SimplePool);
|
||||
candidates.push(scopedTools.pool);
|
||||
}
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
const resolved = unwrapSimplePool(candidate);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
let ingestLocalViewEventRef = null;
|
||||
|
||||
async function loadIngestLocalViewEvent() {
|
||||
@@ -5188,7 +4973,7 @@ function decodeNpubToHex(npub) {
|
||||
trimmed
|
||||
);
|
||||
|
||||
let tools = cachedNostrTools;
|
||||
let tools = getCachedNostrTools();
|
||||
if (!tools || typeof tools?.nip19?.decode !== "function") {
|
||||
const fallbackTools = readToolkitFromScope();
|
||||
if (fallbackTools) {
|
||||
|
||||
@@ -0,0 +1,234 @@
|
||||
// js/nostr/toolkit.js
|
||||
|
||||
import { isDevMode } from "../config.js";
|
||||
import { nostrToolsReady } from "../nostrToolsBootstrap.js";
|
||||
import { devLogger, userLogger } from "../utils/logger.js";
|
||||
|
||||
/**
|
||||
* The default relay set bitvid bootstraps with before loading a user's
|
||||
* preferences.
|
||||
*/
|
||||
export const DEFAULT_RELAY_URLS = Object.freeze([
|
||||
"wss://relay.damus.io",
|
||||
"wss://nos.lol",
|
||||
"wss://relay.snort.social",
|
||||
"wss://relay.primal.net",
|
||||
"wss://relay.nostr.band",
|
||||
]);
|
||||
|
||||
export const RELAY_URLS = Array.from(DEFAULT_RELAY_URLS);
|
||||
|
||||
const globalScope =
|
||||
typeof window !== "undefined"
|
||||
? window
|
||||
: typeof globalThis !== "undefined"
|
||||
? globalThis
|
||||
: null;
|
||||
|
||||
const nostrToolsReadySource =
|
||||
globalScope &&
|
||||
globalScope.nostrToolsReady &&
|
||||
typeof globalScope.nostrToolsReady.then === "function"
|
||||
? globalScope.nostrToolsReady
|
||||
: nostrToolsReady;
|
||||
|
||||
export function normalizeToolkitCandidate(candidate) {
|
||||
if (
|
||||
candidate &&
|
||||
typeof candidate === "object" &&
|
||||
candidate.ok !== false &&
|
||||
typeof candidate.then !== "function"
|
||||
) {
|
||||
return candidate;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
export function readToolkitFromScope(scope = globalScope) {
|
||||
if (!scope || typeof scope !== "object") {
|
||||
return null;
|
||||
}
|
||||
|
||||
const candidates = [];
|
||||
|
||||
const canonical = scope.__BITVID_CANONICAL_NOSTR_TOOLS__;
|
||||
if (canonical) {
|
||||
candidates.push(canonical);
|
||||
}
|
||||
|
||||
const direct = scope.NostrTools;
|
||||
if (direct) {
|
||||
candidates.push(direct);
|
||||
}
|
||||
|
||||
const nestedWindow =
|
||||
scope.window && scope.window !== scope && typeof scope.window === "object"
|
||||
? scope.window
|
||||
: null;
|
||||
if (nestedWindow) {
|
||||
if (nestedWindow.__BITVID_CANONICAL_NOSTR_TOOLS__) {
|
||||
candidates.push(nestedWindow.__BITVID_CANONICAL_NOSTR_TOOLS__);
|
||||
}
|
||||
if (nestedWindow.NostrTools) {
|
||||
candidates.push(nestedWindow.NostrTools);
|
||||
}
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
const normalized = normalizeToolkitCandidate(candidate);
|
||||
if (normalized) {
|
||||
return normalized;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
const __nostrToolsBootstrapResult = await (async () => {
|
||||
try {
|
||||
const result = await nostrToolsReadySource;
|
||||
if (result && typeof result === "object" && result.ok === false) {
|
||||
return {
|
||||
toolkit: normalizeToolkitCandidate(readToolkitFromScope()),
|
||||
failure: result,
|
||||
};
|
||||
}
|
||||
|
||||
const normalized = normalizeToolkitCandidate(result);
|
||||
if (normalized) {
|
||||
return { toolkit: normalized, failure: null };
|
||||
}
|
||||
|
||||
return {
|
||||
toolkit: normalizeToolkitCandidate(readToolkitFromScope()),
|
||||
failure: null,
|
||||
};
|
||||
} catch (error) {
|
||||
return {
|
||||
toolkit: normalizeToolkitCandidate(readToolkitFromScope()),
|
||||
failure: error,
|
||||
};
|
||||
}
|
||||
})();
|
||||
|
||||
let cachedNostrTools = __nostrToolsBootstrapResult.toolkit || null;
|
||||
export const nostrToolsBootstrapFailure =
|
||||
__nostrToolsBootstrapResult.failure || null;
|
||||
|
||||
if (!cachedNostrTools && nostrToolsBootstrapFailure && isDevMode) {
|
||||
userLogger.warn(
|
||||
"[nostr] nostr-tools helpers unavailable after bootstrap.",
|
||||
nostrToolsBootstrapFailure
|
||||
);
|
||||
}
|
||||
|
||||
export function rememberNostrTools(candidate) {
|
||||
const normalized = normalizeToolkitCandidate(candidate);
|
||||
if (normalized) {
|
||||
cachedNostrTools = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
export function getCachedNostrTools() {
|
||||
const fallback = readToolkitFromScope();
|
||||
if (cachedNostrTools && fallback && fallback !== cachedNostrTools) {
|
||||
rememberNostrTools(fallback);
|
||||
} else if (!cachedNostrTools && fallback) {
|
||||
rememberNostrTools(fallback);
|
||||
}
|
||||
return cachedNostrTools || fallback || null;
|
||||
}
|
||||
|
||||
export async function ensureNostrTools() {
|
||||
if (cachedNostrTools) {
|
||||
return cachedNostrTools;
|
||||
}
|
||||
|
||||
try {
|
||||
const result = await nostrToolsReadySource;
|
||||
rememberNostrTools(result);
|
||||
} catch (error) {
|
||||
devLogger.warn("[nostr] Failed to resolve nostr-tools helpers.", error);
|
||||
}
|
||||
|
||||
if (!cachedNostrTools) {
|
||||
rememberNostrTools(readToolkitFromScope());
|
||||
}
|
||||
|
||||
return cachedNostrTools || null;
|
||||
}
|
||||
|
||||
function isSimplePoolConstructor(candidate) {
|
||||
if (typeof candidate !== "function") {
|
||||
return false;
|
||||
}
|
||||
|
||||
const prototype = candidate.prototype;
|
||||
if (!prototype || typeof prototype !== "object") {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (
|
||||
typeof prototype.sub === "function" &&
|
||||
typeof prototype.close === "function"
|
||||
);
|
||||
}
|
||||
|
||||
function unwrapSimplePool(candidate) {
|
||||
if (!candidate) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (isSimplePoolConstructor(candidate)) {
|
||||
return candidate;
|
||||
}
|
||||
|
||||
if (typeof candidate === "object") {
|
||||
if (isSimplePoolConstructor(candidate.SimplePool)) {
|
||||
return candidate.SimplePool;
|
||||
}
|
||||
if (isSimplePoolConstructor(candidate.default)) {
|
||||
return candidate.default;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export function resolveSimplePoolConstructor(tools, scope = globalScope) {
|
||||
const candidates = [
|
||||
tools?.SimplePool,
|
||||
tools?.pool?.SimplePool,
|
||||
tools?.pool,
|
||||
tools?.SimplePool?.SimplePool,
|
||||
tools?.SimplePool?.default,
|
||||
tools?.pool?.default,
|
||||
tools?.default?.SimplePool,
|
||||
tools?.default?.pool?.SimplePool,
|
||||
tools?.default?.pool,
|
||||
];
|
||||
|
||||
if (scope && typeof scope === "object") {
|
||||
candidates.push(scope?.SimplePool);
|
||||
candidates.push(scope?.pool?.SimplePool);
|
||||
candidates.push(scope?.pool);
|
||||
const scopedTools =
|
||||
scope?.NostrTools && scope.NostrTools !== tools ? scope.NostrTools : null;
|
||||
if (scopedTools) {
|
||||
candidates.push(scopedTools.SimplePool);
|
||||
candidates.push(scopedTools.pool?.SimplePool);
|
||||
candidates.push(scopedTools.pool);
|
||||
}
|
||||
}
|
||||
|
||||
for (const candidate of candidates) {
|
||||
const resolved = unwrapSimplePool(candidate);
|
||||
if (resolved) {
|
||||
return resolved;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
export { isSimplePoolConstructor, unwrapSimplePool };
|
||||
+1
-1
@@ -1,6 +1,6 @@
|
||||
import { isDevMode } from "./config.js";
|
||||
import { DEFAULT_RELAY_URLS } from "./nostr/toolkit.js";
|
||||
import {
|
||||
DEFAULT_RELAY_URLS,
|
||||
getActiveSigner,
|
||||
nostrClient,
|
||||
requestDefaultExtensionPermissions,
|
||||
|
||||
+1
-1
@@ -4,8 +4,8 @@ import {
|
||||
nostrClient,
|
||||
convertEventToVideo as sharedConvertEventToVideo,
|
||||
requestDefaultExtensionPermissions,
|
||||
DEFAULT_RELAY_URLS,
|
||||
} from "./nostr.js";
|
||||
import { DEFAULT_RELAY_URLS } from "./nostr/toolkit.js";
|
||||
import {
|
||||
buildSubscriptionListEvent,
|
||||
SUBSCRIPTION_LIST_IDENTIFIER
|
||||
|
||||
@@ -0,0 +1,167 @@
|
||||
import assert from "node:assert/strict";
|
||||
import test from "node:test";
|
||||
|
||||
const originalCanonical = globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__;
|
||||
const originalNostrTools = globalThis.NostrTools;
|
||||
const originalNostrToolsReady = globalThis.nostrToolsReady;
|
||||
|
||||
class BootstrapSimplePool {
|
||||
sub() {}
|
||||
close() {}
|
||||
}
|
||||
|
||||
const bootstrapToolkit = {
|
||||
ok: true,
|
||||
nip19: {
|
||||
decode: (value) => value,
|
||||
npubEncode: (value) => value,
|
||||
},
|
||||
SimplePool: BootstrapSimplePool,
|
||||
};
|
||||
|
||||
globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__ = bootstrapToolkit;
|
||||
globalThis.NostrTools = bootstrapToolkit;
|
||||
globalThis.nostrToolsReady = Promise.resolve(bootstrapToolkit);
|
||||
|
||||
const toolkitModule = await import("../../js/nostr/toolkit.js");
|
||||
const {
|
||||
rememberNostrTools,
|
||||
getCachedNostrTools,
|
||||
ensureNostrTools,
|
||||
resolveSimplePoolConstructor,
|
||||
} = toolkitModule;
|
||||
|
||||
const baselineToolkit = getCachedNostrTools() || bootstrapToolkit;
|
||||
|
||||
test.after(() => {
|
||||
if (originalCanonical === undefined) {
|
||||
delete globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__;
|
||||
} else {
|
||||
globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__ = originalCanonical;
|
||||
}
|
||||
|
||||
if (originalNostrTools === undefined) {
|
||||
delete globalThis.NostrTools;
|
||||
} else {
|
||||
globalThis.NostrTools = originalNostrTools;
|
||||
}
|
||||
|
||||
if (originalNostrToolsReady === undefined) {
|
||||
delete globalThis.nostrToolsReady;
|
||||
} else {
|
||||
globalThis.nostrToolsReady = originalNostrToolsReady;
|
||||
}
|
||||
|
||||
rememberNostrTools(baselineToolkit);
|
||||
});
|
||||
|
||||
test("ensureNostrTools resolves the cached toolkit", async () => {
|
||||
class CachedSimplePool {
|
||||
sub() {}
|
||||
close() {}
|
||||
}
|
||||
|
||||
const cachedToolkit = {
|
||||
ok: true,
|
||||
nip19: {
|
||||
decode: (value) => value,
|
||||
npubEncode: (value) => value,
|
||||
},
|
||||
SimplePool: CachedSimplePool,
|
||||
};
|
||||
|
||||
const previousCanonicalForTest = globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__;
|
||||
const previousNostrToolsForTest = globalThis.NostrTools;
|
||||
|
||||
globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__ = cachedToolkit;
|
||||
globalThis.NostrTools = cachedToolkit;
|
||||
rememberNostrTools(cachedToolkit);
|
||||
|
||||
try {
|
||||
const ensured = await ensureNostrTools();
|
||||
assert.strictEqual(ensured, cachedToolkit);
|
||||
} finally {
|
||||
if (previousCanonicalForTest === undefined) {
|
||||
delete globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__;
|
||||
} else {
|
||||
globalThis.__BITVID_CANONICAL_NOSTR_TOOLS__ = previousCanonicalForTest;
|
||||
}
|
||||
|
||||
if (previousNostrToolsForTest === undefined) {
|
||||
delete globalThis.NostrTools;
|
||||
} else {
|
||||
globalThis.NostrTools = previousNostrToolsForTest;
|
||||
}
|
||||
|
||||
rememberNostrTools(baselineToolkit);
|
||||
}
|
||||
});
|
||||
|
||||
test("resolveSimplePoolConstructor handles supported permutations", () => {
|
||||
class MockSimplePool {
|
||||
sub() {}
|
||||
close() {}
|
||||
}
|
||||
|
||||
const variations = [
|
||||
{ label: "tools.SimplePool", tools: { SimplePool: MockSimplePool } },
|
||||
{ label: "tools.pool.SimplePool", tools: { pool: { SimplePool: MockSimplePool } } },
|
||||
{ label: "tools.pool constructor", tools: { pool: MockSimplePool } },
|
||||
{
|
||||
label: "tools.SimplePool.SimplePool",
|
||||
tools: { SimplePool: { SimplePool: MockSimplePool } },
|
||||
},
|
||||
{
|
||||
label: "tools.SimplePool.default",
|
||||
tools: { SimplePool: { default: MockSimplePool } },
|
||||
},
|
||||
{ label: "tools.pool.default", tools: { pool: { default: MockSimplePool } } },
|
||||
{
|
||||
label: "tools.default.SimplePool",
|
||||
tools: { default: { SimplePool: MockSimplePool } },
|
||||
},
|
||||
{
|
||||
label: "tools.default.pool.SimplePool",
|
||||
tools: { default: { pool: { SimplePool: MockSimplePool } } },
|
||||
},
|
||||
{
|
||||
label: "tools.default.pool constructor",
|
||||
tools: { default: { pool: MockSimplePool } },
|
||||
},
|
||||
];
|
||||
|
||||
for (const { label, tools } of variations) {
|
||||
assert.strictEqual(
|
||||
resolveSimplePoolConstructor(tools),
|
||||
MockSimplePool,
|
||||
`expected ${label}`
|
||||
);
|
||||
}
|
||||
|
||||
assert.strictEqual(
|
||||
resolveSimplePoolConstructor({}, { SimplePool: MockSimplePool }),
|
||||
MockSimplePool,
|
||||
"scope.SimplePool fallback"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
resolveSimplePoolConstructor({}, { pool: { SimplePool: MockSimplePool } }),
|
||||
MockSimplePool,
|
||||
"scope.pool.SimplePool fallback"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
resolveSimplePoolConstructor(
|
||||
{},
|
||||
{ NostrTools: { pool: { SimplePool: MockSimplePool } } }
|
||||
),
|
||||
MockSimplePool,
|
||||
"scope.NostrTools.pool.SimplePool fallback"
|
||||
);
|
||||
|
||||
assert.strictEqual(
|
||||
resolveSimplePoolConstructor({}, {}),
|
||||
null,
|
||||
"returns null when no candidates are available"
|
||||
);
|
||||
});
|
||||
Reference in new issue
Block a user