@nostrify/nostrify 0.46.7 → 0.46.9

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 (154) hide show
  1. package/.turbo/turbo-build.log +121 -2
  2. package/.turbo/turbo-setup.log +13 -0
  3. package/.turbo/turbo-test.log +91 -0
  4. package/BunkerURI.test.ts +19 -14
  5. package/CHANGELOG.md +16 -0
  6. package/NBrowserSigner.test.ts +49 -34
  7. package/NCache.test.ts +14 -7
  8. package/NCache.ts +2 -2
  9. package/NConnectSigner.test.ts +48 -31
  10. package/NConnectSigner.ts +3 -3
  11. package/NIP05.test.ts +36 -44
  12. package/NIP05.ts +6 -6
  13. package/NIP50.test.ts +35 -34
  14. package/NIP98.test.ts +89 -76
  15. package/NIP98.ts +2 -2
  16. package/NKinds.test.ts +37 -36
  17. package/NPool.test.ts +35 -24
  18. package/NPool.ts +42 -23
  19. package/NRelay1.test.ts +100 -68
  20. package/NRelay1.ts +13 -6
  21. package/NSchema.test.ts +98 -56
  22. package/NSchema.ts +74 -37
  23. package/NSecSigner.test.ts +19 -10
  24. package/NSecSigner.ts +4 -3
  25. package/NSet.test.ts +123 -50
  26. package/NSet.ts +13 -6
  27. package/RelayError.test.ts +11 -10
  28. package/RelayError.ts +1 -1
  29. package/dist/NCache.d.ts +2 -2
  30. package/dist/NCache.d.ts.map +1 -1
  31. package/dist/NConnectSigner.d.ts +1 -1
  32. package/dist/NConnectSigner.d.ts.map +1 -1
  33. package/dist/NIP05.d.ts +1 -1
  34. package/dist/NIP05.d.ts.map +1 -1
  35. package/dist/NIP98.d.ts +1 -1
  36. package/dist/NIP98.d.ts.map +1 -1
  37. package/dist/NPool.d.ts +2 -2
  38. package/dist/NPool.d.ts.map +1 -1
  39. package/dist/NRelay1.d.ts +5 -4
  40. package/dist/NRelay1.d.ts.map +1 -1
  41. package/dist/NSchema.d.ts +1 -1
  42. package/dist/NSchema.d.ts.map +1 -1
  43. package/dist/NSecSigner.d.ts +1 -2
  44. package/dist/NSecSigner.d.ts.map +1 -1
  45. package/dist/NSet.d.ts +1 -1
  46. package/dist/NSet.d.ts.map +1 -1
  47. package/dist/RelayError.d.ts +1 -1
  48. package/dist/RelayError.d.ts.map +1 -1
  49. package/dist/ln/LNURL.d.ts +4 -4
  50. package/dist/ln/LNURL.d.ts.map +1 -1
  51. package/dist/ln/mod.d.ts +3 -3
  52. package/dist/mod.d.ts +14 -14
  53. package/dist/test/ErrorRelay.d.ts +1 -1
  54. package/dist/test/ErrorRelay.d.ts.map +1 -1
  55. package/dist/test/MockRelay.d.ts +3 -3
  56. package/dist/test/MockRelay.d.ts.map +1 -1
  57. package/dist/test/TestRelayServer.d.ts +6 -3
  58. package/dist/test/TestRelayServer.d.ts.map +1 -1
  59. package/dist/test/mod.d.ts +3 -3
  60. package/dist/test/mod.d.ts.map +1 -1
  61. package/dist/tsconfig.tsbuildinfo +1 -1
  62. package/dist/uploaders/BlossomUploader.d.ts +1 -1
  63. package/dist/uploaders/BlossomUploader.d.ts.map +1 -1
  64. package/dist/uploaders/NostrBuildUploader.d.ts +1 -2
  65. package/dist/uploaders/NostrBuildUploader.d.ts.map +1 -1
  66. package/dist/uploaders/mod.d.ts +2 -2
  67. package/dist/utils/CircularSet.d.ts +1 -1
  68. package/dist/utils/CircularSet.d.ts.map +1 -1
  69. package/dist/utils/N64.d.ts +1 -1
  70. package/dist/utils/N64.d.ts.map +1 -1
  71. package/dist/utils/mod.d.ts +2 -2
  72. package/ln/LNURL.test.ts +70 -52
  73. package/ln/LNURL.ts +15 -15
  74. package/ln/mod.ts +3 -3
  75. package/mod.ts +14 -14
  76. package/package.json +5 -3
  77. package/test/ErrorRelay.test.ts +11 -10
  78. package/test/ErrorRelay.ts +17 -5
  79. package/test/MockRelay.test.ts +15 -8
  80. package/test/MockRelay.ts +3 -3
  81. package/test/TestRelayServer.ts +46 -17
  82. package/test/mod.ts +4 -4
  83. package/tsconfig.json +5 -3
  84. package/uploaders/BlossomUploader.test.ts +39 -22
  85. package/uploaders/BlossomUploader.ts +2 -2
  86. package/uploaders/NostrBuildUploader.test.ts +36 -18
  87. package/uploaders/NostrBuildUploader.ts +4 -4
  88. package/uploaders/mod.ts +2 -2
  89. package/utils/CircularSet.test.ts +5 -4
  90. package/utils/CircularSet.ts +3 -1
  91. package/utils/Machina.test.ts +30 -19
  92. package/utils/N64.test.ts +12 -11
  93. package/utils/N64.ts +2 -2
  94. package/utils/mod.ts +2 -2
  95. package/dist/BunkerURI.js +0 -48
  96. package/dist/BunkerURI.js.map +0 -1
  97. package/dist/NBrowserSigner.js +0 -92
  98. package/dist/NBrowserSigner.js.map +0 -1
  99. package/dist/NCache.js +0 -60
  100. package/dist/NCache.js.map +0 -1
  101. package/dist/NConnectSigner.js +0 -125
  102. package/dist/NConnectSigner.js.map +0 -1
  103. package/dist/NIP05.js +0 -35
  104. package/dist/NIP05.js.map +0 -1
  105. package/dist/NIP50.js +0 -22
  106. package/dist/NIP50.js.map +0 -1
  107. package/dist/NIP98.js +0 -67
  108. package/dist/NIP98.js.map +0 -1
  109. package/dist/NKinds.js +0 -23
  110. package/dist/NKinds.js.map +0 -1
  111. package/dist/NPool.js +0 -181
  112. package/dist/NPool.js.map +0 -1
  113. package/dist/NRelay1.js +0 -332
  114. package/dist/NRelay1.js.map +0 -1
  115. package/dist/NSchema.js +0 -210
  116. package/dist/NSchema.js.map +0 -1
  117. package/dist/NSecSigner.js +0 -49
  118. package/dist/NSecSigner.js.map +0 -1
  119. package/dist/NSet.js +0 -171
  120. package/dist/NSet.js.map +0 -1
  121. package/dist/RelayError.js +0 -19
  122. package/dist/RelayError.js.map +0 -1
  123. package/dist/ln/LNURL.js +0 -101
  124. package/dist/ln/LNURL.js.map +0 -1
  125. package/dist/ln/mod.js +0 -2
  126. package/dist/ln/mod.js.map +0 -1
  127. package/dist/ln/types/LNURLCallback.js +0 -2
  128. package/dist/ln/types/LNURLCallback.js.map +0 -1
  129. package/dist/ln/types/LNURLDetails.js +0 -2
  130. package/dist/ln/types/LNURLDetails.js.map +0 -1
  131. package/dist/mod.js +0 -15
  132. package/dist/mod.js.map +0 -1
  133. package/dist/test/ErrorRelay.js +0 -22
  134. package/dist/test/ErrorRelay.js.map +0 -1
  135. package/dist/test/MockRelay.js +0 -62
  136. package/dist/test/MockRelay.js.map +0 -1
  137. package/dist/test/TestRelayServer.js +0 -130
  138. package/dist/test/TestRelayServer.js.map +0 -1
  139. package/dist/test/mod.js +0 -21
  140. package/dist/test/mod.js.map +0 -1
  141. package/dist/uploaders/BlossomUploader.js +0 -67
  142. package/dist/uploaders/BlossomUploader.js.map +0 -1
  143. package/dist/uploaders/NostrBuildUploader.js +0 -63
  144. package/dist/uploaders/NostrBuildUploader.js.map +0 -1
  145. package/dist/uploaders/mod.js +0 -3
  146. package/dist/uploaders/mod.js.map +0 -1
  147. package/dist/utils/CircularSet.js +0 -31
  148. package/dist/utils/CircularSet.js.map +0 -1
  149. package/dist/utils/Machina.js +0 -62
  150. package/dist/utils/Machina.js.map +0 -1
  151. package/dist/utils/N64.js +0 -19
  152. package/dist/utils/N64.js.map +0 -1
  153. package/dist/utils/mod.js +0 -3
  154. package/dist/utils/mod.js.map +0 -1
