@qntx/nostr 0.5.0 → 0.7.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.
Files changed (178) hide show
  1. package/dist/{abort-Ba8tDrOI.mjs → abort-DBq2STPj.mjs} +13 -6
  2. package/dist/abort-DBq2STPj.mjs.map +1 -0
  3. package/dist/{builder-9tjI6WQ3.mjs → builder-CdLE4J6O.mjs} +11 -17
  4. package/dist/builder-CdLE4J6O.mjs.map +1 -0
  5. package/dist/{builder-sSflu6nB.d.mts → builder-DgkqDylK.d.mts} +5 -6
  6. package/dist/{client-BtIAtxrL.mjs → client-CILhdfsF.mjs} +104 -314
  7. package/dist/client-CILhdfsF.mjs.map +1 -0
  8. package/dist/client.d.mts +2 -2
  9. package/dist/client.mjs +2 -2
  10. package/dist/collections-DtwMc1NU.mjs +33 -0
  11. package/dist/collections-DtwMc1NU.mjs.map +1 -0
  12. package/dist/core.d.mts +9 -8
  13. package/dist/core.mjs +7 -7
  14. package/dist/{error-BW7re1UN.d.mts → error-BD_0QFKT.d.mts} +2 -2
  15. package/dist/{error-CR8Urc84.d.mts → error-BquXDmIN.d.mts} +4 -4
  16. package/dist/{error-DrEIM7FO.mjs → error-L_QdmSnV.mjs} +2 -2
  17. package/dist/{error-DrEIM7FO.mjs.map → error-L_QdmSnV.mjs.map} +1 -1
  18. package/dist/{error-B__OMBRY.mjs → error-gtJvV6YS.mjs} +2 -2
  19. package/dist/{error-B__OMBRY.mjs.map → error-gtJvV6YS.mjs.map} +1 -1
  20. package/dist/{event-fU3Y01PR.d.mts → event-DJeb_DIL.d.mts} +4 -2
  21. package/dist/{event-D8Nfoh4K.mjs → event-DinQMmJ1.mjs} +16 -10
  22. package/dist/event-DinQMmJ1.mjs.map +1 -0
  23. package/dist/{filter-C0IMByE3.d.mts → filter-jI_9htF7.d.mts} +2 -2
  24. package/dist/{gossip-DpIvkBuj.d.mts → gossip-C7HLW5kI.d.mts} +35 -26
  25. package/dist/{gossip-oloDMWEj.mjs → gossip-CcTp9VpU.mjs} +23 -33
  26. package/dist/gossip-CcTp9VpU.mjs.map +1 -0
  27. package/dist/gossip.d.mts +1 -1
  28. package/dist/gossip.mjs +1 -1
  29. package/dist/{index-CvkvqB16.d.mts → index-DU9tRFTZ.d.mts} +7 -20
  30. package/dist/{index-q4MDce_r.d.mts → index-DiXwNn2M.d.mts} +6 -8
  31. package/dist/{index-QxvrpMfF.d.mts → index-DocgD9K0.d.mts} +92 -167
  32. package/dist/{index-D1bqFHKB.d.mts → index-InQZpHyQ.d.mts} +18 -18
  33. package/dist/{index-MxC28S4P.d.mts → index-Tx15HGAD.d.mts} +26 -28
  34. package/dist/{index-Dmc8FJgO.d.mts → index-iLT8UzY3.d.mts} +19 -37
  35. package/dist/index.d.mts +23 -21
  36. package/dist/index.mjs +21 -19
  37. package/dist/instance-BcKzxHIP.mjs +220 -0
  38. package/dist/instance-BcKzxHIP.mjs.map +1 -0
  39. package/dist/instance-DjsL8h84.d.mts +15 -0
  40. package/dist/{key-Cv4_pN3x.d.mts → key-D_5OgGT7.d.mts} +11 -7
  41. package/dist/{key-Bps-LqX7.mjs → key-bshqfmZL.mjs} +13 -9
  42. package/dist/key-bshqfmZL.mjs.map +1 -0
  43. package/dist/{loaders-o6YXB_Ri.mjs → loaders-DD0XAGzw.mjs} +73 -82
  44. package/dist/loaders-DD0XAGzw.mjs.map +1 -0
  45. package/dist/loaders.d.mts +3 -3
  46. package/dist/loaders.mjs +2 -2
  47. package/dist/{memory-C2EVx0_O.mjs → memory-D_-5-T31.mjs} +2 -2
  48. package/dist/memory-D_-5-T31.mjs.map +1 -0
  49. package/dist/{memory-index-Do1mz0WF.mjs → memory-index-C6rujtoc.mjs} +30 -247
  50. package/dist/memory-index-C6rujtoc.mjs.map +1 -0
  51. package/dist/message-CWLcFTQ1.mjs +194 -0
  52. package/dist/message-CWLcFTQ1.mjs.map +1 -0
  53. package/dist/{message-iGPIqnn0.d.mts → message-CbBZOhq3.d.mts} +3 -3
  54. package/dist/{nip17-CKIufV98.d.mts → nip17-cTDFfFVt.d.mts} +5 -6
  55. package/dist/{nip19-BevCJZsp.d.mts → nip19-D1OnJ192.d.mts} +3 -9
  56. package/dist/{nip46-DDV4dC56.d.mts → nip46-DrsPI8EX.d.mts} +3 -5
  57. package/dist/nip51-DoPUvQ--.d.mts +87 -0
  58. package/dist/{nip59-zQgdLcEr.d.mts → nip59-BFIihLYY.d.mts} +3 -4
  59. package/dist/nip65-52HiwiyD.d.mts +23 -0
  60. package/dist/{nip77-DH4RhS5r.d.mts → nip77-C9QcZn7b.d.mts} +3 -4
  61. package/dist/nips/blossom.d.mts +12 -8
  62. package/dist/nips/blossom.mjs +30 -9
  63. package/dist/nips/blossom.mjs.map +1 -1
  64. package/dist/nips/nip04.mjs +17 -7
  65. package/dist/nips/nip04.mjs.map +1 -1
  66. package/dist/nips/nip05.d.mts +2 -3
  67. package/dist/nips/nip05.mjs +1 -4
  68. package/dist/nips/nip05.mjs.map +1 -1
  69. package/dist/nips/nip10.d.mts +3 -3
  70. package/dist/nips/nip10.mjs +3 -3
  71. package/dist/nips/nip11.d.mts +1 -1
  72. package/dist/nips/nip11.mjs +4 -4
  73. package/dist/nips/nip11.mjs.map +1 -1
  74. package/dist/nips/nip13.d.mts +7 -7
  75. package/dist/nips/nip13.mjs +32 -10
  76. package/dist/nips/nip13.mjs.map +1 -1
  77. package/dist/nips/nip17.d.mts +1 -1
  78. package/dist/nips/nip17.mjs +13 -33
  79. package/dist/nips/nip17.mjs.map +1 -1
  80. package/dist/nips/nip19.d.mts +2 -2
  81. package/dist/nips/nip19.mjs +16 -28
  82. package/dist/nips/nip19.mjs.map +1 -1
  83. package/dist/nips/nip21.d.mts +6 -1
  84. package/dist/nips/nip21.mjs +15 -5
  85. package/dist/nips/nip21.mjs.map +1 -1
  86. package/dist/nips/nip27.d.mts +4 -4
  87. package/dist/nips/nip27.mjs.map +1 -1
  88. package/dist/nips/nip42.d.mts +1 -1
  89. package/dist/nips/nip42.mjs +2 -1
  90. package/dist/nips/nip42.mjs.map +1 -1
  91. package/dist/nips/nip44.mjs +1 -1
  92. package/dist/nips/nip46.d.mts +2 -2
  93. package/dist/nips/nip46.mjs +15 -19
  94. package/dist/nips/nip46.mjs.map +1 -1
  95. package/dist/nips/nip49.d.mts +5 -5
  96. package/dist/nips/nip49.mjs +4 -4
  97. package/dist/nips/nip49.mjs.map +1 -1
  98. package/dist/nips/nip51.d.mts +2 -86
  99. package/dist/nips/nip51.mjs +7 -23
  100. package/dist/nips/nip51.mjs.map +1 -1
  101. package/dist/nips/nip57.d.mts +7 -5
  102. package/dist/nips/nip57.mjs +12 -17
  103. package/dist/nips/nip57.mjs.map +1 -1
  104. package/dist/nips/nip59.d.mts +1 -1
  105. package/dist/nips/nip59.mjs +16 -16
  106. package/dist/nips/nip59.mjs.map +1 -1
  107. package/dist/nips/nip65.d.mts +2 -2
  108. package/dist/nips/nip65.mjs +14 -37
  109. package/dist/nips/nip65.mjs.map +1 -1
  110. package/dist/nips/nip77.d.mts +1 -1
  111. package/dist/nips/nip77.mjs +33 -32
  112. package/dist/nips/nip77.mjs.map +1 -1
  113. package/dist/nips/nip98.d.mts +5 -5
  114. package/dist/nips/nip98.mjs +8 -8
  115. package/dist/nips/nip98.mjs.map +1 -1
  116. package/dist/nostr_crypto_wasm_bg.wasm +0 -0
  117. package/dist/{pool-DBIYMtwy.d.mts → pool-SzJKPIa3.d.mts} +96 -91
  118. package/dist/pool-YHRZgcQ3.mjs +596 -0
  119. package/dist/pool-YHRZgcQ3.mjs.map +1 -0
  120. package/dist/put-DS0yzVJx.mjs +187 -0
  121. package/dist/put-DS0yzVJx.mjs.map +1 -0
  122. package/dist/{reactive-DFpqtIf_.d.mts → reactive-BJ1ggn4d.d.mts} +9 -22
  123. package/dist/{reactive-DDlThDSZ.mjs → reactive-BJRoVHxU.mjs} +113 -64
  124. package/dist/reactive-BJRoVHxU.mjs.map +1 -0
  125. package/dist/{pool-As20OGxB.mjs → relay-CvxPiQ_m.mjs} +178 -721
  126. package/dist/relay-CvxPiQ_m.mjs.map +1 -0
  127. package/dist/relay.d.mts +4 -4
  128. package/dist/relay.mjs +3 -2
  129. package/dist/serial-Bzpw-xz3.mjs +21 -0
  130. package/dist/serial-Bzpw-xz3.mjs.map +1 -0
  131. package/dist/{signer-CYQutDzD.mjs → signer-yW3slDC2.mjs} +12 -14
  132. package/dist/signer-yW3slDC2.mjs.map +1 -0
  133. package/dist/signer.d.mts +2 -2
  134. package/dist/signer.mjs +2 -2
  135. package/dist/{storage-Dky3wuoH.mjs → storage-CZ52ifcQ.mjs} +17 -42
  136. package/dist/storage-CZ52ifcQ.mjs.map +1 -0
  137. package/dist/storage.d.mts +3 -3
  138. package/dist/storage.mjs +4 -4
  139. package/dist/store.d.mts +1 -1
  140. package/dist/store.mjs +1 -1
  141. package/dist/testing.d.mts +18 -18
  142. package/dist/testing.mjs +9 -9
  143. package/dist/testing.mjs.map +1 -1
  144. package/dist/{types-2pCUprRU.d.mts → types-Cm-XMgtH.d.mts} +6 -6
  145. package/dist/{types-CRQEk0Oi.d.mts → types-DNmiscfd.d.mts} +2 -2
  146. package/dist/{util-LfQirgDk.mjs → util-yFYzlbrm.mjs} +29 -7
  147. package/dist/util-yFYzlbrm.mjs.map +1 -0
  148. package/dist/{verifier-t5WoWbtY.mjs → verifier-BTLOpo1n.mjs} +3 -3
  149. package/dist/verifier-BTLOpo1n.mjs.map +1 -0
  150. package/dist/verifier-CgTFpgsC.d.mts +22 -0
  151. package/dist/wasm.browser.d.mts +8 -0
  152. package/dist/wasm.browser.mjs +19 -0
  153. package/dist/wasm.browser.mjs.map +1 -0
  154. package/dist/wasm.d.mts +3 -13
  155. package/dist/wasm.mjs +7 -208
  156. package/dist/wasm.mjs.map +1 -1
  157. package/package.json +13 -10
  158. package/dist/abort-Ba8tDrOI.mjs.map +0 -1
  159. package/dist/builder-9tjI6WQ3.mjs.map +0 -1
  160. package/dist/client-BtIAtxrL.mjs.map +0 -1
  161. package/dist/event-D8Nfoh4K.mjs.map +0 -1
  162. package/dist/gossip-oloDMWEj.mjs.map +0 -1
  163. package/dist/key-Bps-LqX7.mjs.map +0 -1
  164. package/dist/loaders-o6YXB_Ri.mjs.map +0 -1
  165. package/dist/memory-C2EVx0_O.mjs.map +0 -1
  166. package/dist/memory-index-Do1mz0WF.mjs.map +0 -1
  167. package/dist/message-DcY6Fi9o.mjs +0 -193
  168. package/dist/message-DcY6Fi9o.mjs.map +0 -1
  169. package/dist/nip65-CjgmdpPB.d.mts +0 -26
  170. package/dist/nips/nip96.d.mts +0 -40
  171. package/dist/nips/nip96.mjs +0 -118
  172. package/dist/nips/nip96.mjs.map +0 -1
  173. package/dist/pool-As20OGxB.mjs.map +0 -1
  174. package/dist/reactive-DDlThDSZ.mjs.map +0 -1
  175. package/dist/signer-CYQutDzD.mjs.map +0 -1
  176. package/dist/storage-Dky3wuoH.mjs.map +0 -1
  177. package/dist/util-LfQirgDk.mjs.map +0 -1
  178. package/dist/verifier-t5WoWbtY.mjs.map +0 -1
