@estiva-app/protocol 0.2.0 → 0.4.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/CHANGELOG.md +66 -0
- package/dist/bridge.d.ts +62 -4
- package/dist/bridge.d.ts.map +1 -1
- package/dist/bridge.js +128 -24
- package/dist/bridge.js.map +1 -1
- package/dist/index.d.ts +3 -3
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/nip19.d.ts +35 -0
- package/dist/nip19.d.ts.map +1 -1
- package/dist/nip19.js +81 -3
- package/dist/nip19.js.map +1 -1
- package/package.json +1 -1
- package/src/bridge.ts +147 -25
- package/src/index.ts +6 -1
- package/src/nip19.ts +112 -0
package/CHANGELOG.md
CHANGED
|
@@ -4,6 +4,72 @@ Every entry answers the wire question explicitly, including when the answer is
|
|
|
4
4
|
nothing (ADR 0002 §4b). A change to the bytes an app publishes is a MAJOR — in
|
|
5
5
|
`0.x`, a MINOR — even when no TypeScript signature moved.
|
|
6
6
|
|
|
7
|
+
## 0.4.0 — 2026-09-01
|
|
8
|
+
|
|
9
|
+
**Wire behaviour: unchanged.** No builder, tag layout, id computation or
|
|
10
|
+
signature input moved. `queryAll` returns the same array it always did — see
|
|
11
|
+
below, that is the property the tests are about.
|
|
12
|
+
|
|
13
|
+
- **`queryAll` runs its filters concurrently**, bounded by the new
|
|
14
|
+
`DEFAULT_QUERY_CONCURRENCY` (8) and overridable per call via
|
|
15
|
+
`QueryAllOptions.concurrency`. `concurrency: 1` is the old serial read
|
|
16
|
+
exactly.
|
|
17
|
+
|
|
18
|
+
Filters handed to one call are independent; only the pages *inside* a filter
|
|
19
|
+
are a cursor walk, and those stay sequential because page N+1's `until` is
|
|
20
|
+
not known until page N has answered. Running the filters in sequence made a
|
|
21
|
+
read cost the sum of every filter's latency. Measured on Ship's `loadAll`
|
|
22
|
+
against production: **33 filters, 66 round trips, median 206 ms, 100% of wall
|
|
23
|
+
clock spent inside `query` one request at a time.** The same read, same relay,
|
|
24
|
+
same credentials, through this build: **9.0 s → 1.68 s, and the fold compares
|
|
25
|
+
equal event for event** — every project and issue address with its status,
|
|
26
|
+
every change id, every conversation id.
|
|
27
|
+
|
|
28
|
+
The concurrency is deliberately not observable in the answer. Results are
|
|
29
|
+
collected per filter and concatenated in filter order, and a failure reports
|
|
30
|
+
the **lowest-indexed** filter's error rather than whichever request lost the
|
|
31
|
+
race — so a broken read names the same filter twice running.
|
|
32
|
+
|
|
33
|
+
- **What this does not buy you: relay budget.** Buzz meters `POST /query`
|
|
34
|
+
against `human_api_calls_per_min` — a fixed 60-second window, default 300,
|
|
35
|
+
applied to every bridge call whatever tier the caller is. One Ship workspace
|
|
36
|
+
read is 66 of those. Concurrency changes when a read spends its requests,
|
|
37
|
+
never how many, so a poller that simply reads more often now spends the same
|
|
38
|
+
allowance sooner. Documented at `DEFAULT_QUERY_CONCURRENCY` because it is the
|
|
39
|
+
first thing a caller will get wrong.
|
|
40
|
+
|
|
41
|
+
Additive, and behaviour under a caller's existing call changes (requests now
|
|
42
|
+
overlap), so a MINOR: ADR 0002 §4b puts the break on MINOR within `0.x`.
|
|
43
|
+
|
|
44
|
+
## 0.3.0 — 2026-09-01
|
|
45
|
+
|
|
46
|
+
*Backfilled 2026-09-01. This release shipped without an entry, and so did 0.2.0
|
|
47
|
+
below — the file's own rule is that every release answers the wire question, and
|
|
48
|
+
twice it went unanswered. Recorded now from the release commits rather than left
|
|
49
|
+
as a gap.*
|
|
50
|
+
|
|
51
|
+
**Wire behaviour: unchanged.** NIP-19 is an encoding of a pointer, not of an
|
|
52
|
+
event; nothing an app publishes moved.
|
|
53
|
+
|
|
54
|
+
- **`nevent`** — `EventPointer`, `encodeNevent`, `decodeNevent`. An event that
|
|
55
|
+
is not addressable had no reference form at all, so a plain `kind:9` message
|
|
56
|
+
could be resolved by nothing. TLV type 0 carries the event id as 32 raw
|
|
57
|
+
bytes, where `naddr` carries a UTF-8 `d`; that difference is the whole of the
|
|
58
|
+
codec.
|
|
59
|
+
|
|
60
|
+
## 0.2.0 — 2026-08-28
|
|
61
|
+
|
|
62
|
+
*Backfilled 2026-09-01, from the release commit — see the note under 0.3.0.*
|
|
63
|
+
|
|
64
|
+
**Wire behaviour: unchanged.** A read-path fix; no published bytes moved.
|
|
65
|
+
|
|
66
|
+
- **`RELAY_PAGE_CEILING`, and `queryAll` pages instead of truncating.** Buzz
|
|
67
|
+
clamps a REQ to its advertised NIP-11 `max_limit`, which halved from 10000 to
|
|
68
|
+
1000, and NIP-01 has no truncation signal — so a caller asking for 2000 got
|
|
69
|
+
1000 and no indication why. `limit: 2000` was a literal at four call sites
|
|
70
|
+
across two apps and the agent, none of which could know when the relay changed
|
|
71
|
+
it.
|
|
72
|
+
|
|
7
73
|
## 0.1.2 — 2026-08-27
|
|
8
74
|
|
|
9
75
|
**Wire behaviour: unchanged.** One constant added. No builder, tag layout, id
|
package/dist/bridge.d.ts
CHANGED
|
@@ -37,6 +37,48 @@ export interface PublishResult {
|
|
|
37
37
|
* is the relay's real ceiling — see its note on why.
|
|
38
38
|
*/
|
|
39
39
|
export declare const RELAY_PAGE_CEILING = 1000;
|
|
40
|
+
/**
|
|
41
|
+
* How many of a {@link Relay.queryAll} call's filters may be in flight at once.
|
|
42
|
+
*
|
|
43
|
+
* Filters are independent — only paging *within* one is a cursor walk — and
|
|
44
|
+
* running them one after another made a read as slow as the sum of its parts.
|
|
45
|
+
* Measured on Ship's `loadAll` against production: **33 filters, 66 sequential
|
|
46
|
+
* round trips, median 206 ms, 100% of wall clock spent inside `query` one
|
|
47
|
+
* request at a time.** At a concurrency of 8 the same read returned a
|
|
48
|
+
* byte-identical answer in 1.9 s instead of 9.0 s.
|
|
49
|
+
*
|
|
50
|
+
* Bounded rather than unbounded on purpose. A workspace's filter count grows
|
|
51
|
+
* with its Folders, so `Promise.all` over all of them would open a fan-out
|
|
52
|
+
* whose width is set by the *data* — fine at 33, an accidental flood at 500,
|
|
53
|
+
* and the relay is shared. Eight is enough to hide the latency without any
|
|
54
|
+
* caller having to think about it.
|
|
55
|
+
*
|
|
56
|
+
* Pass `concurrency: 1` to restore the strictly serial read.
|
|
57
|
+
*
|
|
58
|
+
* ## This does not buy a caller more relay budget
|
|
59
|
+
*
|
|
60
|
+
* Concurrency changes how fast a read spends its requests, never how many it
|
|
61
|
+
* makes. Buzz meters `POST /query` against `human_api_calls_per_min` — a fixed
|
|
62
|
+
* 60-second window, **default 300, applied to every bridge call whatever tier
|
|
63
|
+
* the caller is** (`enforce_http_admission` in `api/bridge.rs` reads the human
|
|
64
|
+
* limit unconditionally). At 66 requests, one Ship workspace read is 22% of a
|
|
65
|
+
* minute's entire allowance, so no client gets more than ~4.5 of them a minute
|
|
66
|
+
* however it schedules them.
|
|
67
|
+
*
|
|
68
|
+
* A poller therefore has to slow down as its reads get faster, or it simply
|
|
69
|
+
* spends the same budget sooner and starts collecting
|
|
70
|
+
* `rate-limited: quota exceeded`. Making a read cheap is the fix for that;
|
|
71
|
+
* making it parallel is not.
|
|
72
|
+
*/
|
|
73
|
+
export declare const DEFAULT_QUERY_CONCURRENCY = 8;
|
|
74
|
+
export interface QueryAllOptions {
|
|
75
|
+
/** Events per request. Defaults to {@link RELAY_PAGE_CEILING}. */
|
|
76
|
+
pageSize?: number;
|
|
77
|
+
/** Give up after this many pages *per filter*, rather than looping forever. */
|
|
78
|
+
maxPages?: number;
|
|
79
|
+
/** Filters in flight at once. Defaults to {@link DEFAULT_QUERY_CONCURRENCY}; 1 is serial. */
|
|
80
|
+
concurrency?: number;
|
|
81
|
+
}
|
|
40
82
|
export declare function parsePublishResponse(status: number, text: string): PublishResult;
|
|
41
83
|
export interface QueryResult {
|
|
42
84
|
ok: boolean;
|
|
@@ -131,10 +173,26 @@ export declare class Relay {
|
|
|
131
173
|
* value of `until` reaches past them without skipping some, and no correct
|
|
132
174
|
* answer exists from this API — so it says so instead of returning a
|
|
133
175
|
* plausible subset.
|
|
176
|
+
*
|
|
177
|
+
* **Filters run concurrently, up to {@link DEFAULT_QUERY_CONCURRENCY}.** They
|
|
178
|
+
* are independent of one another; only the pages inside one are a cursor
|
|
179
|
+
* walk. Doing them in sequence made a read cost the sum of every filter's
|
|
180
|
+
* latency, which is what put Ship's workspace read at nine seconds against a
|
|
181
|
+
* five-second poll — long enough that a write's re-read had usually not
|
|
182
|
+
* finished before the next one began.
|
|
183
|
+
*
|
|
184
|
+
* The concurrency is deliberately **not observable in the answer**: results
|
|
185
|
+
* are collected per filter and concatenated in filter order, so the returned
|
|
186
|
+
* array is identical to the serial one, and a failure reports the
|
|
187
|
+
* lowest-indexed filter's error rather than whichever lost the race.
|
|
188
|
+
*/
|
|
189
|
+
queryAll(filters: Record<string, unknown>[], options?: QueryAllOptions): Promise<SignedEvent[]>;
|
|
190
|
+
/**
|
|
191
|
+
* One filter, paged to exhaustion. The sequential half, and it has to be:
|
|
192
|
+
* `until` is a cursor, so page N+1's request is not known until page N has
|
|
193
|
+
* answered. Only the filters are independent, which is why they are the
|
|
194
|
+
* axis {@link Relay.queryAll} parallelises.
|
|
134
195
|
*/
|
|
135
|
-
|
|
136
|
-
pageSize?: number;
|
|
137
|
-
maxPages?: number;
|
|
138
|
-
}): Promise<SignedEvent[]>;
|
|
196
|
+
private pageFilter;
|
|
139
197
|
}
|
|
140
198
|
//# sourceMappingURL=bridge.d.ts.map
|
package/dist/bridge.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AA2BA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAA;AAC9C,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,WAAW,CAAA;AAEvC,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,OAAO,CAAA;IACX,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,wDAAwD;IACxD,SAAS,CAAC,EAAE,OAAO,CAAA;IACnB,4EAA4E;IAC5E,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,eAAO,MAAM,kBAAkB,OAAO,CAAA;AAEtC,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,aAAa,CAehF;AAED,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,OAAO,CAAA;IACX,MAAM,EAAE,WAAW,EAAE,CAAA;IACrB,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB;AAED,wDAAwD;AACxD,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,WAAW,CAgB5E;AAED;;;;;;GAMG;AACH,MAAM,MAAM,SAAS,GAAG,CACtB,GAAG,EAAE,MAAM,EACX,IAAI,EAAE;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,KACpE,OAAO,CAAC;IAAE,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,IAAI,OAAO,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC,CAAA;AAKzD,4EAA4E;AAC5E,MAAM,MAAM,YAAY,GAAG,MAAM,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAA;AAEzF,MAAM,WAAW,YAAY;IAC3B;;;;;;;;;;;;;;OAcG;IACH,OAAO,CAAC,EAAE,YAAY,CAAA;IACtB,iEAAiE;IACjE,KAAK,CAAC,EAAE,SAAS,CAAA;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,KAAK;IAChB,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAQ;IAC5B,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAQ;IAC/B,OAAO,CAAC,QAAQ,CAAC,OAAO,CAAc;IACtC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAuB;gBAErC,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,YAAY,GAAG,YAAiB;YAWpE,IAAI;IAwBZ,OAAO,CAAC,KAAK,EAAE,WAAW,GAAG,OAAO,CAAC,aAAa,CAAC;IAKzD;;;;;;OAMG;IACG,KAAK,CAAC,OAAO,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,GAAG,OAAO,CAAC,WAAW,EAAE,CAAC;IAOvE
|
|
1
|
+
{"version":3,"file":"bridge.d.ts","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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"}
|
package/dist/bridge.js
CHANGED
|
@@ -53,6 +53,40 @@ import { authorizationHeader } from './nip98.js';
|
|
|
53
53
|
* is the relay's real ceiling — see its note on why.
|
|
54
54
|
*/
|
|
55
55
|
export const RELAY_PAGE_CEILING = 1000;
|
|
56
|
+
/**
|
|
57
|
+
* How many of a {@link Relay.queryAll} call's filters may be in flight at once.
|
|
58
|
+
*
|
|
59
|
+
* Filters are independent — only paging *within* one is a cursor walk — and
|
|
60
|
+
* running them one after another made a read as slow as the sum of its parts.
|
|
61
|
+
* Measured on Ship's `loadAll` against production: **33 filters, 66 sequential
|
|
62
|
+
* round trips, median 206 ms, 100% of wall clock spent inside `query` one
|
|
63
|
+
* request at a time.** At a concurrency of 8 the same read returned a
|
|
64
|
+
* byte-identical answer in 1.9 s instead of 9.0 s.
|
|
65
|
+
*
|
|
66
|
+
* Bounded rather than unbounded on purpose. A workspace's filter count grows
|
|
67
|
+
* with its Folders, so `Promise.all` over all of them would open a fan-out
|
|
68
|
+
* whose width is set by the *data* — fine at 33, an accidental flood at 500,
|
|
69
|
+
* and the relay is shared. Eight is enough to hide the latency without any
|
|
70
|
+
* caller having to think about it.
|
|
71
|
+
*
|
|
72
|
+
* Pass `concurrency: 1` to restore the strictly serial read.
|
|
73
|
+
*
|
|
74
|
+
* ## This does not buy a caller more relay budget
|
|
75
|
+
*
|
|
76
|
+
* Concurrency changes how fast a read spends its requests, never how many it
|
|
77
|
+
* makes. Buzz meters `POST /query` against `human_api_calls_per_min` — a fixed
|
|
78
|
+
* 60-second window, **default 300, applied to every bridge call whatever tier
|
|
79
|
+
* the caller is** (`enforce_http_admission` in `api/bridge.rs` reads the human
|
|
80
|
+
* limit unconditionally). At 66 requests, one Ship workspace read is 22% of a
|
|
81
|
+
* minute's entire allowance, so no client gets more than ~4.5 of them a minute
|
|
82
|
+
* however it schedules them.
|
|
83
|
+
*
|
|
84
|
+
* A poller therefore has to slow down as its reads get faster, or it simply
|
|
85
|
+
* spends the same budget sooner and starts collecting
|
|
86
|
+
* `rate-limited: quota exceeded`. Making a read cheap is the fix for that;
|
|
87
|
+
* making it parallel is not.
|
|
88
|
+
*/
|
|
89
|
+
export const DEFAULT_QUERY_CONCURRENCY = 8;
|
|
56
90
|
export function parsePublishResponse(status, text) {
|
|
57
91
|
let parsed;
|
|
58
92
|
try {
|
|
@@ -178,38 +212,108 @@ export class Relay {
|
|
|
178
212
|
* value of `until` reaches past them without skipping some, and no correct
|
|
179
213
|
* answer exists from this API — so it says so instead of returning a
|
|
180
214
|
* plausible subset.
|
|
215
|
+
*
|
|
216
|
+
* **Filters run concurrently, up to {@link DEFAULT_QUERY_CONCURRENCY}.** They
|
|
217
|
+
* are independent of one another; only the pages inside one are a cursor
|
|
218
|
+
* walk. Doing them in sequence made a read cost the sum of every filter's
|
|
219
|
+
* latency, which is what put Ship's workspace read at nine seconds against a
|
|
220
|
+
* five-second poll — long enough that a write's re-read had usually not
|
|
221
|
+
* finished before the next one began.
|
|
222
|
+
*
|
|
223
|
+
* The concurrency is deliberately **not observable in the answer**: results
|
|
224
|
+
* are collected per filter and concatenated in filter order, so the returned
|
|
225
|
+
* array is identical to the serial one, and a failure reports the
|
|
226
|
+
* lowest-indexed filter's error rather than whichever lost the race.
|
|
181
227
|
*/
|
|
182
228
|
async queryAll(filters, options = {}) {
|
|
183
229
|
const pageSize = options.pageSize ?? RELAY_PAGE_CEILING;
|
|
184
230
|
const maxPages = options.maxPages ?? 100;
|
|
185
|
-
const
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
231
|
+
const concurrency = Math.max(1, options.concurrency ?? DEFAULT_QUERY_CONCURRENCY);
|
|
232
|
+
/*
|
|
233
|
+
Per filter, in filter order — not one shared accumulator.
|
|
234
|
+
|
|
235
|
+
Concurrency must not be observable in the answer. Collecting each
|
|
236
|
+
filter's pages into its own slot and concatenating in order at the end
|
|
237
|
+
makes the output byte-identical to the serial version, whatever order the
|
|
238
|
+
responses actually arrive in. Dedup then runs over that ordered
|
|
239
|
+
concatenation, so an id first seen under filter 0 still belongs to filter
|
|
240
|
+
0's run of events, exactly as before.
|
|
241
|
+
*/
|
|
242
|
+
const perFilter = new Array(filters.length);
|
|
243
|
+
const failures = new Array(filters.length);
|
|
244
|
+
let next = 0;
|
|
245
|
+
let failed = false;
|
|
246
|
+
const worker = async () => {
|
|
247
|
+
for (;;) {
|
|
248
|
+
// Stop *starting* filters once one has failed. The serial version never
|
|
249
|
+
// reached them at all; this is as close as a fan-out gets, and it keeps
|
|
250
|
+
// a broken read from firing the whole remaining queue at the relay.
|
|
251
|
+
if (failed)
|
|
252
|
+
return;
|
|
253
|
+
const index = next++;
|
|
254
|
+
if (index >= filters.length)
|
|
255
|
+
return;
|
|
256
|
+
try {
|
|
257
|
+
perFilter[index] = await this.pageFilter(filters[index], pageSize, maxPages);
|
|
192
258
|
}
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
break;
|
|
198
|
-
for (const e of events) {
|
|
199
|
-
if (seen.has(e.id))
|
|
200
|
-
continue;
|
|
201
|
-
seen.add(e.id);
|
|
202
|
-
out.push(e);
|
|
259
|
+
catch (error) {
|
|
260
|
+
failures[index] = error;
|
|
261
|
+
failed = true;
|
|
262
|
+
return;
|
|
203
263
|
}
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
264
|
+
}
|
|
265
|
+
};
|
|
266
|
+
await Promise.all(Array.from({ length: Math.min(concurrency, filters.length) }, () => worker()));
|
|
267
|
+
/*
|
|
268
|
+
The lowest-indexed failure, not the first to reject in wall-clock time.
|
|
269
|
+
|
|
270
|
+
Under `Promise.all` the error a caller sees would otherwise depend on
|
|
271
|
+
which request happened to lose the race, so two runs of the same broken
|
|
272
|
+
read could report different filters. Serial order is the one order that
|
|
273
|
+
is reproducible, and it is what the serial version reported.
|
|
274
|
+
*/
|
|
275
|
+
const firstFailure = failures.findIndex((error) => error !== undefined);
|
|
276
|
+
if (firstFailure !== -1)
|
|
277
|
+
throw failures[firstFailure];
|
|
278
|
+
const seen = new Set();
|
|
279
|
+
const out = [];
|
|
280
|
+
for (const events of perFilter) {
|
|
281
|
+
for (const e of events) {
|
|
282
|
+
if (seen.has(e.id))
|
|
283
|
+
continue;
|
|
284
|
+
seen.add(e.id);
|
|
285
|
+
out.push(e);
|
|
286
|
+
}
|
|
287
|
+
}
|
|
288
|
+
return out;
|
|
289
|
+
}
|
|
290
|
+
/**
|
|
291
|
+
* One filter, paged to exhaustion. The sequential half, and it has to be:
|
|
292
|
+
* `until` is a cursor, so page N+1's request is not known until page N has
|
|
293
|
+
* answered. Only the filters are independent, which is why they are the
|
|
294
|
+
* axis {@link Relay.queryAll} parallelises.
|
|
295
|
+
*/
|
|
296
|
+
async pageFilter(filter, pageSize, maxPages) {
|
|
297
|
+
const out = [];
|
|
298
|
+
let until;
|
|
299
|
+
for (let page = 0;; page++) {
|
|
300
|
+
if (page >= maxPages) {
|
|
301
|
+
throw new Error(`queryAll: gave up after ${maxPages} pages — refusing to return a partial set`);
|
|
302
|
+
}
|
|
303
|
+
const events = await this.query([
|
|
304
|
+
{ ...filter, limit: pageSize, ...(until === undefined ? {} : { until }) },
|
|
305
|
+
]);
|
|
306
|
+
if (events.length === 0)
|
|
307
|
+
break;
|
|
308
|
+
out.push(...events);
|
|
309
|
+
const oldest = Math.min(...events.map((e) => e.created_at));
|
|
310
|
+
if (until !== undefined && oldest >= until) {
|
|
311
|
+
if (events.length >= pageSize) {
|
|
312
|
+
throw new Error(`queryAll: more than ${pageSize} events share created_at=${until} — cannot page without skipping`);
|
|
210
313
|
}
|
|
211
|
-
|
|
314
|
+
break;
|
|
212
315
|
}
|
|
316
|
+
until = oldest;
|
|
213
317
|
}
|
|
214
318
|
return out;
|
|
215
319
|
}
|
package/dist/bridge.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"bridge.js","sourceRoot":"","sources":["../src/bridge.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AACH,OAAO,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAchD;;;;;;;;GAQG;AACH;;;;;;;;;;;;;;;;;GAiBG;AACH,MAAM,CAAC,MAAM,kBAAkB,GAAG,IAAI,CAAA;AAEtC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AACH,MAAM,CAAC,MAAM,yBAAyB,GAAG,CAAC,CAAA;AAW1C,MAAM,UAAU,oBAAoB,CAAC,MAAc,EAAE,IAAY;IAC/D,IAAI,MAAmF,CAAA;IACvF,IAAI,CAAC;QACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IAC3B,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,yBAAyB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;IACjG,CAAC;IACD,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAClC,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,CAAC,KAAK,IAAI,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;IACtF,CAAC;IACD,IAAI,MAAM,CAAC,QAAQ,KAAK,KAAK,EAAE,CAAC;QAC9B,MAAM,SAAS,GAAG,CAAC,MAAM,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,UAAU,CAAC,YAAY,CAAC,CAAA;QACjE,OAAO,EAAE,EAAE,EAAE,SAAS,EAAE,SAAS,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,CAAC,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;IAC3G,CAAC;IACD,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,OAAO,EAAE,MAAM,CAAC,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;AACnE,CAAC;AASD,wDAAwD;AACxD,MAAM,UAAU,kBAAkB,CAAC,MAAc,EAAE,IAAY;IAC7D,IAAI,MAAM,GAAG,GAAG,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAClC,IAAI,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;QAC/B,IAAI,CAAC;YACH,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC,KAAK,IAAI,MAAM,CAAA;QAC3C,CAAC;QAAC,MAAM,CAAC;YACP,oBAAoB;QACtB,CAAC;QACD,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;IAC9D,CAAC;IACD,IAAI,CAAC;QACH,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;QAC/B,OAAO,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;IACtF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,yBAAyB,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,GAAG,CAAC,EAAE,EAAE,UAAU,EAAE,MAAM,EAAE,CAAA;IAC7G,CAAC;AACH,CAAC;AAyCD;;;;;;GAMG;AACH,MAAM,OAAO,KAAK;IACC,GAAG,CAAQ;IACX,MAAM,CAAQ;IACd,OAAO,CAAc;IACrB,SAAS,CAAuB;IAEjD,YAAY,GAAW,EAAE,MAAc,EAAE,UAAuC,EAAE;QAChF,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAA;QAClC,IAAI,CAAC,MAAM,GAAG,MAAM,CAAA;QACpB,0EAA0E;QAC1E,4EAA4E;QAC5E,iCAAiC;QACjC,MAAM,IAAI,GAAiB,OAAO,OAAO,KAAK,UAAU,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,CAAC,CAAC,CAAC,OAAO,CAAA;QACzF,IAAI,CAAC,OAAO,GAAG,IAAI,CAAC,OAAO,IAAI,CAAC,GAAG,EAAE,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;QAC3C,IAAI,CAAC,SAAS,GAAG,IAAI,CAAC,KAAK,CAAA;IAC7B,CAAC;IAEO,KAAK,CAAC,IAAI,CAAC,IAAY,EAAE,OAAgB;QAC/C,MAAM,GAAG,GAAG,GAAG,IAAI,CAAC,GAAG,GAAG,IAAI,EAAE,CAAA;QAChC,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,IAAI,GAAG,MAAM,mBAAmB,CAAC,IAAI,CAAC,MAAM,EAAE,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,CAAC,CAAA;QAClF,MAAM,IAAI,GAAG,IAAI,CAAC,SAAS,IAAI,KAAK,CAAA;QACpC,MAAM,GAAG,GAAG,MAAM,IAAI,CAAC,GAAG,EAAE;YAC1B,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,cAAc,EAAE,kBAAkB;gBAClC,GAAG,CAAC,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;gBACzB,yEAAyE;gBACzE,yEAAyE;gBACzE,6DAA6D;gBAC7D,EAAE;gBACF,oEAAoE;gBACpE,kEAAkE;gBAClE,oDAAoD;gBACpD,aAAa,EAAE,IAAI;aACpB;YACD,IAAI;SACL,CAAC,CAAA;QACF,OAAO,EAAE,MAAM,EAAE,GAAG,CAAC,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,CAAC,IAAI,EAAE,EAAE,CAAA;IACvD,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,KAAkB;QAC9B,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,CAAA;QAC1D,OAAO,oBAAoB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;IAC3C,CAAC;IAED;;;;;;OAMG;IACH,KAAK,CAAC,KAAK,CAAC,OAAkC;QAC5C,MAAM,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAA;QAC3D,MAAM,MAAM,GAAG,kBAAkB,CAAC,MAAM,EAAE,IAAI,CAAC,CAAA;QAC/C,IAAI,CAAC,MAAM,CAAC,EAAE;YAAE,MAAM,IAAI,KAAK,CAAC,iBAAiB,MAAM,CAAC,MAAM,EAAE,CAAC,CAAA;QACjE,OAAO,MAAM,CAAC,MAAM,CAAA;IACtB,CAAC;IAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAqCG;IACH,KAAK,CAAC,QAAQ,CACZ,OAAkC,EAClC,UAA2B,EAAE;QAE7B,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,kBAAkB,CAAA;QACvD,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,IAAI,GAAG,CAAA;QACxC,MAAM,WAAW,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,OAAO,CAAC,WAAW,IAAI,yBAAyB,CAAC,CAAA;QAEjF;;;;;;;;;UASE;QACF,MAAM,SAAS,GAAoB,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAC5D,MAAM,QAAQ,GAAc,IAAI,KAAK,CAAC,OAAO,CAAC,MAAM,CAAC,CAAA;QAErD,IAAI,IAAI,GAAG,CAAC,CAAA;QACZ,IAAI,MAAM,GAAG,KAAK,CAAA;QAElB,MAAM,MAAM,GAAG,KAAK,IAAmB,EAAE;YACvC,SAAS,CAAC;gBACR,wEAAwE;gBACxE,wEAAwE;gBACxE,oEAAoE;gBACpE,IAAI,MAAM;oBAAE,OAAM;gBAClB,MAAM,KAAK,GAAG,IAAI,EAAE,CAAA;gBACpB,IAAI,KAAK,IAAI,OAAO,CAAC,MAAM;oBAAE,OAAM;gBACnC,IAAI,CAAC;oBACH,SAAS,CAAC,KAAK,CAAC,GAAG,MAAM,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,KAAK,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAA;gBAC9E,CAAC;gBAAC,OAAO,KAAK,EAAE,CAAC;oBACf,QAAQ,CAAC,KAAK,CAAC,GAAG,KAAK,CAAA;oBACvB,MAAM,GAAG,IAAI,CAAA;oBACb,OAAM;gBACR,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QAED,MAAM,OAAO,CAAC,GAAG,CACf,KAAK,CAAC,IAAI,CAAC,EAAE,MAAM,EAAE,IAAI,CAAC,GAAG,CAAC,WAAW,EAAE,OAAO,CAAC,MAAM,CAAC,EAAE,EAAE,GAAG,EAAE,CAAC,MAAM,EAAE,CAAC,CAC9E,CAAA;QAED;;;;;;;UAOE;QACF,MAAM,YAAY,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,KAAK,SAAS,CAAC,CAAA;QACvE,IAAI,YAAY,KAAK,CAAC,CAAC;YAAE,MAAM,QAAQ,CAAC,YAAY,CAAC,CAAA;QAErD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;QAC9B,MAAM,GAAG,GAAkB,EAAE,CAAA;QAC7B,KAAK,MAAM,MAAM,IAAI,SAAS,EAAE,CAAC;YAC/B,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;gBACvB,IAAI,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC;oBAAE,SAAQ;gBAC5B,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAA;gBACd,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAA;YACb,CAAC;QACH,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;IAED;;;;;OAKG;IACK,KAAK,CAAC,UAAU,CACtB,MAA+B,EAC/B,QAAgB,EAChB,QAAgB;QAEhB,MAAM,GAAG,GAAkB,EAAE,CAAA;QAC7B,IAAI,KAAyB,CAAA;QAC7B,KAAK,IAAI,IAAI,GAAG,CAAC,GAAI,IAAI,EAAE,EAAE,CAAC;YAC5B,IAAI,IAAI,IAAI,QAAQ,EAAE,CAAC;gBACrB,MAAM,IAAI,KAAK,CACb,2BAA2B,QAAQ,2CAA2C,CAC/E,CAAA;YACH,CAAC;YACD,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,KAAK,CAAC;gBAC9B,EAAE,GAAG,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,GAAG,CAAC,KAAK,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,EAAE;aAC1E,CAAC,CAAA;YACF,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC;gBAAE,MAAK;YAC9B,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,CAAC,CAAA;YACnB,MAAM,MAAM,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,CAAA;YAC3D,IAAI,KAAK,KAAK,SAAS,IAAI,MAAM,IAAI,KAAK,EAAE,CAAC;gBAC3C,IAAI,MAAM,CAAC,MAAM,IAAI,QAAQ,EAAE,CAAC;oBAC9B,MAAM,IAAI,KAAK,CACb,uBAAuB,QAAQ,4BAA4B,KAAK,iCAAiC,CAClG,CAAA;gBACH,CAAC;gBACD,MAAK;YACP,CAAC;YACD,KAAK,GAAG,MAAM,CAAA;QAChB,CAAC;QACD,OAAO,GAAG,CAAA;IACZ,CAAC;CACF"}
|
package/dist/index.d.ts
CHANGED
|
@@ -46,12 +46,12 @@
|
|
|
46
46
|
/** Bumped by hand with the version in package.json — `test/version.test.ts`
|
|
47
47
|
* pins the two together. It exists so "the upgrade reached the app" can be
|
|
48
48
|
* checked by grepping a built bundle rather than by trusting a lockfile. */
|
|
49
|
-
export declare const PROTOCOL_VERSION = "0.
|
|
49
|
+
export declare const PROTOCOL_VERSION = "0.4.0";
|
|
50
50
|
export { type NostrTag, type UnsignedEvent, type SignedEvent, type Profile, type ThreadRef, type ChannelVisibility, type ChannelKind, type MemberRole, type Label, type ResolutionAction, KIND, MAX_EMOJI_CHARS, MAX_MESSAGE_BYTES, MAX_MENTIONS, MAX_RATIONALE_BYTES, RELAY_AUTH_TOLERANCE_SECS, ASSERTION_SUBTYPE, computeEventId, toNostrSeconds, canonicalChannelName, threadTags, addr, relayAuthUrl, buildProfile, parseProfile, buildCreateChannel, buildDeleteChannel, buildEditChannelMetadata, buildAddMember, buildReaction, buildDeletion, buildMessage, buildResolution, buildFile, buildComponent, buildHighlight, buildUnsignedRelayAuthEvent, } from './events.js';
|
|
51
|
-
export { type AddressPointer, convertBits, bech32Encode, bech32Decode, encodeNaddr, decodeNaddr, pointerToAddress, addressToPointer, addrToNaddr, naddrToAddr, referenceToPointer, NADDR_RE, findNaddrs, stripNaddrs, } from './nip19.js';
|
|
51
|
+
export { type AddressPointer, type EventPointer, encodeNevent, decodeNevent, convertBits, bech32Encode, bech32Decode, encodeNaddr, decodeNaddr, pointerToAddress, addressToPointer, addrToNaddr, naddrToAddr, referenceToPointer, NADDR_RE, findNaddrs, stripNaddrs, } from './nip19.js';
|
|
52
52
|
export { type AuthEventArgs, TIMESTAMP_TOLERANCE_SECS, normalizeUrl, buildUnsignedAuthEvent, base64, authorizationHeaderFor, authorizationHeader, } from './nip98.js';
|
|
53
53
|
export { type Signer, type SignerKind, publicKeyFromSecret, signEvent, secretKeySigner, } from './sign.js';
|
|
54
|
-
export { type PublishResult, type QueryResult, type RelayHeaders, type RelayOptions, type FetchLike, parsePublishResponse, parseQueryResponse, RELAY_PAGE_CEILING, Relay, } from './bridge.js';
|
|
54
|
+
export { type PublishResult, type QueryResult, type RelayHeaders, type RelayOptions, type FetchLike, type QueryAllOptions, parsePublishResponse, parseQueryResponse, RELAY_PAGE_CEILING, DEFAULT_QUERY_CONCURRENCY, Relay, } from './bridge.js';
|
|
55
55
|
export { type RelayState, type SocketLike, type RelayCredential, type LiveRelayOptions, type Subscription, type LiveRelay, toWebSocketUrl, parseFrame, createLiveRelay, } from './live.js';
|
|
56
56
|
export { type ChannelEventHandler, type ChannelSubscription, type ChannelSubscriptions, createChannelSubscriptions, } from './subscriptions.js';
|
|
57
57
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;4EAE4E;AAC5E,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,KAAK,EACV,KAAK,gBAAgB,EAErB,IAAI,EACJ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB,EAEjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,IAAI,EACJ,YAAY,EAEZ,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,2BAA2B,GAC5B,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,KAAK,cAAc,EACnB,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,aAAa,EAClB,wBAAwB,EACxB,YAAY,EACZ,sBAAsB,EACtB,MAAM,EACN,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,MAAM,EACX,KAAK,UAAU,EACf,mBAAmB,EACnB,SAAS,EACT,eAAe,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,KAAK,GACN,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,cAAc,EACd,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;4EAE4E;AAC5E,eAAO,MAAM,gBAAgB,UAAU,CAAA;AAEvC,OAAO,EAEL,KAAK,QAAQ,EACb,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,OAAO,EACZ,KAAK,SAAS,EACd,KAAK,iBAAiB,EACtB,KAAK,WAAW,EAChB,KAAK,UAAU,EACf,KAAK,KAAK,EACV,KAAK,gBAAgB,EAErB,IAAI,EACJ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB,EAEjB,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,IAAI,EACJ,YAAY,EAEZ,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,2BAA2B,GAC5B,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,aAAa,EAClB,wBAAwB,EACxB,YAAY,EACZ,sBAAsB,EACtB,MAAM,EACN,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EACL,KAAK,MAAM,EACX,KAAK,UAAU,EACf,mBAAmB,EACnB,SAAS,EACT,eAAe,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,WAAW,EAChB,KAAK,YAAY,EACjB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,eAAe,EACpB,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,GACN,MAAM,aAAa,CAAA;AAEpB,OAAO,EACL,KAAK,UAAU,EACf,KAAK,UAAU,EACf,KAAK,eAAe,EACpB,KAAK,gBAAgB,EACrB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,cAAc,EACd,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EACL,KAAK,mBAAmB,EACxB,KAAK,mBAAmB,EACxB,KAAK,oBAAoB,EACzB,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
/** Bumped by hand with the version in package.json — `test/version.test.ts`
|
|
47
47
|
* pins the two together. It exists so "the upgrade reached the app" can be
|
|
48
48
|
* checked by grepping a built bundle rather than by trusting a lockfile. */
|
|
49
|
-
export const PROTOCOL_VERSION = '0.
|
|
49
|
+
export const PROTOCOL_VERSION = '0.4.0';
|
|
50
50
|
export {
|
|
51
51
|
// constants
|
|
52
52
|
KIND, MAX_EMOJI_CHARS, MAX_MESSAGE_BYTES, MAX_MENTIONS, MAX_RATIONALE_BYTES, RELAY_AUTH_TOLERANCE_SECS, ASSERTION_SUBTYPE,
|
|
@@ -54,10 +54,10 @@ KIND, MAX_EMOJI_CHARS, MAX_MESSAGE_BYTES, MAX_MENTIONS, MAX_RATIONALE_BYTES, REL
|
|
|
54
54
|
computeEventId, toNostrSeconds, canonicalChannelName, threadTags, addr, relayAuthUrl,
|
|
55
55
|
// builders
|
|
56
56
|
buildProfile, parseProfile, buildCreateChannel, buildDeleteChannel, buildEditChannelMetadata, buildAddMember, buildReaction, buildDeletion, buildMessage, buildResolution, buildFile, buildComponent, buildHighlight, buildUnsignedRelayAuthEvent, } from './events.js';
|
|
57
|
-
export { convertBits, bech32Encode, bech32Decode, encodeNaddr, decodeNaddr, pointerToAddress, addressToPointer, addrToNaddr, naddrToAddr, referenceToPointer, NADDR_RE, findNaddrs, stripNaddrs, } from './nip19.js';
|
|
57
|
+
export { encodeNevent, decodeNevent, convertBits, bech32Encode, bech32Decode, encodeNaddr, decodeNaddr, pointerToAddress, addressToPointer, addrToNaddr, naddrToAddr, referenceToPointer, NADDR_RE, findNaddrs, stripNaddrs, } from './nip19.js';
|
|
58
58
|
export { TIMESTAMP_TOLERANCE_SECS, normalizeUrl, buildUnsignedAuthEvent, base64, authorizationHeaderFor, authorizationHeader, } from './nip98.js';
|
|
59
59
|
export { publicKeyFromSecret, signEvent, secretKeySigner, } from './sign.js';
|
|
60
|
-
export { parsePublishResponse, parseQueryResponse, RELAY_PAGE_CEILING, Relay, } from './bridge.js';
|
|
60
|
+
export { parsePublishResponse, parseQueryResponse, RELAY_PAGE_CEILING, DEFAULT_QUERY_CONCURRENCY, Relay, } from './bridge.js';
|
|
61
61
|
export { toWebSocketUrl, parseFrame, createLiveRelay, } from './live.js';
|
|
62
62
|
export { createChannelSubscriptions, } from './subscriptions.js';
|
|
63
63
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;4EAE4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAA;AAEvC,OAAO;AAYL,YAAY;AACZ,IAAI,EACJ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB;AACjB,8CAA8C;AAC9C,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,IAAI,EACJ,YAAY;AACZ,WAAW;AACX,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,2BAA2B,GAC5B,MAAM,aAAa,CAAA;AAEpB,OAAO,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAEH;;4EAE4E;AAC5E,MAAM,CAAC,MAAM,gBAAgB,GAAG,OAAO,CAAA;AAEvC,OAAO;AAYL,YAAY;AACZ,IAAI,EACJ,eAAe,EACf,iBAAiB,EACjB,YAAY,EACZ,mBAAmB,EACnB,yBAAyB,EACzB,iBAAiB;AACjB,8CAA8C;AAC9C,cAAc,EACd,cAAc,EACd,oBAAoB,EACpB,UAAU,EACV,IAAI,EACJ,YAAY;AACZ,WAAW;AACX,YAAY,EACZ,YAAY,EACZ,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,cAAc,EACd,aAAa,EACb,aAAa,EACb,YAAY,EACZ,eAAe,EACf,SAAS,EACT,cAAc,EACd,cAAc,EACd,2BAA2B,GAC5B,MAAM,aAAa,CAAA;AAEpB,OAAO,EAGL,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,YAAY,EACZ,YAAY,EACZ,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,EACX,WAAW,EACX,kBAAkB,EAClB,QAAQ,EACR,UAAU,EACV,WAAW,GACZ,MAAM,YAAY,CAAA;AAEnB,OAAO,EAEL,wBAAwB,EACxB,YAAY,EACZ,sBAAsB,EACtB,MAAM,EACN,sBAAsB,EACtB,mBAAmB,GACpB,MAAM,YAAY,CAAA;AAEnB,OAAO,EAGL,mBAAmB,EACnB,SAAS,EACT,eAAe,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EAOL,oBAAoB,EACpB,kBAAkB,EAClB,kBAAkB,EAClB,yBAAyB,EACzB,KAAK,GACN,MAAM,aAAa,CAAA;AAEpB,OAAO,EAOL,cAAc,EACd,UAAU,EACV,eAAe,GAChB,MAAM,WAAW,CAAA;AAElB,OAAO,EAIL,0BAA0B,GAC3B,MAAM,oBAAoB,CAAA"}
|
package/dist/nip19.d.ts
CHANGED
|
@@ -29,6 +29,41 @@ export interface AddressPointer {
|
|
|
29
29
|
* TLV order is identifier, relays, author, kind — see the header on why that is
|
|
30
30
|
* a choice rather than a rule.
|
|
31
31
|
*/
|
|
32
|
+
/**
|
|
33
|
+
* A pointer to **one event**, by its id — NIP-19 `nevent`.
|
|
34
|
+
*
|
|
35
|
+
* The counterpart to `AddressPointer`, and the two are not interchangeable.
|
|
36
|
+
* An address names *whatever is currently at* `(kind, pubkey, d)` and survives
|
|
37
|
+
* its author replacing the event. An event id names one immutable event and
|
|
38
|
+
* nothing else: a `kind:9` message has no `d`, so an address cannot be built
|
|
39
|
+
* for it at all.
|
|
40
|
+
*
|
|
41
|
+
* `author` and `kind` are optional in the format and worth including whenever
|
|
42
|
+
* they are known — a reader that has them can query by author and kind rather
|
|
43
|
+
* than scanning, and a consumer can find the manifest that renders the kind
|
|
44
|
+
* before it has the event.
|
|
45
|
+
*/
|
|
46
|
+
export interface EventPointer {
|
|
47
|
+
/** 32-byte event id, hex. */
|
|
48
|
+
id: string;
|
|
49
|
+
relays: string[];
|
|
50
|
+
/** Optional in NIP-19; include it when known. */
|
|
51
|
+
pubkey?: string;
|
|
52
|
+
/** Optional in NIP-19; include it when known. */
|
|
53
|
+
kind?: number;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* `nevent1…` for one event.
|
|
57
|
+
*
|
|
58
|
+
* The TLV layout is `naddr`'s with one difference that matters: type 0 holds
|
|
59
|
+
* the event id as **32 raw bytes**, where an naddr holds the `d` identifier as
|
|
60
|
+
* UTF-8. Encoding an id as text produces a bech32 string every decoder accepts
|
|
61
|
+
* and no relay can answer — the same silent-but-invalid shape the author-length
|
|
62
|
+
* guard below was added for.
|
|
63
|
+
*/
|
|
64
|
+
export declare function encodeNevent(pointer: EventPointer): string;
|
|
65
|
+
/** The inverse of `encodeNevent`. Throws on anything that is not an `nevent`. */
|
|
66
|
+
export declare function decodeNevent(encoded: string): EventPointer;
|
|
32
67
|
export declare function encodeNaddr(pointer: AddressPointer): string;
|
|
33
68
|
/**
|
|
34
69
|
* Decode `naddr1…`, with or without a `nostr:` prefix, in any case.
|
package/dist/nip19.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip19.d.ts","sourceRoot":"","sources":["../src/nip19.ts"],"names":[],"mappings":"AAkFA,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAqBrG;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAGhE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAgB7E;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAWD;;;;;GAKG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CA8B3D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAyC3D;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAWhE;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,EAAO,GAAG,MAAM,CAG1E;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAKhE;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAwD,CAAA;AAE7E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBhD"}
|
|
1
|
+
{"version":3,"file":"nip19.d.ts","sourceRoot":"","sources":["../src/nip19.ts"],"names":[],"mappings":"AAkFA,iFAAiF;AACjF,wBAAgB,WAAW,CAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,GAAG,MAAM,EAAE,CAqBrG;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,GAAG,MAAM,CAGhE;AAED,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,EAAE,CAAA;CAAE,CAgB7E;AAED,6EAA6E;AAC7E,MAAM,WAAW,cAAc;IAC7B,4CAA4C;IAC5C,UAAU,EAAE,MAAM,CAAA;IAClB,MAAM,EAAE,MAAM,CAAA;IACd,IAAI,EAAE,MAAM,CAAA;IACZ,6DAA6D;IAC7D,MAAM,EAAE,MAAM,EAAE,CAAA;CACjB;AAWD;;;;;GAKG;AACH;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,YAAY;IAC3B,6BAA6B;IAC7B,EAAE,EAAE,MAAM,CAAA;IACV,MAAM,EAAE,MAAM,EAAE,CAAA;IAChB,iDAAiD;IACjD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,iDAAiD;IACjD,IAAI,CAAC,EAAE,MAAM,CAAA;CACd;AAED;;;;;;;;GAQG;AACH,wBAAgB,YAAY,CAAC,OAAO,EAAE,YAAY,GAAG,MAAM,CAgC1D;AAED,iFAAiF;AACjF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,YAAY,CA0C1D;AAED,wBAAgB,WAAW,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CA8B3D;AAED;;;;;;;GAOG;AACH,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAyC3D;AAED,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,MAAM,CAEhE;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,MAAM,GAAG,cAAc,CAWhE;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,GAAE,MAAM,EAAO,GAAG,MAAM,CAG1E;AAED,yCAAyC;AACzC,wBAAgB,WAAW,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEnD;AAED;;;;;;;;;;GAUG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,cAAc,CAKhE;AAED;;;;;GAKG;AACH,eAAO,MAAM,QAAQ,QAAwD,CAAA;AAE7E,wBAAgB,UAAU,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,EAAE,CAEjD;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,WAAW,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAoBhD"}
|
package/dist/nip19.js
CHANGED
|
@@ -136,11 +136,89 @@ const TLV_RELAY = 1;
|
|
|
136
136
|
const TLV_AUTHOR = 2;
|
|
137
137
|
const TLV_KIND = 3;
|
|
138
138
|
/**
|
|
139
|
-
*
|
|
139
|
+
* `nevent1…` for one event.
|
|
140
140
|
*
|
|
141
|
-
* TLV
|
|
142
|
-
*
|
|
141
|
+
* The TLV layout is `naddr`'s with one difference that matters: type 0 holds
|
|
142
|
+
* the event id as **32 raw bytes**, where an naddr holds the `d` identifier as
|
|
143
|
+
* UTF-8. Encoding an id as text produces a bech32 string every decoder accepts
|
|
144
|
+
* and no relay can answer — the same silent-but-invalid shape the author-length
|
|
145
|
+
* guard below was added for.
|
|
143
146
|
*/
|
|
147
|
+
export function encodeNevent(pointer) {
|
|
148
|
+
const bytes = [];
|
|
149
|
+
const push = (type, value) => {
|
|
150
|
+
if (value.length > 255)
|
|
151
|
+
throw new Error(`TLV value too long for type ${type}`);
|
|
152
|
+
bytes.push(type, value.length, ...value);
|
|
153
|
+
};
|
|
154
|
+
const id = hexToBytes(pointer.id);
|
|
155
|
+
if (id.length !== 32)
|
|
156
|
+
throw new Error(`event id must be 32 bytes, got ${id.length}`);
|
|
157
|
+
push(TLV_IDENTIFIER, id);
|
|
158
|
+
for (const relay of pointer.relays)
|
|
159
|
+
push(TLV_RELAY, utf8ToBytes(relay));
|
|
160
|
+
if (pointer.pubkey !== undefined) {
|
|
161
|
+
const author = hexToBytes(pointer.pubkey);
|
|
162
|
+
if (author.length !== 32)
|
|
163
|
+
throw new Error(`author must be 32 bytes, got ${author.length}`);
|
|
164
|
+
push(TLV_AUTHOR, author);
|
|
165
|
+
}
|
|
166
|
+
if (pointer.kind !== undefined) {
|
|
167
|
+
push(TLV_KIND, new Uint8Array([
|
|
168
|
+
(pointer.kind >>> 24) & 0xff,
|
|
169
|
+
(pointer.kind >>> 16) & 0xff,
|
|
170
|
+
(pointer.kind >>> 8) & 0xff,
|
|
171
|
+
pointer.kind & 0xff,
|
|
172
|
+
]));
|
|
173
|
+
}
|
|
174
|
+
return bech32Encode('nevent', convertBits(bytes, 8, 5, true));
|
|
175
|
+
}
|
|
176
|
+
/** The inverse of `encodeNevent`. Throws on anything that is not an `nevent`. */
|
|
177
|
+
export function decodeNevent(encoded) {
|
|
178
|
+
const { hrp, data } = bech32Decode(encoded.replace(/^nostr:/i, '').toLowerCase());
|
|
179
|
+
if (hrp !== 'nevent')
|
|
180
|
+
throw new Error(`expected an nevent, got ${hrp}`);
|
|
181
|
+
const bytes = convertBits(data, 5, 8, false);
|
|
182
|
+
let id;
|
|
183
|
+
let pubkey;
|
|
184
|
+
let kind;
|
|
185
|
+
const relays = [];
|
|
186
|
+
for (let i = 0; i < bytes.length;) {
|
|
187
|
+
const type = bytes[i];
|
|
188
|
+
const length = bytes[i + 1];
|
|
189
|
+
const value = bytes.slice(i + 2, i + 2 + length);
|
|
190
|
+
if (value.length !== length)
|
|
191
|
+
throw new Error('truncated TLV');
|
|
192
|
+
i += 2 + length;
|
|
193
|
+
switch (type) {
|
|
194
|
+
case TLV_IDENTIFIER:
|
|
195
|
+
if (length !== 32)
|
|
196
|
+
throw new Error(`event id must be 32 bytes, got ${length}`);
|
|
197
|
+
id = bytesToHex(new Uint8Array(value));
|
|
198
|
+
break;
|
|
199
|
+
case TLV_RELAY:
|
|
200
|
+
relays.push(new TextDecoder().decode(new Uint8Array(value)));
|
|
201
|
+
break;
|
|
202
|
+
case TLV_AUTHOR:
|
|
203
|
+
if (length !== 32)
|
|
204
|
+
throw new Error(`author must be 32 bytes, got ${length}`);
|
|
205
|
+
pubkey = bytesToHex(new Uint8Array(value));
|
|
206
|
+
break;
|
|
207
|
+
case TLV_KIND:
|
|
208
|
+
if (length !== 4)
|
|
209
|
+
throw new Error(`kind must be 4 bytes, got ${length}`);
|
|
210
|
+
kind = ((value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]) >>> 0;
|
|
211
|
+
break;
|
|
212
|
+
// Unknown TLV types are skipped rather than rejected, as in `decodeNaddr`.
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
// Only the id is required. An `nevent` carrying nothing else is legal and
|
|
216
|
+
// still resolvable — by scanning, which is why the optional fields are worth
|
|
217
|
+
// writing when they are known.
|
|
218
|
+
if (id === undefined)
|
|
219
|
+
throw new Error('nevent is missing its event id');
|
|
220
|
+
return { id, relays, ...(pubkey !== undefined ? { pubkey } : {}), ...(kind !== undefined ? { kind } : {}) };
|
|
221
|
+
}
|
|
144
222
|
export function encodeNaddr(pointer) {
|
|
145
223
|
const bytes = [];
|
|
146
224
|
const push = (type, value) => {
|
package/dist/nip19.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"nip19.js","sourceRoot":"","sources":["../src/nip19.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"nip19.js","sourceRoot":"","sources":["../src/nip19.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@estiva-app/protocol",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"description": "The Estiva wire format: Buzz-shaped Nostr event builders, NIP-01 ids, NIP-19 naddr, NIP-98 HTTP auth, and the relay clients. Speaks the protocol; interprets nothing.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/src/bridge.ts
CHANGED
|
@@ -67,6 +67,50 @@ export interface PublishResult {
|
|
|
67
67
|
*/
|
|
68
68
|
export const RELAY_PAGE_CEILING = 1000
|
|
69
69
|
|
|
70
|
+
/**
|
|
71
|
+
* How many of a {@link Relay.queryAll} call's filters may be in flight at once.
|
|
72
|
+
*
|
|
73
|
+
* Filters are independent — only paging *within* one is a cursor walk — and
|
|
74
|
+
* running them one after another made a read as slow as the sum of its parts.
|
|
75
|
+
* Measured on Ship's `loadAll` against production: **33 filters, 66 sequential
|
|
76
|
+
* round trips, median 206 ms, 100% of wall clock spent inside `query` one
|
|
77
|
+
* request at a time.** At a concurrency of 8 the same read returned a
|
|
78
|
+
* byte-identical answer in 1.9 s instead of 9.0 s.
|
|
79
|
+
*
|
|
80
|
+
* Bounded rather than unbounded on purpose. A workspace's filter count grows
|
|
81
|
+
* with its Folders, so `Promise.all` over all of them would open a fan-out
|
|
82
|
+
* whose width is set by the *data* — fine at 33, an accidental flood at 500,
|
|
83
|
+
* and the relay is shared. Eight is enough to hide the latency without any
|
|
84
|
+
* caller having to think about it.
|
|
85
|
+
*
|
|
86
|
+
* Pass `concurrency: 1` to restore the strictly serial read.
|
|
87
|
+
*
|
|
88
|
+
* ## This does not buy a caller more relay budget
|
|
89
|
+
*
|
|
90
|
+
* Concurrency changes how fast a read spends its requests, never how many it
|
|
91
|
+
* makes. Buzz meters `POST /query` against `human_api_calls_per_min` — a fixed
|
|
92
|
+
* 60-second window, **default 300, applied to every bridge call whatever tier
|
|
93
|
+
* the caller is** (`enforce_http_admission` in `api/bridge.rs` reads the human
|
|
94
|
+
* limit unconditionally). At 66 requests, one Ship workspace read is 22% of a
|
|
95
|
+
* minute's entire allowance, so no client gets more than ~4.5 of them a minute
|
|
96
|
+
* however it schedules them.
|
|
97
|
+
*
|
|
98
|
+
* A poller therefore has to slow down as its reads get faster, or it simply
|
|
99
|
+
* spends the same budget sooner and starts collecting
|
|
100
|
+
* `rate-limited: quota exceeded`. Making a read cheap is the fix for that;
|
|
101
|
+
* making it parallel is not.
|
|
102
|
+
*/
|
|
103
|
+
export const DEFAULT_QUERY_CONCURRENCY = 8
|
|
104
|
+
|
|
105
|
+
export interface QueryAllOptions {
|
|
106
|
+
/** Events per request. Defaults to {@link RELAY_PAGE_CEILING}. */
|
|
107
|
+
pageSize?: number
|
|
108
|
+
/** Give up after this many pages *per filter*, rather than looping forever. */
|
|
109
|
+
maxPages?: number
|
|
110
|
+
/** Filters in flight at once. Defaults to {@link DEFAULT_QUERY_CONCURRENCY}; 1 is serial. */
|
|
111
|
+
concurrency?: number
|
|
112
|
+
}
|
|
113
|
+
|
|
70
114
|
export function parsePublishResponse(status: number, text: string): PublishResult {
|
|
71
115
|
let parsed: { accepted?: boolean; event_id?: string; message?: string; error?: string }
|
|
72
116
|
try {
|
|
@@ -241,44 +285,122 @@ export class Relay {
|
|
|
241
285
|
* value of `until` reaches past them without skipping some, and no correct
|
|
242
286
|
* answer exists from this API — so it says so instead of returning a
|
|
243
287
|
* plausible subset.
|
|
288
|
+
*
|
|
289
|
+
* **Filters run concurrently, up to {@link DEFAULT_QUERY_CONCURRENCY}.** They
|
|
290
|
+
* are independent of one another; only the pages inside one are a cursor
|
|
291
|
+
* walk. Doing them in sequence made a read cost the sum of every filter's
|
|
292
|
+
* latency, which is what put Ship's workspace read at nine seconds against a
|
|
293
|
+
* five-second poll — long enough that a write's re-read had usually not
|
|
294
|
+
* finished before the next one began.
|
|
295
|
+
*
|
|
296
|
+
* The concurrency is deliberately **not observable in the answer**: results
|
|
297
|
+
* are collected per filter and concatenated in filter order, so the returned
|
|
298
|
+
* array is identical to the serial one, and a failure reports the
|
|
299
|
+
* lowest-indexed filter's error rather than whichever lost the race.
|
|
244
300
|
*/
|
|
245
301
|
async queryAll(
|
|
246
302
|
filters: Record<string, unknown>[],
|
|
247
|
-
options:
|
|
303
|
+
options: QueryAllOptions = {},
|
|
248
304
|
): Promise<SignedEvent[]> {
|
|
249
305
|
const pageSize = options.pageSize ?? RELAY_PAGE_CEILING
|
|
250
306
|
const maxPages = options.maxPages ?? 100
|
|
307
|
+
const concurrency = Math.max(1, options.concurrency ?? DEFAULT_QUERY_CONCURRENCY)
|
|
308
|
+
|
|
309
|
+
/*
|
|
310
|
+
Per filter, in filter order — not one shared accumulator.
|
|
311
|
+
|
|
312
|
+
Concurrency must not be observable in the answer. Collecting each
|
|
313
|
+
filter's pages into its own slot and concatenating in order at the end
|
|
314
|
+
makes the output byte-identical to the serial version, whatever order the
|
|
315
|
+
responses actually arrive in. Dedup then runs over that ordered
|
|
316
|
+
concatenation, so an id first seen under filter 0 still belongs to filter
|
|
317
|
+
0's run of events, exactly as before.
|
|
318
|
+
*/
|
|
319
|
+
const perFilter: SignedEvent[][] = new Array(filters.length)
|
|
320
|
+
const failures: unknown[] = new Array(filters.length)
|
|
321
|
+
|
|
322
|
+
let next = 0
|
|
323
|
+
let failed = false
|
|
324
|
+
|
|
325
|
+
const worker = async (): Promise<void> => {
|
|
326
|
+
for (;;) {
|
|
327
|
+
// Stop *starting* filters once one has failed. The serial version never
|
|
328
|
+
// reached them at all; this is as close as a fan-out gets, and it keeps
|
|
329
|
+
// a broken read from firing the whole remaining queue at the relay.
|
|
330
|
+
if (failed) return
|
|
331
|
+
const index = next++
|
|
332
|
+
if (index >= filters.length) return
|
|
333
|
+
try {
|
|
334
|
+
perFilter[index] = await this.pageFilter(filters[index], pageSize, maxPages)
|
|
335
|
+
} catch (error) {
|
|
336
|
+
failures[index] = error
|
|
337
|
+
failed = true
|
|
338
|
+
return
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
await Promise.all(
|
|
344
|
+
Array.from({ length: Math.min(concurrency, filters.length) }, () => worker()),
|
|
345
|
+
)
|
|
346
|
+
|
|
347
|
+
/*
|
|
348
|
+
The lowest-indexed failure, not the first to reject in wall-clock time.
|
|
349
|
+
|
|
350
|
+
Under `Promise.all` the error a caller sees would otherwise depend on
|
|
351
|
+
which request happened to lose the race, so two runs of the same broken
|
|
352
|
+
read could report different filters. Serial order is the one order that
|
|
353
|
+
is reproducible, and it is what the serial version reported.
|
|
354
|
+
*/
|
|
355
|
+
const firstFailure = failures.findIndex((error) => error !== undefined)
|
|
356
|
+
if (firstFailure !== -1) throw failures[firstFailure]
|
|
357
|
+
|
|
251
358
|
const seen = new Set<string>()
|
|
252
359
|
const out: SignedEvent[] = []
|
|
360
|
+
for (const events of perFilter) {
|
|
361
|
+
for (const e of events) {
|
|
362
|
+
if (seen.has(e.id)) continue
|
|
363
|
+
seen.add(e.id)
|
|
364
|
+
out.push(e)
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
return out
|
|
368
|
+
}
|
|
253
369
|
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
370
|
+
/**
|
|
371
|
+
* One filter, paged to exhaustion. The sequential half, and it has to be:
|
|
372
|
+
* `until` is a cursor, so page N+1's request is not known until page N has
|
|
373
|
+
* answered. Only the filters are independent, which is why they are the
|
|
374
|
+
* axis {@link Relay.queryAll} parallelises.
|
|
375
|
+
*/
|
|
376
|
+
private async pageFilter(
|
|
377
|
+
filter: Record<string, unknown>,
|
|
378
|
+
pageSize: number,
|
|
379
|
+
maxPages: number,
|
|
380
|
+
): Promise<SignedEvent[]> {
|
|
381
|
+
const out: SignedEvent[] = []
|
|
382
|
+
let until: number | undefined
|
|
383
|
+
for (let page = 0; ; page++) {
|
|
384
|
+
if (page >= maxPages) {
|
|
385
|
+
throw new Error(
|
|
386
|
+
`queryAll: gave up after ${maxPages} pages — refusing to return a partial set`,
|
|
387
|
+
)
|
|
388
|
+
}
|
|
389
|
+
const events = await this.query([
|
|
390
|
+
{ ...filter, limit: pageSize, ...(until === undefined ? {} : { until }) },
|
|
391
|
+
])
|
|
392
|
+
if (events.length === 0) break
|
|
393
|
+
out.push(...events)
|
|
394
|
+
const oldest = Math.min(...events.map((e) => e.created_at))
|
|
395
|
+
if (until !== undefined && oldest >= until) {
|
|
396
|
+
if (events.length >= pageSize) {
|
|
258
397
|
throw new Error(
|
|
259
|
-
`queryAll:
|
|
398
|
+
`queryAll: more than ${pageSize} events share created_at=${until} — cannot page without skipping`,
|
|
260
399
|
)
|
|
261
400
|
}
|
|
262
|
-
|
|
263
|
-
{ ...filter, limit: pageSize, ...(until === undefined ? {} : { until }) },
|
|
264
|
-
])
|
|
265
|
-
if (events.length === 0) break
|
|
266
|
-
for (const e of events) {
|
|
267
|
-
if (seen.has(e.id)) continue
|
|
268
|
-
seen.add(e.id)
|
|
269
|
-
out.push(e)
|
|
270
|
-
}
|
|
271
|
-
const oldest = Math.min(...events.map((e) => e.created_at))
|
|
272
|
-
if (until !== undefined && oldest >= until) {
|
|
273
|
-
if (events.length >= pageSize) {
|
|
274
|
-
throw new Error(
|
|
275
|
-
`queryAll: more than ${pageSize} events share created_at=${until} — cannot page without skipping`,
|
|
276
|
-
)
|
|
277
|
-
}
|
|
278
|
-
break
|
|
279
|
-
}
|
|
280
|
-
until = oldest
|
|
401
|
+
break
|
|
281
402
|
}
|
|
403
|
+
until = oldest
|
|
282
404
|
}
|
|
283
405
|
return out
|
|
284
406
|
}
|
package/src/index.ts
CHANGED
|
@@ -47,7 +47,7 @@
|
|
|
47
47
|
/** Bumped by hand with the version in package.json — `test/version.test.ts`
|
|
48
48
|
* pins the two together. It exists so "the upgrade reached the app" can be
|
|
49
49
|
* checked by grepping a built bundle rather than by trusting a lockfile. */
|
|
50
|
-
export const PROTOCOL_VERSION = '0.
|
|
50
|
+
export const PROTOCOL_VERSION = '0.4.0'
|
|
51
51
|
|
|
52
52
|
export {
|
|
53
53
|
// types
|
|
@@ -95,6 +95,9 @@ export {
|
|
|
95
95
|
|
|
96
96
|
export {
|
|
97
97
|
type AddressPointer,
|
|
98
|
+
type EventPointer,
|
|
99
|
+
encodeNevent,
|
|
100
|
+
decodeNevent,
|
|
98
101
|
convertBits,
|
|
99
102
|
bech32Encode,
|
|
100
103
|
bech32Decode,
|
|
@@ -134,9 +137,11 @@ export {
|
|
|
134
137
|
type RelayHeaders,
|
|
135
138
|
type RelayOptions,
|
|
136
139
|
type FetchLike,
|
|
140
|
+
type QueryAllOptions,
|
|
137
141
|
parsePublishResponse,
|
|
138
142
|
parseQueryResponse,
|
|
139
143
|
RELAY_PAGE_CEILING,
|
|
144
|
+
DEFAULT_QUERY_CONCURRENCY,
|
|
140
145
|
Relay,
|
|
141
146
|
} from './bridge.js'
|
|
142
147
|
|
package/src/nip19.ts
CHANGED
|
@@ -161,6 +161,118 @@ const TLV_KIND = 3
|
|
|
161
161
|
* TLV order is identifier, relays, author, kind — see the header on why that is
|
|
162
162
|
* a choice rather than a rule.
|
|
163
163
|
*/
|
|
164
|
+
/**
|
|
165
|
+
* A pointer to **one event**, by its id — NIP-19 `nevent`.
|
|
166
|
+
*
|
|
167
|
+
* The counterpart to `AddressPointer`, and the two are not interchangeable.
|
|
168
|
+
* An address names *whatever is currently at* `(kind, pubkey, d)` and survives
|
|
169
|
+
* its author replacing the event. An event id names one immutable event and
|
|
170
|
+
* nothing else: a `kind:9` message has no `d`, so an address cannot be built
|
|
171
|
+
* for it at all.
|
|
172
|
+
*
|
|
173
|
+
* `author` and `kind` are optional in the format and worth including whenever
|
|
174
|
+
* they are known — a reader that has them can query by author and kind rather
|
|
175
|
+
* than scanning, and a consumer can find the manifest that renders the kind
|
|
176
|
+
* before it has the event.
|
|
177
|
+
*/
|
|
178
|
+
export interface EventPointer {
|
|
179
|
+
/** 32-byte event id, hex. */
|
|
180
|
+
id: string
|
|
181
|
+
relays: string[]
|
|
182
|
+
/** Optional in NIP-19; include it when known. */
|
|
183
|
+
pubkey?: string
|
|
184
|
+
/** Optional in NIP-19; include it when known. */
|
|
185
|
+
kind?: number
|
|
186
|
+
}
|
|
187
|
+
|
|
188
|
+
/**
|
|
189
|
+
* `nevent1…` for one event.
|
|
190
|
+
*
|
|
191
|
+
* The TLV layout is `naddr`'s with one difference that matters: type 0 holds
|
|
192
|
+
* the event id as **32 raw bytes**, where an naddr holds the `d` identifier as
|
|
193
|
+
* UTF-8. Encoding an id as text produces a bech32 string every decoder accepts
|
|
194
|
+
* and no relay can answer — the same silent-but-invalid shape the author-length
|
|
195
|
+
* guard below was added for.
|
|
196
|
+
*/
|
|
197
|
+
export function encodeNevent(pointer: EventPointer): string {
|
|
198
|
+
const bytes: number[] = []
|
|
199
|
+
const push = (type: number, value: Uint8Array) => {
|
|
200
|
+
if (value.length > 255) throw new Error(`TLV value too long for type ${type}`)
|
|
201
|
+
bytes.push(type, value.length, ...value)
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
const id = hexToBytes(pointer.id)
|
|
205
|
+
if (id.length !== 32) throw new Error(`event id must be 32 bytes, got ${id.length}`)
|
|
206
|
+
push(TLV_IDENTIFIER, id)
|
|
207
|
+
|
|
208
|
+
for (const relay of pointer.relays) push(TLV_RELAY, utf8ToBytes(relay))
|
|
209
|
+
|
|
210
|
+
if (pointer.pubkey !== undefined) {
|
|
211
|
+
const author = hexToBytes(pointer.pubkey)
|
|
212
|
+
if (author.length !== 32) throw new Error(`author must be 32 bytes, got ${author.length}`)
|
|
213
|
+
push(TLV_AUTHOR, author)
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
if (pointer.kind !== undefined) {
|
|
217
|
+
push(
|
|
218
|
+
TLV_KIND,
|
|
219
|
+
new Uint8Array([
|
|
220
|
+
(pointer.kind >>> 24) & 0xff,
|
|
221
|
+
(pointer.kind >>> 16) & 0xff,
|
|
222
|
+
(pointer.kind >>> 8) & 0xff,
|
|
223
|
+
pointer.kind & 0xff,
|
|
224
|
+
]),
|
|
225
|
+
)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
return bech32Encode('nevent', convertBits(bytes, 8, 5, true))
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
/** The inverse of `encodeNevent`. Throws on anything that is not an `nevent`. */
|
|
232
|
+
export function decodeNevent(encoded: string): EventPointer {
|
|
233
|
+
const { hrp, data } = bech32Decode(encoded.replace(/^nostr:/i, '').toLowerCase())
|
|
234
|
+
if (hrp !== 'nevent') throw new Error(`expected an nevent, got ${hrp}`)
|
|
235
|
+
const bytes = convertBits(data, 5, 8, false)
|
|
236
|
+
|
|
237
|
+
let id: string | undefined
|
|
238
|
+
let pubkey: string | undefined
|
|
239
|
+
let kind: number | undefined
|
|
240
|
+
const relays: string[] = []
|
|
241
|
+
|
|
242
|
+
for (let i = 0; i < bytes.length; ) {
|
|
243
|
+
const type = bytes[i]
|
|
244
|
+
const length = bytes[i + 1]
|
|
245
|
+
const value = bytes.slice(i + 2, i + 2 + length)
|
|
246
|
+
if (value.length !== length) throw new Error('truncated TLV')
|
|
247
|
+
i += 2 + length
|
|
248
|
+
|
|
249
|
+
switch (type) {
|
|
250
|
+
case TLV_IDENTIFIER:
|
|
251
|
+
if (length !== 32) throw new Error(`event id must be 32 bytes, got ${length}`)
|
|
252
|
+
id = bytesToHex(new Uint8Array(value))
|
|
253
|
+
break
|
|
254
|
+
case TLV_RELAY:
|
|
255
|
+
relays.push(new TextDecoder().decode(new Uint8Array(value)))
|
|
256
|
+
break
|
|
257
|
+
case TLV_AUTHOR:
|
|
258
|
+
if (length !== 32) throw new Error(`author must be 32 bytes, got ${length}`)
|
|
259
|
+
pubkey = bytesToHex(new Uint8Array(value))
|
|
260
|
+
break
|
|
261
|
+
case TLV_KIND:
|
|
262
|
+
if (length !== 4) throw new Error(`kind must be 4 bytes, got ${length}`)
|
|
263
|
+
kind = ((value[0] << 24) | (value[1] << 16) | (value[2] << 8) | value[3]) >>> 0
|
|
264
|
+
break
|
|
265
|
+
// Unknown TLV types are skipped rather than rejected, as in `decodeNaddr`.
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
|
|
269
|
+
// Only the id is required. An `nevent` carrying nothing else is legal and
|
|
270
|
+
// still resolvable — by scanning, which is why the optional fields are worth
|
|
271
|
+
// writing when they are known.
|
|
272
|
+
if (id === undefined) throw new Error('nevent is missing its event id')
|
|
273
|
+
return { id, relays, ...(pubkey !== undefined ? { pubkey } : {}), ...(kind !== undefined ? { kind } : {}) }
|
|
274
|
+
}
|
|
275
|
+
|
|
164
276
|
export function encodeNaddr(pointer: AddressPointer): string {
|
|
165
277
|
const bytes: number[] = []
|
|
166
278
|
const push = (type: number, value: Uint8Array) => {
|