package/NIP98.test.ts CHANGED
@@ -1,181 +1,194 @@
1
- import { assertEquals, assertRejects } from '@std/assert';
2
- import { generateSecretKey } from 'nostr-tools';
3
- import { ZodError } from 'zod';
1
+ import { test } from "node:test";
2
+ import { deepStrictEqual, rejects } from "node:assert";
3
+ import { generateSecretKey } from "nostr-tools";
4
+ import { ZodError } from "zod";
4
5
 
5
- import { NIP98 } from './NIP98.ts';
6
- import { NSecSigner } from './NSecSigner.ts';
7
- import { N64 } from './utils/mod.ts';
6
+ import { NIP98 } from "./NIP98.ts";
7
+ import { NSecSigner } from "./NSecSigner.ts";
8
+ import { N64 } from "./utils/mod.ts";
8
9
 
9
- Deno.test('NIP98.template', async () => {
10
- const request = new Request('https://example.com');
10
+ await test("NIP98.template", async () => {
11
+ const request = new Request("https://example.com");
11
12
  const event = await NIP98.template(request);
12
13
 
13
- assertEquals(event.kind, 27235);
14
- assertEquals(event.tags, [
15
- ['method', 'GET'],
16
- ['u', 'https://example.com/'],
14
+ deepStrictEqual(event.kind, 27235);
15
+ deepStrictEqual(event.tags, [
16
+ ["method", "GET"],
17
+ ["u", "https://example.com/"],
17
18
  ]);
18
19
  });
19
20
 
20
- Deno.test('NIP98.template with payload', async () => {
21
- const request = new Request('https://example.com', {
22
- method: 'POST',
23
- body: 'Hello, world!',
21
+ await test("NIP98.template with payload", async () => {
22
+ const request = new Request("https://example.com", {
23
+ method: "POST",
24
+ body: "Hello, world!",
24
25
  });
25
26
  const event = await NIP98.template(request);
26
27
 
27
- assertEquals(event.kind, 27235);
28
- assertEquals(event.tags, [
29
- ['method', 'POST'],
30
- ['u', 'https://example.com/'],
31
- ['payload', '315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3'],
28
+ deepStrictEqual(event.kind, 27235);
29
+ deepStrictEqual(event.tags, [
30
+ ["method", "POST"],
31
+ ["u", "https://example.com/"],
32
+ [
33
+ "payload",
34
+ "315f5bdb76d078c43b8ac0064e4a0164612b1fce77c869345bfc94c75894edd3",
35
+ ],
32
36
  ]);
33
37
  });
34
38
 
35
- Deno.test('NIP98.verify', async () => {
39
+ await test("NIP98.verify", async () => {
36
40
  const signer = new NSecSigner(generateSecretKey());
37
- const request = new Request('https://example.com');
41
+ const request = new Request("https://example.com");
38
42
 
39
43
  const t = await NIP98.template(request);
40
44
  const event = await signer.signEvent(t);
41
45
 
42
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
46
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
43
47
 
44
48
  const proof = await NIP98.verify(request);
45
49
 
46
- assertEquals(proof, event);
47
- assertEquals(proof.pubkey, await signer.getPublicKey());
50
+ deepStrictEqual(proof, event);
51
+ deepStrictEqual(proof.pubkey, await signer.getPublicKey());
48
52
  });
49
53
 
50
- Deno.test('NIP98.verify fails with missing header', async () => {
51
- const request = new Request('https://example.com');
54
+ await test("NIP98.verify fails with missing header", async () => {
55
+ const request = new Request("https://example.com");
52
56
 
53
- await assertRejects(
57
+ await rejects(
54
58
  () => NIP98.verify(request),
55
59
  Error,
56
- 'Missing Nostr authorization header',
60
+ "Missing Nostr authorization header",
57
61
  );
58
62
  });
59
63
 
60
- Deno.test('NIP98.verify fails with missing token', async () => {
61
- const request = new Request('https://example.com');
62
- request.headers.set('authorization', 'Nostr');
64
+ await test("NIP98.verify fails with missing token", async () => {
65
+ const request = new Request("https://example.com");
66
+ request.headers.set("authorization", "Nostr");
63
67
 
64
- await assertRejects(
68
+ await rejects(
65
69
  () => NIP98.verify(request),
66
70
  Error,
67
- 'Missing Nostr authorization token',
71
+ "Missing Nostr authorization token",
68
72
  );
69
73
  });
70
74
 
71
- Deno.test('NIP98.verify fails with invalid token', async () => {
72
- const request = new Request('https://example.com');
73
- request.headers.set('authorization', 'Nostr invalid');
75
+ await test("NIP98.verify fails with invalid token", async () => {
76
+ const request = new Request("https://example.com");
77
+ request.headers.set("authorization", "Nostr invalid");
74
78
 
75
- await assertRejects(
79
+ await rejects(
76
80
  () => NIP98.verify(request),
77
81
  ZodError,
78
82
  );
79
83
  });
80
84
 
81
- Deno.test('NIP98.verify fails with invalid event', async () => {
85
+ await test("NIP98.verify fails with invalid event", async () => {
82
86
  const signer = new NSecSigner(generateSecretKey());
83
- const request = new Request('https://example.com');
87
+ const request = new Request("https://example.com");
84
88
 
85
89
  const t = await NIP98.template(request);
86
90
  const event = await signer.signEvent(t);
87
91
 
88
- event.sig = 'invalid';
92
+ event.sig = "invalid";
89
93
 
90
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
94
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
91
95
 
92
- await assertRejects(
96
+ await rejects(
93
97
  () => NIP98.verify(request),
94
98
  Error,
95
- 'Event signature is invalid',
99
+ "Event signature is invalid",
96
100
  );
97
101
  });
98
102
 
99
- Deno.test('NIP98.verify fails with wrong event kind', async () => {
103
+ await test("NIP98.verify fails with wrong event kind", async () => {
100
104
  const signer = new NSecSigner(generateSecretKey());
101
- const request = new Request('https://example.com');
105
+ const request = new Request("https://example.com");
102
106
 
103
107
  const t = await NIP98.template(request);
104
108
  const event = await signer.signEvent({ ...t, kind: 1 });
105
109
 
106
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
110
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
107
111
 
108
- await assertRejects(
112
+ await rejects(
109
113
  () => NIP98.verify(request),
110
114
  Error,
111
- 'Event must be kind 27235',
115
+ "Event must be kind 27235",
112
116
  );
113
117
  });
114
118
 
115
- Deno.test('NIP98.verify fails with wrong request URL', async () => {
119
+ await test("NIP98.verify fails with wrong request URL", async () => {
116
120
  const signer = new NSecSigner(generateSecretKey());
117
- const request = new Request('https://example.com');
121
+ const request = new Request("https://example.com");
118
122
 
119
123
  const t = await NIP98.template(request);
120
- const event = await signer.signEvent({ ...t, tags: [['u', 'https://example.org/']] });
124
+ const event = await signer.signEvent({
125
+ ...t,
126
+ tags: [["u", "https://example.org/"]],
127
+ });
121
128
 
122
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
129
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
123
130
 
124
- await assertRejects(
131
+ await rejects(
125
132
  () => NIP98.verify(request),
126
133
  Error,
127
- 'Event URL does not match request URL',
134
+ "Event URL does not match request URL",
128
135
  );
129
136
  });
130
137
 
131
- Deno.test('NIP98.verify fails with wrong request method', async () => {
138
+ await test("NIP98.verify fails with wrong request method", async () => {
132
139
  const signer = new NSecSigner(generateSecretKey());
133
- const request = new Request('https://example.com');
140
+ const request = new Request("https://example.com");
134
141
 
135
142
  const t = await NIP98.template(request);
136
- const event = await signer.signEvent({ ...t, tags: [['u', 'https://example.com/'], ['method', 'POST']] });
143
+ const event = await signer.signEvent({
144
+ ...t,
145
+ tags: [["u", "https://example.com/"], ["method", "POST"]],
146
+ });
137
147
 
138
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
148
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
139
149
 
140
- await assertRejects(
150
+ await rejects(
141
151
  () => NIP98.verify(request),
142
152
  Error,
143
- 'Event method does not match HTTP request method',
153
+ "Event method does not match HTTP request method",
144
154
  );
145
155
  });
146
156
 
147
- Deno.test('NIP98.verify fails with expired event', async () => {
157
+ await test("NIP98.verify fails with expired event", async () => {
148
158
  const signer = new NSecSigner(generateSecretKey());
149
- const request = new Request('https://example.com');
159
+ const request = new Request("https://example.com");
150
160
 
151
161
  const t = await NIP98.template(request);
152
162
  const event = await signer.signEvent({ ...t, created_at: 0 });
153
163
 
154
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
164
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
155
165
 
156
- await assertRejects(
166
+ await rejects(
157
167
  () => NIP98.verify(request),
158
168
  Error,
159
- 'Event expired',
169
+ "Event expired",
160
170
  );
161
171
  });
162
172
 
163
- Deno.test('NIP98.verify fails with invalid payload', async () => {
173
+ await test("NIP98.verify fails with invalid payload", async () => {
164
174
  const signer = new NSecSigner(generateSecretKey());
165
- const request = new Request('https://example.com', {
166
- method: 'POST',
167
- body: 'Hello, world!',
175
+ const request = new Request("https://example.com", {
176
+ method: "POST",
177
+ body: "Hello, world!",
168
178
  });
169
179
 
170
180
  const t = await NIP98.template(request);
171
- const tags = t.tags.filter(([name]) => name !== 'payload');
172
- const event = await signer.signEvent({ ...t, tags: [...tags, ['payload', 'invalid']] });
181
+ const tags = t.tags.filter(([name]) => name !== "payload");
182
+ const event = await signer.signEvent({
183
+ ...t,
184
+ tags: [...tags, ["payload", "invalid"]],
185
+ });
173
186
 
174
- request.headers.set('authorization', `Nostr ${N64.encodeEvent(event)}`);
187
+ request.headers.set("authorization", `Nostr ${N64.encodeEvent(event)}`);
175
188
 
176
- await assertRejects(
189
+ await rejects(
177
190
  () => NIP98.verify(request),
178
191
  Error,
179
- 'Event payload does not match request body',
192
+ "Event payload does not match request body",
180
193
  );
181
194
  });
package/NIP98.ts CHANGED
@@ -1,8 +1,8 @@
1
- import { NostrEvent } from '@nostrify/types';
1
+ import type { NostrEvent } from '@nostrify/types';
2
2
  import { encodeHex } from '@std/encoding/hex';
3
3
  import { verifyEvent as _verifyEvent } from 'nostr-tools';
4
4
 
5
- import { N64 } from './utils/N64.js';
5
+ import { N64 } from './utils/N64.ts';
6
6
 
7
7
  /** [NIP-98](https://github.com/nostr-protocol/nips/blob/master/98.md) HTTP auth. */
8
8
  export class NIP98 {
package/NKinds.test.ts CHANGED
@@ -1,42 +1,43 @@
1
- import { assertEquals } from '@std/assert';
1
+ import { test } from "node:test";
2
+ import { deepStrictEqual } from "node:assert";
2
3
 
3
- import { NKinds } from './NKinds.ts';
4
+ import { NKinds } from "./NKinds.ts";
4
5
 
5
- Deno.test('NKinds', () => {
6
- assertEquals(NKinds.regular(1000), true);
7
- assertEquals(NKinds.regular(10000), false);
8
- assertEquals(NKinds.regular(0), false);
9
- assertEquals(NKinds.regular(44), true);
10
- assertEquals(NKinds.regular(45), false);
11
- assertEquals(NKinds.regular(100000), false);
6
+ await test("NKinds", () => {
7
+ deepStrictEqual(NKinds.regular(1000), true);
8
+ deepStrictEqual(NKinds.regular(10000), false);
9
+ deepStrictEqual(NKinds.regular(0), false);
10
+ deepStrictEqual(NKinds.regular(44), true);
11
+ deepStrictEqual(NKinds.regular(45), false);
12
+ deepStrictEqual(NKinds.regular(100000), false);
12
13
 
13
- assertEquals(NKinds.replaceable(1000), false);
14
- assertEquals(NKinds.replaceable(10000), true);
15
- assertEquals(NKinds.replaceable(0), true);
16
- assertEquals(NKinds.replaceable(3), true);
17
- assertEquals(NKinds.replaceable(44), false);
18
- assertEquals(NKinds.replaceable(45), false);
19
- assertEquals(NKinds.replaceable(100000), false);
14
+ deepStrictEqual(NKinds.replaceable(1000), false);
15
+ deepStrictEqual(NKinds.replaceable(10000), true);
16
+ deepStrictEqual(NKinds.replaceable(0), true);
17
+ deepStrictEqual(NKinds.replaceable(3), true);
18
+ deepStrictEqual(NKinds.replaceable(44), false);
19
+ deepStrictEqual(NKinds.replaceable(45), false);
20
+ deepStrictEqual(NKinds.replaceable(100000), false);
20
21
 
21
- assertEquals(NKinds.ephemeral(1000), false);
22
- assertEquals(NKinds.ephemeral(10000), false);
23
- assertEquals(NKinds.ephemeral(0), false);
24
- assertEquals(NKinds.ephemeral(3), false);
25
- assertEquals(NKinds.ephemeral(44), false);
26
- assertEquals(NKinds.ephemeral(45), false);
27
- assertEquals(NKinds.ephemeral(20000), true);
28
- assertEquals(NKinds.ephemeral(30000), false);
29
- assertEquals(NKinds.ephemeral(40000), false);
30
- assertEquals(NKinds.ephemeral(100000), false);
22
+ deepStrictEqual(NKinds.ephemeral(1000), false);
23
+ deepStrictEqual(NKinds.ephemeral(10000), false);
24
+ deepStrictEqual(NKinds.ephemeral(0), false);
25
+ deepStrictEqual(NKinds.ephemeral(3), false);
26
+ deepStrictEqual(NKinds.ephemeral(44), false);
27
+ deepStrictEqual(NKinds.ephemeral(45), false);
28
+ deepStrictEqual(NKinds.ephemeral(20000), true);
29
+ deepStrictEqual(NKinds.ephemeral(30000), false);
30
+ deepStrictEqual(NKinds.ephemeral(40000), false);
31
+ deepStrictEqual(NKinds.ephemeral(100000), false);
31
32
 
32
- assertEquals(NKinds.addressable(1000), false);
33
- assertEquals(NKinds.addressable(10000), false);
34
- assertEquals(NKinds.addressable(0), false);
35
- assertEquals(NKinds.addressable(3), false);
36
- assertEquals(NKinds.addressable(44), false);
37
- assertEquals(NKinds.addressable(45), false);
38
- assertEquals(NKinds.addressable(20000), false);
39
- assertEquals(NKinds.addressable(30000), true);
40
- assertEquals(NKinds.addressable(40000), false);
41
- assertEquals(NKinds.addressable(100000), false);
33
+ deepStrictEqual(NKinds.addressable(1000), false);
34
+ deepStrictEqual(NKinds.addressable(10000), false);
35
+ deepStrictEqual(NKinds.addressable(0), false);
36
+ deepStrictEqual(NKinds.addressable(3), false);
37
+ deepStrictEqual(NKinds.addressable(44), false);
38
+ deepStrictEqual(NKinds.addressable(45), false);
39
+ deepStrictEqual(NKinds.addressable(20000), false);
40
+ deepStrictEqual(NKinds.addressable(30000), true);
41
+ deepStrictEqual(NKinds.addressable(40000), false);
42
+ deepStrictEqual(NKinds.addressable(100000), false);
42
43
  });
package/NPool.test.ts CHANGED
@@ -1,24 +1,25 @@
1
- import { NostrEvent } from '@nostrify/types';
2
- import { assert, assertEquals } from '@std/assert';
3
- import { finalizeEvent, generateSecretKey } from 'nostr-tools';
1
+ import { test } from "node:test";
2
+ import type { NostrEvent } from "@nostrify/types";
3
+ import { deepStrictEqual, ok } from "node:assert";
4
+ import { finalizeEvent, generateSecretKey } from "nostr-tools";
4
5
 
5
- import { NPool } from './NPool.ts';
6
- import { NRelay1 } from './NRelay1.ts';
6
+ import { NPool } from "./NPool.ts";
7
+ import { NRelay1 } from "./NRelay1.ts";
7
8
 
8
- import events from '../../fixtures/events.json' with { type: 'json' };
9
- import { TestRelayServer } from './test/TestRelayServer.ts';
9
+ import events from "../../fixtures/events.json" with { type: "json" };
10
+ import { TestRelayServer } from "./test/TestRelayServer.ts";
10
11
 
11
12
  const event1s = events
12
13
  .filter((e) => e.kind === 1)
13
14
  .toSorted((_) => 0.5 - Math.random())
14
15
  .slice(0, 10);
15
16
 
16
- Deno.test('NPool.query', async () => {
17
+ await test("NPool.query", async () => {
17
18
  const controller = new AbortController();
18
19
  const tid = setTimeout(() => controller.abort(), 5000);
19
20
 
20
- await using server1 = new TestRelayServer();
21
- await using server2 = new TestRelayServer();
21
+ await using server1 = await TestRelayServer.create();
22
+ await using server2 = await TestRelayServer.create();
22
23
 
23
24
  for (const event of event1s) {
24
25
  await server1.event(event);
@@ -37,18 +38,18 @@ Deno.test('NPool.query', async () => {
37
38
 
38
39
  const events = await pool.query([{ kinds: [1], limit: 15 }]);
39
40
 
40
- assertEquals(events.length, 10);
41
- assert(events[0].created_at >= events[1].created_at);
41
+ deepStrictEqual(events.length, 10);
42
+ ok(events[0].created_at >= events[1].created_at);
42
43
 
43
44
  clearTimeout(tid);
44
45
  });
45
46
 
46
- Deno.test('NPool.req', async () => {
47
+ await test("NPool.req", async () => {
47
48
  const controller = new AbortController();
48
49
  const tid = setTimeout(() => controller.abort(), 3000);
49
50
 
50
- await using server1 = new TestRelayServer();
51
- await using server2 = new TestRelayServer();
51
+ await using server1 = await TestRelayServer.create();
52
+ await using server2 = await TestRelayServer.create();
52
53
 
53
54
  for (const event of event1s) {
54
55
  await server1.event(event);
@@ -67,25 +68,29 @@ Deno.test('NPool.req', async () => {
67
68
  eventRouter: () => [server1.url],
68
69
  });
69
70
 
70
- for await (const msg of pool.req([{ kinds: [1], limit: 3 }], { signal: controller.signal })) {
71
- if (msg[0] === 'EVENT') {
71
+ for await (
72
+ const msg of pool.req([{ kinds: [1], limit: 3 }], {
73
+ signal: controller.signal,
74
+ })
75
+ ) {
76
+ if (msg[0] === "EVENT") {
72
77
  events.push(msg[2]);
73
78
  }
74
79
 
75
80
  if (events.length === 3) break;
76
81
  }
77
82
 
78
- assertEquals(events.length, 3);
83
+ deepStrictEqual(events.length, 3);
79
84
 
80
85
  clearTimeout(tid);
81
86
  });
82
87
 
83
- Deno.test('NPool.event', async () => {
88
+ await test("NPool.event", async () => {
84
89
  const controller = new AbortController();
85
90
  const tid = setTimeout(() => controller.abort(), 5000);
86
91
 
87
- await using server1 = new TestRelayServer();
88
- await using server2 = new TestRelayServer();
92
+ await using server1 = await TestRelayServer.create();
93
+ await using server2 = await TestRelayServer.create();
89
94
 
90
95
  for (const event of event1s) {
91
96
  await server1.event(event);
@@ -94,8 +99,9 @@ Deno.test('NPool.event', async () => {
94
99
 
95
100
  const event: NostrEvent = finalizeEvent({
96
101
  kind: 1,
97
- content: 'This is an automated test from Nostrify: https://gitlab.com/soapbox-pub/nostrify',
98
- tags: [['unique', 'uniqueTag']],
102
+ content:
103
+ "This is an automated test from Nostrify: https://gitlab.com/soapbox-pub/nostrify",
104
+ tags: [["unique", "uniqueTag"]],
99
105
  created_at: Math.floor(Date.now() / 1000),
100
106
  }, generateSecretKey());
101
107
 
@@ -111,7 +117,12 @@ Deno.test('NPool.event', async () => {
111
117
 
112
118
  await pool.event(event, { signal: controller.signal });
113
119
 
114
- assertEquals((await pool.query([{ kinds: [1], '#unique': ['uniqueTag'] }], { signal: controller.signal })).length, 1);
120
+ deepStrictEqual(
121
+ (await pool.query([{ kinds: [1], "#unique": ["uniqueTag"] }], {
122
+ signal: controller.signal,
123
+ })).length,
124
+ 1,
125
+ );
115
126
 
116
127
  clearTimeout(tid);
117
128
  });
package/NPool.ts CHANGED
@@ -1,9 +1,16 @@
1
- import { NostrEvent, NostrFilter, NostrRelayCLOSED, NostrRelayEOSE, NostrRelayEVENT, NRelay } from '@nostrify/types';
1
+ import type {
2
+ NostrEvent,
3
+ NostrFilter,
4
+ NostrRelayCLOSED,
5
+ NostrRelayEOSE,
6
+ NostrRelayEVENT,
7
+ NRelay,
8
+ } from '@nostrify/types';
2
9
  import { getFilterLimit } from 'nostr-tools';
3
10
 
4
- import { CircularSet } from './utils/CircularSet.js';
5
- import { Machina } from './utils/Machina.js';
6
- import { NSet } from './NSet.js';
11
+ import { CircularSet } from './utils/CircularSet.ts';
12
+ import { Machina } from './utils/Machina.ts';
13
+ import { NSet } from './NSet.ts';
7
14
 
8
15
  export interface NPoolOpts<T extends NRelay> {
9
16
  /** Creates an `NRelay` instance for the given URL. */
@@ -49,8 +56,11 @@ export interface NPoolOpts<T extends NRelay> {
49
56
  */
50
57
  export class NPool<T extends NRelay = NRelay> implements NRelay {
51
58
  private _relays = new Map<string, T>();
59
+ private opts: NPoolOpts<T>;
52
60
 
53
- constructor(private opts: NPoolOpts<T>) {}
61
+ constructor(opts: NPoolOpts<T>) {
62
+ this.opts = opts;
63
+ }
54
64
 
55
65
  /** Get or create a relay instance for the given URL. */
56
66
  public relay(url: string): T {
@@ -111,31 +121,38 @@ export class NPool<T extends NRelay = NRelay> implements NRelay {
111
121
  const closes = new Set<string>();
112
122
  const events = new CircularSet<string>(1000);
113
123
 
124
+ const relayPromises: Promise<void>[] = [];
125
+
114
126
  for (const [url, filters] of routes.entries()) {
115
127
  const relay = this.relay(url);
116
- (async () => {
117
- for await (const msg of relay.req(filters, { signal })) {
118
- if (msg[0] === 'EOSE') {
119
- eoses.add(url);
120
- if (eoses.size === routes.size) {
121
- machina.push(msg);
128
+ const relayPromise = (async () => {
129
+ try {
130
+ for await (const msg of relay.req(filters, { signal })) {
131
+ if (msg[0] === 'EOSE') {
132
+ eoses.add(url);
133
+ if (eoses.size === routes.size) {
134
+ machina.push(msg);
135
+ }
122
136
  }
123
- }
124
- if (msg[0] === 'CLOSED') {
125
- closes.add(url);
126
- if (closes.size === routes.size) {
127
- machina.push(msg);
137
+ if (msg[0] === 'CLOSED') {
138
+ closes.add(url);
139
+ if (closes.size === routes.size) {
140
+ machina.push(msg);
141
+ }
128
142
  }
129
- }
130
- if (msg[0] === 'EVENT') {
131
- const [, , event] = msg;
132
- if (!events.has(event.id)) {
133
- events.add(event.id);
134
- machina.push(msg);
143
+ if (msg[0] === 'EVENT') {
144
+ const [, , event] = msg;
145
+ if (!events.has(event.id)) {
146
+ events.add(event.id);
147
+ machina.push(msg);
148
+ }
135
149
  }
136
150
  }
151
+ } catch {
152
+ // Handle errors silently
137
153
  }
138
- })().catch(() => {});
154
+ })();
155
+ relayPromises.push(relayPromise);
139
156
  }
140
157
 
141
158
  try {
@@ -144,6 +161,8 @@ export class NPool<T extends NRelay = NRelay> implements NRelay {
144
161
  }
145
162
  } finally {
146
163
  controller.abort();
164
+ // Wait for all relay promises to complete to prevent hanging promises
165
+ await Promise.allSettled(relayPromises);
147
166
  }
148
167
  }
149
168