@@ -1,222 +1,22 @@
1
- import { g as NostrError, l as normalizeURL } from "./util-LfQirgDk.mjs";
1
+ import { u as normalizeURL, v as NostrError, x as errorMessage } from "./util-yFYzlbrm.mjs";
2
2
  import { t as Kind } from "./kind-Cxwhhkx8.mjs";
3
- import { f as sortedEvents, o as itemCompare } from "./event-D8Nfoh4K.mjs";
4
- import { t as EventBuilder } from "./builder-9tjI6WQ3.mjs";
3
+ import { f as sortedEvents, o as itemCompare } from "./event-DinQMmJ1.mjs";
4
+ import { t as EventBuilder } from "./builder-CdLE4J6O.mjs";
5
5
  import { n as canonicalizeFilters, o as matchFilters, t as canonicalizeFilter } from "./filter-BQl3GlHt.mjs";
6
- import { t as NoSignerError } from "./error-B__OMBRY.mjs";
6
+ import { t as NoSignerError } from "./error-gtJvV6YS.mjs";
7
7
  import { t as invokeSafely } from "./report-CHld4uWj.mjs";
8
- import { n as fanIn, r as fetchRouted, t as Pool } from "./pool-As20OGxB.mjs";
9
- import { r as throwIfAborted } from "./abort-Ba8tDrOI.mjs";
8
+ import { n as fanIn, r as fetchRouted, t as Pool } from "./pool-YHRZgcQ3.mjs";
9
+ import { i as throwIfAborted, n as onAbort } from "./abort-DBq2STPj.mjs";
10
10
  import { storageFromItems } from "./nips/nip77.mjs";
