@qntx/nostr 0.4.1 → 0.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{client-C6EultPx.mjs → client-CadO5fAX.mjs} +33 -3
- package/dist/client-CadO5fAX.mjs.map +1 -0
- package/dist/client.d.mts +2 -2
- package/dist/client.mjs +1 -1
- package/dist/{index-BP4UmZKF.d.mts → index-CNl2q67H.d.mts} +20 -5
- package/dist/{index-skvsYz00.d.mts → index-lvXeER5t.d.mts} +3 -3
- package/dist/{index-D-TK_KJG.d.mts → index-q4MDce_r.d.mts} +2 -2
- package/dist/index.d.mts +6 -6
- package/dist/index.mjs +3 -3
- package/dist/instance-CIca-ynn.d.mts +15 -0
- package/dist/instance-DQE8BoWt.mjs +221 -0
- package/dist/instance-DQE8BoWt.mjs.map +1 -0
- package/dist/loaders.d.mts +1 -1
- package/dist/nostr_crypto_wasm_bg.wasm +0 -0
- package/dist/{pool-BGVx59yd.mjs → pool-As20OGxB.mjs} +95 -34
- package/dist/pool-As20OGxB.mjs.map +1 -0
- package/dist/{pool-B7p_reAm.d.mts → pool-DBIYMtwy.d.mts} +42 -4
- package/dist/{reactive-DFpqtIf_.d.mts → reactive-7aqeip4A.d.mts} +3 -1
- package/dist/{reactive-DDlThDSZ.mjs → reactive-BfhPp9a3.mjs} +38 -4
- package/dist/reactive-BfhPp9a3.mjs.map +1 -0
- package/dist/relay.d.mts +3 -3
- package/dist/relay.mjs +1 -1
- package/dist/store.d.mts +1 -1
- package/dist/store.mjs +1 -1
- package/dist/wasm.browser.d.mts +8 -0
- package/dist/wasm.browser.mjs +19 -0
- package/dist/wasm.browser.mjs.map +1 -0
- package/dist/wasm.d.mts +1 -11
- package/dist/wasm.mjs +6 -207
- package/dist/wasm.mjs.map +1 -1
- package/package.json +10 -3
- package/dist/client-C6EultPx.mjs.map +0 -1
- package/dist/pool-BGVx59yd.mjs.map +0 -1
- package/dist/reactive-DDlThDSZ.mjs.map +0 -1
|
@@ -5,7 +5,7 @@ import { t as EventBuilder } from "./builder-9tjI6WQ3.mjs";
|
|
|
5
5
|
import { n as canonicalizeFilters, o as matchFilters, t as canonicalizeFilter } from "./filter-BQl3GlHt.mjs";
|
|
6
6
|
import { t as NoSignerError } from "./error-B__OMBRY.mjs";
|
|
7
7
|
import { t as invokeSafely } from "./report-CHld4uWj.mjs";
|
|
8
|
-
import { n as fanIn, r as fetchRouted, t as Pool } from "./pool-
|
|
8
|
+
import { n as fanIn, r as fetchRouted, t as Pool } from "./pool-As20OGxB.mjs";
|
|
9
9
|
import { r as throwIfAborted } from "./abort-Ba8tDrOI.mjs";
|
|
10
10
|
import { storageFromItems } from "./nips/nip77.mjs";
|
|
11
11
|
import { isGiftWrapKind, requireNip59Crypto, unwrap } from "./nips/nip59.mjs";
|
|
@@ -15,7 +15,7 @@ import { i as createOutboxFeed, t as createLoaders } from "./loaders-o6YXB_Ri.mj
|
|
|
15
15
|
import { n as toStorageError } from "./error-DrEIM7FO.mjs";
|
|
16
16
|
import { t as MemoryIndex } from "./memory-index-Do1mz0WF.mjs";
|
|
17
17
|
import { t as MemoryEventStore } from "./memory-C2EVx0_O.mjs";
|
|
18
|
-
import { t as ReactiveEventStore } from "./reactive-
|
|
18
|
+
import { t as ReactiveEventStore } from "./reactive-BfhPp9a3.mjs";
|
|
19
19
|
//#region src/client/builder.ts
|
|
20
20
|
/**
|
|
21
21
|
* Fluent constructor for {@link Client}. The constructor is supplied by {@link Client.builder} so
|
|
@@ -906,6 +906,36 @@ var Client = class Client {
|
|
|
906
906
|
for (const e of merged) if (tmp.put(e) === "ephemeral" && matchFilters(filters, e)) ephemeral.set(e.id, e);
|
|
907
907
|
return sortedEvents([...tmp.query(filters), ...ephemeral.values()]);
|
|
908
908
|
}
|
|
909
|
+
/**
|
|
910
|
+
* One-shot fetch with per-relay results: each entry reports its events and end reason (`eose`,
|
|
911
|
+
* `closed`, `timeout`, or `failed` when the relay could not be reached). Events are ingested into
|
|
912
|
+
* the index with each relay's URL in `seenOn` and persisted exactly like {@link fetchEvents}
|
|
913
|
+
* (`observe` defaults to true). No gossip routing and no local merge.
|
|
914
|
+
*/
|
|
915
|
+
async fetchEach(filter, opts) {
|
|
916
|
+
this.#assertAlive();
|
|
917
|
+
const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);
|
|
918
|
+
const results = await this.pool.fetchEach(this.#defaultRelays(opts?.relays), filters, {
|
|
919
|
+
timeoutMs: opts?.timeoutMs,
|
|
920
|
+
signal: opts?.signal
|
|
921
|
+
});
|
|
922
|
+
if (this.#wantObserve(opts?.observe)) {
|
|
923
|
+
const unique = [];
|
|
924
|
+
const seen = /* @__PURE__ */ new Set();
|
|
925
|
+
for (const result of results) for (const event of result.events) {
|
|
926
|
+
this.#ingest(event, result.url, {
|
|
927
|
+
persist: false,
|
|
928
|
+
meta: false
|
|
929
|
+
});
|
|
930
|
+
if (!seen.has(event.id)) {
|
|
931
|
+
seen.add(event.id);
|
|
932
|
+
unique.push(event);
|
|
933
|
+
}
|
|
934
|
+
}
|
|
935
|
+
for (const event of unique) this.observe(event);
|
|
936
|
+
}
|
|
937
|
+
return results;
|
|
938
|
+
}
|
|
909
939
|
/** Query local storage only (no network). */
|
|
910
940
|
async queryLocal(filter) {
|
|
911
941
|
this.#assertAlive();
|
|
@@ -1009,4 +1039,4 @@ var Client = class Client {
|
|
|
1009
1039
|
//#endregion
|
|
1010
1040
|
export { ClientBuilder as i, ClientError as n, SyncDirection as r, Client as t };
|
|
1011
1041
|
|
|
1012
|
-
//# sourceMappingURL=client-
|
|
1042
|
+
//# sourceMappingURL=client-CadO5fAX.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client-CadO5fAX.mjs","names":[],"sources":["../src/client/builder.ts","../src/client/dm.ts","../src/client/types.ts","../src/client/gossip-io.ts","../src/client/sync.ts","../src/client/client.ts"],"sourcesContent":["import type { Event } from \"../core/event.ts\";\nimport type { Gossip } from \"../gossip/gossip.ts\";\nimport type { InvalidEventPolicy } from \"../relay/pool.ts\";\nimport type { WebSocketConstructor } from \"../relay/websocket.ts\";\nimport type { NostrSigner } from \"../signer/types.ts\";\nimport type { StorageError } from \"../storage/error.ts\";\nimport type { EventStore } from \"../storage/types.ts\";\nimport type { ReactiveEventStore } from \"../store/reactive.ts\";\nimport type { Client } from \"./client.ts\";\nimport type { ClientOptions } from \"./types.ts\";\n\n/**\n * Fluent constructor for {@link Client}. The constructor is supplied by {@link Client.builder} so\n * this module never imports the `Client` value, keeping the client/builder dependency\n * one-directional.\n */\nexport class ClientBuilder {\n #opts: ClientOptions = {};\n readonly #newClient: (opts: ClientOptions) => Client;\n\n constructor(newClient: (opts: ClientOptions) => Client) {\n this.#newClient = newClient;\n }\n\n signer(signer: NostrSigner): this {\n this.#opts = { ...this.#opts, signer };\n return this;\n }\n\n relays(urls: ReadonlyArray<string>): this {\n this.#opts = { ...this.#opts, relays: [...urls] };\n return this;\n }\n\n addRelay(url: string): this {\n this.#opts = { ...this.#opts, relays: [...(this.#opts.relays ?? []), url] };\n return this;\n }\n\n websocketImplementation(impl: WebSocketConstructor): this {\n this.#opts = { ...this.#opts, websocketImplementation: impl };\n return this;\n }\n\n verifyEvent(fn: (event: Event) => boolean): this {\n this.#opts = { ...this.#opts, verifyEvent: fn };\n return this;\n }\n\n connectTimeoutMs(ms: number): this {\n this.#opts = { ...this.#opts, connectTimeoutMs: ms };\n return this;\n }\n\n publishTimeoutMs(ms: number): this {\n this.#opts = { ...this.#opts, publishTimeoutMs: ms };\n return this;\n }\n\n automaticAuth(enabled: boolean): this {\n this.#opts = { ...this.#opts, automaticAuth: enabled };\n return this;\n }\n\n /** Allow `ws://` relays. Default false. */\n allowInsecure(allow: boolean): this {\n this.#opts = { ...this.#opts, allowInsecure: allow };\n return this;\n }\n\n /** `ws://` URLs allowed despite `allowInsecure` being off. */\n trustedInsecureUrls(urls: ReadonlyArray<string>): this {\n this.#opts = { ...this.#opts, trustedInsecureUrls: urls };\n return this;\n }\n\n /** Close idle relays after this many ms. Unset = disabled. */\n idleTimeoutMs(ms: number): this {\n this.#opts = { ...this.#opts, idleTimeoutMs: ms };\n return this;\n }\n\n /** Soft cap on connected non-pinned relays. */\n maxRelays(n: number): this {\n this.#opts = { ...this.#opts, maxRelays: n };\n return this;\n }\n\n /** Relays never closed by idle cleanup or `maxRelays` eviction. */\n pinnedUrls(urls: ReadonlyArray<string>): this {\n this.#opts = { ...this.#opts, pinnedUrls: urls };\n return this;\n }\n\n /** Forwarded to the pool: suspend a relay delivering too many invalid events. */\n invalidEventPolicy(policy: InvalidEventPolicy): this {\n this.#opts = { ...this.#opts, invalidEventPolicy: policy };\n return this;\n }\n\n /** Forwarded to the pool: fired once when a relay is suspended, with the lift time. */\n onRelaySuspended(cb: (url: string, until: number) => void): this {\n this.#opts = { ...this.#opts, onRelaySuspended: cb };\n return this;\n }\n\n enableReconnect(enabled: boolean): this {\n this.#opts = { ...this.#opts, enableReconnect: enabled };\n return this;\n }\n\n enablePing(enabled: boolean): this {\n this.#opts = { ...this.#opts, enablePing: enabled };\n return this;\n }\n\n pingIntervalMs(ms: number): this {\n this.#opts = { ...this.#opts, pingIntervalMs: ms };\n return this;\n }\n\n pingTimeoutMs(ms: number): this {\n this.#opts = { ...this.#opts, pingTimeoutMs: ms };\n return this;\n }\n\n /**\n * Local event store. Defaults to {@link MemoryEventStore}. Browser apps that want persistence must\n * pass {@link IndexedDbEventStore} and `await open()`.\n */\n storage(store: EventStore): this {\n this.#opts = { ...this.#opts, storage: store };\n return this;\n }\n\n /**\n * Synchronous reactive index mirroring ingested events. Defaults to a new\n * {@link ReactiveEventStore}.\n */\n index(index: ReactiveEventStore): this {\n this.#opts = { ...this.#opts, index };\n return this;\n }\n\n /** When false, Client will not auto-write events to storage. Default true. */\n persistEvents(enabled: boolean): this {\n this.#opts = { ...this.#opts, persistEvents: enabled };\n return this;\n }\n\n gossip(gossip: Gossip): this {\n this.#opts = { ...this.#opts, gossip };\n return this;\n }\n\n onstorageerror(fn: (err: StorageError) => void): this {\n this.#opts = { ...this.#opts, onstorageerror: fn };\n return this;\n }\n\n build(): Client {\n return this.#newClient(this.#opts);\n }\n}\n","import type { EventBuilder } from \"../core/builder.ts\";\nimport type { Event } from \"../core/event.ts\";\nimport { itemCompare } from \"../core/event.ts\";\nimport { Kind } from \"../core/kind.ts\";\nimport type { Gossip } from \"../gossip/gossip.ts\";\nimport {\n Nip17Error,\n buildChatMessageRumor,\n dmRelayListEventBuilder,\n normalizeRecipients,\n requireDmRelays,\n wrapDirectMessage,\n} from \"../nips/nip17.ts\";\nimport type { Recipient } from \"../nips/nip17.ts\";\nimport { unwrap } from \"../nips/nip59.ts\";\nimport type { Nip59Crypto } from \"../nips/nip59.ts\";\nimport type { Pool, PoolPublishResult } from \"../relay/pool.ts\";\nimport type {\n FetchPrivateMessagesOptions,\n PrivateMessageSendResult,\n PublishOptions,\n ReceivedPrivateMessage,\n SendPrivateMessageOptions,\n SubscribePrivateMessagesOptions,\n} from \"./types.ts\";\n\nexport type DmDeps = {\n pool: Pool;\n gossip: Gossip;\n hydrateGossip: (pubkeys: ReadonlyArray<string>) => Promise<void>;\n ingest: (event: Event, relayUrl?: string) => void;\n markSeen: (id: string, relayUrl: string) => void;\n assertAlive: () => void;\n requireNip59Crypto: () => Nip59Crypto;\n throwIfAborted: (signal?: AbortSignal) => void;\n wantObserve: (flag?: boolean) => boolean;\n publish: (\n eventOrBuilder: Event | EventBuilder,\n opts?: PublishOptions,\n ) => Promise<PoolPublishResult[]>;\n};\n\nexport function giftWrapRelays(gossip: Gossip, event: Event): string[] {\n const targets: string[] = [];\n for (const tag of event.tags) {\n if (tag[0] === \"p\" && tag[1] !== undefined && tag[1] !== \"\") {\n targets.push(tag[1].toLowerCase());\n }\n }\n if (targets.length === 0) {\n throw new Nip17Error(\"gift wrap has no p-tag recipient\");\n }\n const [target] = targets;\n if (targets.length !== 1 || target === undefined) {\n throw new Nip17Error(\"gift wrap must have exactly one p-tag recipient\");\n }\n const relays = gossip.dmRelays(target);\n if (relays.length === 0) {\n throw new Nip17Error(\"no kind 10050 in gossip; use sendPrivateMessage or pass relays\");\n }\n return relays;\n}\n\nexport async function setDmRelays(\n deps: DmDeps,\n relays: ReadonlyArray<string>,\n opts?: PublishOptions,\n): Promise<PoolPublishResult[]> {\n return deps.publish(dmRelayListEventBuilder(relays), { gossip: true, ...opts });\n}\n\nexport async function sendPrivateMessage(\n deps: DmDeps,\n recipients: string | Recipient | ReadonlyArray<string | Recipient>,\n content: string,\n opts?: SendPrivateMessageOptions,\n): Promise<PrivateMessageSendResult> {\n deps.assertAlive();\n const crypto = deps.requireNip59Crypto();\n const sender = await crypto.getPublicKey();\n const list = normalizeRecipients(recipients);\n if (list.length === 0) {\n throw new Nip17Error(\"recipients must not be empty\");\n }\n\n const targets = new Set<string>([sender.toLowerCase(), ...list.map((r) => r.pubkey)]);\n await deps.hydrateGossip([...targets]);\n for (const pk of targets) {\n requireDmRelays(pk, deps.gossip.dmRelays(pk));\n }\n\n const rumor = buildChatMessageRumor(sender, list, content, {\n created_at: opts?.created_at,\n subject: opts?.subject,\n replyTo: opts?.replyTo,\n });\n const wraps = await wrapDirectMessage(crypto, list, rumor);\n const sent = await Promise.all(\n wraps.map(async ({ recipient, wrap }) => {\n const relays = requireDmRelays(recipient, deps.gossip.dmRelays(recipient));\n const results = await deps.pool.publish(relays, wrap, { timeoutMs: opts?.timeoutMs });\n if (results.some((r) => r.result?.ok === true) && deps.wantObserve(opts?.observe)) {\n deps.ingest(wrap);\n }\n return { recipient, wrap, results };\n }),\n );\n return { rumor, wraps: sent };\n}\n\nexport async function fetchPrivateMessages(\n deps: DmDeps,\n opts?: FetchPrivateMessagesOptions,\n): Promise<ReceivedPrivateMessage[]> {\n deps.assertAlive();\n const crypto = deps.requireNip59Crypto();\n const self = await crypto.getPublicKey();\n deps.throwIfAborted(opts?.signal);\n await deps.hydrateGossip([self]);\n deps.throwIfAborted(opts?.signal);\n const relays = requireDmRelays(self, deps.gossip.dmRelays(self));\n const urls = new Map<string, Set<string>>();\n const events = await deps.pool.fetch(\n relays,\n [\n {\n kinds: [Kind.GiftWrap],\n \"#p\": [self],\n since: opts?.since,\n until: opts?.until,\n },\n ],\n {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n onevent: (event, relayUrl) => {\n let set = urls.get(event.id);\n if (!set) {\n urls.set(event.id, (set = new Set()));\n }\n set.add(relayUrl);\n },\n },\n );\n\n const byRumor = new Map<string, ReceivedPrivateMessage>();\n for (const wrap of events) {\n try {\n // oxlint-disable-next-line no-await-in-loop -- unwraps run serially so ingest/seenOn keep relay order\n const rumor = await unwrap(crypto, wrap);\n const wrapUrls = urls.get(wrap.id);\n const firstUrl = wrapUrls?.values().next().value;\n if (deps.wantObserve(opts?.observe)) {\n deps.ingest(wrap, firstUrl);\n // Every other relay that delivered the same wrap is recorded too.\n if (wrapUrls) {\n for (const url of wrapUrls) {\n if (url !== firstUrl) {\n deps.markSeen(wrap.id, url);\n }\n }\n }\n }\n byRumor.set(rumor.id, {\n wrap,\n rumor,\n ...(firstUrl === undefined ? {} : { relayUrl: firstUrl }),\n });\n } catch {\n // junk / forgery / key mismatch — not stored\n }\n }\n\n return [...byRumor.values()].sort((a, b) => itemCompare(a.rumor, b.rumor));\n}\n\nexport async function subscribePrivateMessages(\n deps: DmDeps,\n opts?: SubscribePrivateMessagesOptions,\n): Promise<{ close: (reason?: string) => void }> {\n deps.assertAlive();\n const crypto = deps.requireNip59Crypto();\n const self = await crypto.getPublicKey();\n deps.throwIfAborted(opts?.signal);\n await deps.hydrateGossip([self]);\n deps.throwIfAborted(opts?.signal);\n const relays = requireDmRelays(self, deps.gossip.dmRelays(self));\n\n const seen = new Set<string>();\n // Wrap ids processed (observed) already; receipts before that are buffered\n // so every delivering relay URL lands in seenOn once the wrap is indexed.\n const processed = new Set<string>();\n const pendingUrls = new Map<string, string[]>();\n const flushSeen = (wrapId: string): void => {\n processed.add(wrapId);\n const extra = pendingUrls.get(wrapId);\n if (extra === undefined) {\n return;\n }\n pendingUrls.delete(wrapId);\n for (const url of extra) {\n deps.markSeen(wrapId, url);\n }\n };\n let tail = Promise.resolve();\n let closed = false;\n const markClosed = (): void => {\n closed = true;\n };\n if (opts?.signal?.aborted === true) {\n markClosed();\n } else {\n opts?.signal?.addEventListener(\"abort\", markClosed, { once: true });\n }\n\n const inner = deps.pool.subscribe(\n relays,\n // 21059 is ephemeral (relays MUST NOT store); live inbox has to REQ it.\n [{ kinds: [Kind.GiftWrap, Kind.GiftWrapEphemeral], \"#p\": [self], since: opts?.since }],\n {\n signal: opts?.signal,\n oneose: opts?.oneose,\n onclose: (reason) => {\n markClosed();\n opts?.onclose?.(reason);\n },\n eoseTimeoutMs: opts?.eoseTimeoutMs,\n receivedEvent: (id, relayUrl) => {\n if (closed) {\n return;\n }\n if (processed.has(id)) {\n deps.markSeen(id, relayUrl);\n return;\n }\n const list = pendingUrls.get(id);\n if (list === undefined) {\n pendingUrls.set(id, [relayUrl]);\n } else if (!list.includes(relayUrl)) {\n list.push(relayUrl);\n }\n },\n onevent: (wrap, relayUrl) => {\n if (closed) {\n return;\n }\n const prev = tail;\n let release: (() => void) | undefined;\n tail = new Promise<void>((resolve) => {\n release = resolve;\n });\n void (async () => {\n await prev;\n try {\n if (closed) {\n return;\n }\n const rumor = await unwrap(crypto, wrap);\n if (closed) {\n return;\n }\n if (seen.has(rumor.id)) {\n flushSeen(wrap.id);\n return;\n }\n seen.add(rumor.id);\n if (deps.wantObserve(opts?.observe)) {\n deps.ingest(wrap, relayUrl);\n }\n flushSeen(wrap.id);\n opts?.onevent?.({ wrap, rumor, relayUrl });\n } catch {\n // junk / forgery — not stored; keep the queue alive if a handler throws\n } finally {\n release?.();\n }\n })();\n },\n },\n );\n\n return {\n close: (reason?: string) => {\n markClosed();\n inner.close(reason);\n },\n };\n}\n","import { NostrError } from \"../core/error.ts\";\nimport type { Event } from \"../core/event.ts\";\nimport type { Gossip } from \"../gossip/gossip.ts\";\nimport type { ReplyTo } from \"../nips/nip17.ts\";\nimport type { Rumor } from \"../nips/nip59.ts\";\nimport type { InvalidEventPolicy, PoolPublishResult } from \"../relay/pool.ts\";\nimport type { WebSocketConstructor } from \"../relay/websocket.ts\";\nimport type { NostrSigner } from \"../signer/types.ts\";\nimport type { StorageError } from \"../storage/error.ts\";\nimport type { EventStore } from \"../storage/types.ts\";\nimport type { ReactiveEventStore } from \"../store/reactive.ts\";\n\n/** Direction of a {@link Client.sync} run: upload, download, or both. */\nexport const SyncDirection = {\n Up: \"up\",\n Down: \"down\",\n Both: \"both\",\n} as const;\n\n/** Union of the {@link SyncDirection} values. */\nexport type SyncDirectionName = (typeof SyncDirection)[keyof typeof SyncDirection];\n\n/** Options for {@link Client.sync} (NIP-77 set reconciliation). */\nexport type SyncOptions = {\n relays?: ReadonlyArray<string>;\n direction?: SyncDirectionName;\n /**\n * Wall-clock deadline for the Negentropy reconciliation session (`NEG-OPEN` through `NEG-CLOSE`),\n * in milliseconds. One clock for the whole session — not reset per `NEG-MSG`. Default: the relay\n * `publishTimeoutMs`. Upload/download phases reuse this value as their per-call timeout.\n */\n timeoutMs?: number;\n signal?: AbortSignal;\n dryRun?: boolean;\n /** When false, skip observe/storage on downloaded events. Default true. */\n observe?: boolean;\n};\n\n/** Outcome of a {@link Client.sync} run: ids compared, sent, received, and failures. */\nexport type SyncSummary = {\n local: string[];\n remote: string[];\n sent: string[];\n received: string[];\n sendFailures: Record<string, string>;\n persistFailures: Record<string, string>;\n};\n\n/** Options for {@link Client.builder} / `ClientOptions` accepted by the builder. */\nexport type ClientOptions = {\n signer?: NostrSigner;\n relays?: ReadonlyArray<string>;\n websocketImplementation?: WebSocketConstructor;\n /** Injected EVENT verifier. Default is core BIP-340. */\n verifyEvent?: (event: Event) => boolean;\n connectTimeoutMs?: number;\n publishTimeoutMs?: number;\n /**\n * When true (default), answer NIP-42 AUTH automatically. The signer is read at challenge time, so\n * `setSigner()` applies to live connections; challenges received while no signer is set are\n * ignored.\n */\n automaticAuth?: boolean;\n /** When true (default), relays reconnect with backoff after disconnect. */\n enableReconnect?: boolean;\n /** Keepalive ping. Default false. */\n enablePing?: boolean;\n pingIntervalMs?: number;\n pingTimeoutMs?: number;\n /** Forwarded to the pool: when false (default), `ws://` relays are rejected. */\n allowInsecure?: boolean;\n /** Forwarded to the pool: `ws://` URLs allowed despite `allowInsecure`. */\n trustedInsecureUrls?: ReadonlyArray<string>;\n /** Forwarded to the pool: close idle relays after this many ms. */\n idleTimeoutMs?: number;\n /** Forwarded to the pool: soft cap on connected non-pinned relays. */\n maxRelays?: number;\n /** Forwarded to the pool: relays never closed by idle cleanup or `maxRelays`. */\n pinnedUrls?: ReadonlyArray<string>;\n /**\n * Forwarded to the pool: a relay exceeding `limit` verification failures inside `windowMs` is\n * disconnected and suspended for `cooldownMs`.\n */\n invalidEventPolicy?: InvalidEventPolicy;\n /** Forwarded to the pool: fired once when a relay is suspended, with the lift time. */\n onRelaySuspended?: (url: string, until: number) => void;\n gossip?: Gossip;\n /**\n * Local event store. Defaults to {@link MemoryEventStore}. Browser apps that want persistence must\n * pass {@link IndexedDbEventStore} and `await open()`.\n */\n storage?: EventStore;\n /**\n * Synchronous reactive index that mirrors every ingested event before callbacks and persistence.\n * Defaults to a new {@link ReactiveEventStore}.\n */\n index?: ReactiveEventStore;\n /**\n * When true (default), every ingested event is written to storage. Set false to disable automatic\n * persistence while keeping the store for manual use.\n */\n persistEvents?: boolean;\n /**\n * Storage I/O failures: live `putMany` flush and `fetchEvents({ localFirst: true })` query. Those\n * paths do not throw.\n */\n onstorageerror?: (err: StorageError) => void;\n};\n\nexport type FetchEventsOptions = {\n relays?: string[];\n timeoutMs?: number;\n signal?: AbortSignal;\n gossip?: boolean;\n /** When true, query local storage first and merge with network results. Defaults to false. */\n localFirst?: boolean;\n /** When false, skip writing fetched events to storage/observe. Default true. */\n observe?: boolean;\n /**\n * Every event of every relay batch, including duplicates across relays. `relayUrl` is the\n * normalized URL of the relay that delivered it.\n */\n onevent?: (event: Event, relayUrl: string) => void;\n};\n\n/** Options for {@link Client.fetchEach}: one-shot per-relay fetch, no gossip routing. */\nexport type FetchEachOptions = {\n relays?: string[];\n timeoutMs?: number;\n signal?: AbortSignal;\n /** When false, skip writing fetched events to storage/observe. Default true. */\n observe?: boolean;\n};\n\nexport type SubscribeOptions = {\n relays?: string[];\n /**\n * First receipt of each event only (deduped across relays). `relayUrl` is the normalized URL of\n * the relay that delivered it first.\n */\n onevent?: (event: Event, relayUrl: string) => void;\n /** Every receipt from every relay, including duplicates skipped by dedupe. */\n receivedEvent?: (id: string, relayUrl: string) => void;\n oneose?: () => void;\n onclose?: (reason: string) => void;\n signal?: AbortSignal;\n id?: string;\n /**\n * If set, fire `oneose` once after this many ms if not all relays have EOSEd. Does not close the\n * subscription.\n */\n eoseTimeoutMs?: number;\n /** Fan out REQs via NIP-65 gossip routes when available. */\n gossip?: boolean;\n /** When false, skip writing received events to storage/observe. Default true. */\n observe?: boolean;\n};\n\nexport type PublishOptions = {\n relays?: string[];\n timeoutMs?: number;\n gossip?: boolean;\n /** When false, skip writing the published event to storage/observe. Default true. */\n observe?: boolean;\n};\n\n/** Options for sending a NIP-17 private message. */\nexport type SendPrivateMessageOptions = {\n readonly subject?: string;\n readonly replyTo?: ReplyTo;\n readonly created_at?: number;\n readonly timeoutMs?: number;\n readonly observe?: boolean;\n};\n\n/** Result of sending a NIP-17 DM: the rumor plus per-recipient wrap publish results. */\nexport type PrivateMessageSendResult = {\n rumor: Rumor;\n wraps: ReadonlyArray<{\n recipient: string;\n wrap: Event;\n results: PoolPublishResult[];\n }>;\n};\n\n/** An unwrapped NIP-17 private message: the received gift wrap and its inner rumor. */\nexport type ReceivedPrivateMessage = {\n wrap: Event;\n rumor: Rumor;\n /** Normalized URL of the relay that delivered the wrap, when known. */\n relayUrl?: string;\n};\n\n/** Options for fetching NIP-17 private-message history. */\nexport type FetchPrivateMessagesOptions = {\n readonly since?: number;\n readonly until?: number;\n readonly timeoutMs?: number;\n readonly signal?: AbortSignal;\n readonly observe?: boolean;\n};\n\n/** Options for a live NIP-17 private-message subscription. */\nexport type SubscribePrivateMessagesOptions = {\n readonly since?: number;\n readonly onevent?: (msg: ReceivedPrivateMessage) => void;\n readonly oneose?: () => void;\n readonly onclose?: (reason: string) => void;\n readonly signal?: AbortSignal;\n readonly eoseTimeoutMs?: number;\n readonly observe?: boolean;\n};\n\n/** Client lifecycle, configuration, or abort failure (not cryptographic). */\nexport class ClientError extends NostrError {\n override name = \"ClientError\";\n}\n","import type { Event } from \"../core/event.ts\";\nimport type { Filter } from \"../core/filter.ts\";\nimport type { Gossip } from \"../gossip/gossip.ts\";\nimport { fanIn, fetchRouted } from \"../relay/fan-in.ts\";\nimport type { FanInOptions, RoutedJob } from \"../relay/fan-in.ts\";\nimport type { Pool } from \"../relay/pool.ts\";\nimport { ClientError } from \"./types.ts\";\n\n/** Remainder is one job on defaults; throw before any REQ when defaults are empty. */\nexport function jobsForFilters(\n gossip: Gossip,\n filters: Filter[],\n defaultRelays: () => string[],\n): RoutedJob[] {\n const routed = filters.map((f) => gossip.route(f));\n const needsDefaults = routed.some((r) => r.remainder !== undefined);\n const defaults = needsDefaults ? defaultRelays() : undefined;\n const jobs: RoutedJob[] = [];\n for (const r of routed) {\n for (const [url, sub] of r.perRelay) {\n jobs.push({ urls: [url], filters: [sub] });\n }\n if (r.remainder !== undefined) {\n if (defaults === undefined) {\n throw new ClientError(\"unrouted remainder without default relays\");\n }\n jobs.push({ urls: defaults, filters: [r.remainder] });\n }\n }\n return jobs;\n}\n\nexport async function fetchGossip(\n pool: Pool,\n gossip: Gossip,\n filters: Filter[],\n defaultRelays: () => string[],\n opts?: {\n timeoutMs?: number | undefined;\n signal?: AbortSignal | undefined;\n onevent?: ((event: Event, relayUrl: string) => void) | undefined;\n },\n): Promise<Event[]> {\n return fetchRouted(pool, jobsForFilters(gossip, filters, defaultRelays), {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n onevent: opts?.onevent,\n });\n}\n\nexport function subscribeGossip(\n pool: Pool,\n gossip: Gossip,\n filters: Filter[],\n defaultRelays: () => string[],\n opts: FanInOptions,\n): { close: (reason?: string) => void } {\n const jobs = jobsForFilters(gossip, filters, defaultRelays);\n if (jobs.length === 0) {\n queueMicrotask(() => opts.oneose?.());\n return {\n close: () => {\n /* empty */\n },\n };\n }\n return fanIn(pool, jobs, opts);\n}\n","import type { Event } from \"../core/event.ts\";\nimport { canonicalizeFilter } from \"../core/filter.ts\";\nimport type { Filter } from \"../core/filter.ts\";\nimport { storageFromItems } from \"../nips/nip77.ts\";\nimport type { NegentropyStorageVector } from \"../nips/nip77.ts\";\nimport type { Pool } from \"../relay/pool.ts\";\nimport type { EventStore, PutResult } from \"../storage/types.ts\";\nimport { SyncDirection } from \"./types.ts\";\nimport type { SyncOptions, SyncSummary } from \"./types.ts\";\n\nexport type SyncDeps = {\n pool: Pool;\n storage: EventStore;\n persistEvents: boolean;\n assertAlive: () => void;\n throwIfAborted: (signal?: AbortSignal) => void;\n wantObserve: (flag?: boolean) => boolean;\n /**\n * The client's single ingest path: index (with relay URL) → meta → persistence. `persist: false`\n * when this function already wrote storage via an awaited `putMany`.\n */\n ingest: (event: Event, relayUrl?: string, opts?: { persist?: boolean }) => void;\n /** Record a relay sighting for an id already in the index. */\n markSeen: (id: string, relayUrl: string) => void;\n defaultRelays: (urls?: string[]) => string[];\n};\n\nconst SYNC_ID_BATCH = 100;\nconst SYNC_UPLOAD_CONCURRENCY = 8;\n\nfunction uniqueIds(ids: ReadonlyArray<string>): string[] {\n return [...new Set(ids)];\n}\n\nfunction emptySummary(): SyncSummary {\n return {\n local: [],\n remote: [],\n sent: [],\n received: [],\n sendFailures: {},\n persistFailures: {},\n };\n}\n\nfunction mergeSyncSummary(into: SyncSummary, other: SyncSummary): SyncSummary {\n const sendFailures = { ...into.sendFailures, ...other.sendFailures };\n const persistFailures = { ...into.persistFailures, ...other.persistFailures };\n return {\n local: uniqueIds([...into.local, ...other.local]),\n remote: uniqueIds([...into.remote, ...other.remote]),\n sent: uniqueIds([...into.sent, ...other.sent]),\n received: uniqueIds([...into.received, ...other.received]),\n sendFailures,\n persistFailures,\n };\n}\n\n/**\n * NIP-77 sync against one relay: reconcile, then optionally upload local-only events and/or\n * download remote-only events. `observe: false` skips putMany and ingest; received ids are still\n * listed. `persistEvents: false` skips putMany, still ingests when observe is on.\n */\nexport async function syncToRelay(\n deps: SyncDeps,\n url: string,\n filter: Filter,\n opts?: Omit<SyncOptions, \"relays\">,\n): Promise<SyncSummary> {\n deps.assertAlive();\n deps.throwIfAborted(opts?.signal);\n const direction = opts?.direction ?? SyncDirection.Down;\n const canon = canonicalizeFilter(filter);\n const items = await deps.storage.negentropyItems(canon);\n const storage: NegentropyStorageVector = storageFromItems(items);\n const relay = await deps.pool.ensureRelay(url, { signal: opts?.signal });\n const { have, need } = await relay.negReconcile(canon, storage, {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n });\n\n const summary: SyncSummary = {\n local: have,\n remote: need,\n sent: [],\n received: [],\n sendFailures: {},\n persistFailures: {},\n };\n\n if (opts?.dryRun === true) {\n return summary;\n }\n\n if ((direction === SyncDirection.Up || direction === SyncDirection.Both) && have.length > 0) {\n const found = await deps.storage.query([{ ids: have }]);\n const foundById = new Map(found.map((event) => [event.id, event]));\n for (const id of have) {\n if (!foundById.has(id)) {\n summary.sendFailures[id] = \"event not found in local store\";\n }\n }\n for (let i = 0; i < found.length; i += SYNC_UPLOAD_CONCURRENCY) {\n const chunk = found.slice(i, i + SYNC_UPLOAD_CONCURRENCY);\n // Upload chunks are rate-limited serially.\n // oxlint-disable-next-line no-await-in-loop\n await Promise.all(\n chunk.map(async (event) => {\n try {\n const results = await deps.pool.publish([url], event, {\n timeoutMs: opts?.timeoutMs,\n });\n const ok = results.some((r) => r.result?.ok === true);\n if (ok) {\n summary.sent.push(event.id);\n } else {\n summary.sendFailures[event.id] =\n results[0]?.error ?? results[0]?.result?.message ?? \"publish failed\";\n }\n } catch (error) {\n summary.sendFailures[event.id] = error instanceof Error ? error.message : String(error);\n }\n }),\n );\n }\n }\n\n if ((direction === SyncDirection.Down || direction === SyncDirection.Both) && need.length > 0) {\n const shouldObserve = deps.wantObserve(opts?.observe);\n for (let i = 0; i < need.length; i += SYNC_ID_BATCH) {\n const batch = need.slice(i, i + SYNC_ID_BATCH);\n deps.throwIfAborted(opts?.signal);\n // Every relay that delivered an event is recorded once it is ingested.\n const urlsById = new Map<string, string[]>();\n // Id batches are fetched serially so backpressure stays bounded.\n // oxlint-disable-next-line no-await-in-loop\n const events = await deps.pool.fetch([url], [{ ids: batch }], {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n onevent: shouldObserve\n ? (event, relayUrl) => {\n const urls = urlsById.get(event.id);\n if (urls === undefined) {\n urlsById.set(event.id, [relayUrl]);\n } else if (!urls.includes(relayUrl)) {\n urls.push(relayUrl);\n }\n }\n : undefined,\n });\n if (!shouldObserve) {\n for (const event of events) {\n summary.received.push(event.id);\n }\n continue;\n }\n const ingestAll = (event: Event): void => {\n const urls = urlsById.get(event.id) ?? [];\n deps.ingest(event, urls[0], { persist: false });\n for (const url of urls.slice(1)) {\n deps.markSeen(event.id, url);\n }\n };\n if (!deps.persistEvents) {\n for (const event of events) {\n ingestAll(event);\n summary.received.push(event.id);\n }\n continue;\n }\n // The awaited putMany reports persistFailures; accepted events then go\n // through the ingest path with persistence already done.\n let results: PutResult[];\n try {\n // Persisted serially per batch so failures land on the right ids.\n // oxlint-disable-next-line no-await-in-loop\n results = await deps.storage.putMany(events);\n } catch (error) {\n const message = error instanceof Error ? error.message : String(error);\n for (const event of events) {\n summary.persistFailures[event.id] = message;\n }\n break;\n }\n for (const [j, event] of events.entries()) {\n if (results[j] === \"rejected\" || results[j] === \"invalid\") {\n continue;\n }\n ingestAll(event);\n summary.received.push(event.id);\n }\n }\n }\n\n return summary;\n}\n\n/**\n * NIP-77 sync against the given relays (or Client default relays). Independent sessions run in\n * parallel. Fulfilled summaries are merged; if every relay rejects, throws the first rejection in\n * URL order.\n */\nexport async function sync(\n deps: SyncDeps,\n filter: Filter,\n opts?: SyncOptions,\n): Promise<SyncSummary> {\n deps.assertAlive();\n const urls = deps.defaultRelays(opts?.relays ? [...opts.relays] : undefined);\n const results = await Promise.allSettled(\n urls.map(async (url) => syncToRelay(deps, url, filter, opts)),\n );\n let merged = emptySummary();\n let fulfilled = 0;\n let firstRejection: unknown;\n for (const result of results) {\n if (result.status === \"fulfilled\") {\n fulfilled += 1;\n merged = mergeSyncSummary(merged, result.value);\n } else {\n firstRejection ??= result.reason;\n }\n }\n if (urls.length > 0 && fulfilled === 0) {\n throw firstRejection;\n }\n return merged;\n}\n","import { throwIfAborted } from \"../core/abort.ts\";\nimport { EventBuilder } from \"../core/builder.ts\";\nimport { sortedEvents } from \"../core/event.ts\";\nimport type { Event, EventTemplate, UnsignedEvent } from \"../core/event.ts\";\nimport { canonicalizeFilters, matchFilters } from \"../core/filter.ts\";\nimport type { Filter } from \"../core/filter.ts\";\nimport { invokeSafely } from \"../core/report.ts\";\nimport { normalizeURL } from \"../core/util.ts\";\nimport { Gossip } from \"../gossip/index.ts\";\nimport { createLoaders, createOutboxFeed } from \"../loaders/index.ts\";\nimport type { Loaders, OutboxFeed } from \"../loaders/index.ts\";\nimport type { Recipient } from \"../nips/nip17.ts\";\nimport { isGiftWrapKind, requireNip59Crypto } from \"../nips/nip59.ts\";\nimport type { Nip59Crypto } from \"../nips/nip59.ts\";\nimport { Pool } from \"../relay/pool.ts\";\nimport type { PoolFetchResult, PoolPublishResult } from \"../relay/pool.ts\";\nimport { NoSignerError } from \"../signer/error.ts\";\nimport type { NostrSigner } from \"../signer/types.ts\";\nimport { toStorageError } from \"../storage/error.ts\";\nimport type { StorageError } from \"../storage/error.ts\";\nimport { MemoryIndex } from \"../storage/memory-index.ts\";\nimport { MemoryEventStore } from \"../storage/memory.ts\";\nimport type { EventStore } from \"../storage/types.ts\";\nimport { ReactiveEventStore } from \"../store/reactive.ts\";\nimport { ClientBuilder } from \"./builder.ts\";\nimport {\n fetchPrivateMessages,\n giftWrapRelays,\n sendPrivateMessage,\n setDmRelays,\n subscribePrivateMessages,\n} from \"./dm.ts\";\nimport type { DmDeps } from \"./dm.ts\";\nimport { fetchGossip, subscribeGossip } from \"./gossip-io.ts\";\nimport { sync, syncToRelay } from \"./sync.ts\";\nimport type { SyncDeps } from \"./sync.ts\";\nimport { ClientError } from \"./types.ts\";\nimport type {\n ClientOptions,\n FetchEachOptions,\n FetchEventsOptions,\n FetchPrivateMessagesOptions,\n PrivateMessageSendResult,\n PublishOptions,\n ReceivedPrivateMessage,\n SendPrivateMessageOptions,\n SubscribeOptions,\n SubscribePrivateMessagesOptions,\n SyncOptions,\n SyncSummary,\n} from \"./types.ts\";\n\n/** Layer-5 facade: signer + default relays + pool + loaders + gossip + event store. */\nexport class Client {\n readonly pool: Pool;\n readonly loaders: Loaders;\n readonly gossip: Gossip;\n readonly storage: EventStore;\n readonly index: ReactiveEventStore;\n onstorageerror: ((err: StorageError) => void) | undefined;\n #signer: NostrSigner | undefined;\n #relays: string[];\n #shutdown = false;\n readonly #persistEvents: boolean;\n readonly #persistQueue: Event[] = [];\n #flushing: Promise<void> | undefined;\n\n constructor(opts: ClientOptions = {}) {\n this.#signer = opts.signer;\n this.#relays = [];\n for (const raw of opts.relays ?? []) {\n const url = normalizeURL(raw);\n if (!this.#relays.includes(url)) {\n this.#relays.push(url);\n }\n }\n this.gossip = opts.gossip ?? new Gossip();\n this.storage = opts.storage ?? new MemoryEventStore();\n this.index = opts.index ?? new ReactiveEventStore();\n this.#persistEvents = opts.persistEvents ?? true;\n this.onstorageerror = opts.onstorageerror;\n this.pool = new Pool({\n websocketImplementation: opts.websocketImplementation,\n verifyEvent: opts.verifyEvent,\n enablePing: opts.enablePing,\n pingIntervalMs: opts.pingIntervalMs,\n pingTimeoutMs: opts.pingTimeoutMs,\n connectTimeoutMs: opts.connectTimeoutMs,\n publishTimeoutMs: opts.publishTimeoutMs,\n enableReconnect: opts.enableReconnect ?? true,\n allowInsecure: opts.allowInsecure,\n trustedInsecureUrls: opts.trustedInsecureUrls,\n idleTimeoutMs: opts.idleTimeoutMs,\n maxRelays: opts.maxRelays,\n pinnedUrls: opts.pinnedUrls,\n invalidEventPolicy: opts.invalidEventPolicy,\n onRelaySuspended: opts.onRelaySuspended,\n // The sign function resolves the signer at challenge time, so\n // setSigner() takes effect on already-connected relays; challenges\n // without a signer are ignored by the relay (NoSignerError).\n automaticallyAuth:\n (opts.automaticAuth ?? true)\n ? () => async (template) => {\n const signer = this.#signer;\n if (!signer) {\n throw new NoSignerError(\"no signer configured for AUTH\");\n }\n const pk = await signer.getPublicKey();\n return signer.signEvent({ ...template, pubkey: pk });\n }\n : undefined,\n });\n this.loaders = createLoaders({\n pool: this.pool,\n relays: this.#relays,\n index: this.index,\n ingest: (event, relayUrl) => this.#ingest(event, relayUrl),\n });\n }\n\n static builder(): ClientBuilder {\n return new ClientBuilder((opts) => new Client(opts));\n }\n\n get signer(): NostrSigner | undefined {\n return this.#signer;\n }\n\n get relays(): ReadonlyArray<string> {\n return this.#relays;\n }\n\n get isShutdown(): boolean {\n return this.#shutdown;\n }\n\n setSigner(signer: NostrSigner | undefined): void {\n this.#signer = signer;\n // Re-arm relays whose AUTH challenge was ignored or rejected.\n this.pool.resetAuth();\n }\n\n addRelay(url: string): void {\n const normalized = normalizeURL(url);\n if (!this.#relays.includes(normalized)) {\n this.#relays.push(normalized);\n this.loaders.addRelay(normalized);\n }\n }\n\n removeRelay(url: string): void {\n const normalized = normalizeURL(url);\n this.#relays = this.#relays.filter((r) => r !== normalized);\n this.loaders.removeRelay(normalized);\n this.pool.close([normalized]);\n }\n\n /** Connect all configured relays (best-effort; failures are ignored). */\n async connect(opts?: { signal?: AbortSignal }): Promise<void> {\n this.#assertAlive();\n await Promise.allSettled(\n this.#relays.map(async (url) => this.pool.ensureRelay(url, { signal: opts?.signal })),\n );\n }\n\n async shutdown(): Promise<void> {\n this.#shutdown = true;\n while (this.#flushing !== undefined) {\n // oxlint-disable-next-line no-await-in-loop -- waits for the current flush to settle before closing\n await this.#flushing;\n }\n this.pool.close();\n }\n\n #assertAlive(): void {\n if (this.#shutdown) {\n throw new ClientError(\"client is shut down\");\n }\n }\n\n #defaultRelays(urls?: string[]): string[] {\n const list = urls ?? this.#relays;\n if (list.length === 0) {\n throw new ClientError(\"no relays configured\");\n }\n return list;\n }\n\n #wantObserve(flag?: boolean): boolean {\n return flag !== false;\n }\n\n /** Ingest one inbound event: index (with relay URL) → meta → persistence. */\n observe(event: Event, relayUrl?: string): void {\n this.#ingest(event, relayUrl);\n }\n\n /** Ingest many events (deduped by id, order preserved) as one persist batch. */\n observeAll(events: ReadonlyArray<Event>): void {\n const seen = new Set<string>();\n for (const event of events) {\n if (seen.has(event.id)) {\n continue;\n }\n seen.add(event.id);\n this.#ingest(event);\n }\n }\n\n /**\n * The single inbound-event pipeline: reactive index add (with the source relay URL recorded in\n * seenOn), gossip routing meta, then the persistence decision. `persist: false` skips the storage\n * queue for callers that persist via their own awaited `putMany` (down-sync); `meta: false` is a\n * pure sighting/index add.\n */\n #ingest(event: Event, relayUrl?: string, opts?: { persist?: boolean; meta?: boolean }): void {\n this.index.add(event, relayUrl);\n if (opts?.meta !== false) {\n this.#ingestMeta(event);\n }\n if (opts?.persist === false || !this.#persistEvents) {\n return;\n }\n this.#persistQueue.push(event);\n this.#armFlush();\n }\n\n /** Record a relay sighting for an id already in the index. */\n #markSeen(id: string, relayUrl: string): void {\n this.index.markSeen(id, relayUrl);\n }\n\n #ingestMeta(event: Event): void {\n this.gossip.ingest(event);\n }\n\n #armFlush(): void {\n if (this.#flushing) {\n return;\n }\n this.#flushing = this.#flushLoop();\n }\n\n async #flushLoop(): Promise<void> {\n try {\n await new Promise<void>((resolve) => {\n queueMicrotask(resolve);\n });\n while (this.#persistQueue.length > 0) {\n const batch = this.#persistQueue.splice(0);\n try {\n // oxlint-disable-next-line no-await-in-loop -- queued batches are persisted in order\n await this.storage.putMany(batch);\n } catch (error) {\n invokeSafely(() => this.onstorageerror?.(toStorageError(error)));\n }\n }\n } finally {\n this.#flushing = undefined;\n if (this.#persistQueue.length > 0) {\n this.#armFlush();\n }\n }\n }\n\n /**\n * Explicitly load kind:10002 and kind:10050 lists for pubkeys and feed gossip. Does not\n * background-fetch unknown authors on every subscribe (predictable DX).\n */\n async hydrateGossip(\n pubkeys: ReadonlyArray<string>,\n opts?: { hints?: string[]; force?: boolean },\n ): Promise<void> {\n this.#assertAlive();\n await Promise.all(\n pubkeys.map(async (pk) => {\n const style = opts?.force === true ? \"force\" : \"default\";\n const [relayList, dmList] = await Promise.all([\n this.loaders.relayList(pk, { hints: opts?.hints, style }),\n this.loaders.dmRelayList(pk, { hints: opts?.hints, style }),\n ]);\n if (relayList.event) {\n this.observe(relayList.event);\n }\n if (dmList.event) {\n this.observe(dmList.event);\n }\n }),\n );\n }\n\n /**\n * Create an outbox-model feed for the given authors (NIP-65 write relays). Live events go through\n * {@link observe}; sync persists via applySync.\n */\n outbox(opts: {\n authors: ReadonlyArray<string>;\n kinds?: ReadonlyArray<number>;\n onEvent?: (event: Event) => void;\n maxRelaysPerAuthor?: number;\n }): OutboxFeed {\n this.#assertAlive();\n return createOutboxFeed({\n pool: this.pool,\n gossip: this.gossip,\n storage: this.storage,\n discoveryRelays: this.#relays,\n authors: opts.authors,\n kinds: opts.kinds,\n onEvent: opts.onEvent,\n maxRelaysPerAuthor: opts.maxRelaysPerAuthor,\n observe: (event, relayUrl) => this.observe(event, relayUrl),\n seen: (event, relayUrl) => this.#ingest(event, relayUrl, { persist: false, meta: false }),\n applySync: async (events) => {\n if (!this.#persistEvents) {\n for (const event of events) {\n this.#ingest(event, undefined, { persist: false });\n }\n return [];\n }\n const results = await this.storage.putMany(events);\n const applied: Event[] = [];\n for (const [i, event] of events.entries()) {\n const result = results[i];\n if (result === \"rejected\" || result === \"ephemeral\" || result === \"invalid\") {\n continue;\n }\n this.#ingest(event, undefined, { persist: false });\n applied.push(event);\n }\n return applied;\n },\n hydrate: async (pubkeys) => this.hydrateGossip(pubkeys),\n });\n }\n\n async getPublicKey(): Promise<string> {\n if (!this.#signer) {\n throw new ClientError(\"no signer configured\");\n }\n return this.#signer.getPublicKey();\n }\n\n async signEvent(unsigned: UnsignedEvent): Promise<Event> {\n if (!this.#signer) {\n throw new ClientError(\"no signer configured\");\n }\n return this.#signer.signEvent(unsigned);\n }\n\n async signEventBuilder(builder: EventBuilder): Promise<Event> {\n if (!this.#signer) {\n throw new ClientError(\"no signer configured\");\n }\n return builder.sign(this.#signer);\n }\n\n async signTemplate(template: EventTemplate): Promise<Event> {\n if (!this.#signer) {\n throw new ClientError(\"no signer configured\");\n }\n const pubkey = await this.#signer.getPublicKey();\n return this.#signer.signEvent({ ...template, pubkey });\n }\n\n /**\n * Sign (if builder) and publish to relays. With `gossip: true`, prefers the author's NIP-65\n * outbox relays, tagged `p` inboxes, and up to 5 `e`/`a` tag relay hints when known. On any\n * successful OK, observes the event into storage/gossip.\n */\n async publish(\n eventOrBuilder: Event | EventBuilder,\n opts?: PublishOptions,\n ): Promise<PoolPublishResult[]> {\n this.#assertAlive();\n const event =\n eventOrBuilder instanceof EventBuilder\n ? await this.signEventBuilder(eventOrBuilder)\n : eventOrBuilder;\n\n let relays = opts?.relays;\n if (!relays && isGiftWrapKind(event.kind)) {\n relays = giftWrapRelays(this.gossip, event);\n } else if (!relays && opts?.gossip === true) {\n const urls: string[] = [];\n const add = (list: ReadonlyArray<string>) => {\n for (const url of list) {\n if (!urls.includes(url)) {\n urls.push(url);\n }\n }\n };\n add(this.gossip.outboxRelays(event.pubkey));\n for (const tag of event.tags) {\n if (tag[0] === \"p\" && tag[1] !== undefined) {\n add(this.gossip.inboxRelays(tag[1]));\n }\n }\n let hintCount = 0;\n for (const tag of event.tags) {\n if (hintCount >= 5) {\n break;\n }\n if ((tag[0] !== \"e\" && tag[0] !== \"a\") || tag[2] === undefined) {\n continue;\n }\n try {\n const url = normalizeURL(tag[2]);\n if (!urls.includes(url)) {\n urls.push(url);\n hintCount += 1;\n }\n } catch {\n // not a relay URL\n }\n }\n if (urls.length > 0) {\n relays = urls;\n }\n }\n const results = await this.pool.publish(this.#defaultRelays(relays), event, {\n timeoutMs: opts?.timeoutMs,\n });\n\n const anyOk = results.some((r) => r.result?.ok === true);\n if (anyOk && this.#wantObserve(opts?.observe)) {\n this.observe(event);\n }\n return results;\n }\n\n /**\n * Fetch events. With `gossip: true`, routes filters by NIP-65 when possible. With `localFirst:\n * true`, merges storage hits with network results.\n */\n async fetchEvents(filter: Filter | Filter[], opts?: FetchEventsOptions): Promise<Event[]> {\n this.#assertAlive();\n const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);\n const shouldObserve = this.#wantObserve(opts?.observe);\n const candidates: Event[] = [];\n\n if (opts?.localFirst === true) {\n // Persisted storage is merged with the index below; storage may hold a\n // stale replaceable version, so it is only a candidate — the index wins.\n try {\n const local = await this.storage.query(filters);\n for (const e of local) {\n candidates.push(e);\n if (shouldObserve) {\n this.#ingest(e, undefined, { persist: false, meta: false });\n }\n }\n } catch (error) {\n invokeSafely(() => this.onstorageerror?.(toStorageError(error)));\n }\n }\n\n // Every inbound event lands in the index (with its relay URL) before the\n // caller's onevent runs; the batch below re-ingests for persistence.\n const onevent = (event: Event, relayUrl: string) => {\n if (shouldObserve) {\n this.#ingest(event, relayUrl, { persist: false, meta: false });\n }\n opts?.onevent?.(event, relayUrl);\n };\n\n const batch =\n opts?.gossip !== true || opts.relays !== undefined\n ? await this.pool.fetch(this.#defaultRelays(opts?.relays), filters, {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n onevent,\n })\n : await fetchGossip(this.pool, this.gossip, filters, () => this.#defaultRelays(), {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n onevent,\n });\n for (const e of batch) {\n candidates.push(e);\n if (shouldObserve) {\n this.observe(e);\n }\n }\n\n // Merge through a scratch index so NIP-01 replaceable winners, kind-5\n // deletions, dedupe and per-filter limits all apply to the result.\n // Ephemeral kinds are never stored; matching ones join the result directly.\n const tmp = new MemoryIndex();\n const ephemeral = new Map<string, Event>();\n const merged =\n opts?.localFirst === true ? [...this.index.query(filters), ...candidates] : candidates;\n for (const e of merged) {\n if (tmp.put(e) === \"ephemeral\" && matchFilters(filters, e)) {\n ephemeral.set(e.id, e);\n }\n }\n return sortedEvents([...tmp.query(filters), ...ephemeral.values()]);\n }\n\n /**\n * One-shot fetch with per-relay results: each entry reports its events and end reason (`eose`,\n * `closed`, `timeout`, or `failed` when the relay could not be reached). Events are ingested into\n * the index with each relay's URL in `seenOn` and persisted exactly like {@link fetchEvents}\n * (`observe` defaults to true). No gossip routing and no local merge.\n */\n async fetchEach(filter: Filter | Filter[], opts?: FetchEachOptions): Promise<PoolFetchResult[]> {\n this.#assertAlive();\n const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);\n const results = await this.pool.fetchEach(this.#defaultRelays(opts?.relays), filters, {\n timeoutMs: opts?.timeoutMs,\n signal: opts?.signal,\n });\n if (this.#wantObserve(opts?.observe)) {\n const unique: Event[] = [];\n const seen = new Set<string>();\n for (const result of results) {\n for (const event of result.events) {\n this.#ingest(event, result.url, { persist: false, meta: false });\n if (!seen.has(event.id)) {\n seen.add(event.id);\n unique.push(event);\n }\n }\n }\n for (const event of unique) {\n this.observe(event);\n }\n }\n return results;\n }\n\n /** Query local storage only (no network). */\n async queryLocal(filter: Filter | Filter[]): Promise<Event[]> {\n this.#assertAlive();\n const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);\n return this.storage.query(filters);\n }\n\n subscribe(\n filter: Filter | Filter[],\n opts?: SubscribeOptions,\n ): { close: (reason?: string) => void } {\n this.#assertAlive();\n const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);\n const shouldObserve = this.#wantObserve(opts?.observe);\n\n const wrapEvent = (event: Event, relayUrl: string) => {\n if (shouldObserve) {\n this.observe(event, relayUrl);\n }\n opts?.onevent?.(event, relayUrl);\n };\n\n const wrapReceived = (id: string, relayUrl: string) => {\n if (shouldObserve) {\n this.#markSeen(id, relayUrl);\n }\n opts?.receivedEvent?.(id, relayUrl);\n };\n\n if (opts?.gossip !== true || opts.relays !== undefined) {\n return this.pool.subscribe(this.#defaultRelays(opts?.relays), filters, {\n onevent: wrapEvent,\n receivedEvent: wrapReceived,\n oneose: opts?.oneose,\n onclose: opts?.onclose,\n signal: opts?.signal,\n id: opts?.id,\n eoseTimeoutMs: opts?.eoseTimeoutMs,\n });\n }\n\n return subscribeGossip(this.pool, this.gossip, filters, () => this.#defaultRelays(), {\n onevent: wrapEvent,\n receivedEvent: wrapReceived,\n oneose: opts?.oneose,\n onclose: opts?.onclose,\n signal: opts?.signal,\n eoseTimeoutMs: opts?.eoseTimeoutMs,\n });\n }\n\n #requireNip59Crypto(): Nip59Crypto {\n if (!this.#signer) {\n throw new ClientError(\"no signer configured\");\n }\n return requireNip59Crypto(this.#signer);\n }\n\n #throwIfAborted(signal?: AbortSignal): void {\n throwIfAborted(signal);\n }\n\n #dmDeps(): DmDeps {\n return {\n pool: this.pool,\n gossip: this.gossip,\n hydrateGossip: async (pubkeys) => this.hydrateGossip(pubkeys),\n ingest: (event, relayUrl) => this.#ingest(event, relayUrl),\n markSeen: (id, relayUrl) => this.#markSeen(id, relayUrl),\n assertAlive: () => this.#assertAlive(),\n requireNip59Crypto: () => this.#requireNip59Crypto(),\n throwIfAborted: (signal) => this.#throwIfAborted(signal),\n wantObserve: (flag) => this.#wantObserve(flag),\n publish: async (eventOrBuilder, opts) => this.publish(eventOrBuilder, opts),\n };\n }\n\n #syncDeps(): SyncDeps {\n return {\n pool: this.pool,\n storage: this.storage,\n persistEvents: this.#persistEvents,\n assertAlive: () => this.#assertAlive(),\n throwIfAborted: (signal) => this.#throwIfAborted(signal),\n wantObserve: (flag) => this.#wantObserve(flag),\n ingest: (event, relayUrl, opts) => this.#ingest(event, relayUrl, opts),\n markSeen: (id, relayUrl) => this.#markSeen(id, relayUrl),\n defaultRelays: (urls) => this.#defaultRelays(urls),\n };\n }\n\n /** Publish a kind:10050 NIP-17 DM relay list (`relay` tags). Not kind 10002. */\n async setDmRelays(\n relays: ReadonlyArray<string>,\n opts?: PublishOptions,\n ): Promise<PoolPublishResult[]> {\n return setDmRelays(this.#dmDeps(), relays, opts);\n }\n\n async sendPrivateMessage(\n recipients: string | Recipient | ReadonlyArray<string | Recipient>,\n content: string,\n opts?: SendPrivateMessageOptions,\n ): Promise<PrivateMessageSendResult> {\n return sendPrivateMessage(this.#dmDeps(), recipients, content, opts);\n }\n\n async fetchPrivateMessages(\n opts?: FetchPrivateMessagesOptions,\n ): Promise<ReceivedPrivateMessage[]> {\n return fetchPrivateMessages(this.#dmDeps(), opts);\n }\n\n async subscribePrivateMessages(\n opts?: SubscribePrivateMessagesOptions,\n ): Promise<{ close: (reason?: string) => void }> {\n return subscribePrivateMessages(this.#dmDeps(), opts);\n }\n\n /**\n * NIP-77 sync against one relay: reconcile, then optionally upload local-only events and/or\n * download remote-only events. `observe: false` skips putMany and ingest; received ids are still\n * listed. `persistEvents: false` skips putMany, still ingests when observe is on.\n */\n async syncToRelay(\n url: string,\n filter: Filter,\n opts?: Omit<SyncOptions, \"relays\">,\n ): Promise<SyncSummary> {\n return syncToRelay(this.#syncDeps(), url, filter, opts);\n }\n\n /**\n * NIP-77 sync against the given relays (or Client default relays). Independent sessions run in\n * parallel. Fulfilled summaries are merged; if every relay rejects, throws the first rejection in\n * URL order.\n */\n async sync(filter: Filter, opts?: SyncOptions): Promise<SyncSummary> {\n return sync(this.#syncDeps(), filter, opts);\n }\n}\n"],"mappings":"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"}
|
package/dist/client.d.mts
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as
|
|
2
|
-
export { Client, ClientBuilder, ClientError, type ClientOptions, type FetchEventsOptions, type FetchPrivateMessagesOptions, type PrivateMessageSendResult, type PublishOptions, type ReceivedPrivateMessage, type SendPrivateMessageOptions, type SubscribeOptions, type SubscribePrivateMessagesOptions, SyncDirection, type SyncDirectionName, type SyncOptions, type SyncSummary };
|
|
1
|
+
import { _ as SyncSummary, a as FetchEachOptions, c as PrivateMessageSendResult, d as SendPrivateMessageOptions, f as SubscribeOptions, g as SyncOptions, h as SyncDirectionName, i as ClientOptions, l as PublishOptions, m as SyncDirection, n as ClientBuilder, o as FetchEventsOptions, p as SubscribePrivateMessagesOptions, r as ClientError, s as FetchPrivateMessagesOptions, t as Client, u as ReceivedPrivateMessage } from "./index-CNl2q67H.mjs";
|
|
2
|
+
export { Client, ClientBuilder, ClientError, type ClientOptions, type FetchEachOptions, type FetchEventsOptions, type FetchPrivateMessagesOptions, type PrivateMessageSendResult, type PublishOptions, type ReceivedPrivateMessage, type SendPrivateMessageOptions, type SubscribeOptions, type SubscribePrivateMessagesOptions, SyncDirection, type SyncDirectionName, type SyncOptions, type SyncSummary };
|
package/dist/client.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { i as ClientBuilder, n as ClientError, r as SyncDirection, t as Client } from "./client-
|
|
1
|
+
import { i as ClientBuilder, n as ClientError, r as SyncDirection, t as Client } from "./client-CadO5fAX.mjs";
|
|
2
2
|
export { Client, ClientBuilder, ClientError, SyncDirection };
|
|
@@ -3,11 +3,11 @@ import { t as EventBuilder } from "./builder-sSflu6nB.mjs";
|
|
|
3
3
|
import { t as Filter } from "./filter-C0IMByE3.mjs";
|
|
4
4
|
import { t as Gossip } from "./gossip-DpIvkBuj.mjs";
|
|
5
5
|
import { a as NostrError } from "./error-CR8Urc84.mjs";
|
|
6
|
-
import {
|
|
6
|
+
import { i as PoolFetchResult, n as Pool, o as PoolPublishResult, t as InvalidEventPolicy } from "./pool-DBIYMtwy.mjs";
|
|
7
7
|
import { t as WebSocketConstructor } from "./websocket-CmeqvAkp.mjs";
|
|
8
8
|
import { t as EventStore } from "./types-2pCUprRU.mjs";
|
|
9
|
-
import { t as ReactiveEventStore } from "./reactive-
|
|
10
|
-
import { a as OutboxFeed, n as Loaders } from "./index-
|
|
9
|
+
import { t as ReactiveEventStore } from "./reactive-7aqeip4A.mjs";
|
|
10
|
+
import { a as OutboxFeed, n as Loaders } from "./index-lvXeER5t.mjs";
|
|
11
11
|
import { a as Rumor } from "./nip59-zQgdLcEr.mjs";
|
|
12
12
|
import { i as ReplyTo, r as Recipient } from "./nip17-CKIufV98.mjs";
|
|
13
13
|
import { t as NostrSigner } from "./types-CRQEk0Oi.mjs";
|
|
@@ -120,6 +120,14 @@ type FetchEventsOptions = {
|
|
|
120
120
|
*/
|
|
121
121
|
onevent?: (event: Event, relayUrl: string) => void;
|
|
122
122
|
};
|
|
123
|
+
/** Options for {@link Client.fetchEach}: one-shot per-relay fetch, no gossip routing. */
|
|
124
|
+
type FetchEachOptions = {
|
|
125
|
+
relays?: string[];
|
|
126
|
+
timeoutMs?: number;
|
|
127
|
+
signal?: AbortSignal;
|
|
128
|
+
/** When false, skip writing fetched events to storage/observe. Default true. */
|
|
129
|
+
observe?: boolean;
|
|
130
|
+
};
|
|
123
131
|
type SubscribeOptions = {
|
|
124
132
|
relays?: string[];
|
|
125
133
|
/**
|
|
@@ -309,6 +317,13 @@ declare class Client {
|
|
|
309
317
|
* true`, merges storage hits with network results.
|
|
310
318
|
*/
|
|
311
319
|
fetchEvents(filter: Filter | Filter[], opts?: FetchEventsOptions): Promise<Event[]>;
|
|
320
|
+
/**
|
|
321
|
+
* One-shot fetch with per-relay results: each entry reports its events and end reason (`eose`,
|
|
322
|
+
* `closed`, `timeout`, or `failed` when the relay could not be reached). Events are ingested into
|
|
323
|
+
* the index with each relay's URL in `seenOn` and persisted exactly like {@link fetchEvents}
|
|
324
|
+
* (`observe` defaults to true). No gossip routing and no local merge.
|
|
325
|
+
*/
|
|
326
|
+
fetchEach(filter: Filter | Filter[], opts?: FetchEachOptions): Promise<PoolFetchResult[]>;
|
|
312
327
|
/** Query local storage only (no network). */
|
|
313
328
|
queryLocal(filter: Filter | Filter[]): Promise<Event[]>;
|
|
314
329
|
subscribe(filter: Filter | Filter[], opts?: SubscribeOptions): {
|
|
@@ -335,5 +350,5 @@ declare class Client {
|
|
|
335
350
|
sync(filter: Filter, opts?: SyncOptions): Promise<SyncSummary>;
|
|
336
351
|
}
|
|
337
352
|
//#endregion
|
|
338
|
-
export {
|
|
339
|
-
//# sourceMappingURL=index-
|
|
353
|
+
export { SyncSummary as _, FetchEachOptions as a, PrivateMessageSendResult as c, SendPrivateMessageOptions as d, SubscribeOptions as f, SyncOptions as g, SyncDirectionName as h, ClientOptions as i, PublishOptions as l, SyncDirection as m, ClientBuilder as n, FetchEventsOptions as o, SubscribePrivateMessagesOptions as p, ClientError as r, FetchPrivateMessagesOptions as s, Client as t, ReceivedPrivateMessage as u };
|
|
354
|
+
//# sourceMappingURL=index-CNl2q67H.d.mts.map
|
|
@@ -3,9 +3,9 @@ import { n as ProfileMetadata } from "./builder-sSflu6nB.mjs";
|
|
|
3
3
|
import { t as RelayListItem } from "./nip65-CjgmdpPB.mjs";
|
|
4
4
|
import { t as Gossip } from "./gossip-DpIvkBuj.mjs";
|
|
5
5
|
import { a as NostrError } from "./error-CR8Urc84.mjs";
|
|
6
|
-
import { n as Pool } from "./pool-
|
|
6
|
+
import { n as Pool } from "./pool-DBIYMtwy.mjs";
|
|
7
7
|
import { r as OutboxBound, t as EventStore } from "./types-2pCUprRU.mjs";
|
|
8
|
-
import { t as ReactiveEventStore } from "./reactive-
|
|
8
|
+
import { t as ReactiveEventStore } from "./reactive-7aqeip4A.mjs";
|
|
9
9
|
import { i as EventPointer, t as AddressPointer } from "./nip19-BevCJZsp.mjs";
|
|
10
10
|
//#region src/loaders/event.d.ts
|
|
11
11
|
type EventRef = string | EventPointer | AddressPointer;
|
|
@@ -204,4 +204,4 @@ type CreateLoadersOptions = {
|
|
|
204
204
|
declare function createLoaders(opts: CreateLoadersOptions): Loaders;
|
|
205
205
|
//#endregion
|
|
206
206
|
export { ReplaceableLoader as _, OutboxFeed as a, groupAuthorsByOutboxRelay as c, bareNostrUser as d, ListLoaders as f, ReplaceableLoadResult as g, LoadStyle as h, OutboxError as i, NostrUser as l, MutedEntity as m, Loaders as n, OutboxFeedOptions as o, ListResult as p, createLoaders as r, createOutboxFeed as s, CreateLoadersOptions as t, ProfileLoader as u, EventLoader as v, EventRef as y };
|
|
207
|
-
//# sourceMappingURL=index-
|
|
207
|
+
//# sourceMappingURL=index-lvXeER5t.d.mts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as Event } from "./event-fU3Y01PR.mjs";
|
|
2
2
|
import { t as Filter } from "./filter-C0IMByE3.mjs";
|
|
3
3
|
import { a as NostrError } from "./error-CR8Urc84.mjs";
|
|
4
|
-
import { n as Pool } from "./pool-
|
|
4
|
+
import { n as Pool } from "./pool-DBIYMtwy.mjs";
|
|
5
5
|
//#region src/relay/error.d.ts
|
|
6
6
|
/** Base class for relay errors; carries the relay URL when known. */
|
|
7
7
|
declare class RelayError extends NostrError {
|
|
@@ -81,4 +81,4 @@ declare function fetchRouted(pool: Pool, jobs: ReadonlyArray<RoutedJob>, opts?:
|
|
|
81
81
|
}): Promise<Event[]>;
|
|
82
82
|
//#endregion
|
|
83
83
|
export { isInsecureRelayUrl as a, RelayError as c, RelayTimeoutError as d, fetchRouted as i, RelayPublishError as l, RoutedJob as n, RelayClosedError as o, fanIn as r, RelayConnectionError as s, FanInOptions as t, RelaySuspendedError as u };
|
|
84
|
-
//# sourceMappingURL=index-
|
|
84
|
+
//# sourceMappingURL=index-q4MDce_r.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -6,19 +6,19 @@ import { a as readRelays, c as writeRelays, i as parseRelayList, n as RelayMarke
|
|
|
6
6
|
import { i as RoutedFilter, r as PubkeyRoutes, t as Gossip } from "./gossip-DpIvkBuj.mjs";
|
|
7
7
|
import { a as assertSubscriptionId, c as encodeRelayMessage, d as parseRelayMessage, i as SubscriptionId, l as mergeCountHll, n as CountResult, o as createSubscriptionId, r as RelayMessage, s as encodeClientMessage, t as ClientMessage, u as parseClientMessage } from "./message-iGPIqnn0.mjs";
|
|
8
8
|
import { a as NostrError, i as MessageError, n as EventValidationError, o as UrlError, r as HexError, s as WasmVerifyPoisonedError, t as CryptoError } from "./error-CR8Urc84.mjs";
|
|
9
|
-
import { a as
|
|
9
|
+
import { a as PoolOptions, c as PublishResult, d as RelayStatus, f as RelayStatusName, h as SubscribeOptions, i as PoolFetchResult, l as Relay, m as RelayFetchResult, n as Pool, o as PoolPublishResult, p as RelayFetchEnd, r as PoolCountResult, s as PoolSubscribeOptions, t as InvalidEventPolicy, u as RelayOptions } from "./pool-DBIYMtwy.mjs";
|
|
10
10
|
import { i as useWebSocketImplementation } from "./websocket-CmeqvAkp.mjs";
|
|
11
11
|
import { i as PutResult, n as NegentropyItem, r as OutboxBound, t as EventStore } from "./types-2pCUprRU.mjs";
|
|
12
|
-
import { n as ReactiveEventStoreOptions, r as Watch, t as ReactiveEventStore } from "./reactive-
|
|
12
|
+
import { n as ReactiveEventStoreOptions, r as Watch, t as ReactiveEventStore } from "./reactive-7aqeip4A.mjs";
|
|
13
13
|
import { _ as neventEncode, a as NAddr, b as npubEncode, c as NPub, d as Note, f as ProfilePointer, g as naddrEncode, i as EventPointer, l as NSec, m as decodeNostrURI, n as Bech32MaxSize, o as NEvent, p as decode, r as DecodedResult, s as NProfile, t as AddressPointer, u as Nip19Error, v as noteEncode, x as nsecEncode, y as nprofileEncode } from "./nip19-BevCJZsp.mjs";
|
|
14
|
-
import { _ as ReplaceableLoader, a as OutboxFeed, c as groupAuthorsByOutboxRelay, d as bareNostrUser, g as ReplaceableLoadResult, h as LoadStyle, i as OutboxError, l as NostrUser, m as MutedEntity, n as Loaders, o as OutboxFeedOptions, p as ListResult, r as createLoaders, s as createOutboxFeed } from "./index-
|
|
14
|
+
import { _ as ReplaceableLoader, a as OutboxFeed, c as groupAuthorsByOutboxRelay, d as bareNostrUser, g as ReplaceableLoadResult, h as LoadStyle, i as OutboxError, l as NostrUser, m as MutedEntity, n as Loaders, o as OutboxFeedOptions, p as ListResult, r as createLoaders, s as createOutboxFeed } from "./index-lvXeER5t.mjs";
|
|
15
15
|
import { t as NostrSigner } from "./types-CRQEk0Oi.mjs";
|
|
16
16
|
import { t as StorageError } from "./error-BW7re1UN.mjs";
|
|
17
|
-
import {
|
|
17
|
+
import { _ as SyncSummary, c as PrivateMessageSendResult, d as SendPrivateMessageOptions, g as SyncOptions, h as SyncDirectionName, i as ClientOptions, m as SyncDirection, n as ClientBuilder, p as SubscribePrivateMessagesOptions, r as ClientError, s as FetchPrivateMessagesOptions, t as Client, u as ReceivedPrivateMessage } from "./index-CNl2q67H.mjs";
|
|
18
18
|
import { C as SIGNATURE_BYTES, S as SECRET_KEY_BYTES, _ as isHex32, a as KindClassification, b as EVENT_ID_BYTES, c as classifyKind, d as isRegularKind, f as isReplaceableKind, g as hexToBytes, h as bytesToHex, i as Kind, l as isAddressableKind, n as createEventVerifier, o as KindName, r as verifyEvent, s as KnownKind, t as SerializedEventVerifier, u as isEphemeralKind, v as isHex64, w as SUBSCRIPTION_ID_MAX_CHARS, x as PUBLIC_KEY_BYTES, y as normalizeURL } from "./index-CvkvqB16.mjs";
|
|
19
19
|
import { a as Nip07Signer, c as isNip07Available, i as Nip46Transport, l as KeysSigner, n as Nip46SignerOptions, o as WindowNostr, r as Nip46SubscribeOptions, s as getWindowNostr, t as Nip46Signer, u as NoSignerError } from "./index-MxC28S4P.mjs";
|
|
20
20
|
import { ReplyTagsOptions, ThreadReferences, buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
|
|
21
21
|
import { isAuthRequired, makeAuthEvent } from "./nips/nip42.mjs";
|
|
22
|
-
import { a as isInsecureRelayUrl, c as RelayError, d as RelayTimeoutError, l as RelayPublishError, o as RelayClosedError, s as RelayConnectionError, u as RelaySuspendedError } from "./index-
|
|
22
|
+
import { a as isInsecureRelayUrl, c as RelayError, d as RelayTimeoutError, l as RelayPublishError, o as RelayClosedError, s as RelayConnectionError, u as RelaySuspendedError } from "./index-q4MDce_r.mjs";
|
|
23
23
|
import { a as IndexedDbEventStoreOptions, i as IndexedDbEventStore, n as SqlValue, o as MemoryEventStore, r as SqliteEventStore, t as SqlDriver } from "./index-D1bqFHKB.mjs";
|
|
24
|
-
export { type AddressPointer, Bech32MaxSize, Client, ClientBuilder, ClientError, type ClientMessage, type ClientOptions, type CountResult, CryptoError, type DecodedResult, EVENT_ID_BYTES, type Event, type EventAddress, EventBuilder, type EventPointer, type EventStore, type EventTemplate, EventValidationError, type FetchPrivateMessagesOptions, type Filter, Gossip, HexError, IndexedDbEventStore, type IndexedDbEventStoreOptions, type InvalidEventPolicy, Keys, KeysSigner, Kind, type KindClassification, type KindName, type KnownKind, type ListResult, type LoadStyle, type Loaders, MemoryEventStore, MessageError, type MutedEntity, type NAddr, type NEvent, type NProfile, type NPub, type NSec, type NegentropyItem, Nip07Signer, Nip19Error, Nip46Signer, type Nip46SignerOptions, type Nip46SubscribeOptions, type Nip46Transport, NoSignerError, NostrError, type NostrSigner, type NostrUser, type Note, type OutboxBound, OutboxError, OutboxFeed, type OutboxFeedOptions, PUBLIC_KEY_BYTES, Pool, type PoolCountResult, type PoolOptions, type PoolPublishResult, type PoolSubscribeOptions, type PrivateMessageSendResult, type ProfileMetadata, type ProfilePointer, type PubkeyRoutes, type PublicKey, type PublishResult, type PutResult, ReactiveEventStore, type ReactiveEventStoreOptions, type ReceivedPrivateMessage, Relay, RelayClosedError, RelayConnectionError, RelayError, type RelayListItem, type RelayMarker, type RelayMessage, type RelayOptions, RelayPublishError, RelayStatus, type RelayStatusName, RelaySuspendedError, RelayTimeoutError, type ReplaceableLoadResult, type ReplaceableLoader, type ReplyTagsOptions, type RoutedFilter, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, type SendPrivateMessageOptions, type SerializedEventVerifier, type SigningBackend, type SqlDriver, type SqlValue, SqliteEventStore, StorageError, type SubscribeOptions, type SubscribePrivateMessagesOptions, type SubscriptionId, SyncDirection, type SyncDirectionName, type SyncOptions, type SyncSummary, Tag, type TagInput, type ThreadReferences, type UnsignedEvent, UrlError, WasmVerifyPoisonedError, type Watch, type WindowNostr, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createOutboxFeed, createSubscriptionId, decodeNostrURI, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, markerOf, matchFilter, matchFilters, mergeCountHll, mergeFilters, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, useWebSocketImplementation, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
|
|
24
|
+
export { type AddressPointer, Bech32MaxSize, Client, ClientBuilder, ClientError, type ClientMessage, type ClientOptions, type CountResult, CryptoError, type DecodedResult, EVENT_ID_BYTES, type Event, type EventAddress, EventBuilder, type EventPointer, type EventStore, type EventTemplate, EventValidationError, type FetchPrivateMessagesOptions, type Filter, Gossip, HexError, IndexedDbEventStore, type IndexedDbEventStoreOptions, type InvalidEventPolicy, Keys, KeysSigner, Kind, type KindClassification, type KindName, type KnownKind, type ListResult, type LoadStyle, type Loaders, MemoryEventStore, MessageError, type MutedEntity, type NAddr, type NEvent, type NProfile, type NPub, type NSec, type NegentropyItem, Nip07Signer, Nip19Error, Nip46Signer, type Nip46SignerOptions, type Nip46SubscribeOptions, type Nip46Transport, NoSignerError, NostrError, type NostrSigner, type NostrUser, type Note, type OutboxBound, OutboxError, OutboxFeed, type OutboxFeedOptions, PUBLIC_KEY_BYTES, Pool, type PoolCountResult, type PoolFetchResult, type PoolOptions, type PoolPublishResult, type PoolSubscribeOptions, type PrivateMessageSendResult, type ProfileMetadata, type ProfilePointer, type PubkeyRoutes, type PublicKey, type PublishResult, type PutResult, ReactiveEventStore, type ReactiveEventStoreOptions, type ReceivedPrivateMessage, Relay, RelayClosedError, RelayConnectionError, RelayError, type RelayFetchEnd, type RelayFetchResult, type RelayListItem, type RelayMarker, type RelayMessage, type RelayOptions, RelayPublishError, RelayStatus, type RelayStatusName, RelaySuspendedError, RelayTimeoutError, type ReplaceableLoadResult, type ReplaceableLoader, type ReplyTagsOptions, type RoutedFilter, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, type SendPrivateMessageOptions, type SerializedEventVerifier, type SigningBackend, type SqlDriver, type SqlValue, SqliteEventStore, StorageError, type SubscribeOptions, type SubscribePrivateMessagesOptions, type SubscriptionId, SyncDirection, type SyncDirectionName, type SyncOptions, type SyncSummary, Tag, type TagInput, type ThreadReferences, type UnsignedEvent, UrlError, WasmVerifyPoisonedError, type Watch, type WindowNostr, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createOutboxFeed, createSubscriptionId, decodeNostrURI, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, markerOf, matchFilter, matchFilters, mergeCountHll, mergeFilters, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, useWebSocketImplementation, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
|
package/dist/index.mjs
CHANGED
|
@@ -12,14 +12,14 @@ import { Bech32MaxSize, Nip19Error, decode, decodeNostrURI, naddrEncode, neventE
|
|
|
12
12
|
import { buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
|
|
13
13
|
import { isAuthRequired, makeAuthEvent } from "./nips/nip42.mjs";
|
|
14
14
|
import { markerOf, parseRelayList, readRelays, relayListEventBuilder, relayListToTags, writeRelays } from "./nips/nip65.mjs";
|
|
15
|
-
import { a as RelayStatus, c as isInsecureRelayUrl, d as RelayClosedError, f as RelayConnectionError, g as RelayTimeoutError, h as RelaySuspendedError, i as Relay, m as RelayPublishError, p as RelayError, t as Pool, u as useWebSocketImplementation } from "./pool-
|
|
15
|
+
import { a as RelayStatus, c as isInsecureRelayUrl, d as RelayClosedError, f as RelayConnectionError, g as RelayTimeoutError, h as RelaySuspendedError, i as Relay, m as RelayPublishError, p as RelayError, t as Pool, u as useWebSocketImplementation } from "./pool-As20OGxB.mjs";
|
|
16
16
|
import "./relay.mjs";
|
|
17
17
|
import { t as Gossip } from "./gossip-oloDMWEj.mjs";
|
|
18
18
|
import { a as groupAuthorsByOutboxRelay, i as createOutboxFeed, n as OutboxError, o as bareNostrUser, r as OutboxFeed, t as createLoaders } from "./loaders-o6YXB_Ri.mjs";
|
|
19
19
|
import { t as StorageError } from "./error-DrEIM7FO.mjs";
|
|
20
20
|
import { t as MemoryEventStore } from "./memory-C2EVx0_O.mjs";
|
|
21
|
-
import { t as ReactiveEventStore } from "./reactive-
|
|
22
|
-
import { i as ClientBuilder, n as ClientError, r as SyncDirection, t as Client } from "./client-
|
|
21
|
+
import { t as ReactiveEventStore } from "./reactive-BfhPp9a3.mjs";
|
|
22
|
+
import { i as ClientBuilder, n as ClientError, r as SyncDirection, t as Client } from "./client-CadO5fAX.mjs";
|
|
23
23
|
import { n as IndexedDbEventStore, t as SqliteEventStore } from "./storage-Dky3wuoH.mjs";
|
|
24
24
|
import "./store.mjs";
|
|
25
25
|
export { Bech32MaxSize, Client, ClientBuilder, ClientError, CryptoError, EVENT_ID_BYTES, EventBuilder, EventValidationError, Gossip, HexError, IndexedDbEventStore, Keys, KeysSigner, Kind, MemoryEventStore, MessageError, Nip07Signer, Nip19Error, Nip46Signer, NoSignerError, NostrError, OutboxError, OutboxFeed, PUBLIC_KEY_BYTES, Pool, ReactiveEventStore, Relay, RelayClosedError, RelayConnectionError, RelayError, RelayPublishError, RelayStatus, RelaySuspendedError, RelayTimeoutError, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, SqliteEventStore, StorageError, SyncDirection, Tag, UrlError, WasmVerifyPoisonedError, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createOutboxFeed, createSubscriptionId, decodeNostrURI, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, markerOf, matchFilter, matchFilters, mergeCountHll, mergeFilters, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, useWebSocketImplementation, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { t as Event } from "./event-fU3Y01PR.mjs";
|
|
2
|
+
import { i as SigningBackend } from "./key-Cv4_pN3x.mjs";
|
|
3
|
+
//#region src/wasm/instance.d.ts
|
|
4
|
+
type LoadNostrWasmOptions = {
|
|
5
|
+
/** Bytes, or a URL whose bytes will be read by the platform loader. */
|
|
6
|
+
module?: ArrayBuffer | ArrayBufferView | URL;
|
|
7
|
+
};
|
|
8
|
+
type NostrWasm = SigningBackend & {
|
|
9
|
+
verify: (id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;
|
|
10
|
+
verifySerialized: (serializedUtf8: Uint8Array, id: Uint8Array, pubkey: Uint8Array, sig: Uint8Array) => boolean;
|
|
11
|
+
verifyEvent: (event: Event) => boolean;
|
|
12
|
+
};
|
|
13
|
+
//#endregion
|
|
14
|
+
export { NostrWasm as n, LoadNostrWasmOptions as t };
|
|
15
|
+
//# sourceMappingURL=instance-CIca-ynn.d.mts.map
|