@qntx/nostr 0.12.1 → 0.13.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/{builder-BrmLOVj_.d.mts → builder-C72nJITG.d.mts} +2 -2
- package/dist/{builder-Cf2N12CG.mjs → builder-CGgM_QHT.mjs} +5 -5
- package/dist/{builder-Cf2N12CG.mjs.map → builder-CGgM_QHT.mjs.map} +1 -1
- package/dist/{client-B3_vToDX.mjs → client-COkEihj_.mjs} +87 -79
- package/dist/client-COkEihj_.mjs.map +1 -0
- package/dist/client.d.mts +1 -1
- package/dist/client.mjs +1 -1
- package/dist/core.d.mts +7 -7
- package/dist/core.mjs +9 -9
- package/dist/{emitter-DkCY6NkU.mjs → emitter-u4kJqQDk.mjs} +2 -2
- package/dist/{emitter-DkCY6NkU.mjs.map → emitter-u4kJqQDk.mjs.map} +1 -1
- package/dist/{error-BquXDmIN.d.mts → error-BPqAU5RB.d.mts} +2 -6
- package/dist/{error-BD_0QFKT.d.mts → error-BjSUsx6M.d.mts} +2 -2
- package/dist/{error-D3VNRVhL.mjs → error-Dyb89ahb.mjs} +2 -2
- package/dist/{error-D3VNRVhL.mjs.map → error-Dyb89ahb.mjs.map} +1 -1
- package/dist/{error-DH4guike.mjs → error-QyECUDIp.mjs} +2 -2
- package/dist/{error-DH4guike.mjs.map → error-QyECUDIp.mjs.map} +1 -1
- package/dist/{event-B3ua2_oL.mjs → event-DvM1f03b.mjs} +7 -3
- package/dist/event-DvM1f03b.mjs.map +1 -0
- package/dist/{filter-B16P33dz.mjs → filter-3jOh4uLN.mjs} +50 -20
- package/dist/filter-3jOh4uLN.mjs.map +1 -0
- package/dist/{filter-PG7r79rt.d.mts → filter-oYG2zjJ3.d.mts} +6 -2
- package/dist/{gossip-u0iBlZ1U.d.mts → gossip-BvCItMVZ.d.mts} +3 -3
- package/dist/{gossip-K_JIexQs.mjs → gossip-CRyhK6E6.mjs} +4 -4
- package/dist/{gossip-K_JIexQs.mjs.map → gossip-CRyhK6E6.mjs.map} +1 -1
- package/dist/gossip.d.mts +1 -1
- package/dist/gossip.mjs +1 -1
- package/dist/http-CuazNRIP.mjs.map +1 -1
- package/dist/{index-DD0Ywpay.d.mts → index-B2JlP2Jf.d.mts} +9 -9
- package/dist/{index-yq9xkONo.d.mts → index-DCobP2Jj.d.mts} +10 -10
- package/dist/{index-Hp26bgYG.d.mts → index-Dpj_MUxb.d.mts} +8 -5
- package/dist/{index-rKcmI6ex.d.mts → index-DzHmhHqD.d.mts} +3 -3
- package/dist/{index-SwMknboJ.d.mts → index-YID-zPDF.d.mts} +7 -7
- package/dist/{index-DxQO1eWA.d.mts → index-muydfuYD.d.mts} +21 -21
- package/dist/index.d.mts +19 -20
- package/dist/index.mjs +20 -20
- package/dist/{key-B218_SoL.mjs → key-D_oEutQ6.mjs} +5 -7
- package/dist/{key-B218_SoL.mjs.map → key-D_oEutQ6.mjs.map} +1 -1
- package/dist/{key-CwMVo14x.d.mts → key-DojW2QZl.d.mts} +3 -5
- package/dist/{kind-D8fENiiL.mjs → kind-I2Tvbe82.mjs} +6 -5
- package/dist/kind-I2Tvbe82.mjs.map +1 -0
- package/dist/{loaders-Xdbx-K61.mjs → loaders-BRh2riV9.mjs} +17 -16
- package/dist/loaders-BRh2riV9.mjs.map +1 -0
- package/dist/loaders.d.mts +2 -2
- package/dist/loaders.mjs +1 -1
- package/dist/{memory-VyPnOBU3.mjs → memory-D_GdEQYG.mjs} +2 -2
- package/dist/memory-D_GdEQYG.mjs.map +1 -0
- package/dist/memory-index-3GSrPIWj.mjs +671 -0
- package/dist/memory-index-3GSrPIWj.mjs.map +1 -0
- package/dist/{message-pYfVKxPn.mjs → message-BMfreCQc.mjs} +6 -6
- package/dist/message-BMfreCQc.mjs.map +1 -0
- package/dist/{nip17-BM4hJYBq.d.mts → nip17-BZvFQLcs.d.mts} +4 -4
- package/dist/{nip19-DpPN17bY.d.mts → nip19-D4RKn6GC.d.mts} +2 -2
- package/dist/{nip46-BHaxC9TZ.d.mts → nip46-i8L8_nIm.d.mts} +2 -2
- package/dist/{nip51-D_bu8Hph.d.mts → nip51-C_kTYcud.d.mts} +2 -2
- package/dist/{nip59-CGWfoItR.d.mts → nip59-DfJ6Moeu.d.mts} +2 -2
- package/dist/{nip65-DaWMg943.d.mts → nip65-CPNE0SV0.d.mts} +2 -2
- package/dist/{nip77-wHA_nEV5.d.mts → nip77-DhpoL7d8.d.mts} +2 -2
- package/dist/nips/blossom.d.mts +2 -2
- package/dist/nips/blossom.mjs +3 -3
- package/dist/nips/blossom.mjs.map +1 -1
- package/dist/nips/nip04.d.mts +9 -12
- package/dist/nips/nip04.mjs +38 -45
- package/dist/nips/nip04.mjs.map +1 -1
- package/dist/nips/nip05.d.mts +6 -3
- package/dist/nips/nip05.mjs +6 -3
- package/dist/nips/nip05.mjs.map +1 -1
- package/dist/nips/nip10.d.mts +2 -2
- package/dist/nips/nip10.mjs +4 -4
- package/dist/nips/nip11.d.mts +1 -1
- package/dist/nips/nip11.mjs +1 -1
- package/dist/nips/nip13.d.mts +1 -1
- package/dist/nips/nip13.mjs +1 -1
- package/dist/nips/nip13.mjs.map +1 -1
- package/dist/nips/nip17.d.mts +1 -1
- package/dist/nips/nip17.mjs +4 -4
- package/dist/nips/nip17.mjs.map +1 -1
- package/dist/nips/nip19.d.mts +1 -1
- package/dist/nips/nip19.mjs +2 -2
- package/dist/nips/nip19.mjs.map +1 -1
- package/dist/nips/nip21.d.mts +6 -3
- package/dist/nips/nip21.mjs +8 -5
- package/dist/nips/nip21.mjs.map +1 -1
- package/dist/nips/nip27.d.mts +1 -1
- package/dist/nips/nip27.mjs +15 -9
- package/dist/nips/nip27.mjs.map +1 -1
- package/dist/nips/nip42.mjs +2 -2
- package/dist/nips/nip44.mjs +1 -1
- package/dist/nips/nip46.d.mts +1 -1
- package/dist/nips/nip46.mjs +9 -7
- package/dist/nips/nip46.mjs.map +1 -1
- package/dist/nips/nip49.d.mts +1 -1
- package/dist/nips/nip49.mjs +1 -1
- package/dist/nips/nip51.d.mts +1 -1
- package/dist/nips/nip51.mjs +5 -5
- package/dist/nips/nip51.mjs.map +1 -1
- package/dist/nips/nip57.mjs +6 -5
- package/dist/nips/nip57.mjs.map +1 -1
- package/dist/nips/nip59.d.mts +1 -1
- package/dist/nips/nip59.mjs +5 -5
- package/dist/nips/nip59.mjs.map +1 -1
- package/dist/nips/nip65.d.mts +1 -1
- package/dist/nips/nip65.mjs +3 -3
- package/dist/nips/nip77.d.mts +1 -1
- package/dist/nips/nip77.mjs +1 -1
- package/dist/nips/nip77.mjs.map +1 -1
- package/dist/nips/nip98.d.mts +1 -1
- package/dist/nips/nip98.mjs +9 -6
- package/dist/nips/nip98.mjs.map +1 -1
- package/dist/{pool-DUuYJ0x4.d.mts → pool-MehgIIzm.d.mts} +20 -16
- package/dist/{pool-THuuOW4S.mjs → pool-lMT_mvzn.mjs} +25 -25
- package/dist/pool-lMT_mvzn.mjs.map +1 -0
- package/dist/{put-DRmV1wHD.mjs → put-BEM5j8xK.mjs} +5 -5
- package/dist/{put-DRmV1wHD.mjs.map → put-BEM5j8xK.mjs.map} +1 -1
- package/dist/{reactive-jyKrA9ej.d.mts → reactive-B7lPFgTS.d.mts} +3 -3
- package/dist/{reactive--pDpLt2H.mjs → reactive-DFHY-f00.mjs} +24 -9
- package/dist/reactive-DFHY-f00.mjs.map +1 -0
- package/dist/{relay-BGPqiGKF.mjs → relay-DIR77xQ2.mjs} +102 -89
- package/dist/relay-DIR77xQ2.mjs.map +1 -0
- package/dist/relay.d.mts +5 -5
- package/dist/relay.mjs +3 -3
- package/dist/{report-CHld4uWj.mjs → report-D2BM5dgn.mjs} +2 -2
- package/dist/{report-CHld4uWj.mjs.map → report-D2BM5dgn.mjs.map} +1 -1
- package/dist/{signer-CNTIeYH4.mjs → signer-DJcmC4nA.mjs} +17 -17
- package/dist/signer-DJcmC4nA.mjs.map +1 -0
- package/dist/signer.d.mts +1 -1
- package/dist/signer.mjs +2 -2
- package/dist/{storage-B5Wdt_Mn.mjs → storage-n2BE1bdY.mjs} +108 -179
- package/dist/storage-n2BE1bdY.mjs.map +1 -0
- package/dist/storage.d.mts +3 -3
- package/dist/storage.mjs +4 -4
- package/dist/store.d.mts +1 -1
- package/dist/store.mjs +1 -1
- package/dist/testing.d.mts +4 -4
- package/dist/testing.mjs +35 -10
- package/dist/testing.mjs.map +1 -1
- package/dist/{types-CqhnT-Mx.d.mts → types-DiVVyf1e.d.mts} +2 -2
- package/dist/{util-DDpPkiED.mjs → util-DfsyJ9nz.mjs} +30 -10
- package/dist/util-DfsyJ9nz.mjs.map +1 -0
- package/dist/{verifier-CjH1vnP2.mjs → verifier-DEHUy4AD.mjs} +3 -3
- package/dist/{verifier-CjH1vnP2.mjs.map → verifier-DEHUy4AD.mjs.map} +1 -1
- package/dist/{verifier-Cl24c9ph.d.mts → verifier-DhAbqVJF.d.mts} +2 -2
- package/dist/{websocket-CmeqvAkp.d.mts → websocket-DaCvJkF9.d.mts} +2 -5
- package/package.json +4 -3
- package/dist/client-B3_vToDX.mjs.map +0 -1
- package/dist/event-B3ua2_oL.mjs.map +0 -1
- package/dist/filter-B16P33dz.mjs.map +0 -1
- package/dist/kind-D8fENiiL.mjs.map +0 -1
- package/dist/loaders-Xdbx-K61.mjs.map +0 -1
- package/dist/memory-VyPnOBU3.mjs.map +0 -1
- package/dist/memory-index-Bhwe0ZdG.mjs +0 -374
- package/dist/memory-index-Bhwe0ZdG.mjs.map +0 -1
- package/dist/message-pYfVKxPn.mjs.map +0 -1
- package/dist/pool-THuuOW4S.mjs.map +0 -1
- package/dist/reactive--pDpLt2H.mjs.map +0 -1
- package/dist/relay-BGPqiGKF.mjs.map +0 -1
- package/dist/signer-CNTIeYH4.mjs.map +0 -1
- package/dist/storage-B5Wdt_Mn.mjs.map +0 -1
- package/dist/util-DDpPkiED.mjs.map +0 -1
|
@@ -1,16 +1,16 @@
|
|
|
1
1
|
import { n as EventTemplate, r as UnsignedEvent, t as Event } from "./event-j3BwI5dF.mjs";
|
|
2
|
-
import { t as EventBuilder } from "./builder-
|
|
3
|
-
import { t as Filter } from "./filter-
|
|
4
|
-
import { t as Gossip } from "./gossip-
|
|
5
|
-
import { a as NostrError } from "./error-
|
|
6
|
-
import { _ as Closer, a as PoolFetchResult, n as Pool, o as PoolOptions, s as PoolPublishResult } from "./pool-
|
|
7
|
-
import { t as EventStore } from "./types-
|
|
8
|
-
import { t as ReactiveEventStore } from "./reactive-
|
|
9
|
-
import { a as OutboxFeed, n as Loaders } from "./index-
|
|
10
|
-
import { a as Rumor } from "./nip59-
|
|
11
|
-
import { i as ReplyTo, r as Recipient } from "./nip17-
|
|
2
|
+
import { t as EventBuilder } from "./builder-C72nJITG.mjs";
|
|
3
|
+
import { t as Filter } from "./filter-oYG2zjJ3.mjs";
|
|
4
|
+
import { t as Gossip } from "./gossip-BvCItMVZ.mjs";
|
|
5
|
+
import { a as NostrError } from "./error-BPqAU5RB.mjs";
|
|
6
|
+
import { _ as Closer, a as PoolFetchResult, n as Pool, o as PoolOptions, s as PoolPublishResult } from "./pool-MehgIIzm.mjs";
|
|
7
|
+
import { t as EventStore } from "./types-DiVVyf1e.mjs";
|
|
8
|
+
import { t as ReactiveEventStore } from "./reactive-B7lPFgTS.mjs";
|
|
9
|
+
import { a as OutboxFeed, n as Loaders } from "./index-DCobP2Jj.mjs";
|
|
10
|
+
import { a as Rumor } from "./nip59-DfJ6Moeu.mjs";
|
|
11
|
+
import { i as ReplyTo, r as Recipient } from "./nip17-BZvFQLcs.mjs";
|
|
12
12
|
import { t as NostrSigner } from "./types-BJ4wZ7JJ.mjs";
|
|
13
|
-
import { t as StorageError } from "./error-
|
|
13
|
+
import { t as StorageError } from "./error-BjSUsx6M.mjs";
|
|
14
14
|
//#region src/client/types.d.ts
|
|
15
15
|
/** Direction of a {@link Client.sync} run: upload, download, or both. */
|
|
16
16
|
declare const SyncDirection: {
|
|
@@ -97,7 +97,7 @@ type FetchEventsOptions = {
|
|
|
97
97
|
* Every event of every relay batch, including duplicates across relays. `relayUrl` is the
|
|
98
98
|
* normalized URL of the relay that delivered it.
|
|
99
99
|
*/
|
|
100
|
-
|
|
100
|
+
onEvent?: ((event: Event, relayUrl: string) => void) | undefined;
|
|
101
101
|
};
|
|
102
102
|
/** Options for {@link Client.fetchEach}: one-shot per-relay fetch, no gossip routing. */
|
|
103
103
|
type FetchEachOptions = {
|
|
@@ -113,15 +113,15 @@ type SubscribeOptions = {
|
|
|
113
113
|
* First receipt of each event only (deduped across relays). `relayUrl` is the normalized URL of
|
|
114
114
|
* the relay that delivered it first.
|
|
115
115
|
*/
|
|
116
|
-
|
|
116
|
+
onEvent?: ((event: Event, relayUrl: string) => void) | undefined;
|
|
117
117
|
/** Every receipt from every relay, including duplicates skipped by dedupe. */
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
118
|
+
onEventSeen?: ((id: string, relayUrl: string) => void) | undefined;
|
|
119
|
+
onEose?: (() => void) | undefined;
|
|
120
|
+
onClose?: ((reason: string) => void) | undefined;
|
|
121
121
|
signal?: AbortSignal | undefined;
|
|
122
122
|
id?: string | undefined;
|
|
123
123
|
/**
|
|
124
|
-
* If set, fire `
|
|
124
|
+
* If set, fire `onEose` once after this many ms if not all relays have EOSEd. Does not close the
|
|
125
125
|
* subscription.
|
|
126
126
|
*/
|
|
127
127
|
eoseTimeoutMs?: number | undefined;
|
|
@@ -176,9 +176,9 @@ type FetchPrivateMessagesOptions = {
|
|
|
176
176
|
/** Options for a live NIP-17 private-message subscription. */
|
|
177
177
|
type SubscribePrivateMessagesOptions = {
|
|
178
178
|
readonly since?: number | undefined;
|
|
179
|
-
readonly
|
|
180
|
-
readonly
|
|
181
|
-
readonly
|
|
179
|
+
readonly onEvent?: ((msg: ReceivedPrivateMessage) => void) | undefined;
|
|
180
|
+
readonly onEose?: (() => void) | undefined;
|
|
181
|
+
readonly onClose?: ((reason: string) => void) | undefined;
|
|
182
182
|
readonly signal?: AbortSignal | undefined;
|
|
183
183
|
readonly eoseTimeoutMs?: number | undefined;
|
|
184
184
|
readonly observe?: boolean | undefined;
|
|
@@ -290,4 +290,4 @@ declare class Client {
|
|
|
290
290
|
}
|
|
291
291
|
//#endregion
|
|
292
292
|
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, ClientError as n, FetchEventsOptions as o, SubscribePrivateMessagesOptions as p, ClientEventMap as r, FetchPrivateMessagesOptions as s, Client as t, ReceivedPrivateMessage as u };
|
|
293
|
-
//# sourceMappingURL=index-
|
|
293
|
+
//# sourceMappingURL=index-muydfuYD.d.mts.map
|
package/dist/index.d.mts
CHANGED
|
@@ -1,25 +1,24 @@
|
|
|
1
1
|
import { C as tagName, S as parseEventAddress, _ as eventAddress, b as getDTag, c as serializeEvent, d as sortedEvents, f as validateEvent, g as TagInput, h as Tag, i as getEventHash, l as signedMatchesUnsigned, m as EventAddress, n as EventTemplate, o as isReplaceableWinner, p as validateSignedEvent, r as UnsignedEvent, s as itemCompare, t as Event, u as sortEvents, w as tagValue, x as isTag, y as formatEventAddress } from "./event-j3BwI5dF.mjs";
|
|
2
|
-
import { a as SigningBackend, c as publicKeyFromHex, i as SecretKeyInput, l as signEvent, n as PublicKey, o as finalizeEvent, r as SecretKey, s as getPublicKey, t as Keys, u as toSecretKey } from "./key-
|
|
3
|
-
import { n as ProfileMetadata, t as EventBuilder } from "./builder-
|
|
4
|
-
import { a as getFilterLimit, i as filterFingerprint, n as canonicalizeFilter, o as matchFilter, r as canonicalizeFilters, s as matchFilters, t as Filter } from "./filter-
|
|
5
|
-
import { a as relayListEventBuilder, i as readRelays, n as RelayMarker, o as relayListToTags, r as parseRelayList, s as writeRelays, t as RelayListItem } from "./nip65-
|
|
6
|
-
import { i as RoutedFilter, r as PubkeyRoutes, t as Gossip } from "./gossip-
|
|
7
|
-
import { a as ClientMessage, c as SubscriptionId, d as encodeClientMessage, f as encodeRelayMessage, h as parseRelayMessage, i as verifyEvent, l as assertSubscriptionId, m as parseClientMessage, n as SerializedEventVerifier, o as CountResult, p as mergeCountHll, r as createEventVerifier, s as RelayMessage, t as EventVerifier, u as createSubscriptionId } from "./verifier-
|
|
8
|
-
import { a as NostrError, i as MessageError, n as EventValidationError, o as UrlError, r as HexError,
|
|
9
|
-
import { _ as Closer, a as PoolFetchResult, c as PoolSubscribeOptions, d as RelayOptions, f as RelayStatus, g as RelayFetchResult, h as RelayFetchEnd, i as PoolEventMap, l as Relay, m as PublishResult, n as Pool, o as PoolOptions, p as RelayStatusName, r as PoolCountResult, s as PoolPublishResult, t as InvalidEventPolicy, u as RelayEventMap, v as RelaySubscription, y as SubscribeOptions } from "./pool-
|
|
10
|
-
import { i as
|
|
11
|
-
import { i as
|
|
12
|
-
import { i as
|
|
13
|
-
import {
|
|
14
|
-
import { a as OutboxFeed, c as NostrUser, f as ListResult, h as ReplaceableLoader, i as OutboxError, m as ReplaceableLoadResult, n as Loaders, o as OutboxFeedOptions, p as LoadStyle, r as createLoaders, s as groupAuthorsByOutboxRelay, u as bareNostrUser } from "./index-yq9xkONo.mjs";
|
|
2
|
+
import { a as SigningBackend, c as publicKeyFromHex, i as SecretKeyInput, l as signEvent, n as PublicKey, o as finalizeEvent, r as SecretKey, s as getPublicKey, t as Keys, u as toSecretKey } from "./key-DojW2QZl.mjs";
|
|
3
|
+
import { n as ProfileMetadata, t as EventBuilder } from "./builder-C72nJITG.mjs";
|
|
4
|
+
import { a as getFilterLimit, i as filterFingerprint, n as canonicalizeFilter, o as matchFilter, r as canonicalizeFilters, s as matchFilters, t as Filter } from "./filter-oYG2zjJ3.mjs";
|
|
5
|
+
import { a as relayListEventBuilder, i as readRelays, n as RelayMarker, o as relayListToTags, r as parseRelayList, s as writeRelays, t as RelayListItem } from "./nip65-CPNE0SV0.mjs";
|
|
6
|
+
import { i as RoutedFilter, r as PubkeyRoutes, t as Gossip } from "./gossip-BvCItMVZ.mjs";
|
|
7
|
+
import { a as ClientMessage, c as SubscriptionId, d as encodeClientMessage, f as encodeRelayMessage, h as parseRelayMessage, i as verifyEvent, l as assertSubscriptionId, m as parseClientMessage, n as SerializedEventVerifier, o as CountResult, p as mergeCountHll, r as createEventVerifier, s as RelayMessage, t as EventVerifier, u as createSubscriptionId } from "./verifier-DhAbqVJF.mjs";
|
|
8
|
+
import { a as NostrError, i as MessageError, n as EventValidationError, o as UrlError, r as HexError, t as CryptoError } from "./error-BPqAU5RB.mjs";
|
|
9
|
+
import { _ as Closer, a as PoolFetchResult, c as PoolSubscribeOptions, d as RelayOptions, f as RelayStatus, g as RelayFetchResult, h as RelayFetchEnd, i as PoolEventMap, l as Relay, m as PublishResult, n as Pool, o as PoolOptions, p as RelayStatusName, r as PoolCountResult, s as PoolPublishResult, t as InvalidEventPolicy, u as RelayEventMap, v as RelaySubscription, y as SubscribeOptions } from "./pool-MehgIIzm.mjs";
|
|
10
|
+
import { i as PutResult, n as NegentropyItem, r as OutboxBound, t as EventStore } from "./types-DiVVyf1e.mjs";
|
|
11
|
+
import { i as Watch, n as ReactiveEventStoreEventMap, r as ReactiveEventStoreOptions, t as ReactiveEventStore } from "./reactive-B7lPFgTS.mjs";
|
|
12
|
+
import { _ as noteEncode, a as NAddr, b as nsecEncode, c as NPub, d as Note, f as ProfilePointer, g as neventEncode, h as naddrEncode, i as EventPointer, l as NSec, n as Bech32MaxSize, o as NEvent, p as decode, r as DecodedResult, s as NProfile, t as AddressPointer, u as Nip19Error, v as nprofileEncode, y as npubEncode } from "./nip19-D4RKn6GC.mjs";
|
|
13
|
+
import { a as OutboxFeed, c as NostrUser, f as ListResult, h as ReplaceableLoader, i as OutboxError, m as ReplaceableLoadResult, n as Loaders, o as OutboxFeedOptions, p as LoadStyle, r as createLoaders, s as groupAuthorsByOutboxRelay, u as bareNostrUser } from "./index-DCobP2Jj.mjs";
|
|
15
14
|
import { t as NostrSigner } from "./types-BJ4wZ7JJ.mjs";
|
|
16
|
-
import { t as StorageError } from "./error-
|
|
17
|
-
import { _ as SyncSummary, c as PrivateMessageSendResult, d as SendPrivateMessageOptions, g as SyncOptions, h as SyncDirectionName, i as ClientOptions, m as SyncDirection, n as ClientError, p as SubscribePrivateMessagesOptions, r as ClientEventMap, s as FetchPrivateMessagesOptions, t as Client, u as ReceivedPrivateMessage } from "./index-
|
|
18
|
-
import {
|
|
19
|
-
import { a as Nip07Signer, c as isNip07Available, d as NostrKeyOperations, f as NoSignerError, i as Nip46Transport, l as KeysSigner, n as Nip46SignerOptions, o as WindowNostr, p as SignerDisposedError, r as Nip46SubscribeOptions, s as getWindowNostr, t as Nip46Signer, u as DelegatedSigner } from "./index-
|
|
15
|
+
import { t as StorageError } from "./error-BjSUsx6M.mjs";
|
|
16
|
+
import { _ as SyncSummary, c as PrivateMessageSendResult, d as SendPrivateMessageOptions, g as SyncOptions, h as SyncDirectionName, i as ClientOptions, m as SyncDirection, n as ClientError, p as SubscribePrivateMessagesOptions, r as ClientEventMap, s as FetchPrivateMessagesOptions, t as Client, u as ReceivedPrivateMessage } from "./index-muydfuYD.mjs";
|
|
17
|
+
import { C as SUBSCRIPTION_ID_MAX_CHARS, S as SIGNATURE_BYTES, _ as normalizeURL, a as classifyKind, b as PUBLIC_KEY_BYTES, c as isRegularKind, f as bytesToHex, h as isHex64, i as KnownKind, l as isReplaceableKind, m as isHex32, n as KindClassification, o as isAddressableKind, p as hexToBytes, r as KindName, s as isEphemeralKind, t as Kind, x as SECRET_KEY_BYTES, y as EVENT_ID_BYTES } from "./index-Dpj_MUxb.mjs";
|
|
18
|
+
import { a as Nip07Signer, c as isNip07Available, d as NostrKeyOperations, f as NoSignerError, i as Nip46Transport, l as KeysSigner, n as Nip46SignerOptions, o as WindowNostr, p as SignerDisposedError, r as Nip46SubscribeOptions, s as getWindowNostr, t as Nip46Signer, u as DelegatedSigner } from "./index-YID-zPDF.mjs";
|
|
20
19
|
import { Nip21Error, NostrURI, isNostrURI, parseNostrURI } from "./nips/nip21.mjs";
|
|
21
20
|
import { ReplyTagsOptions, ThreadReferences, buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
|
|
22
21
|
import { isAuthRequired, makeAuthEvent } from "./nips/nip42.mjs";
|
|
23
|
-
import { a as isInsecureRelayUrl, c as RelayError, d as RelayTimeoutError, l as RelayPublishError, o as RelayClosedError, s as RelayConnectionError, u as RelaySuspendedError } from "./index-
|
|
24
|
-
import { a as IndexedDbEventStoreOptions, i as IndexedDbEventStore, n as SqlValue, o as MemoryEventStore, r as SqliteEventStore, t as SqlDriver } from "./index-
|
|
25
|
-
export { type AddressPointer, Bech32MaxSize, Client, ClientError, type ClientEventMap, type ClientMessage, type ClientOptions, type Closer, type CountResult, CryptoError, type DecodedResult, DelegatedSigner, EVENT_ID_BYTES, type Event, type EventAddress, EventBuilder, type EventPointer, type EventStore, type EventTemplate, EventValidationError, type EventVerifier, 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 NAddr, type NEvent, type NProfile, type NPub, type NSec, type NegentropyItem, Nip07Signer, Nip19Error, Nip21Error, Nip46Signer, type Nip46SignerOptions, type Nip46SubscribeOptions, type Nip46Transport, NoSignerError, NostrError, type NostrKeyOperations, type NostrSigner, type NostrURI, type NostrUser, type Note, type OutboxBound, OutboxError, OutboxFeed, type OutboxFeedOptions, PUBLIC_KEY_BYTES, Pool, type PoolCountResult, type PoolEventMap, type PoolFetchResult, type PoolOptions, type PoolPublishResult, type PoolSubscribeOptions, type PrivateMessageSendResult, type ProfileMetadata, type ProfilePointer, type PubkeyRoutes, type PublicKey, type PublishResult, type PutResult, ReactiveEventStore, type ReactiveEventStoreEventMap, type ReactiveEventStoreOptions, type ReceivedPrivateMessage, Relay, RelayClosedError, RelayConnectionError, RelayError, type RelayEventMap, type RelayFetchEnd, type RelayFetchResult, type RelayListItem, type RelayMarker, type RelayMessage, type RelayOptions, RelayPublishError, RelayStatus, type RelayStatusName, type RelaySubscription, RelaySuspendedError, RelayTimeoutError, type ReplaceableLoadResult, type ReplaceableLoader, type ReplyTagsOptions, type RoutedFilter, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, type SecretKeyInput, type SendPrivateMessageOptions, type SerializedEventVerifier, SignerDisposedError, 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,
|
|
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-B2JlP2Jf.mjs";
|
|
23
|
+
import { a as IndexedDbEventStoreOptions, i as IndexedDbEventStore, n as SqlValue, o as MemoryEventStore, r as SqliteEventStore, t as SqlDriver } from "./index-DzHmhHqD.mjs";
|
|
24
|
+
export { type AddressPointer, Bech32MaxSize, Client, ClientError, type ClientEventMap, type ClientMessage, type ClientOptions, type Closer, type CountResult, CryptoError, type DecodedResult, DelegatedSigner, EVENT_ID_BYTES, type Event, type EventAddress, EventBuilder, type EventPointer, type EventStore, type EventTemplate, EventValidationError, type EventVerifier, 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 NAddr, type NEvent, type NProfile, type NPub, type NSec, type NegentropyItem, Nip07Signer, Nip19Error, Nip21Error, Nip46Signer, type Nip46SignerOptions, type Nip46SubscribeOptions, type Nip46Transport, NoSignerError, NostrError, type NostrKeyOperations, type NostrSigner, type NostrURI, type NostrUser, type Note, type OutboxBound, OutboxError, OutboxFeed, type OutboxFeedOptions, PUBLIC_KEY_BYTES, Pool, type PoolCountResult, type PoolEventMap, type PoolFetchResult, type PoolOptions, type PoolPublishResult, type PoolSubscribeOptions, type PrivateMessageSendResult, type ProfileMetadata, type ProfilePointer, type PubkeyRoutes, type PublicKey, type PublishResult, type PutResult, ReactiveEventStore, type ReactiveEventStoreEventMap, type ReactiveEventStoreOptions, type ReceivedPrivateMessage, Relay, RelayClosedError, RelayConnectionError, RelayError, type RelayEventMap, type RelayFetchEnd, type RelayFetchResult, type RelayListItem, type RelayMarker, type RelayMessage, type RelayOptions, RelayPublishError, RelayStatus, type RelayStatusName, type RelaySubscription, RelaySuspendedError, RelayTimeoutError, type ReplaceableLoadResult, type ReplaceableLoader, type ReplyTagsOptions, type RoutedFilter, SECRET_KEY_BYTES, SIGNATURE_BYTES, SUBSCRIPTION_ID_MAX_CHARS, SecretKey, type SecretKeyInput, type SendPrivateMessageOptions, type SerializedEventVerifier, SignerDisposedError, 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, type Watch, type WindowNostr, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createSubscriptionId, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isNostrURI, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, matchFilter, matchFilters, mergeCountHll, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseNostrURI, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, toSecretKey, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
|
package/dist/index.mjs
CHANGED
|
@@ -1,27 +1,27 @@
|
|
|
1
|
-
import { D as
|
|
2
|
-
import { a as isRegularKind, i as isEphemeralKind, n as classifyKind, o as isReplaceableKind, r as isAddressableKind, t as Kind } from "./kind-
|
|
3
|
-
import { C as tagName, S as parseEventAddress, _ as eventAddress, a as isReplaceableWinner, b as getDTag, d as signedMatchesUnsigned, f as sortEvents, g as Tag, h as validateSignedEvent, l as serializeEvent, m as validateEvent, n as getEventHash, o as itemCompare, p as sortedEvents, w as tagValue, x as isTag, y as formatEventAddress } from "./event-
|
|
4
|
-
import { a as publicKeyFromHex, i as getPublicKey, n as SecretKey, o as signEvent, r as finalizeEvent, s as toSecretKey, t as Keys } from "./key-
|
|
5
|
-
import { n as verifyEvent, t as createEventVerifier } from "./verifier-
|
|
6
|
-
import { t as EventBuilder } from "./builder-
|
|
7
|
-
import { a as
|
|
8
|
-
import { a as mergeCountHll, i as encodeRelayMessage, n as createSubscriptionId, o as parseClientMessage, r as encodeClientMessage, s as parseRelayMessage, t as assertSubscriptionId } from "./message-
|
|
9
|
-
import { n as SignerDisposedError, t as NoSignerError } from "./error-
|
|
10
|
-
import { a as KeysSigner, i as isNip07Available, n as Nip07Signer, o as DelegatedSigner, r as getWindowNostr, t as Nip46Signer } from "./signer-
|
|
1
|
+
import { D as SECRET_KEY_BYTES, E as PUBLIC_KEY_BYTES, O as SIGNATURE_BYTES, S as UrlError, T as EVENT_ID_BYTES, _ as CryptoError, b as MessageError, c as isHex32, f as normalizeURL, i as bytesToHex, k as SUBSCRIPTION_ID_MAX_CHARS, l as isHex64, s as hexToBytes, v as EventValidationError, x as NostrError, y as HexError } from "./util-DfsyJ9nz.mjs";
|
|
2
|
+
import { a as isRegularKind, i as isEphemeralKind, n as classifyKind, o as isReplaceableKind, r as isAddressableKind, t as Kind } from "./kind-I2Tvbe82.mjs";
|
|
3
|
+
import { C as tagName, S as parseEventAddress, _ as eventAddress, a as isReplaceableWinner, b as getDTag, d as signedMatchesUnsigned, f as sortEvents, g as Tag, h as validateSignedEvent, l as serializeEvent, m as validateEvent, n as getEventHash, o as itemCompare, p as sortedEvents, w as tagValue, x as isTag, y as formatEventAddress } from "./event-DvM1f03b.mjs";
|
|
4
|
+
import { a as publicKeyFromHex, i as getPublicKey, n as SecretKey, o as signEvent, r as finalizeEvent, s as toSecretKey, t as Keys } from "./key-D_oEutQ6.mjs";
|
|
5
|
+
import { n as verifyEvent, t as createEventVerifier } from "./verifier-DEHUy4AD.mjs";
|
|
6
|
+
import { t as EventBuilder } from "./builder-CGgM_QHT.mjs";
|
|
7
|
+
import { a as getFilterLimit, n as canonicalizeFilters, o as matchFilter, r as filterFingerprint, s as matchFilters, t as canonicalizeFilter } from "./filter-3jOh4uLN.mjs";
|
|
8
|
+
import { a as mergeCountHll, i as encodeRelayMessage, n as createSubscriptionId, o as parseClientMessage, r as encodeClientMessage, s as parseRelayMessage, t as assertSubscriptionId } from "./message-BMfreCQc.mjs";
|
|
9
|
+
import { n as SignerDisposedError, t as NoSignerError } from "./error-Dyb89ahb.mjs";
|
|
10
|
+
import { a as KeysSigner, i as isNip07Available, n as Nip07Signer, o as DelegatedSigner, r as getWindowNostr, t as Nip46Signer } from "./signer-DJcmC4nA.mjs";
|
|
11
11
|
import { Bech32MaxSize, Nip19Error, decode, naddrEncode, neventEncode, noteEncode, nprofileEncode, npubEncode, nsecEncode } from "./nips/nip19.mjs";
|
|
12
12
|
import { Nip21Error, isNostrURI, parseNostrURI } from "./nips/nip21.mjs";
|
|
13
13
|
import { buildReplyTags, parseThreadTags, replyTo } from "./nips/nip10.mjs";
|
|
14
14
|
import { isAuthRequired, makeAuthEvent } from "./nips/nip42.mjs";
|
|
15
15
|
import { parseRelayList, readRelays, relayListEventBuilder, relayListToTags, writeRelays } from "./nips/nip65.mjs";
|
|
16
|
-
import {
|
|
17
|
-
import { i as isInsecureRelayUrl, t as Pool } from "./pool-
|
|
16
|
+
import { a as RelayClosedError, c as RelayPublishError, l as RelaySuspendedError, n as Relay, o as RelayConnectionError, r as RelayStatus, s as RelayError, u as RelayTimeoutError } from "./relay-DIR77xQ2.mjs";
|
|
17
|
+
import { i as isInsecureRelayUrl, t as Pool } from "./pool-lMT_mvzn.mjs";
|
|
18
18
|
import "./relay.mjs";
|
|
19
|
-
import { t as Gossip } from "./gossip-
|
|
20
|
-
import { a as bareNostrUser, i as groupAuthorsByOutboxRelay, n as OutboxError, r as OutboxFeed, t as createLoaders } from "./loaders-
|
|
21
|
-
import { t as StorageError } from "./error-
|
|
22
|
-
import { t as MemoryEventStore } from "./memory-
|
|
23
|
-
import { t as ReactiveEventStore } from "./reactive
|
|
24
|
-
import { n as ClientError, r as SyncDirection, t as Client } from "./client-
|
|
25
|
-
import { n as IndexedDbEventStore, t as SqliteEventStore } from "./storage-
|
|
19
|
+
import { t as Gossip } from "./gossip-CRyhK6E6.mjs";
|
|
20
|
+
import { a as bareNostrUser, i as groupAuthorsByOutboxRelay, n as OutboxError, r as OutboxFeed, t as createLoaders } from "./loaders-BRh2riV9.mjs";
|
|
21
|
+
import { t as StorageError } from "./error-QyECUDIp.mjs";
|
|
22
|
+
import { t as MemoryEventStore } from "./memory-D_GdEQYG.mjs";
|
|
23
|
+
import { t as ReactiveEventStore } from "./reactive-DFHY-f00.mjs";
|
|
24
|
+
import { n as ClientError, r as SyncDirection, t as Client } from "./client-COkEihj_.mjs";
|
|
25
|
+
import { n as IndexedDbEventStore, t as SqliteEventStore } from "./storage-n2BE1bdY.mjs";
|
|
26
26
|
import "./store.mjs";
|
|
27
|
-
export { Bech32MaxSize, Client, ClientError, CryptoError, DelegatedSigner, EVENT_ID_BYTES, EventBuilder, EventValidationError, Gossip, HexError, IndexedDbEventStore, Keys, KeysSigner, Kind, MemoryEventStore, MessageError, Nip07Signer, Nip19Error, Nip21Error, 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, SignerDisposedError, SqliteEventStore, StorageError, SyncDirection, Tag, UrlError,
|
|
27
|
+
export { Bech32MaxSize, Client, ClientError, CryptoError, DelegatedSigner, EVENT_ID_BYTES, EventBuilder, EventValidationError, Gossip, HexError, IndexedDbEventStore, Keys, KeysSigner, Kind, MemoryEventStore, MessageError, Nip07Signer, Nip19Error, Nip21Error, 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, SignerDisposedError, SqliteEventStore, StorageError, SyncDirection, Tag, UrlError, assertSubscriptionId, bareNostrUser, buildReplyTags, bytesToHex, canonicalizeFilter, canonicalizeFilters, classifyKind, createEventVerifier, createLoaders, createSubscriptionId, encodeClientMessage, encodeRelayMessage, eventAddress, filterFingerprint, finalizeEvent, formatEventAddress, getDTag, getEventHash, getFilterLimit, getPublicKey, getWindowNostr, groupAuthorsByOutboxRelay, hexToBytes, isAddressableKind, isAuthRequired, isEphemeralKind, isHex32, isHex64, isInsecureRelayUrl, isNip07Available, isNostrURI, isRegularKind, isReplaceableKind, isReplaceableWinner, isTag, itemCompare, makeAuthEvent, matchFilter, matchFilters, mergeCountHll, naddrEncode, neventEncode, decode as nip19Decode, normalizeURL, noteEncode, nprofileEncode, npubEncode, nsecEncode, parseClientMessage, parseEventAddress, parseNostrURI, parseRelayList, parseRelayMessage, parseThreadTags, publicKeyFromHex, readRelays, relayListEventBuilder, relayListToTags, replyTo, serializeEvent, signEvent, signedMatchesUnsigned, sortEvents, sortedEvents, tagName, tagValue, toSecretKey, validateEvent, validateSignedEvent, verifyEvent, writeRelays };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { c as markVerified, m as validateEvent, u as serializeValidatedEvent } from "./event-
|
|
1
|
+
import { _ as CryptoError, g as utf8Encoder, i as bytesToHex$1, n as assertHex32, r as assertSecretKeyBytes, s as hexToBytes$1, v as EventValidationError } from "./util-DfsyJ9nz.mjs";
|
|
2
|
+
import { c as markVerified, m as validateEvent, u as serializeValidatedEvent } from "./event-DvM1f03b.mjs";
|
|
3
3
|
import { randomBytes } from "@noble/hashes/utils.js";
|
|
4
4
|
import { sha256 } from "@noble/hashes/sha2.js";
|
|
5
5
|
import { schnorr } from "@noble/curves/secp256k1.js";
|
|
@@ -91,8 +91,7 @@ function resolveKeys(secretKey) {
|
|
|
91
91
|
*
|
|
92
92
|
* `auxRand` is the 32-byte BIP-340 auxiliary randomness. It defaults to a fresh `randomBytes(32)`
|
|
93
93
|
* draw; an explicit value makes the signature reproducible, which is required for vectors and
|
|
94
|
-
* tests.
|
|
95
|
-
* in production.
|
|
94
|
+
* tests. Never reuse aux randomness in production.
|
|
96
95
|
*/
|
|
97
96
|
function finalizeEvent(template, secretKey, auxRand) {
|
|
98
97
|
const keys = resolveKeys(secretKey);
|
|
@@ -110,8 +109,7 @@ function finalizeEvent(template, secretKey, auxRand) {
|
|
|
110
109
|
*
|
|
111
110
|
* `auxRand` is the 32-byte BIP-340 auxiliary randomness. It defaults to a fresh `randomBytes(32)`
|
|
112
111
|
* draw; an explicit value makes the signature reproducible, which is required for vectors and
|
|
113
|
-
* tests.
|
|
114
|
-
* in production.
|
|
112
|
+
* tests. Never reuse aux randomness in production.
|
|
115
113
|
*/
|
|
116
114
|
function signEvent(unsigned, secretKey, auxRand) {
|
|
117
115
|
const keys = resolveKeys(secretKey);
|
|
@@ -145,4 +143,4 @@ function signEvent(unsigned, secretKey, auxRand) {
|
|
|
145
143
|
//#endregion
|
|
146
144
|
export { publicKeyFromHex as a, getPublicKey as i, SecretKey as n, signEvent as o, finalizeEvent as r, toSecretKey as s, Keys as t };
|
|
147
145
|
|
|
148
|
-
//# sourceMappingURL=key-
|
|
146
|
+
//# sourceMappingURL=key-D_oEutQ6.mjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"key-
|
|
1
|
+
{"version":3,"file":"key-D_oEutQ6.mjs","names":["hexToBytes","bytesToHex"],"sources":["../src/core/key.ts"],"sourcesContent":["import { schnorr } from \"@noble/curves/secp256k1.js\";\nimport { sha256 } from \"@noble/hashes/sha2.js\";\nimport { randomBytes } from \"@noble/hashes/utils.js\";\n\nimport { CryptoError, EventValidationError } from \"./error.ts\";\nimport { markVerified, serializeValidatedEvent, validateEvent } from \"./event.ts\";\nimport type { Event, EventTemplate, UnsignedEvent } from \"./event.ts\";\nimport { assertHex32, assertSecretKeyBytes, bytesToHex, hexToBytes, utf8Encoder } from \"./util.ts\";\n\n/** 32-byte secret key held as bytes; prefer zeroize when done. */\nexport class SecretKey {\n #bytes: Uint8Array | undefined;\n\n private constructor(bytes: Uint8Array) {\n assertSecretKeyBytes(bytes);\n this.#bytes = new Uint8Array(bytes);\n }\n\n static generate(): SecretKey {\n return new SecretKey(schnorr.utils.randomSecretKey());\n }\n\n static fromBytes(bytes: Uint8Array): SecretKey {\n return new SecretKey(bytes);\n }\n\n static fromHex(hex: string): SecretKey {\n return new SecretKey(hexToBytes(assertHex32(hex, \"secret key\")));\n }\n\n get bytes(): Uint8Array {\n if (!this.#bytes) {\n throw new CryptoError(\"secret key has been zeroized\");\n }\n return new Uint8Array(this.#bytes);\n }\n\n toHex(): string {\n return bytesToHex(this.bytes);\n }\n\n /** Best-effort wipe of the internal buffer. */\n zeroize(): void {\n if (this.#bytes) {\n this.#bytes.fill(0);\n this.#bytes = undefined;\n }\n }\n}\n\n/** Anything a secret key can be given as: instance, raw bytes, or hex. */\nexport type SecretKeyInput = SecretKey | Uint8Array | string;\n\n/** Coerce a {@link SecretKeyInput} to {@link SecretKey}. */\nexport function toSecretKey(input: SecretKeyInput): SecretKey {\n if (input instanceof SecretKey) {\n return input;\n }\n if (typeof input === \"string\") {\n return SecretKey.fromHex(input);\n }\n return SecretKey.fromBytes(input);\n}\n\n/** Lowercase hex-encoded secp256k1 public key (x-only, 64 chars). */\nexport type PublicKey = string;\n\n/** Validate and normalize a hex public key; throws {@link HexError} on bad input. */\nexport function publicKeyFromHex(hex: string): PublicKey {\n return assertHex32(hex, \"public key\");\n}\n\n/**\n * BIP-340 signing backend. `publicKey` returns the 32-byte x-only public key of a 32-byte secret\n * key; `sign` returns the 64-byte BIP-340 signature of a 32-byte `id` using 32 bytes of auxiliary\n * randomness. Both throw on invalid input (for example an out-of-range secret key).\n */\nexport type SigningBackend = {\n publicKey: (secretKey: Uint8Array) => Uint8Array;\n sign: (id: Uint8Array, secretKey: Uint8Array, auxRand: Uint8Array) => Uint8Array;\n};\n\nconst nobleSigning: SigningBackend = {\n publicKey: (secretKey) => schnorr.getPublicKey(secretKey),\n sign: (id, secretKey, auxRand) => schnorr.sign(id, secretKey, auxRand),\n};\n\n/** Derive the public key for a secret key given as SecretKey, bytes, or hex. */\nexport function getPublicKey(secretKey: SecretKeyInput): PublicKey {\n return bytesToHex(schnorr.getPublicKey(toSecretKey(secretKey).bytes));\n}\n\n/** Keypair convenience wrapper. */\nexport class Keys {\n readonly secretKey: SecretKey;\n readonly publicKey: PublicKey;\n /**\n * BIP-340 backend that derived {@link publicKey} and signs in {@link finalizeEvent}/\n * {@link signEvent}. Defaults to noble; pass a loaded `NostrWasm` module or a native backend to\n * delegate signing.\n */\n readonly backend: SigningBackend;\n\n private constructor(secretKey: SecretKey, backend: SigningBackend) {\n this.secretKey = secretKey;\n this.backend = backend;\n const secretBytes = secretKey.bytes;\n let pubkey: Uint8Array;\n try {\n pubkey = backend.publicKey(secretBytes);\n } finally {\n secretBytes.fill(0);\n }\n if (pubkey.length !== 32) {\n throw new CryptoError(\"signing backend returned an invalid public key\");\n }\n this.publicKey = bytesToHex(pubkey);\n }\n\n static generate(backend: SigningBackend = nobleSigning): Keys {\n return new Keys(SecretKey.generate(), backend);\n }\n\n static fromSecretKey(secretKey: SecretKeyInput, backend: SigningBackend = nobleSigning): Keys {\n return new Keys(toSecretKey(secretKey), backend);\n }\n}\n\nfunction resolveKeys(secretKey: SecretKeyInput | Keys): Keys {\n return secretKey instanceof Keys ? secretKey : Keys.fromSecretKey(secretKey);\n}\n\n/**\n * Fill pubkey/id/sig on a template and return a signed event.\n *\n * `auxRand` is the 32-byte BIP-340 auxiliary randomness. It defaults to a fresh `randomBytes(32)`\n * draw; an explicit value makes the signature reproducible, which is required for vectors and\n * tests. Never reuse aux randomness in production.\n */\nexport function finalizeEvent(\n template: EventTemplate,\n secretKey: SecretKeyInput | Keys,\n auxRand?: Uint8Array,\n): Event {\n const keys = resolveKeys(secretKey);\n const unsigned: UnsignedEvent = {\n kind: template.kind,\n tags: template.tags,\n content: template.content,\n created_at: template.created_at,\n pubkey: keys.publicKey,\n };\n return signEvent(unsigned, keys, auxRand);\n}\n\n/**\n * Sign an already-assembled unsigned event. Rejects when `unsigned.pubkey` does not match the\n * secret key.\n *\n * `auxRand` is the 32-byte BIP-340 auxiliary randomness. It defaults to a fresh `randomBytes(32)`\n * draw; an explicit value makes the signature reproducible, which is required for vectors and\n * tests. Never reuse aux randomness in production.\n */\nexport function signEvent(\n unsigned: UnsignedEvent,\n secretKey: SecretKeyInput | Keys,\n auxRand?: Uint8Array,\n): Event {\n const keys = resolveKeys(secretKey);\n if (auxRand !== undefined && auxRand.length !== 32) {\n throw new CryptoError(\"auxRand must be 32 bytes\");\n }\n if (!validateEvent(unsigned)) {\n throw new EventValidationError(\"cannot sign invalid unsigned event\");\n }\n\n if (unsigned.pubkey !== keys.publicKey) {\n throw new CryptoError(\"unsigned event pubkey does not match secret key\");\n }\n\n const normalized: UnsignedEvent = {\n kind: unsigned.kind,\n tags: unsigned.tags,\n content: unsigned.content,\n created_at: unsigned.created_at,\n pubkey: keys.publicKey,\n };\n\n const id = bytesToHex(sha256(utf8Encoder.encode(serializeValidatedEvent(normalized))));\n const secretBytes = keys.secretKey.bytes;\n let sig: Uint8Array;\n try {\n sig = keys.backend.sign(hexToBytes(id), secretBytes, auxRand ?? randomBytes(32));\n } finally {\n secretBytes.fill(0);\n }\n if (sig.length !== 64) {\n throw new CryptoError(\"signing backend returned an invalid signature\");\n }\n const event: Event = { ...normalized, id, sig: bytesToHex(sig) };\n markVerified(event);\n return event;\n}\n"],"mappings":"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"}
|
|
@@ -50,8 +50,7 @@ declare class Keys {
|
|
|
50
50
|
*
|
|
51
51
|
* `auxRand` is the 32-byte BIP-340 auxiliary randomness. It defaults to a fresh `randomBytes(32)`
|
|
52
52
|
* draw; an explicit value makes the signature reproducible, which is required for vectors and
|
|
53
|
-
* tests.
|
|
54
|
-
* in production.
|
|
53
|
+
* tests. Never reuse aux randomness in production.
|
|
55
54
|
*/
|
|
56
55
|
declare function finalizeEvent(template: EventTemplate, secretKey: SecretKeyInput | Keys, auxRand?: Uint8Array): Event;
|
|
57
56
|
/**
|
|
@@ -60,10 +59,9 @@ declare function finalizeEvent(template: EventTemplate, secretKey: SecretKeyInpu
|
|
|
60
59
|
*
|
|
61
60
|
* `auxRand` is the 32-byte BIP-340 auxiliary randomness. It defaults to a fresh `randomBytes(32)`
|
|
62
61
|
* draw; an explicit value makes the signature reproducible, which is required for vectors and
|
|
63
|
-
* tests.
|
|
64
|
-
* in production.
|
|
62
|
+
* tests. Never reuse aux randomness in production.
|
|
65
63
|
*/
|
|
66
64
|
declare function signEvent(unsigned: UnsignedEvent, secretKey: SecretKeyInput | Keys, auxRand?: Uint8Array): Event;
|
|
67
65
|
//#endregion
|
|
68
66
|
export { SigningBackend as a, publicKeyFromHex as c, SecretKeyInput as i, signEvent as l, PublicKey as n, finalizeEvent as o, SecretKey as r, getPublicKey as s, Keys as t, toSecretKey as u };
|
|
69
|
-
//# sourceMappingURL=key-
|
|
67
|
+
//# sourceMappingURL=key-DojW2QZl.d.mts.map
|
|
@@ -1,10 +1,11 @@
|
|
|
1
1
|
//#region src/core/kind.ts
|
|
2
2
|
/**
|
|
3
|
-
*
|
|
4
|
-
*
|
|
3
|
+
* Regular means relays store the event: every kind below 10000 except the replaceable kinds 0 and 3.
|
|
4
|
+
* The NIP-01 enumerated regular ranges are a subset; kinds 45–999 are stored like regular events in
|
|
5
|
+
* practice (nostr-tools and rust-nostr agree).
|
|
5
6
|
*/
|
|
6
7
|
function isRegularKind(kind) {
|
|
7
|
-
return kind
|
|
8
|
+
return kind < 1e4 && kind !== 0 && kind !== 3;
|
|
8
9
|
}
|
|
9
10
|
/** Replaceable: latest per (pubkey, kind) wins. */
|
|
10
11
|
function isReplaceableKind(kind) {
|
|
@@ -21,7 +22,7 @@ function isAddressableKind(kind) {
|
|
|
21
22
|
/**
|
|
22
23
|
* Classify a kind number into its NIP-01 storage class. NIP-01 leaves kinds 45–999 and 40000+
|
|
23
24
|
* undefined (rather than forbidden); relays store them like regular events, so they classify
|
|
24
|
-
* `"regular"` here even though {@link isRegularKind} returns false for
|
|
25
|
+
* `"regular"` here even though {@link isRegularKind} returns false for kinds 40000+.
|
|
25
26
|
*/
|
|
26
27
|
function classifyKind(kind) {
|
|
27
28
|
if (isReplaceableKind(kind)) return "replaceable";
|
|
@@ -63,4 +64,4 @@ const Kind = {
|
|
|
63
64
|
//#endregion
|
|
64
65
|
export { isRegularKind as a, isEphemeralKind as i, classifyKind as n, isReplaceableKind as o, isAddressableKind as r, Kind as t };
|
|
65
66
|
|
|
66
|
-
//# sourceMappingURL=kind-
|
|
67
|
+
//# sourceMappingURL=kind-I2Tvbe82.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"kind-I2Tvbe82.mjs","names":[],"sources":["../src/core/kind.ts"],"sourcesContent":["/**\n * Regular means relays store the event: every kind below 10000 except the replaceable kinds 0 and 3.\n * The NIP-01 enumerated regular ranges are a subset; kinds 45–999 are stored like regular events in\n * practice (nostr-tools and rust-nostr agree).\n */\nexport function isRegularKind(kind: number): boolean {\n return kind < 10000 && kind !== 0 && kind !== 3;\n}\n\n/** Replaceable: latest per (pubkey, kind) wins. */\nexport function isReplaceableKind(kind: number): boolean {\n return kind === 0 || kind === 3 || (kind >= 10000 && kind < 20000);\n}\n\n/** Ephemeral: not expected to be stored. */\nexport function isEphemeralKind(kind: number): boolean {\n return kind >= 20000 && kind < 30000;\n}\n\n/** Addressable (parameterized replaceable): latest per (pubkey, kind, d-tag) wins. */\nexport function isAddressableKind(kind: number): boolean {\n return kind >= 30000 && kind < 40000;\n}\n\n/** NIP-01 kind classes: regular / replaceable / ephemeral / addressable. */\nexport type KindClassification = \"regular\" | \"replaceable\" | \"ephemeral\" | \"addressable\";\n\n/**\n * Classify a kind number into its NIP-01 storage class. NIP-01 leaves kinds 45–999 and 40000+\n * undefined (rather than forbidden); relays store them like regular events, so they classify\n * `\"regular\"` here even though {@link isRegularKind} returns false for kinds 40000+.\n */\nexport function classifyKind(kind: number): KindClassification {\n if (isReplaceableKind(kind)) {\n return \"replaceable\";\n }\n if (isEphemeralKind(kind)) {\n return \"ephemeral\";\n }\n if (isAddressableKind(kind)) {\n return \"addressable\";\n }\n return \"regular\";\n}\n\n/** Kind numbers used by this package. */\nexport const Kind = {\n Metadata: 0,\n TextNote: 1,\n Contacts: 3,\n EventDeletion: 5,\n Repost: 6,\n Reaction: 7,\n Seal: 13,\n PrivateDirectMessage: 14,\n GenericRepost: 16,\n GiftWrap: 1059,\n ZapRequest: 9734,\n Zap: 9735,\n MuteList: 10000,\n PinList: 10001,\n RelayList: 10002,\n BookmarkList: 10003,\n FavoriteRelays: 10012,\n UserEmojiList: 10030,\n DirectMessageRelaysList: 10050,\n BlossomServerList: 10063,\n GiftWrapEphemeral: 21059,\n ClientAuth: 22242,\n NostrConnect: 24133,\n BlobsAuth: 24242,\n HttpAuth: 27235,\n RelaySets: 30002,\n EmojiSet: 30030,\n StarterPack: 39089,\n} as const;\n\n/** Name of a kind constant on {@link Kind}. */\nexport type KindName = keyof typeof Kind;\n/** Union of the numeric kind values on {@link Kind}. */\nexport type KnownKind = (typeof Kind)[KindName];\n"],"mappings":";;;;;;AAKA,SAAgB,cAAc,MAAuB;CACnD,OAAO,OAAO,OAAS,SAAS,KAAK,SAAS;AAChD;;AAGA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,SAAS,KAAK,SAAS,KAAM,QAAQ,OAAS,OAAO;AAC9D;;AAGA,SAAgB,gBAAgB,MAAuB;CACrD,OAAO,QAAQ,OAAS,OAAO;AACjC;;AAGA,SAAgB,kBAAkB,MAAuB;CACvD,OAAO,QAAQ,OAAS,OAAO;AACjC;;;;;;AAUA,SAAgB,aAAa,MAAkC;CAC7D,IAAI,kBAAkB,IAAI,GACxB,OAAO;CAET,IAAI,gBAAgB,IAAI,GACtB,OAAO;CAET,IAAI,kBAAkB,IAAI,GACxB,OAAO;CAET,OAAO;AACT;;AAGA,MAAa,OAAO;CAClB,UAAU;CACV,UAAU;CACV,UAAU;CACV,eAAe;CACf,QAAQ;CACR,UAAU;CACV,MAAM;CACN,sBAAsB;CACtB,eAAe;CACf,UAAU;CACV,YAAY;CACZ,KAAK;CACL,UAAU;CACV,SAAS;CACT,WAAW;CACX,cAAc;CACd,gBAAgB;CAChB,eAAe;CACf,yBAAyB;CACzB,mBAAmB;CACnB,mBAAmB;CACnB,YAAY;CACZ,cAAc;CACd,WAAW;CACX,UAAU;CACV,WAAW;CACX,UAAU;CACV,aAAa;AACf"}
|
|
@@ -1,16 +1,16 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { r as isAddressableKind, t as Kind } from "./kind-
|
|
3
|
-
import { p as sortedEvents, y as formatEventAddress } from "./event-
|
|
1
|
+
import { c as isHex32, d as normalizeRelayUrls, p as nowSeconds, u as isRecord, x as NostrError } from "./util-DfsyJ9nz.mjs";
|
|
2
|
+
import { r as isAddressableKind, t as Kind } from "./kind-I2Tvbe82.mjs";
|
|
3
|
+
import { p as sortedEvents, y as formatEventAddress } from "./event-DvM1f03b.mjs";
|
|
4
4
|
import { i as throwIfAborted } from "./abort-DBq2STPj.mjs";
|
|
5
|
-
import { t as invokeSafely } from "./report-
|
|
5
|
+
import { t as invokeSafely } from "./report-D2BM5dgn.mjs";
|
|
6
6
|
import { Nip19Error, decode, npubEncode } from "./nips/nip19.mjs";
|
|
7
7
|
import { parseRelayList } from "./nips/nip65.mjs";
|
|
8
|
-
import "./relay-
|
|
8
|
+
import "./relay-DIR77xQ2.mjs";
|
|
9
9
|
import { i as trimOldest, r as touchKey } from "./collections-DtwMc1NU.mjs";
|
|
10
10
|
import { parseDmRelayList } from "./nips/nip17.mjs";
|
|
11
11
|
import { parseMuteList } from "./nips/nip51.mjs";
|
|
12
|
-
import { n as toStorageError } from "./error-
|
|
13
|
-
import { r as outboxBoundKey } from "./put-
|
|
12
|
+
import { n as toStorageError } from "./error-QyECUDIp.mjs";
|
|
13
|
+
import { r as outboxBoundKey } from "./put-BEM5j8xK.mjs";
|
|
14
14
|
//#region src/loaders/context.ts
|
|
15
15
|
/** Internal dependency bag for loaders — never a module-level singleton. */
|
|
16
16
|
var LoaderContext = class {
|
|
@@ -130,7 +130,7 @@ function createEventLoader(ctx) {
|
|
|
130
130
|
if (relays.length === 0) return;
|
|
131
131
|
await ctx.pool.fetch(relays, [parsed.filter], {
|
|
132
132
|
timeoutMs: ctx.fetchTimeoutMs,
|
|
133
|
-
|
|
133
|
+
onEvent: (event, relayUrl) => ctx.ingest(event, relayUrl)
|
|
134
134
|
});
|
|
135
135
|
return parsed.lookup(ctx);
|
|
136
136
|
} finally {
|
|
@@ -321,13 +321,14 @@ var DataLoader = class {
|
|
|
321
321
|
queueMicrotask(() => this.#dispatch());
|
|
322
322
|
}
|
|
323
323
|
});
|
|
324
|
-
const
|
|
324
|
+
const cleanup = async () => {
|
|
325
325
|
try {
|
|
326
326
|
return await pending;
|
|
327
327
|
} finally {
|
|
328
|
-
this.#inflight.delete(cacheKey);
|
|
328
|
+
if (this.#inflight.get(cacheKey) === promise) this.#inflight.delete(cacheKey);
|
|
329
329
|
}
|
|
330
|
-
}
|
|
330
|
+
};
|
|
331
|
+
const promise = cleanup();
|
|
331
332
|
this.#inflight.set(cacheKey, promise);
|
|
332
333
|
if (this.#useCache) this.#cache.set(cacheKey, promise);
|
|
333
334
|
return promise;
|
|
@@ -377,7 +378,7 @@ var DataLoader = class {
|
|
|
377
378
|
const MAX_FETCHED_AT = 1e4;
|
|
378
379
|
/**
|
|
379
380
|
* Batch-fetch replaceable events (kind + authors) via the pool. Fetched events are written into the
|
|
380
|
-
* reactive index (`
|
|
381
|
+
* reactive index (`onEvent` records `seenOn`) and the winner is read back from it; the index — not
|
|
381
382
|
* the loader — owns the stored value and winner selection. The loader only tracks per-address
|
|
382
383
|
* `fetchedAt` timestamps so a recent fetch (including a miss) is not repeated within
|
|
383
384
|
* `staleAfterSec`.
|
|
@@ -401,7 +402,7 @@ function createReplaceableLoader(ctx, kind) {
|
|
|
401
402
|
};
|
|
402
403
|
await ctx.pool.fetch(relays, [filter], {
|
|
403
404
|
timeoutMs: ctx.fetchTimeoutMs,
|
|
404
|
-
|
|
405
|
+
onEvent: (event, relayUrl) => ctx.ingest(event, relayUrl)
|
|
405
406
|
});
|
|
406
407
|
}
|
|
407
408
|
const now = nowSeconds();
|
|
@@ -550,7 +551,7 @@ var OutboxFeed = class {
|
|
|
550
551
|
const batch = await this.#pool.fetch([url], filters, {
|
|
551
552
|
timeoutMs: this.#timeoutMs,
|
|
552
553
|
signal: opts?.signal,
|
|
553
|
-
|
|
554
|
+
onEvent: (event, relayUrl) => invokeSafely(() => this.#seen?.(event, relayUrl))
|
|
554
555
|
});
|
|
555
556
|
for (const event of batch) byId.set(event.id, event);
|
|
556
557
|
} catch (error) {
|
|
@@ -593,7 +594,7 @@ var OutboxFeed = class {
|
|
|
593
594
|
};
|
|
594
595
|
closers.push(this.#pool.subscribe([url], [filter], {
|
|
595
596
|
signal: opts?.signal,
|
|
596
|
-
|
|
597
|
+
onEvent: (event, relayUrl) => {
|
|
597
598
|
invokeSafely(() => this.#seen?.(event, relayUrl));
|
|
598
599
|
if (seen.has(event.id)) return;
|
|
599
600
|
seen.add(event.id);
|
|
@@ -780,4 +781,4 @@ function createLoaders(opts) {
|
|
|
780
781
|
//#endregion
|
|
781
782
|
export { bareNostrUser as a, groupAuthorsByOutboxRelay as i, OutboxError as n, OutboxFeed as r, createLoaders as t };
|
|
782
783
|
|
|
783
|
-
//# sourceMappingURL=loaders-
|
|
784
|
+
//# sourceMappingURL=loaders-BRh2riV9.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"loaders-BRh2riV9.mjs","names":[],"sources":["../src/loaders/context.ts","../src/loaders/event.ts","../src/loaders/lists.ts","../src/loaders/profile.ts","../src/loaders/dataloader.ts","../src/loaders/replaceable.ts","../src/loaders/outbox.ts","../src/loaders/index.ts"],"sourcesContent":["import type { Event } from \"../core/event.ts\";\nimport { nowSeconds } from \"../core/util.ts\";\nimport type { Pool } from \"../relay/pool.ts\";\nimport { DEFAULT_REQUEST_TIMEOUT_MS } from \"../relay/relay.ts\";\nimport type { ReactiveEventStore } from \"../store/reactive.ts\";\n\nexport type LoaderContextOptions = {\n pool: Pool;\n /** Fallback / discovery relays when no per-user routing is known. */\n relays: ReadonlyArray<string>;\n /** The reactive index loaders read from and feed fetched events into. */\n index: ReactiveEventStore;\n /**\n * Inbound-event sink for fetched events. Defaults to `index.add`; Client supplies its single\n * ingest path so loader fetches get gossip meta and persistence like every other inbound event.\n */\n ingest?: ((event: Event, relayUrl: string) => void) | undefined;\n /** Max age (seconds) before a fetched replaceable is considered stale. Default 2 days. */\n staleAfterSec?: number | undefined;\n fetchTimeoutMs?: number | undefined;\n};\n\n/** Internal dependency bag for loaders — never a module-level singleton. */\nexport class LoaderContext {\n readonly pool: Pool;\n readonly index: ReactiveEventStore;\n readonly ingest: (event: Event, relayUrl: string) => void;\n readonly staleAfterSec: number;\n readonly fetchTimeoutMs: number;\n #relays: string[];\n\n constructor(opts: LoaderContextOptions) {\n this.pool = opts.pool;\n this.#relays = [...opts.relays];\n this.index = opts.index;\n this.ingest = opts.ingest ?? ((event, relayUrl) => this.index.add(event, relayUrl));\n this.staleAfterSec = opts.staleAfterSec ?? 60 * 60 * 24 * 2;\n this.fetchTimeoutMs = opts.fetchTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n }\n\n /** Snapshot of discovery/fallback relays. */\n get relays(): ReadonlyArray<string> {\n return this.#relays;\n }\n\n addRelay(url: string): void {\n if (!this.#relays.includes(url)) {\n this.#relays.push(url);\n }\n }\n\n removeRelay(url: string): void {\n this.#relays = this.#relays.filter((r) => r !== url);\n }\n\n setRelays(urls: ReadonlyArray<string>): void {\n this.#relays = [...urls];\n }\n\n isFresh(fetchedAt: number, now: number = nowSeconds()): boolean {\n return now - fetchedAt < this.staleAfterSec;\n }\n}\n","import type { Event } from \"../core/event.ts\";\nimport { isAddressableKind } from \"../core/kind.ts\";\nimport { formatEventAddress } from \"../core/tag.ts\";\nimport { isHex32 } from \"../core/util.ts\";\nimport { decode, Nip19Error } from \"../nips/nip19.ts\";\nimport type { AddressPointer, EventPointer } from \"../nips/nip19.ts\";\nimport type { LoaderContext } from \"./context.ts\";\n\nexport type EventRef = string | EventPointer | AddressPointer;\n\ntype ParsedRef = {\n filter: { ids?: string[]; authors?: string[]; kinds?: number[]; \"#d\"?: string[] };\n hints: ReadonlyArray<string>;\n /** Resolve the fetched event from the index after the network round. */\n lookup: (ctx: LoaderContext) => Event | undefined;\n cacheKey: string;\n};\n\nfunction dFilter(kind: number, identifier: string): { \"#d\"?: string[] } {\n if (isAddressableKind(kind)) {\n return { \"#d\": [identifier] };\n }\n return {};\n}\n\nfunction addressRef(kind: number, pubkey: string, identifier: string): string {\n return formatEventAddress(kind, pubkey.toLowerCase(), identifier);\n}\n\nfunction parseRef(ref: EventRef): ParsedRef {\n if (typeof ref === \"string\") {\n if (isHex32(ref.toLowerCase())) {\n const id = ref.toLowerCase();\n return {\n filter: { ids: [id] },\n hints: [],\n lookup: (ctx) => ctx.index.get(id),\n cacheKey: `id:${id}`,\n };\n }\n const decoded = decode(ref);\n switch (decoded.type) {\n case \"note\":\n return {\n filter: { ids: [decoded.data] },\n hints: [],\n lookup: (ctx) => ctx.index.get(decoded.data),\n cacheKey: `id:${decoded.data}`,\n };\n case \"nevent\":\n return {\n filter: { ids: [decoded.data.id] },\n hints: decoded.data.relays ?? [],\n lookup: (ctx) => ctx.index.get(decoded.data.id),\n cacheKey: `id:${decoded.data.id}`,\n };\n case \"naddr\": {\n const addr = addressRef(decoded.data.kind, decoded.data.pubkey, decoded.data.identifier);\n return {\n filter: {\n authors: [decoded.data.pubkey.toLowerCase()],\n kinds: [decoded.data.kind],\n ...dFilter(decoded.data.kind, decoded.data.identifier),\n },\n hints: decoded.data.relays ?? [],\n lookup: (ctx) => ctx.index.getByAddress(addr),\n cacheKey: `addr:${addr}`,\n };\n }\n default:\n throw new Nip19Error(`cannot load event from ${decoded.type}`);\n }\n }\n if (\"id\" in ref) {\n const id = ref.id.toLowerCase();\n return {\n filter: { ids: [id] },\n hints: ref.relays ?? [],\n lookup: (ctx) => ctx.index.get(id),\n cacheKey: `id:${id}`,\n };\n }\n const addr = addressRef(ref.kind, ref.pubkey, ref.identifier);\n return {\n filter: {\n authors: [ref.pubkey.toLowerCase()],\n kinds: [ref.kind],\n ...dFilter(ref.kind, ref.identifier),\n },\n hints: ref.relays ?? [],\n lookup: (ctx) => ctx.index.getByAddress(addr),\n cacheKey: `addr:${addr}`,\n };\n}\n\n/**\n * Resolve an event reference (hex id, note, nevent, naddr, or pointer object) through the reactive\n * index, fetching from relays on a miss. The index is the durable store — the loader keeps only\n * in-flight coalescing, so a miss never blocks a later retry.\n */\nexport type EventLoader = {\n load: (ref: EventRef) => Promise<Event | undefined>;\n};\n\nexport function createEventLoader(ctx: LoaderContext): EventLoader {\n const inflight = new Map<string, Promise<Event | undefined>>();\n return {\n // oxlint-disable-next-line typescript/promise-function-async -- parseRef must throw synchronously on malformed refs\n load(ref: EventRef): Promise<Event | undefined> {\n const parsed = parseRef(ref);\n const hit = parsed.lookup(ctx);\n if (hit !== undefined) {\n return Promise.resolve(hit);\n }\n const pending = inflight.get(parsed.cacheKey);\n if (pending !== undefined) {\n return pending;\n }\n const p = (async (): Promise<Event | undefined> => {\n try {\n const relays = [...new Set([...parsed.hints, ...ctx.relays])];\n if (relays.length === 0) {\n return undefined;\n }\n await ctx.pool.fetch(relays, [parsed.filter], {\n timeoutMs: ctx.fetchTimeoutMs,\n onEvent: (event, relayUrl) => ctx.ingest(event, relayUrl),\n });\n return parsed.lookup(ctx);\n } finally {\n inflight.delete(parsed.cacheKey);\n }\n })();\n inflight.set(parsed.cacheKey, p);\n return p;\n },\n };\n}\n","import type { Event } from \"../core/event.ts\";\nimport { Kind } from \"../core/kind.ts\";\nimport { isHex32 } from \"../core/util.ts\";\nimport { parseDmRelayList } from \"../nips/nip17.ts\";\nimport { parseMuteList } from \"../nips/nip51.ts\";\nimport type { MuteItem } from \"../nips/nip51.ts\";\nimport type { RelayListItem } from \"../nips/nip65.ts\";\nimport { parseRelayList } from \"../nips/nip65.ts\";\nimport type { LoadStyle, ReplaceableLoader } from \"./replaceable.ts\";\n\n/** Result of a list loader: the source event, its decoded items, and freshness. */\nexport type ListResult<T> = {\n readonly event: Event | undefined;\n readonly items: ReadonlyArray<T>;\n readonly fresh: boolean;\n};\n\nfunction fromTags<T>(\n event: Event | undefined,\n map: (tag: ReadonlyArray<string>) => T | undefined,\n): T[] {\n if (event === undefined) {\n return [];\n }\n const out: T[] = [];\n for (const tag of event.tags) {\n const item = map(tag);\n if (item !== undefined) {\n out.push(item);\n }\n }\n return out;\n}\n\ntype ListLoaderOpts = { hints?: string[] | undefined; style?: LoadStyle | undefined };\n\nexport type ListLoaders = {\n follows: (pubkey: string, opts?: ListLoaderOpts) => Promise<ListResult<string>>;\n muteList: (pubkey: string, opts?: ListLoaderOpts) => Promise<ListResult<MuteItem>>;\n relayList: (pubkey: string, opts?: ListLoaderOpts) => Promise<ListResult<RelayListItem>>;\n dmRelayList: (pubkey: string, opts?: ListLoaderOpts) => Promise<ListResult<string>>;\n};\n\nexport function createListLoaders(replaceable: (kind: number) => ReplaceableLoader): ListLoaders {\n const followsLoader = replaceable(Kind.Contacts);\n const muteLoader = replaceable(Kind.MuteList);\n const relayListLoader = replaceable(Kind.RelayList);\n const dmRelayListLoader = replaceable(Kind.DirectMessageRelaysList);\n\n return {\n async follows(pubkey: string, opts?: ListLoaderOpts): Promise<ListResult<string>> {\n const { event, fresh } = await followsLoader(pubkey, opts);\n return {\n event,\n fresh,\n items: fromTags(event, (tag) =>\n tag[0] === \"p\" && tag[1] !== undefined && isHex32(tag[1].toLowerCase())\n ? tag[1].toLowerCase()\n : undefined,\n ),\n };\n },\n\n async muteList(pubkey: string, opts?: ListLoaderOpts): Promise<ListResult<MuteItem>> {\n const { event, fresh } = await muteLoader(pubkey, opts);\n let items: MuteItem[] = [];\n if (event) {\n try {\n items = parseMuteList(event);\n } catch {\n items = [];\n }\n }\n return { event, fresh, items };\n },\n\n async relayList(pubkey: string, opts?: ListLoaderOpts): Promise<ListResult<RelayListItem>> {\n const { event, fresh } = await relayListLoader(pubkey, opts);\n let items: RelayListItem[] = [];\n if (event) {\n try {\n items = parseRelayList(event);\n } catch {\n items = [];\n }\n }\n return { event, fresh, items };\n },\n\n async dmRelayList(pubkey: string, opts?: ListLoaderOpts): Promise<ListResult<string>> {\n const { event, fresh } = await dmRelayListLoader(pubkey, opts);\n let items: string[] = [];\n if (event) {\n try {\n items = parseDmRelayList(event);\n } catch {\n items = [];\n }\n }\n return { event, fresh, items };\n },\n };\n}\n","import type { ProfileMetadata } from \"../core/builder.ts\";\nimport type { Event } from \"../core/event.ts\";\nimport { Kind } from \"../core/kind.ts\";\nimport { isRecord } from \"../core/util.ts\";\nimport { npubEncode } from \"../nips/nip19.ts\";\nimport type { LoadStyle, ReplaceableLoader } from \"./replaceable.ts\";\n\n/** A profile-card view of a pubkey: identity fields plus the kind:0 event. */\nexport type NostrUser = {\n readonly pubkey: string;\n readonly npub: string;\n readonly shortName: string;\n readonly image?: string | undefined;\n readonly metadata: ProfileMetadata;\n readonly lastUpdated: number;\n readonly event: Event | undefined;\n readonly fresh: boolean;\n};\n\n/** A {@link NostrUser} with no metadata — used when no kind:0 event exists. */\nexport function bareNostrUser(pubkey: string): NostrUser {\n const pk = pubkey.toLowerCase();\n let npub: string;\n try {\n npub = npubEncode(pk);\n } catch {\n npub = pk;\n }\n return {\n pubkey: pk,\n npub,\n shortName: npub.startsWith(\"npub1\") ? `${npub.slice(0, 8)}…${npub.slice(-4)}` : pk.slice(0, 8),\n metadata: {},\n lastUpdated: 0,\n event: undefined,\n fresh: false,\n };\n}\n\nfunction nonEmpty(value: unknown): string | undefined {\n return typeof value === \"string\" && value !== \"\" ? value : undefined;\n}\n\nconst PROFILE_METADATA_KEYS: ReadonlyArray<keyof ProfileMetadata> = [\n \"name\",\n \"display_name\",\n \"about\",\n \"picture\",\n \"banner\",\n \"website\",\n \"nip05\",\n \"lud06\",\n \"lud16\",\n];\n\nfunction parseMetadata(content: string): ProfileMetadata {\n try {\n const obj: unknown = JSON.parse(content);\n if (!isRecord(obj)) {\n return {};\n }\n const out: Record<string, string> = {};\n for (const key of PROFILE_METADATA_KEYS) {\n const value = obj[key];\n if (typeof value === \"string\") {\n out[key] = value;\n }\n }\n return out;\n } catch {\n return {};\n }\n}\n\nexport type ProfileLoader = {\n load: (\n pubkey: string,\n opts?: { hints?: string[] | undefined; style?: LoadStyle | undefined },\n ) => Promise<NostrUser>;\n};\n\nexport function createProfileLoader(\n replaceable: (kind: number) => ReplaceableLoader,\n): ProfileLoader {\n const loader = replaceable(Kind.Metadata);\n\n return {\n async load(\n pubkey: string,\n opts?: { hints?: string[] | undefined; style?: LoadStyle | undefined },\n ): Promise<NostrUser> {\n const base = bareNostrUser(pubkey);\n const { event, fresh } = await loader(pubkey, opts);\n if (!event) {\n return { ...base, fresh };\n }\n\n const metadata = parseMetadata(event.content);\n const display = nonEmpty(metadata.display_name) ?? nonEmpty(metadata.name);\n return {\n ...base,\n shortName: display ?? base.shortName,\n ...(metadata.picture === undefined ? {} : { image: metadata.picture }),\n metadata,\n lastUpdated: event.created_at,\n event,\n fresh,\n };\n },\n };\n}\n","import { NostrError } from \"../core/error.ts\";\n\nexport class LoaderError extends NostrError {\n override name = \"LoaderError\";\n}\n\n/** Minimal request coalescer. Batches keys within a microtask; no global state. */\nexport type BatchLoadFn<K, V> = (keys: ReadonlyArray<K>) => Promise<ReadonlyArray<V | Error>>;\n\nexport type DataLoaderOptions<K, C = K> = {\n cacheKeyFn?: (key: K) => C;\n maxBatchSize?: number;\n /** When false, only coalesces in-flight requests (no durable memoization). Default true. */\n cache?: boolean;\n};\n\nexport class DataLoader<K, V, C = K> {\n readonly #batchLoadFn: BatchLoadFn<K, V>;\n readonly #cacheKeyFn: (key: K) => C;\n readonly #maxBatchSize: number;\n readonly #useCache: boolean;\n readonly #cache = new Map<C, Promise<V>>();\n readonly #inflight = new Map<C, Promise<V>>();\n readonly #queue: Array<{\n key: K;\n resolve: (v: V) => void;\n reject: (e: unknown) => void;\n }> = [];\n #scheduled = false;\n\n constructor(batchLoadFn: BatchLoadFn<K, V>, options: DataLoaderOptions<K, C> = {}) {\n this.#batchLoadFn = batchLoadFn;\n // oxlint-disable-next-line typescript/no-unsafe-type-assertion -- the default C = K makes this the identity for callers that omit cacheKeyFn\n this.#cacheKeyFn = options.cacheKeyFn ?? ((k: K) => k as unknown as C);\n this.#maxBatchSize = options.maxBatchSize ?? Number.POSITIVE_INFINITY;\n this.#useCache = options.cache !== false;\n }\n\n async load(key: K): Promise<V> {\n const cacheKey = this.#cacheKeyFn(key);\n if (this.#useCache) {\n const cached = this.#cache.get(cacheKey);\n if (cached) {\n return cached;\n }\n }\n const inflight = this.#inflight.get(cacheKey);\n if (inflight) {\n return inflight;\n }\n\n const pending = new Promise<V>((resolve, reject) => {\n this.#queue.push({ key, resolve, reject });\n if (this.#queue.length >= this.#maxBatchSize) {\n this.#dispatch();\n } else if (!this.#scheduled) {\n this.#scheduled = true;\n queueMicrotask(() => this.#dispatch());\n }\n });\n // Identity guard: clear()+re-load may have registered a fresh entry under\n // this key; the stale settle must not evict it.\n const cleanup = async (): Promise<V> => {\n try {\n return await pending;\n } finally {\n if (this.#inflight.get(cacheKey) === promise) {\n this.#inflight.delete(cacheKey);\n }\n }\n };\n const promise = cleanup();\n\n this.#inflight.set(cacheKey, promise);\n if (this.#useCache) {\n this.#cache.set(cacheKey, promise);\n }\n return promise;\n }\n\n clear(key: K): void {\n this.#cache.delete(this.#cacheKeyFn(key));\n this.#inflight.delete(this.#cacheKeyFn(key));\n }\n\n clearAll(): void {\n this.#cache.clear();\n this.#inflight.clear();\n }\n\n #dispatch(): void {\n this.#scheduled = false;\n const batch = this.#queue.splice(0, this.#maxBatchSize);\n if (batch.length === 0) {\n return;\n }\n\n const keys = batch.map((b) => b.key);\n void (async () => {\n let values: ReadonlyArray<V | Error>;\n try {\n values = await this.#batchLoadFn(keys);\n } catch (error: unknown) {\n for (const item of batch) {\n item.reject(error);\n }\n return;\n }\n if (values.length !== keys.length) {\n const err = new LoaderError(\n `DataLoader batch function must return array of length ${keys.length}, got ${values.length}`,\n );\n for (const item of batch) {\n item.reject(err);\n }\n return;\n }\n for (const [i, value] of values.entries()) {\n const item = batch[i];\n if (item === undefined) {\n continue;\n }\n if (value instanceof Error) {\n item.reject(value);\n } else {\n item.resolve(value);\n }\n }\n })();\n\n if (this.#queue.length > 0) {\n this.#scheduled = true;\n queueMicrotask(() => this.#dispatch());\n }\n }\n}\n","import { touchKey, trimOldest } from \"../core/collections.ts\";\nimport type { Event } from \"../core/event.ts\";\nimport type { Filter } from \"../core/filter.ts\";\nimport { formatEventAddress } from \"../core/tag.ts\";\nimport { nowSeconds } from \"../core/util.ts\";\nimport type { LoaderContext } from \"./context.ts\";\nimport { DataLoader } from \"./dataloader.ts\";\n\n/** Result of a replaceable load: the winning event (or none) and freshness. */\nexport type ReplaceableLoadResult = {\n readonly event: Event | undefined;\n readonly fresh: boolean;\n};\n\n/** `default`: fetch when stale or unfetched; `force`: always fetch; `cache-only`: index only. */\nexport type LoadStyle = \"default\" | \"force\" | \"cache-only\";\n\n/** Loads the winning replaceable/addressable event of one kind for a pubkey. */\nexport type ReplaceableLoader = (\n pubkey: string,\n opts?: { hints?: string[] | undefined; style?: LoadStyle | undefined },\n) => Promise<ReplaceableLoadResult>;\n\n/** FIFO cap on per-address fetch records (misses included). */\nconst MAX_FETCHED_AT = 10_000;\n\n/**\n * Address -> last network fetch. `hit` is true when the index held a winner right after that fetch;\n * a fresh `hit` record whose winner was evicted since must refetch instead of reporting a miss.\n */\ntype FetchedAt = Map<string, { at: number; hit: boolean }>;\n\n/**\n * Batch-fetch replaceable events (kind + authors) via the pool. Fetched events are written into the\n * reactive index (`onEvent` records `seenOn`) and the winner is read back from it; the index — not\n * the loader — owns the stored value and winner selection. The loader only tracks per-address\n * `fetchedAt` timestamps so a recent fetch (including a miss) is not repeated within\n * `staleAfterSec`.\n */\nexport function createReplaceableLoader(ctx: LoaderContext, kind: number): ReplaceableLoader {\n type Key = { pubkey: string; hints?: string[] | undefined };\n\n const fetchedAt: FetchedAt = new Map();\n const markFetched = (addr: string, hit: boolean, now: number): void => {\n touchKey(fetchedAt, addr, { at: now, hit });\n trimOldest(fetchedAt, MAX_FETCHED_AT);\n };\n\n const loader = new DataLoader<Key, ReplaceableLoadResult, string>(\n async (keys) => {\n const authors = [...new Set(keys.map((k) => k.pubkey))];\n const relays = [...new Set([...keys.flatMap((k) => k.hints ?? []), ...ctx.relays])];\n if (relays.length > 0) {\n const filter: Filter = { kinds: [kind], authors };\n await ctx.pool.fetch(relays, [filter], {\n timeoutMs: ctx.fetchTimeoutMs,\n onEvent: (event, relayUrl) => ctx.ingest(event, relayUrl),\n });\n }\n const now = nowSeconds();\n return keys.map((k) => {\n const addr = formatEventAddress(kind, k.pubkey, \"\");\n const event = ctx.index.getByAddress(addr);\n // Record the fetch even when nothing came back: a recent miss must\n // not be retried on every `default` load.\n markFetched(addr, event !== undefined, now);\n return { event, fresh: true };\n });\n },\n {\n cache: false,\n cacheKeyFn: (k) => `${kind}:${k.pubkey}:${(k.hints ?? []).join(\",\")}`,\n maxBatchSize: 50,\n },\n );\n\n return async (pubkey, opts) => {\n const pk = pubkey.toLowerCase();\n const address = formatEventAddress(kind, pk, \"\");\n const style = opts?.style ?? \"default\";\n const current = (): Event | undefined => ctx.index.getByAddress(address);\n\n if (style === \"cache-only\") {\n return { event: current(), fresh: false };\n }\n if (style === \"default\") {\n const rec = fetchedAt.get(address);\n const event = current();\n // A fresh record short-circuits the fetch, unless it was a hit whose\n // winner has since been evicted — that would report a stale miss.\n if (rec !== undefined && ctx.isFresh(rec.at) && (!rec.hit || event !== undefined)) {\n return { event, fresh: false };\n }\n }\n return loader.load({ pubkey: pk, hints: opts?.hints });\n };\n}\n","import { throwIfAborted } from \"../core/abort.ts\";\nimport { NostrError } from \"../core/error.ts\";\nimport type { Event } from \"../core/event.ts\";\nimport { sortedEvents } from \"../core/event.ts\";\nimport type { Filter } from \"../core/filter.ts\";\nimport { Kind } from \"../core/kind.ts\";\nimport { invokeSafely } from \"../core/report.ts\";\nimport type { Mutable } from \"../core/util.ts\";\nimport { normalizeRelayUrls, nowSeconds } from \"../core/util.ts\";\nimport type { Gossip } from \"../gossip/gossip.ts\";\nimport type { Pool } from \"../relay/pool.ts\";\nimport { DEFAULT_REQUEST_TIMEOUT_MS } from \"../relay/relay.ts\";\nimport type { Closer } from \"../relay/subscription.ts\";\nimport { toStorageError } from \"../storage/error.ts\";\nimport { outboxBoundKey } from \"../storage/put.ts\";\nimport type { EventStore, OutboxBound } from \"../storage/types.ts\";\n\nexport type { OutboxBound } from \"../storage/types.ts\";\n\n/** Outbox feed lifecycle error (e.g. use after close). */\nexport class OutboxError extends NostrError {\n override name = \"OutboxError\";\n}\n\n/** Trailing-flush delay for live bound persistence: one write per dirty bound per window. */\nexport const BOUND_FLUSH_MS = 1000;\n\n/** Options for {@link OutboxFeed}. */\nexport type OutboxFeedOptions = {\n pool: Pool;\n gossip: Gossip;\n storage: EventStore;\n /** Fallback relays when an author has no known outbox routes. */\n discoveryRelays: ReadonlyArray<string>;\n authors: ReadonlyArray<string>;\n /** Event kinds to fetch. Default `[Kind.TextNote]`. */\n kinds?: ReadonlyArray<number> | undefined;\n /** Max write-relays to use per author. Default 3. */\n maxRelaysPerAuthor?: number | undefined;\n fetchTimeoutMs?: number | undefined;\n /** Called for live events after observe, and for sync events returned by applySync. */\n onEvent?: ((event: Event) => void) | undefined;\n /** Live ingest (e.g. `client.observe`) with the source relay URL. StartLive never putManys. */\n observe?: ((event: Event, relayUrl: string) => void) | undefined;\n /**\n * Every receipt from every relay — live (including duplicates the feed's own dedupe skips) and\n * sync fetch batches — for seenOn bookkeeping.\n */\n seen?: ((event: Event, relayUrl: string) => void) | undefined;\n /**\n * Sync path only. Awaited. Return events that should advance bounds. Throw → sync throws, bounds\n * unchanged.\n */\n applySync?: ((events: ReadonlyArray<Event>) => Promise<ReadonlyArray<Event>>) | undefined;\n /** Load kind:10002 for authors before sync when routes are missing. Requires a relay-list loader. */\n hydrate?: ((pubkeys: ReadonlyArray<string>) => Promise<void>) | undefined;\n};\n\n/**\n * Group authors by outbox relay (discovery fallback). `prefer` reorders existing candidates only;\n * it never appends a URL that is not already in the author's outbox or discovery list. Returns\n * Map<relayUrl, authors[]>.\n */\nexport function groupAuthorsByOutboxRelay(\n authors: ReadonlyArray<string>,\n gossip: Gossip,\n discoveryRelays: ReadonlyArray<string>,\n maxRelaysPerAuthor = 3,\n prefer: ReadonlyArray<string> = [],\n): Map<string, string[]> {\n const leftover = new Set(\n (gossip.route({ authors: authors.map((a) => a.toLowerCase()) }).remainder?.authors ?? []).map(\n (a) => a.toLowerCase(),\n ),\n );\n const preferSet = new Set(normalizeRelayUrls(prefer));\n const discovery = normalizeRelayUrls(discoveryRelays);\n const map = new Map<string, string[]>();\n\n for (const author of authors) {\n const pk = author.toLowerCase();\n const urls = leftover.has(pk) ? discovery : gossip.outboxRelays(pk);\n const preferred: string[] = [];\n const rest: string[] = [];\n for (const url of urls) {\n if (preferSet.has(url)) {\n preferred.push(url);\n } else {\n rest.push(url);\n }\n }\n for (const url of [...preferred, ...rest].slice(0, maxRelaysPerAuthor)) {\n const list = map.get(url) ?? [];\n if (!list.includes(pk)) {\n list.push(pk);\n }\n map.set(url, list);\n }\n }\n return map;\n}\n\n/**\n * Outbox-model feed: history sync + live subscription for a set of authors, routed via NIP-65 write\n * relays (with discovery fallback).\n */\nexport class OutboxFeed {\n readonly #pool: Pool;\n readonly #gossip: Gossip;\n readonly #storage: EventStore;\n readonly #discovery: string[];\n readonly #kinds: number[];\n readonly #maxRelays: number;\n readonly #timeoutMs: number;\n readonly #onEvent: ((event: Event) => void) | undefined;\n readonly #observe: ((event: Event, relayUrl: string) => void) | undefined;\n readonly #seen: ((event: Event, relayUrl: string) => void) | undefined;\n readonly #applySync:\n | ((events: ReadonlyArray<Event>) => Promise<ReadonlyArray<Event>>)\n | undefined;\n readonly #hydrate: ((pubkeys: ReadonlyArray<string>) => Promise<void>) | undefined;\n readonly #bounds = new Map<string, Mutable<OutboxBound>>();\n /** Bound keys dirtied by live events since the last flush. */\n readonly #dirtyBounds = new Set<string>();\n #boundTimer: ReturnType<typeof setTimeout> | undefined;\n #authors: string[];\n #liveCloser: Closer | undefined;\n #closed = false;\n\n constructor(opts: OutboxFeedOptions) {\n this.#pool = opts.pool;\n this.#gossip = opts.gossip;\n this.#storage = opts.storage;\n this.#discovery = [...opts.discoveryRelays];\n this.#authors = [...new Set(opts.authors.map((a) => a.toLowerCase()))];\n this.#kinds = [...(opts.kinds ?? [Kind.TextNote])];\n this.#maxRelays = opts.maxRelaysPerAuthor ?? 3;\n this.#timeoutMs = opts.fetchTimeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n this.#onEvent = opts.onEvent;\n this.#observe = opts.observe;\n this.#seen = opts.seen;\n this.#applySync = opts.applySync;\n this.#hydrate = opts.hydrate;\n }\n\n get authors(): ReadonlyArray<string> {\n return this.#authors;\n }\n\n get kinds(): ReadonlyArray<number> {\n return this.#kinds;\n }\n\n /** Replace the author set (does not auto-restart live). */\n setAuthors(authors: ReadonlyArray<string>): void {\n this.#authors = [...new Set(authors.map((a) => a.toLowerCase()))];\n }\n\n getBound(pubkey: string, kind: number): OutboxBound | undefined {\n return this.#bounds.get(outboxBoundKey(pubkey, kind));\n }\n\n /** Load NIP-65 relay lists for authors that have no outbox routes yet. */\n async hydrate(): Promise<void> {\n this.#assertOpen();\n if (!this.#hydrate) {\n return;\n }\n const missing = this.#authors.filter((pk) => this.#gossip.outboxRelays(pk).length === 0);\n if (missing.length === 0) {\n return;\n }\n await this.#hydrate(missing);\n }\n\n /** One-shot history pull. Persistence is `applySync`; bounds move only for events it returns. */\n async sync(opts?: {\n limit?: number | undefined;\n since?: number | undefined;\n until?: number | undefined;\n signal?: AbortSignal | undefined;\n /** Skip hydrate() even if provided. */\n skipHydrate?: boolean | undefined;\n }): Promise<Event[]> {\n this.#assertOpen();\n if (opts?.skipHydrate !== true) {\n await this.hydrate();\n }\n await this.#hydrateBoundsFromStore();\n\n const byRelay = groupAuthorsByOutboxRelay(\n this.#authors,\n this.#gossip,\n this.#discovery,\n this.#maxRelays,\n this.#pool.connectedUrls(),\n );\n\n if (byRelay.size === 0) {\n return [];\n }\n\n const byId = new Map<string, Event>();\n await Promise.all(\n [...byRelay.entries()].map(async ([url, authors]) => {\n throwIfAborted(opts?.signal);\n\n const filters = this.#syncFilters(authors, opts);\n try {\n const batch = await this.#pool.fetch([url], filters, {\n timeoutMs: this.#timeoutMs,\n signal: opts?.signal,\n onEvent: (event, relayUrl) => invokeSafely(() => this.#seen?.(event, relayUrl)),\n });\n for (const event of batch) {\n byId.set(event.id, event);\n }\n } catch (error) {\n // An abort rejects the whole sync; per-relay failures are skipped.\n if (opts?.signal?.aborted === true) {\n throw error;\n }\n }\n }),\n );\n\n const unique = [...byId.values()];\n if (unique.length === 0) {\n return [];\n }\n\n let applied: ReadonlyArray<Event> = [];\n if (this.#applySync) {\n try {\n applied = await this.#applySync(unique);\n } catch (error) {\n throw toStorageError(error);\n }\n }\n const dirty = new Set<string>();\n for (const event of applied) {\n this.#updateBounds(event);\n dirty.add(outboxBoundKey(event.pubkey, event.kind));\n invokeSafely(() => this.#onEvent?.(event));\n }\n await this.#persistBounds(dirty);\n return sortedEvents(unique);\n }\n\n /**\n * Start a live subscription across outbox relays for the current authors. Closes any previous\n * live subscription.\n */\n startLive(opts?: { signal?: AbortSignal | undefined; since?: number | undefined }): Closer {\n this.#assertOpen();\n this.#liveCloser?.close(\"restart\");\n\n const byRelay = groupAuthorsByOutboxRelay(\n this.#authors,\n this.#gossip,\n this.#discovery,\n this.#maxRelays,\n this.#pool.connectedUrls(),\n );\n\n const seen = new Set<string>();\n const closers: Closer[] = [];\n const since = opts?.since ?? nowSeconds() - 60;\n\n for (const [url, authors] of byRelay) {\n const filter: Filter = {\n authors,\n kinds: this.#kinds,\n since,\n };\n closers.push(\n this.#pool.subscribe([url], [filter], {\n signal: opts?.signal,\n onEvent: (event, relayUrl) => {\n invokeSafely(() => this.#seen?.(event, relayUrl));\n if (seen.has(event.id)) {\n return;\n }\n seen.add(event.id);\n this.#noteEvent(event, relayUrl);\n },\n }),\n );\n }\n\n const closer = {\n close: (reason?: string) => {\n for (const c of closers) {\n c.close(reason);\n }\n if (this.#liveCloser === closer) {\n this.#liveCloser = undefined;\n }\n },\n };\n this.#liveCloser = closer;\n return closer;\n }\n\n /** Convenience: hydrate + sync + startLive. */\n async start(opts?: {\n limit?: number | undefined;\n signal?: AbortSignal | undefined;\n }): Promise<Closer & { events: Event[] }> {\n const events = await this.sync({ limit: opts?.limit, signal: opts?.signal });\n const live = this.startLive({ signal: opts?.signal });\n return { close: (r) => live.close(r), events };\n }\n\n close(): void {\n this.#closed = true;\n this.#liveCloser?.close(\"feed closed\");\n this.#liveCloser = undefined;\n if (this.#boundTimer !== undefined) {\n clearTimeout(this.#boundTimer);\n this.#boundTimer = undefined;\n }\n void this.#flushBounds();\n }\n\n #assertOpen(): void {\n if (this.#closed) {\n throw new OutboxError(\"OutboxFeed is closed\");\n }\n }\n\n async #hydrateBoundsFromStore(): Promise<void> {\n await Promise.all(\n this.#authors.flatMap((pk) =>\n this.#kinds.map(async (kind) => {\n const key = outboxBoundKey(pk, kind);\n if (this.#bounds.has(key)) {\n return;\n }\n const bound = await this.#storage.getOutboxBound(pk, kind);\n if (!bound) {\n return;\n }\n await this.#storage.setOutboxBound(pk, kind, bound);\n this.#bounds.set(key, { oldest: bound.oldest, newest: bound.newest });\n }),\n ),\n );\n }\n\n #syncFilters(\n authors: string[],\n opts?: { limit?: number | undefined; since?: number | undefined; until?: number | undefined },\n ): Filter[] {\n const base: Filter = {\n kinds: this.#kinds,\n limit: opts?.limit ?? 50,\n ...(opts?.until === undefined ? {} : { until: opts.until }),\n };\n\n if (opts?.since !== undefined) {\n return [{ ...base, authors, since: opts.since }];\n }\n\n const bounded: string[] = [];\n const unbounded: string[] = [];\n let minBoundedNewest: number | undefined;\n\n for (const pk of authors) {\n let newest: number | undefined;\n let complete = true;\n for (const kind of this.#kinds) {\n const b = this.#bounds.get(outboxBoundKey(pk, kind));\n if (!b) {\n complete = false;\n break;\n }\n newest = Math.min(newest ?? b.newest, b.newest);\n }\n if (complete && newest !== undefined) {\n bounded.push(pk);\n if (minBoundedNewest === undefined || newest < minBoundedNewest) {\n minBoundedNewest = newest;\n }\n } else {\n unbounded.push(pk);\n }\n }\n\n if (bounded.length === 0 || minBoundedNewest === undefined) {\n return [{ ...base, authors }];\n }\n // A bound far in the future (bad clock, hostile stored data) must not push `since` past wall\n // clock — clamp at this single consumer point so live-updated, persisted, and store-derived\n // bounds are all covered. Worst case is re-delivery, never loss.\n const since = Math.max(0, Math.min(minBoundedNewest, nowSeconds()) - 1);\n if (unbounded.length === 0) {\n return [{ ...base, authors, since }];\n }\n return [\n { ...base, authors: bounded, since },\n { ...base, authors: unbounded },\n ];\n }\n\n #noteEvent(event: Event, relayUrl: string): void {\n this.#updateBounds(event);\n const key = outboxBoundKey(event.pubkey, event.kind);\n if (this.#bounds.has(key)) {\n this.#dirtyBounds.add(key);\n this.#boundTimer ??= setTimeout(() => {\n this.#boundTimer = undefined;\n void this.#flushBounds();\n }, BOUND_FLUSH_MS);\n }\n invokeSafely(() => this.#observe?.(event, relayUrl));\n invokeSafely(() => this.#onEvent?.(event));\n }\n\n /** Persist all bounds dirtied since the last flush. Best-effort: errors are swallowed. */\n async #flushBounds(): Promise<void> {\n const keys = [...this.#dirtyBounds];\n this.#dirtyBounds.clear();\n try {\n await this.#persistBounds(keys);\n } catch {\n // Bound persistence is best-effort.\n }\n }\n\n async #persistBounds(keys: Iterable<string>): Promise<void> {\n const writes: Array<Promise<void>> = [];\n for (const key of keys) {\n const bound = this.#bounds.get(key);\n if (!bound) {\n continue;\n }\n const sep = key.lastIndexOf(\":\");\n writes.push(\n this.#storage.setOutboxBound(key.slice(0, sep), Number(key.slice(sep + 1)), {\n oldest: bound.oldest,\n newest: bound.newest,\n }),\n );\n }\n if (writes.length === 0) {\n return;\n }\n try {\n await Promise.all(writes);\n } catch (error) {\n throw toStorageError(error);\n }\n }\n\n #updateBounds(event: Event): void {\n const key = outboxBoundKey(event.pubkey, event.kind);\n const prev = this.#bounds.get(key);\n if (!prev) {\n this.#bounds.set(key, { oldest: event.created_at, newest: event.created_at });\n return;\n }\n if (event.created_at < prev.oldest) {\n prev.oldest = event.created_at;\n }\n if (event.created_at > prev.newest) {\n prev.newest = event.created_at;\n }\n }\n}\n","import type { Event } from \"../core/event.ts\";\nimport type { Pool } from \"../relay/pool.ts\";\nimport type { ReactiveEventStore } from \"../store/reactive.ts\";\nimport { LoaderContext } from \"./context.ts\";\nimport { createEventLoader } from \"./event.ts\";\nimport type { EventLoader } from \"./event.ts\";\nimport { createListLoaders } from \"./lists.ts\";\nimport type { ListLoaders } from \"./lists.ts\";\nimport { createProfileLoader } from \"./profile.ts\";\nimport type { ProfileLoader } from \"./profile.ts\";\nimport { createReplaceableLoader } from \"./replaceable.ts\";\nimport type { ReplaceableLoader } from \"./replaceable.ts\";\n\nexport {\n type LoadStyle,\n type ReplaceableLoader,\n type ReplaceableLoadResult,\n} from \"./replaceable.ts\";\nexport { type ListResult, type ListLoaders } from \"./lists.ts\";\nexport { bareNostrUser, type NostrUser, type ProfileLoader } from \"./profile.ts\";\nexport { type EventLoader, type EventRef } from \"./event.ts\";\nexport {\n OutboxError,\n OutboxFeed,\n groupAuthorsByOutboxRelay,\n type OutboxBound,\n type OutboxFeedOptions,\n} from \"./outbox.ts\";\n\n/** The loader surface returned by {@link createLoaders}. */\nexport type Loaders = {\n follows: ListLoaders[\"follows\"];\n muteList: ListLoaders[\"muteList\"];\n relayList: ListLoaders[\"relayList\"];\n dmRelayList: ListLoaders[\"dmRelayList\"];\n profile: ProfileLoader[\"load\"];\n event: EventLoader[\"load\"];\n /** Generic replaceable loader for any kind; memoized per kind. */\n replaceable: (kind: number) => ReplaceableLoader;\n addRelay: (url: string) => void;\n removeRelay: (url: string) => void;\n};\n\n/** Options for {@link createLoaders}. */\nexport type CreateLoadersOptions = {\n pool: Pool;\n relays: ReadonlyArray<string>;\n /** The reactive index loaders read from and feed fetched events into. */\n index: ReactiveEventStore;\n /**\n * Inbound-event sink for fetched events; defaults to `index.add`. Client wires its single ingest\n * path so loader fetches get gossip meta and persistence like every other inbound event.\n */\n ingest?: ((event: Event, relayUrl: string) => void) | undefined;\n staleAfterSec?: number | undefined;\n fetchTimeoutMs?: number | undefined;\n};\n\n/** Build an instance-scoped loader suite (no module globals). */\nexport function createLoaders(opts: CreateLoadersOptions): Loaders {\n const context = new LoaderContext(opts);\n const byKind = new Map<number, ReplaceableLoader>();\n const replaceable = (kind: number): ReplaceableLoader => {\n let loader = byKind.get(kind);\n if (loader === undefined) {\n loader = createReplaceableLoader(context, kind);\n byKind.set(kind, loader);\n }\n return loader;\n };\n const lists = createListLoaders(replaceable);\n const profile = createProfileLoader(replaceable);\n const event = createEventLoader(context);\n return {\n follows: async (pubkey, o) => lists.follows(pubkey, o),\n muteList: async (pubkey, o) => lists.muteList(pubkey, o),\n relayList: async (pubkey, o) => lists.relayList(pubkey, o),\n dmRelayList: async (pubkey, o) => lists.dmRelayList(pubkey, o),\n profile: async (pubkey, o) => profile.load(pubkey, o),\n // oxlint-disable-next-line typescript/promise-function-async -- must pass through load's synchronous throw on malformed refs\n event: (ref) => event.load(ref),\n replaceable,\n addRelay: (url) => context.addRelay(url),\n removeRelay: (url) => context.removeRelay(url),\n };\n}\n"],"mappings":"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"}
|
package/dist/loaders.d.mts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { r as OutboxBound } from "./types-
|
|
2
|
-
import { _ as EventRef, a as OutboxFeed, c as NostrUser, d as ListLoaders, f as ListResult, g as EventLoader, h as ReplaceableLoader, i as OutboxError, l as ProfileLoader, m as ReplaceableLoadResult, n as Loaders, o as OutboxFeedOptions, p as LoadStyle, r as createLoaders, s as groupAuthorsByOutboxRelay, t as CreateLoadersOptions, u as bareNostrUser } from "./index-
|
|
1
|
+
import { r as OutboxBound } from "./types-DiVVyf1e.mjs";
|
|
2
|
+
import { _ as EventRef, a as OutboxFeed, c as NostrUser, d as ListLoaders, f as ListResult, g as EventLoader, h as ReplaceableLoader, i as OutboxError, l as ProfileLoader, m as ReplaceableLoadResult, n as Loaders, o as OutboxFeedOptions, p as LoadStyle, r as createLoaders, s as groupAuthorsByOutboxRelay, t as CreateLoadersOptions, u as bareNostrUser } from "./index-DCobP2Jj.mjs";
|
|
3
3
|
export { CreateLoadersOptions, type EventLoader, type EventRef, type ListLoaders, type ListResult, type LoadStyle, Loaders, type NostrUser, type OutboxBound, OutboxError, OutboxFeed, type OutboxFeedOptions, type ProfileLoader, type ReplaceableLoadResult, type ReplaceableLoader, bareNostrUser, createLoaders, groupAuthorsByOutboxRelay };
|