11
11
  import { isGiftWrapKind, requireNip59Crypto, unwrap } from "./nips/nip59.mjs";
12
12
  import { Nip17Error, buildChatMessageRumor, dmRelayListEventBuilder, normalizeRecipients, requireDmRelays, wrapDirectMessage } from "./nips/nip17.mjs";
13
- import { t as Gossip } from "./gossip-oloDMWEj.mjs";
14
- import { i as createOutboxFeed, t as createLoaders } from "./loaders-o6YXB_Ri.mjs";
15
- import { n as toStorageError } from "./error-DrEIM7FO.mjs";
16
- import { t as MemoryIndex } from "./memory-index-Do1mz0WF.mjs";
17
- import { t as MemoryEventStore } from "./memory-C2EVx0_O.mjs";
18
- import { t as ReactiveEventStore } from "./reactive-DDlThDSZ.mjs";
19
- //#region src/client/builder.ts
20
- /**
21
- * Fluent constructor for {@link Client}. The constructor is supplied by {@link Client.builder} so
22
- * this module never imports the `Client` value, keeping the client/builder dependency
23
- * one-directional.
24
- */
25
- var ClientBuilder = class {
26
- #opts = {};
27
- #newClient;
28
- constructor(newClient) {
29
- this.#newClient = newClient;
30
- }
31
- signer(signer) {
32
- this.#opts = {
33
- ...this.#opts,
34
- signer
35
- };
36
- return this;
37
- }
38
- relays(urls) {
39
- this.#opts = {
40
- ...this.#opts,
41
- relays: [...urls]
42
- };
43
- return this;
44
- }
45
- addRelay(url) {
46
- this.#opts = {
47
- ...this.#opts,
48
- relays: [...this.#opts.relays ?? [], url]
49
- };
50
- return this;
51
- }
52
- websocketImplementation(impl) {
53
- this.#opts = {
54
- ...this.#opts,
55
- websocketImplementation: impl
56
- };
57
- return this;
58
- }
59
- verifyEvent(fn) {
60
- this.#opts = {
61
- ...this.#opts,
62
- verifyEvent: fn
63
- };
64
- return this;
65
- }
66
- connectTimeoutMs(ms) {
67
- this.#opts = {
68
- ...this.#opts,
69
- connectTimeoutMs: ms
70
- };
71
- return this;
72
- }
73
- publishTimeoutMs(ms) {
74
- this.#opts = {
75
- ...this.#opts,
76
- publishTimeoutMs: ms
77
- };
78
- return this;
79
- }
80
- automaticAuth(enabled) {
81
- this.#opts = {
82
- ...this.#opts,
83
- automaticAuth: enabled
84
- };
85
- return this;
86
- }
87
- /** Allow `ws://` relays. Default false. */
88
- allowInsecure(allow) {
89
- this.#opts = {
90
- ...this.#opts,
91
- allowInsecure: allow
92
- };
93
- return this;
94
- }
95
- /** `ws://` URLs allowed despite `allowInsecure` being off. */
96
- trustedInsecureUrls(urls) {
97
- this.#opts = {
98
- ...this.#opts,
99
- trustedInsecureUrls: urls
100
- };
101
- return this;
102
- }
103
- /** Close idle relays after this many ms. Unset = disabled. */
104
- idleTimeoutMs(ms) {
105
- this.#opts = {
106
- ...this.#opts,
107
- idleTimeoutMs: ms
108
- };
109
- return this;
110
- }
111
- /** Soft cap on connected non-pinned relays. */
112
- maxRelays(n) {
113
- this.#opts = {
114
- ...this.#opts,
115
- maxRelays: n
116
- };
117
- return this;
118
- }
119
- /** Relays never closed by idle cleanup or `maxRelays` eviction. */
120
- pinnedUrls(urls) {
121
- this.#opts = {
122
- ...this.#opts,
123
- pinnedUrls: urls
124
- };
125
- return this;
126
- }
127
- /** Forwarded to the pool: suspend a relay delivering too many invalid events. */
128
- invalidEventPolicy(policy) {
129
- this.#opts = {
130
- ...this.#opts,
131
- invalidEventPolicy: policy
132
- };
133
- return this;
134
- }
135
- /** Forwarded to the pool: fired once when a relay is suspended, with the lift time. */
136
- onRelaySuspended(cb) {
137
- this.#opts = {
138
- ...this.#opts,
139
- onRelaySuspended: cb
140
- };
141
- return this;
142
- }
143
- enableReconnect(enabled) {
144
- this.#opts = {
145
- ...this.#opts,
146
- enableReconnect: enabled
147
- };
148
- return this;
149
- }
150
- enablePing(enabled) {
151
- this.#opts = {
152
- ...this.#opts,
153
- enablePing: enabled
154
- };
155
- return this;
156
- }
157
- pingIntervalMs(ms) {
158
- this.#opts = {
159
- ...this.#opts,
160
- pingIntervalMs: ms
161
- };
162
- return this;
163
- }
164
- pingTimeoutMs(ms) {
165
- this.#opts = {
166
- ...this.#opts,
167
- pingTimeoutMs: ms
168
- };
169
- return this;
170
- }
171
- /**
172
- * Local event store. Defaults to {@link MemoryEventStore}. Browser apps that want persistence must
173
- * pass {@link IndexedDbEventStore} and `await open()`.
174
- */
175
- storage(store) {
176
- this.#opts = {
177
- ...this.#opts,
178
- storage: store
179
- };
180
- return this;
181
- }
182
- /**
183
- * Synchronous reactive index mirroring ingested events. Defaults to a new
184
- * {@link ReactiveEventStore}.
185
- */
186
- index(index) {
187
- this.#opts = {
188
- ...this.#opts,
189
- index
190
- };
191
- return this;
192
- }
193
- /** When false, Client will not auto-write events to storage. Default true. */
194
- persistEvents(enabled) {
195
- this.#opts = {
196
- ...this.#opts,
197
- persistEvents: enabled
198
- };
199
- return this;
200
- }
201
- gossip(gossip) {
202
- this.#opts = {
203
- ...this.#opts,
204
- gossip
205
- };
206
- return this;
207
- }
208
- onstorageerror(fn) {
209
- this.#opts = {
210
- ...this.#opts,
211
- onstorageerror: fn
212
- };
213
- return this;
214
- }
215
- build() {
216
- return this.#newClient(this.#opts);
217
- }
218
- };
219
- //#endregion
13
+ import { t as Gossip } from "./gossip-CcTp9VpU.mjs";
14
+ import { r as OutboxFeed, t as createLoaders } from "./loaders-DD0XAGzw.mjs";
15
+ import { n as toStorageError } from "./error-L_QdmSnV.mjs";
16
+ import { t as MemoryIndex } from "./memory-index-C6rujtoc.mjs";
17
+ import { t as MemoryEventStore } from "./memory-D_-5-T31.mjs";
18
+ import { t as ReactiveEventStore } from "./reactive-BJRoVHxU.mjs";
19
+ import { t as SerialQueue } from "./serial-Bzpw-xz3.mjs";
220
20
  //#region src/client/dm.ts
221
21
  function giftWrapRelays(gossip, event) {
222
22
  const targets = [];
@@ -254,7 +54,7 @@ async function sendPrivateMessage(deps, recipients, content, opts) {
254
54
  wraps: await Promise.all(wraps.map(async ({ recipient, wrap }) => {
255
55
  const relays = requireDmRelays(recipient, deps.gossip.dmRelays(recipient));
256
56
  const results = await deps.pool.publish(relays, wrap, { timeoutMs: opts?.timeoutMs });
257
- if (results.some((r) => r.result?.ok === true) && deps.wantObserve(opts?.observe)) deps.ingest(wrap);
57
+ if (results.some((r) => r.status === "ok") && opts?.observe !== false) deps.ingest(wrap);
258
58
  return {
259
59
  recipient,
260
60
  wrap,
@@ -267,9 +67,9 @@ async function fetchPrivateMessages(deps, opts) {
267
67
  deps.assertAlive();
268
68
  const crypto = deps.requireNip59Crypto();
269
69
  const self = await crypto.getPublicKey();
270
- deps.throwIfAborted(opts?.signal);
70
+ throwIfAborted(opts?.signal);
271
71
  await deps.hydrateGossip([self]);
272
- deps.throwIfAborted(opts?.signal);
72
+ throwIfAborted(opts?.signal);
273
73
  const relays = requireDmRelays(self, deps.gossip.dmRelays(self));
274
74
  const urls = /* @__PURE__ */ new Map();
275
75
  const events = await deps.pool.fetch(relays, [{
@@ -291,7 +91,7 @@ async function fetchPrivateMessages(deps, opts) {
291
91
  const rumor = await unwrap(crypto, wrap);
292
92
  const wrapUrls = urls.get(wrap.id);
293
93
  const firstUrl = wrapUrls?.values().next().value;
294
- if (deps.wantObserve(opts?.observe)) {
94
+ if (opts?.observe !== false) {
295
95
  deps.ingest(wrap, firstUrl);
296
96
  if (wrapUrls) {
297
97
  for (const url of wrapUrls) if (url !== firstUrl) deps.markSeen(wrap.id, url);
@@ -309,9 +109,9 @@ async function subscribePrivateMessages(deps, opts) {
309
109
  deps.assertAlive();
310
110
  const crypto = deps.requireNip59Crypto();
311
111
  const self = await crypto.getPublicKey();
312
- deps.throwIfAborted(opts?.signal);
112
+ throwIfAborted(opts?.signal);
313
113
  await deps.hydrateGossip([self]);
314
- deps.throwIfAborted(opts?.signal);
114
+ throwIfAborted(opts?.signal);
315
115
  const relays = requireDmRelays(self, deps.gossip.dmRelays(self));
316
116
  const seen = /* @__PURE__ */ new Set();
317
117
  const processed = /* @__PURE__ */ new Set();
@@ -323,13 +123,15 @@ async function subscribePrivateMessages(deps, opts) {
323
123
  pendingUrls.delete(wrapId);
324
124
  for (const url of extra) deps.markSeen(wrapId, url);
325
125
  };
326
- let tail = Promise.resolve();
126
+ const queue = new SerialQueue();
327
127
  let closed = false;
128
+ let disposeAbort;
328
129
  const markClosed = () => {
329
130
  closed = true;
131
+ disposeAbort?.();
330
132
  };
331
133
  if (opts?.signal?.aborted === true) markClosed();
332
- else opts?.signal?.addEventListener("abort", markClosed, { once: true });
134
+ else disposeAbort = onAbort(opts?.signal, markClosed);
333
135
  const inner = deps.pool.subscribe(relays, [{
334
136
  kinds: [Kind.GiftWrap, Kind.GiftWrapEphemeral],
335
137
  "#p": [self],
@@ -354,13 +156,7 @@ async function subscribePrivateMessages(deps, opts) {
354
156
  },
355
157
  onevent: (wrap, relayUrl) => {
356
158
  if (closed) return;
357
- const prev = tail;
358
- let release;
359
- tail = new Promise((resolve) => {
360
- release = resolve;
361
- });
362
- (async () => {
363
- await prev;
159
+ queue.run(async () => {
364
160
  try {
365
161
  if (closed) return;
366
162
  const rumor = await unwrap(crypto, wrap);
@@ -370,17 +166,15 @@ async function subscribePrivateMessages(deps, opts) {
370
166
  return;
371
167
  }
372
168
  seen.add(rumor.id);
373
- if (deps.wantObserve(opts?.observe)) deps.ingest(wrap, relayUrl);
169
+ if (opts?.observe !== false) deps.ingest(wrap, relayUrl);
374
170
  flushSeen(wrap.id);
375
171
  opts?.onevent?.({
376
172
  wrap,
377
173
  rumor,
378
174
  relayUrl
379
175
  });
380
- } catch {} finally {
381
- release?.();
382
- }
383
- })();
176
+ } catch {}
177
+ });
384
178
  }
385
179
  });
386
180
  return { close: (reason) => {
@@ -479,7 +273,7 @@ function mergeSyncSummary(into, other) {
479
273
  */
480
274
  async function syncToRelay(deps, url, filter, opts) {
481
275
  deps.assertAlive();
482
- deps.throwIfAborted(opts?.signal);
276
+ throwIfAborted(opts?.signal);
483
277
  const direction = opts?.direction ?? SyncDirection.Down;
484
278
  const canon = canonicalizeFilter(filter);
485
279
  const items = await deps.storage.negentropyItems(canon);
@@ -506,19 +300,22 @@ async function syncToRelay(deps, url, filter, opts) {
506
300
  await Promise.all(chunk.map(async (event) => {
507
301
  try {
508
302
  const results = await deps.pool.publish([url], event, { timeoutMs: opts?.timeoutMs });
509
- if (results.some((r) => r.result?.ok === true)) summary.sent.push(event.id);
510
- else summary.sendFailures[event.id] = results[0]?.error ?? results[0]?.result?.message ?? "publish failed";
303
+ if (results.some((r) => r.status === "ok")) summary.sent.push(event.id);
304
+ else {
305
+ const [first] = results;
306
+ summary.sendFailures[event.id] = first === void 0 ? "publish failed" : first.status === "failed" ? first.error : first.message;
307
+ }
511
308
  } catch (error) {
512
- summary.sendFailures[event.id] = error instanceof Error ? error.message : String(error);
309
+ summary.sendFailures[event.id] = errorMessage(error);
513
310
  }
514
311
  }));
515
312
  }
516
313
  }
517
314
  if ((direction === SyncDirection.Down || direction === SyncDirection.Both) && need.length > 0) {
518
- const shouldObserve = deps.wantObserve(opts?.observe);
315
+ const shouldObserve = opts?.observe !== false;
519
316
  for (let i = 0; i < need.length; i += SYNC_ID_BATCH) {
520
317
  const batch = need.slice(i, i + SYNC_ID_BATCH);
521
- deps.throwIfAborted(opts?.signal);
318
+ throwIfAborted(opts?.signal);
522
319
  const urlsById = /* @__PURE__ */ new Map();
523
320
  const events = await deps.pool.fetch([url], [{ ids: batch }], {
524
321
  timeoutMs: opts?.timeoutMs,
@@ -549,7 +346,7 @@ async function syncToRelay(deps, url, filter, opts) {
549
346
  try {
550
347
  results = await deps.storage.putMany(events);
551
348
  } catch (error) {
552
- const message = error instanceof Error ? error.message : String(error);
349
+ const message = errorMessage(error);
553
350
  for (const event of events) summary.persistFailures[event.id] = message;
554
351
  break;
555
352
  }
@@ -569,7 +366,7 @@ async function syncToRelay(deps, url, filter, opts) {
569
366
  */
570
367
  async function sync(deps, filter, opts) {
571
368
  deps.assertAlive();
572
- const urls = deps.defaultRelays(opts?.relays ? [...opts.relays] : void 0);
369
+ const urls = deps.defaultRelays(opts?.relays);
573
370
  const results = await Promise.allSettled(urls.map(async (url) => syncToRelay(deps, url, filter, opts)));
574
371
  let merged = emptySummary();
575
372
  let fulfilled = 0;
@@ -583,49 +380,42 @@ async function sync(deps, filter, opts) {
583
380
  }
584
381
  //#endregion
585
382
  //#region src/client/client.ts
383
+ function isFilterList(filter) {
384
+ return Array.isArray(filter);
385
+ }
386
+ function toFilterList(filter) {
387
+ return canonicalizeFilters(isFilterList(filter) ? filter : [filter]);
388
+ }
586
389
  /** Layer-5 facade: signer + default relays + pool + loaders + gossip + event store. */
587
- var Client = class Client {
390
+ var Client = class {
588
391
  pool;
589
392
  loaders;
590
393
  gossip;
591
394
  storage;
592
395
  index;
593
- onstorageerror;
594
396
  #signer;
595
397
  #relays;
596
398
  #shutdown = false;
597
399
  #persistEvents;
598
400
  #persistQueue = [];
599
401
  #flushing;
402
+ #listeners = { storageerror: /* @__PURE__ */ new Set() };
600
403
  constructor(opts = {}) {
601
- this.#signer = opts.signer;
404
+ const { signer, relays, automaticAuth, gossip, storage, index, persistEvents, ...poolOptions } = opts;
405
+ this.#signer = signer;
602
406
  this.#relays = [];
603
- for (const raw of opts.relays ?? []) {
407
+ for (const raw of relays ?? []) {
604
408
  const url = normalizeURL(raw);
605
409
  if (!this.#relays.includes(url)) this.#relays.push(url);
606
410
  }
607
- this.gossip = opts.gossip ?? new Gossip();
608
- this.storage = opts.storage ?? new MemoryEventStore();
609
- this.index = opts.index ?? new ReactiveEventStore();
610
- this.#persistEvents = opts.persistEvents ?? true;
611
- this.onstorageerror = opts.onstorageerror;
411
+ this.gossip = gossip ?? new Gossip();
412
+ this.storage = storage ?? new MemoryEventStore();
413
+ this.index = index ?? new ReactiveEventStore();
414
+ this.#persistEvents = persistEvents ?? true;
612
415
  this.pool = new Pool({
613
- websocketImplementation: opts.websocketImplementation,
614
- verifyEvent: opts.verifyEvent,
615
- enablePing: opts.enablePing,
616
- pingIntervalMs: opts.pingIntervalMs,
617
- pingTimeoutMs: opts.pingTimeoutMs,
618
- connectTimeoutMs: opts.connectTimeoutMs,
619
- publishTimeoutMs: opts.publishTimeoutMs,
620
- enableReconnect: opts.enableReconnect ?? true,
621
- allowInsecure: opts.allowInsecure,
622
- trustedInsecureUrls: opts.trustedInsecureUrls,
623
- idleTimeoutMs: opts.idleTimeoutMs,
624
- maxRelays: opts.maxRelays,
625
- pinnedUrls: opts.pinnedUrls,
626
- invalidEventPolicy: opts.invalidEventPolicy,
627
- onRelaySuspended: opts.onRelaySuspended,
628
- automaticallyAuth: opts.automaticAuth ?? true ? () => async (template) => {
416
+ ...poolOptions,
417
+ enableReconnect: poolOptions.enableReconnect ?? true,
418
+ automaticallyAuth: automaticAuth ?? true ? () => async (template) => {
629
419
  const signer = this.#signer;
630
420
  if (!signer) throw new NoSignerError("no signer configured for AUTH");
631
421
  const pk = await signer.getPublicKey();
@@ -642,9 +432,6 @@ var Client = class Client {
642
432
  ingest: (event, relayUrl) => this.#ingest(event, relayUrl)
643
433
  });
644
434
  }
645
- static builder() {
646
- return new ClientBuilder((opts) => new Client(opts));
647
- }
648
435
  get signer() {
649
436
  return this.#signer;
650
437
  }
@@ -681,6 +468,21 @@ var Client = class Client {
681
468
  while (this.#flushing !== void 0) await this.#flushing;
682
469
  this.pool.close();
683
470
  }
471
+ /**
472
+ * Listen for a client event. Multiple listeners per type are allowed and fire in registration
473
+ * order; a throwing listener is reported and does not break the dispatch. Returns an unsubscribe
474
+ * function.
475
+ */
476
+ on(type, listener) {
477
+ const set = this.#listeners[type];
478
+ set.add(listener);
479
+ return () => {
480
+ set.delete(listener);
481
+ };
482
+ }
483
+ #emit(type, err) {
484
+ for (const listener of [...this.#listeners[type]]) invokeSafely(() => listener(err));
485
+ }
684
486
  #assertAlive() {
685
487
  if (this.#shutdown) throw new ClientError("client is shut down");
686
488
  }
@@ -689,9 +491,6 @@ var Client = class Client {
689
491
  if (list.length === 0) throw new ClientError("no relays configured");
690
492
  return list;
691
493
  }
692
- #wantObserve(flag) {
693
- return flag !== false;
694
- }
695
494
  /** Ingest one inbound event: index (with relay URL) → meta → persistence. */
696
495
  observe(event, relayUrl) {
697
496
  this.#ingest(event, relayUrl);
@@ -713,18 +512,11 @@ var Client = class Client {
713
512
  */
714
513
  #ingest(event, relayUrl, opts) {
715
514
  this.index.add(event, relayUrl);
716
- if (opts?.meta !== false) this.#ingestMeta(event);
515
+ if (opts?.meta !== false) this.gossip.ingest(event);
717
516
  if (opts?.persist === false || !this.#persistEvents) return;
718
517
  this.#persistQueue.push(event);
719
518
  this.#armFlush();
720
519
  }
721
- /** Record a relay sighting for an id already in the index. */
722
- #markSeen(id, relayUrl) {
723
- this.index.markSeen(id, relayUrl);
724
- }
725
- #ingestMeta(event) {
726
- this.gossip.ingest(event);
727
- }
728
520
  #armFlush() {
729
521
  if (this.#flushing) return;
730
522
  this.#flushing = this.#flushLoop();
@@ -739,7 +531,7 @@ var Client = class Client {
739
531
  try {
740
532
  await this.storage.putMany(batch);
741
533
  } catch (error) {
742
- invokeSafely(() => this.onstorageerror?.(toStorageError(error)));
534
+ this.#emit("storageerror", toStorageError(error));
743
535
  }
744
536
  }
745
537
  } finally {
@@ -772,7 +564,7 @@ var Client = class Client {
772
564
  */
773
565
  outbox(opts) {
774
566
  this.#assertAlive();
775
- return createOutboxFeed({
567
+ return new OutboxFeed({
776
568
  pool: this.pool,
777
569
  gossip: this.gossip,
778
570
  storage: this.storage,
@@ -804,22 +596,24 @@ var Client = class Client {
804
596
  hydrate: async (pubkeys) => this.hydrateGossip(pubkeys)
805
597
  });
806
598
  }
599
+ #requireSigner() {
600
+ const signer = this.#signer;
601
+ if (!signer) throw new ClientError("no signer configured");
602
+ return signer;
603
+ }
807
604
  async getPublicKey() {
808
- if (!this.#signer) throw new ClientError("no signer configured");
809
- return this.#signer.getPublicKey();
605
+ return this.#requireSigner().getPublicKey();
810
606
  }
811
607
  async signEvent(unsigned) {
812
- if (!this.#signer) throw new ClientError("no signer configured");
813
- return this.#signer.signEvent(unsigned);
608
+ return this.#requireSigner().signEvent(unsigned);
814
609
  }
815
610
  async signEventBuilder(builder) {
816
- if (!this.#signer) throw new ClientError("no signer configured");
817
- return builder.sign(this.#signer);
611
+ return builder.sign(this.#requireSigner());
818
612
  }
819
613
  async signTemplate(template) {
820
- if (!this.#signer) throw new ClientError("no signer configured");
821
- const pubkey = await this.#signer.getPublicKey();
822
- return this.#signer.signEvent({
614
+ const signer = this.#requireSigner();
615
+ const pubkey = await signer.getPublicKey();
616
+ return signer.signEvent({
823
617
  ...template,
824
618
  pubkey
825
619
  });
@@ -856,7 +650,7 @@ var Client = class Client {
856
650
  if (urls.length > 0) relays = urls;
857
651
  }
858
652
  const results = await this.pool.publish(this.#defaultRelays(relays), event, { timeoutMs: opts?.timeoutMs });
859
- if (results.some((r) => r.result?.ok === true) && this.#wantObserve(opts?.observe)) this.observe(event);
653
+ if (results.some((r) => r.status === "ok") && opts?.observe !== false) this.observe(event);
860
654
  return results;
861
655
  }
862
656
  /**
@@ -865,8 +659,8 @@ var Client = class Client {
865
659
  */
866
660
  async fetchEvents(filter, opts) {
867
661
  this.#assertAlive();
868
- const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);
869
- const shouldObserve = this.#wantObserve(opts?.observe);
662
+ const filters = toFilterList(filter);
663
+ const shouldObserve = opts?.observe !== false;
870
664
  const candidates = [];
871
665
  if (opts?.localFirst === true) try {
872
666
  const local = await this.storage.query(filters);
@@ -878,7 +672,7 @@ var Client = class Client {
878
672
  });
879
673
  }
880
674
  } catch (error) {
881
- invokeSafely(() => this.onstorageerror?.(toStorageError(error)));
675
+ this.#emit("storageerror", toStorageError(error));
882
676
  }
883
677
  const onevent = (event, relayUrl) => {
884
678
  if (shouldObserve) this.#ingest(event, relayUrl, {
@@ -914,12 +708,12 @@ var Client = class Client {
914
708
  */
915
709
  async fetchEach(filter, opts) {
916
710
  this.#assertAlive();
917
- const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);
711
+ const filters = toFilterList(filter);
918
712
  const results = await this.pool.fetchEach(this.#defaultRelays(opts?.relays), filters, {
919
713
  timeoutMs: opts?.timeoutMs,
920
714
  signal: opts?.signal
921
715
  });
922
- if (this.#wantObserve(opts?.observe)) {
716
+ if (opts?.observe !== false) {
923
717
  const unique = [];
924
718
  const seen = /* @__PURE__ */ new Set();
925
719
  for (const result of results) for (const event of result.events) {
@@ -939,19 +733,19 @@ var Client = class Client {
939
733
  /** Query local storage only (no network). */
940
734
  async queryLocal(filter) {
941
735
  this.#assertAlive();
942
- const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);
736
+ const filters = toFilterList(filter);
943
737
  return this.storage.query(filters);
944
738
  }
945
739
  subscribe(filter, opts) {
946
740
  this.#assertAlive();
947
- const filters = canonicalizeFilters(Array.isArray(filter) ? filter : [filter]);
948
- const shouldObserve = this.#wantObserve(opts?.observe);
741
+ const filters = toFilterList(filter);
742
+ const shouldObserve = opts?.observe !== false;
949
743
  const wrapEvent = (event, relayUrl) => {
950
744
  if (shouldObserve) this.observe(event, relayUrl);
951
745
  opts?.onevent?.(event, relayUrl);
952
746
  };
953
747
  const wrapReceived = (id, relayUrl) => {
954
- if (shouldObserve) this.#markSeen(id, relayUrl);
748
+ if (shouldObserve) this.index.markSeen(id, relayUrl);
955
749
  opts?.receivedEvent?.(id, relayUrl);
956
750
  };
957
751
  if (opts?.gossip !== true || opts.relays !== void 0) return this.pool.subscribe(this.#defaultRelays(opts?.relays), filters, {
@@ -973,11 +767,7 @@ var Client = class Client {
973
767
  });
974
768
  }
975
769
  #requireNip59Crypto() {
976
- if (!this.#signer) throw new ClientError("no signer configured");
977
- return requireNip59Crypto(this.#signer);
978
- }
979
- #throwIfAborted(signal) {
980
- throwIfAborted(signal);
770
+ return requireNip59Crypto(this.#requireSigner());
981
771
  }
982
772
  #dmDeps() {
983
773
  return {
@@ -985,11 +775,11 @@ var Client = class Client {
985
775
  gossip: this.gossip,
986
776
  hydrateGossip: async (pubkeys) => this.hydrateGossip(pubkeys),
987
777
  ingest: (event, relayUrl) => this.#ingest(event, relayUrl),
988
- markSeen: (id, relayUrl) => this.#markSeen(id, relayUrl),
778
+ markSeen: (id, relayUrl) => {
779
+ this.index.markSeen(id, relayUrl);
780
+ },
989
781
  assertAlive: () => this.#assertAlive(),
990
782
  requireNip59Crypto: () => this.#requireNip59Crypto(),
991
- throwIfAborted: (signal) => this.#throwIfAborted(signal),
992
- wantObserve: (flag) => this.#wantObserve(flag),
993
783
  publish: async (eventOrBuilder, opts) => this.publish(eventOrBuilder, opts)
994
784
  };
995
785
  }
@@ -999,10 +789,10 @@ var Client = class Client {
999
789
  storage: this.storage,
1000
790
  persistEvents: this.#persistEvents,
1001
791
  assertAlive: () => this.#assertAlive(),
1002
- throwIfAborted: (signal) => this.#throwIfAborted(signal),
1003
- wantObserve: (flag) => this.#wantObserve(flag),
1004
792
  ingest: (event, relayUrl, opts) => this.#ingest(event, relayUrl, opts),
1005
- markSeen: (id, relayUrl) => this.#markSeen(id, relayUrl),
793
+ markSeen: (id, relayUrl) => {
794
+ this.index.markSeen(id, relayUrl);
795
+ },
1006
796
  defaultRelays: (urls) => this.#defaultRelays(urls)
1007
797
  };
1008
798
  }
@@ -1037,6 +827,6 @@ var Client = class Client {
1037
827
  }
1038
828
  };
1039
829
  //#endregion
1040
- export { ClientBuilder as i, ClientError as n, SyncDirection as r, Client as t };
830
+ export { ClientError as n, SyncDirection as r, Client as t };
1041
831
 
1042
- //# sourceMappingURL=client-BtIAtxrL.mjs.map
832
+ //# sourceMappingURL=client-CILhdfsF.mjs.map