@solarpunkltd/swarm-chat-js 8.1.0 → 10.0.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/README.md +249 -193
- package/dist/chat.d.ts +8 -6
- package/dist/index.cjs +1 -1
- package/dist/index.js +121 -151
- package/dist/message/binding.d.ts +12 -6
- package/dist/message/entry.d.ts +14 -6
- package/dist/message/index.d.ts +1 -0
- package/dist/message/message.d.ts +32 -13
- package/dist/message/ownFeed.d.ts +2 -2
- package/dist/message/personalSign.d.ts +7 -0
- package/dist/message/walletLink.d.ts +45 -0
- package/dist/message-BUFAxjtN.js +551 -0
- package/dist/message-BjeTRy2F.cjs +4 -0
- package/dist/message.cjs +1 -1
- package/dist/message.js +1 -2
- package/dist/pacer.d.ts +1 -1
- package/dist/sender.d.ts +4 -7
- package/package.json +3 -3
- package/dist/message-Bmwh3SCs.cjs +0 -3
- package/dist/message-Dbh8qrpg.js +0 -455
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { A as e, B as t, C as n, D as r, E as i, F as a,
|
|
2
|
-
import { Bee as
|
|
3
|
-
|
|
4
|
-
var
|
|
1
|
+
import { A as e, B as t, C as n, D as r, E as i, F as a, G as o, H as s, I as c, J as ee, K as l, L as te, M as u, N as ne, O as d, P as f, R as p, S as m, T as h, U as g, V as _, W as v, _ as y, a as b, b as re, c as ie, d as x, f as ae, g as oe, h as se, i as ce, j as le, k as ue, l as S, m as de, n as C, o as fe, p as pe, q as me, r as he, s as w, t as T, u as E, v as D, w as O, x as k, y as A, z as j } from "./message-BUFAxjtN.js";
|
|
2
|
+
import { Bee as M, BeeResponseError as N, Identifier as P, PrivateKey as F, Topic as I } from "@ethersphere/bee-js";
|
|
3
|
+
// src/events.ts
|
|
4
|
+
var L = {
|
|
5
5
|
LOADING_INIT: "loadingInit",
|
|
6
6
|
LOADING_PREVIOUS_MESSAGES: "loadingPreviousMessages",
|
|
7
7
|
MESSAGE_RECEIVED: "messageReceived",
|
|
@@ -13,13 +13,13 @@ var R = {
|
|
|
13
13
|
MESSAGE_SKIPPED: "messageSkipped",
|
|
14
14
|
ERROR: "error"
|
|
15
15
|
};
|
|
16
|
-
function
|
|
17
|
-
return
|
|
16
|
+
function R(e) {
|
|
17
|
+
return B(e, -1, e.ts);
|
|
18
18
|
}
|
|
19
|
-
function
|
|
20
|
-
return
|
|
19
|
+
function z(e) {
|
|
20
|
+
return B(e.msg, e.seq, e.at);
|
|
21
21
|
}
|
|
22
|
-
function
|
|
22
|
+
function B(e, t, n) {
|
|
23
23
|
return {
|
|
24
24
|
id: e.id,
|
|
25
25
|
type: e.type,
|
|
@@ -32,7 +32,7 @@ function V(e, t, n) {
|
|
|
32
32
|
signedMessage: e
|
|
33
33
|
};
|
|
34
34
|
}
|
|
35
|
-
var
|
|
35
|
+
var V = class {
|
|
36
36
|
constructor() {
|
|
37
37
|
this.listeners = /* @__PURE__ */ new Map(), this.on = (e, t) => {
|
|
38
38
|
this.listeners.set(e, [...this.listeners.get(e) ?? [], t]);
|
|
@@ -49,7 +49,7 @@ var H = class {
|
|
|
49
49
|
console.error(`a listener for ${e} threw`, t);
|
|
50
50
|
}
|
|
51
51
|
}
|
|
52
|
-
},
|
|
52
|
+
}, H = 2e4, U = class {
|
|
53
53
|
constructor(e, t) {
|
|
54
54
|
this.spacingMs = e, this.now = t, this.missedAt = /* @__PURE__ */ new Map();
|
|
55
55
|
}
|
|
@@ -73,33 +73,33 @@ var H = class {
|
|
|
73
73
|
expired(e, t) {
|
|
74
74
|
return e > t || t - e >= this.spacingMs;
|
|
75
75
|
}
|
|
76
|
-
},
|
|
76
|
+
}, W = class extends Error {
|
|
77
77
|
constructor(e) {
|
|
78
78
|
super("the feed head lookup did not answer in time", e), this.name = "HeadLookupTimeoutError";
|
|
79
79
|
}
|
|
80
|
-
},
|
|
80
|
+
}, G = class extends Error {
|
|
81
81
|
constructor(e, t) {
|
|
82
82
|
super(`feed slot ${e} was served but could not be read`, t), this.index = e, this.name = "UnreadableSlotError";
|
|
83
83
|
}
|
|
84
84
|
};
|
|
85
|
-
function
|
|
86
|
-
return e instanceof
|
|
85
|
+
function K(e) {
|
|
86
|
+
return e instanceof N && (e.status === 404 || e.status === 500);
|
|
87
87
|
}
|
|
88
|
-
async function
|
|
88
|
+
async function q(e, t) {
|
|
89
89
|
try {
|
|
90
90
|
return await t();
|
|
91
91
|
} catch (t) {
|
|
92
|
-
if (
|
|
93
|
-
throw t instanceof
|
|
92
|
+
if (K(t)) return null;
|
|
93
|
+
throw t instanceof N ? t : new G(e, { cause: t });
|
|
94
94
|
}
|
|
95
95
|
}
|
|
96
|
-
function
|
|
97
|
-
let a =
|
|
96
|
+
function ge(e, t, n, r, i = C) {
|
|
97
|
+
let a = I.fromString(n), o = (n) => e.feed.makeReader(a, t, J(n));
|
|
98
98
|
return {
|
|
99
|
-
readNote: (a) =>
|
|
100
|
-
readSlot: (e) =>
|
|
99
|
+
readNote: (a) => q(a, async () => (await e.soc.makeReader(t, J(r.slotReadMs)).download(w(n, i, a))).payload.toUint8Array()),
|
|
100
|
+
readSlot: (e) => q(e, async () => (await o(r.slotReadMs).downloadPayload({ index: e })).payload.toUint8Array()),
|
|
101
101
|
async readHead() {
|
|
102
|
-
let n =
|
|
102
|
+
let n = J(r.feedReadMs);
|
|
103
103
|
try {
|
|
104
104
|
let { payload: r, feedIndex: i } = await e.feed.makeReader(a, t, n).downloadPayload();
|
|
105
105
|
return {
|
|
@@ -107,34 +107,33 @@ function le(e, t, n, r, i = C) {
|
|
|
107
107
|
payload: r.toUint8Array()
|
|
108
108
|
};
|
|
109
109
|
} catch (e) {
|
|
110
|
-
if (
|
|
111
|
-
throw n.signal?.aborted ? new
|
|
110
|
+
if (K(e)) return null;
|
|
111
|
+
throw n.signal?.aborted ? new W({ cause: e }) : e;
|
|
112
112
|
}
|
|
113
113
|
},
|
|
114
114
|
async readFile(t) {
|
|
115
|
-
return (await e.data.download(t, void 0,
|
|
115
|
+
return (await e.data.download(t, void 0, J(r.feedReadMs))).toUint8Array();
|
|
116
116
|
}
|
|
117
117
|
};
|
|
118
118
|
}
|
|
119
|
-
function
|
|
119
|
+
function J(e) {
|
|
120
120
|
return { signal: AbortSignal.timeout(e) };
|
|
121
121
|
}
|
|
122
|
-
var
|
|
123
|
-
function
|
|
124
|
-
let a = new
|
|
122
|
+
var _e = "0123456789abcdef".repeat(4);
|
|
123
|
+
function ve(e, t, n, r, i) {
|
|
124
|
+
let a = new F(n), o = P.fromString(r);
|
|
125
125
|
return async (n) => {
|
|
126
|
-
await e.messaging.gsocSend(t, a, o, n, { deferred: !1 },
|
|
126
|
+
await e.messaging.gsocSend(t, a, o, n, { deferred: !1 }, J(i.writeMs));
|
|
127
127
|
};
|
|
128
128
|
}
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
var X = {
|
|
129
|
+
// src/follower.ts
|
|
130
|
+
var Y = {
|
|
132
131
|
LIVE: "live",
|
|
133
132
|
RECONNECTING: "reconnecting",
|
|
134
133
|
STALLED: "stalled"
|
|
135
|
-
},
|
|
134
|
+
}, ye = {
|
|
136
135
|
pollIntervalMs: 1e3,
|
|
137
|
-
missingReadSpacingMs:
|
|
136
|
+
missingReadSpacingMs: H,
|
|
138
137
|
maxSlotsPerPoll: 16,
|
|
139
138
|
unservedPollsBeforeProbe: 3,
|
|
140
139
|
unreadablePollsBeforeFailure: 3,
|
|
@@ -152,16 +151,16 @@ var X = {
|
|
|
152
151
|
stallAfterMs: 8e3,
|
|
153
152
|
random: Math.random,
|
|
154
153
|
now: Date.now
|
|
155
|
-
},
|
|
154
|
+
}, X = class extends Error {
|
|
156
155
|
constructor(e) {
|
|
157
156
|
super(`the gateway keeps answering feed slot ${e} with something that is not a chunk`), this.index = e, this.name = "UnreadableGatewayError";
|
|
158
157
|
}
|
|
159
|
-
},
|
|
158
|
+
}, be = class {
|
|
160
159
|
constructor(e, t, n, r = {}, i = null) {
|
|
161
160
|
this.source = e, this.topic = t, this.events = n, this.notes = i, this.next = 0, this.ceiling = null, this.nextNoteSlot = 0, this.lastNoteFoundAt = 0, this.unservedPolls = 0, this.nextProbeAt = 0, this.unreadablePolls = 0, this.gatewayFailures = 0, this.missed = /* @__PURE__ */ new Map(), this.timer = null, this.generation = 0, this.running = !1, this.status = null, this.settings = {
|
|
162
|
-
...
|
|
161
|
+
...ye,
|
|
163
162
|
...r
|
|
164
|
-
}, this.pacer = new
|
|
163
|
+
}, this.pacer = new U(this.settings.missingReadSpacingMs, this.settings.now);
|
|
165
164
|
}
|
|
166
165
|
get nextIndex() {
|
|
167
166
|
return this.next;
|
|
@@ -191,13 +190,7 @@ var X = {
|
|
|
191
190
|
} catch (t) {
|
|
192
191
|
n = !0, e === this.generation && this.gatewayFailed(t);
|
|
193
192
|
}
|
|
194
|
-
|
|
195
|
-
if (n) {
|
|
196
|
-
this.schedule(this.backoffMs());
|
|
197
|
-
return;
|
|
198
|
-
}
|
|
199
|
-
this.gatewayAnswered(), this.schedule(t >= this.settings.maxSlotsPerPoll ? 0 : this.untilNextRead());
|
|
200
|
-
}
|
|
193
|
+
e === this.generation && this.running && (n ? this.schedule(this.backoffMs()) : (this.gatewayAnswered(), this.schedule(t >= this.settings.maxSlotsPerPoll ? 0 : this.untilNextRead())));
|
|
201
194
|
}
|
|
202
195
|
untilNextRead() {
|
|
203
196
|
let e = this.settings.now(), t = (t) => {
|
|
@@ -210,20 +203,14 @@ var X = {
|
|
|
210
203
|
let n = this.settings.now(), r = e.lastReadableSlot(n);
|
|
211
204
|
if (r < this.nextNoteSlot) return;
|
|
212
205
|
let i = Math.max(this.nextNoteSlot, r - e.lookBackSlots + 1), a = await e.scan(r, i);
|
|
213
|
-
|
|
214
|
-
if (this.nextNoteSlot = r + 1, a) {
|
|
215
|
-
this.lastNoteFoundAt = n, this.ceiling = Math.max(this.ceiling ?? -1, a.note.newest, this.next - 1);
|
|
216
|
-
return;
|
|
217
|
-
}
|
|
218
|
-
n - this.lastNoteFoundAt >= e.silenceMs && (this.lastNoteFoundAt = n, e.clock.distrust(), this.nextNoteSlot = Math.min(this.nextNoteSlot, e.lastReadableSlot(n) + 1));
|
|
219
|
-
}
|
|
206
|
+
t === this.generation && (this.nextNoteSlot = r + 1, a ? (this.lastNoteFoundAt = n, this.ceiling = Math.max(this.ceiling ?? -1, a.note.newest, this.next - 1)) : n - this.lastNoteFoundAt >= e.silenceMs && (this.lastNoteFoundAt = n, e.clock.distrust(), this.nextNoteSlot = Math.min(this.nextNoteSlot, e.lastReadableSlot(n) + 1)));
|
|
220
207
|
}
|
|
221
208
|
async read(e) {
|
|
222
209
|
let t;
|
|
223
210
|
try {
|
|
224
211
|
t = await this.source.readSlot(e);
|
|
225
212
|
} catch (e) {
|
|
226
|
-
if (e instanceof
|
|
213
|
+
if (e instanceof G) return "unreadable";
|
|
227
214
|
throw e;
|
|
228
215
|
}
|
|
229
216
|
return t === null ? this.pacer.missed(e) : this.pacer.found(e), t;
|
|
@@ -237,21 +224,20 @@ var X = {
|
|
|
237
224
|
if (this.ceiling !== null && n > this.ceiling) return t;
|
|
238
225
|
let r = this.ceiling === null ? await this.readUnnamed(n) : await this.read(n);
|
|
239
226
|
if (e !== this.generation || r === "held") return t;
|
|
240
|
-
if (this.ceiling !== null && (r === null || r === "unreadable"))
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
227
|
+
if (this.ceiling !== null && (r === null || r === "unreadable")) this.remember(n), this.next = n + 1;
|
|
228
|
+
else {
|
|
229
|
+
if (r === null || r === "unreadable") {
|
|
230
|
+
if (t === 0) {
|
|
231
|
+
if (this.unservedPolls++, this.unreadablePolls = r === "unreadable" ? this.unreadablePolls + 1 : 0, this.shouldProbe() && await this.probePast(n, e)) {
|
|
232
|
+
this.unreadablePolls = 0;
|
|
233
|
+
continue;
|
|
234
|
+
}
|
|
235
|
+
if (this.unreadablePolls >= this.settings.unreadablePollsBeforeFailure) throw new X(n);
|
|
249
236
|
}
|
|
250
|
-
|
|
237
|
+
return t;
|
|
251
238
|
}
|
|
252
|
-
|
|
239
|
+
this.resetRefusals(), this.unreadablePolls = 0, this.next = n + 1, this.accept(n, r);
|
|
253
240
|
}
|
|
254
|
-
this.resetRefusals(), this.unreadablePolls = 0, this.next = n + 1, this.accept(n, r);
|
|
255
241
|
}
|
|
256
242
|
return this.settings.maxSlotsPerPoll;
|
|
257
243
|
}
|
|
@@ -268,28 +254,21 @@ var X = {
|
|
|
268
254
|
for (let r of this.settings.probeDistances) {
|
|
269
255
|
let i = e + r, a = await this.readUnnamed(i);
|
|
270
256
|
if (t !== this.generation) return !1;
|
|
271
|
-
if (a === null || a === "unreadable" || a === "held")
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
257
|
+
if (a === null || a === "unreadable" || a === "held") n.add(i);
|
|
258
|
+
else {
|
|
259
|
+
this.resetRefusals(), this.remember(e);
|
|
260
|
+
for (let r = e + 1; r < i; r++) {
|
|
261
|
+
let e = n.has(r) ? null : await this.readUnnamed(r);
|
|
262
|
+
if (t !== this.generation) return !1;
|
|
263
|
+
e === null || e === "unreadable" || e === "held" ? this.remember(r) : this.accept(r, e);
|
|
264
|
+
}
|
|
265
|
+
return this.next = i + 1, this.accept(i, a), !0;
|
|
280
266
|
}
|
|
281
|
-
return this.next = i + 1, this.accept(i, a), !0;
|
|
282
267
|
}
|
|
283
268
|
return !1;
|
|
284
269
|
}
|
|
285
270
|
remember(e) {
|
|
286
|
-
|
|
287
|
-
if (this.missed.size >= this.settings.missedLimit) {
|
|
288
|
-
this.events.skipped(e, "unreachable", "stepped past with the retry list full");
|
|
289
|
-
return;
|
|
290
|
-
}
|
|
291
|
-
this.missed.set(e, this.settings.now());
|
|
292
|
-
}
|
|
271
|
+
this.missed.has(e) || (this.missed.size >= this.settings.missedLimit ? this.events.skipped(e, "unreachable", "stepped past with the retry list full") : this.missed.set(e, this.settings.now()));
|
|
293
272
|
}
|
|
294
273
|
async readMissed(e) {
|
|
295
274
|
let t = this.settings.now();
|
|
@@ -303,16 +282,16 @@ var X = {
|
|
|
303
282
|
}
|
|
304
283
|
}
|
|
305
284
|
accept(e, t) {
|
|
306
|
-
let n =
|
|
285
|
+
let n = D(t, e, this.topic);
|
|
307
286
|
n.ok ? (this.notes?.clock.observe(n.value.at, this.settings.now()), this.events.entry(n.value)) : this.events.skipped(e, n.reason, n.detail);
|
|
308
287
|
}
|
|
309
288
|
gatewayFailed(e) {
|
|
310
|
-
this.gatewayFailures++, this.setStatus(
|
|
289
|
+
this.gatewayFailures++, this.setStatus(Y.RECONNECTING), this.events.error(e);
|
|
311
290
|
}
|
|
312
291
|
gatewayAnswered() {
|
|
313
292
|
this.gatewayFailures = 0;
|
|
314
293
|
let e = this.settings.now(), t = [...this.missed.values()].some((t) => e - t >= this.settings.stallAfterMs);
|
|
315
|
-
this.setStatus(t ?
|
|
294
|
+
this.setStatus(t ? Y.STALLED : Y.LIVE);
|
|
316
295
|
}
|
|
317
296
|
backoffMs() {
|
|
318
297
|
let { pollIntervalMs: e, backoffCapMs: t, random: n } = this.settings, r = Math.min(t, e * 2 ** this.gatewayFailures);
|
|
@@ -321,7 +300,7 @@ var X = {
|
|
|
321
300
|
setStatus(e) {
|
|
322
301
|
e !== this.status && (this.status = e, this.events.status(e));
|
|
323
302
|
}
|
|
324
|
-
},
|
|
303
|
+
}, xe = 16, Se = class {
|
|
325
304
|
constructor(e, t, n, r = null) {
|
|
326
305
|
this.source = e, this.topic = t, this.events = n, this.notes = r, this.older = null, this.loading = null;
|
|
327
306
|
}
|
|
@@ -366,7 +345,7 @@ var X = {
|
|
|
366
345
|
try {
|
|
367
346
|
return await this.source.readHead();
|
|
368
347
|
} catch (e) {
|
|
369
|
-
if (e instanceof
|
|
348
|
+
if (e instanceof W) return this.events.error(e), null;
|
|
370
349
|
throw e;
|
|
371
350
|
}
|
|
372
351
|
}
|
|
@@ -381,30 +360,30 @@ var X = {
|
|
|
381
360
|
async loadOlderOnce() {
|
|
382
361
|
let e = this.older;
|
|
383
362
|
if (e === null) return [];
|
|
384
|
-
let t = await this.source.readFile(e.ref), n =
|
|
363
|
+
let t = await this.source.readFile(e.ref), n = A(t, this.topic, e);
|
|
385
364
|
if (!n.ok) throw this.older = null, Error(`history file ${e.ref} refused (${n.reason}): ${n.detail}`);
|
|
386
365
|
return this.report(n.value.skipped), this.older = n.value.prev, n.value.rows;
|
|
387
366
|
}
|
|
388
367
|
async newestLink(e, t) {
|
|
389
368
|
let n = t === void 0 ? e : e - 1;
|
|
390
369
|
if (t !== void 0) {
|
|
391
|
-
let n =
|
|
370
|
+
let n = D(t, e, this.topic);
|
|
392
371
|
if (n.ok) return n.value.history;
|
|
393
372
|
}
|
|
394
|
-
for (let t = n; t >= Math.max(0, e -
|
|
373
|
+
for (let t = n; t >= Math.max(0, e - xe); t--) {
|
|
395
374
|
let e = await this.source.readSlot(t).catch((e) => {
|
|
396
|
-
if (e instanceof
|
|
375
|
+
if (e instanceof G) return null;
|
|
397
376
|
throw e;
|
|
398
377
|
});
|
|
399
378
|
if (e === null) continue;
|
|
400
|
-
let n =
|
|
379
|
+
let n = D(e, t, this.topic);
|
|
401
380
|
if (n.ok) return n.value.history;
|
|
402
381
|
}
|
|
403
382
|
return null;
|
|
404
383
|
}
|
|
405
384
|
async readFile(e) {
|
|
406
385
|
try {
|
|
407
|
-
let t =
|
|
386
|
+
let t = A(await this.source.readFile(e.ref), this.topic, e);
|
|
408
387
|
return t.ok ? (this.report(t.value.skipped), this.older = t.value.prev, t.value.rows) : (this.events.error(/* @__PURE__ */ Error(`history file ${e.ref} refused (${t.reason}): ${t.detail}`)), "refused");
|
|
409
388
|
} catch (t) {
|
|
410
389
|
return this.events.error(t), this.older = e, null;
|
|
@@ -413,18 +392,18 @@ var X = {
|
|
|
413
392
|
report(e) {
|
|
414
393
|
e > 0 && this.events.skipped(e);
|
|
415
394
|
}
|
|
416
|
-
},
|
|
395
|
+
}, Ce = {
|
|
417
396
|
slotMs: C,
|
|
418
|
-
heartbeatMs:
|
|
397
|
+
heartbeatMs: T,
|
|
419
398
|
marginMs: 1e3,
|
|
420
399
|
scanBatch: 4,
|
|
421
400
|
clockLimitMs: 3e5,
|
|
422
|
-
missingReadSpacingMs:
|
|
401
|
+
missingReadSpacingMs: H
|
|
423
402
|
};
|
|
424
|
-
function
|
|
403
|
+
function we(e) {
|
|
425
404
|
return typeof e.readNote == "function";
|
|
426
405
|
}
|
|
427
|
-
var
|
|
406
|
+
var Te = class {
|
|
428
407
|
constructor(e) {
|
|
429
408
|
this.limitMs = e, this.aheadAtMost = Infinity, this.trusted = !0;
|
|
430
409
|
}
|
|
@@ -441,21 +420,21 @@ var ve = class {
|
|
|
441
420
|
let e = Number.isFinite(this.aheadAtMost), t = this.trusted || !e ? Math.min(0, this.aheadAtMost) : this.aheadAtMost;
|
|
442
421
|
return Math.max(-this.limitMs, Math.min(this.limitMs, t));
|
|
443
422
|
}
|
|
444
|
-
},
|
|
423
|
+
}, Z = class {
|
|
445
424
|
constructor(e, t, n) {
|
|
446
425
|
this.source = e, this.now = n, this.counts = {
|
|
447
426
|
found: 0,
|
|
448
427
|
empty: 0
|
|
449
428
|
}, this.settings = {
|
|
450
|
-
...
|
|
429
|
+
...Ce,
|
|
451
430
|
...t
|
|
452
|
-
}, this.clock = new
|
|
431
|
+
}, this.clock = new Te(this.settings.clockLimitMs), this.pacer = new U(this.settings.missingReadSpacingMs, n);
|
|
453
432
|
}
|
|
454
433
|
lastReadableSlot(e = this.now()) {
|
|
455
|
-
return
|
|
434
|
+
return E(e - this.settings.marginMs - this.clock.ms, this.settings.slotMs) - 1;
|
|
456
435
|
}
|
|
457
436
|
readableAt(e) {
|
|
458
|
-
return
|
|
437
|
+
return S(e, this.settings.slotMs) + this.settings.marginMs + this.clock.ms;
|
|
459
438
|
}
|
|
460
439
|
get lookBackSlots() {
|
|
461
440
|
return Math.ceil(this.settings.heartbeatMs / this.settings.slotMs) + 2;
|
|
@@ -469,10 +448,10 @@ var ve = class {
|
|
|
469
448
|
try {
|
|
470
449
|
t = await this.source.readNote(e), t === null && this.pacer.missed(e);
|
|
471
450
|
} catch (e) {
|
|
472
|
-
if (!(e instanceof
|
|
451
|
+
if (!(e instanceof G)) throw e;
|
|
473
452
|
t = null;
|
|
474
453
|
}
|
|
475
|
-
let n = t === null ? null :
|
|
454
|
+
let n = t === null ? null : x(t);
|
|
476
455
|
return n === null ? (this.counts.empty++, null) : (this.counts.found++, this.clock.observe(n.writtenAt, this.now()), n);
|
|
477
456
|
}
|
|
478
457
|
async scan(e, t) {
|
|
@@ -492,7 +471,7 @@ var ve = class {
|
|
|
492
471
|
maxResends: 5,
|
|
493
472
|
reactionWindowMs: 1e3,
|
|
494
473
|
isLive: () => !0
|
|
495
|
-
},
|
|
474
|
+
}, Ee = class {
|
|
496
475
|
constructor(e, t, n, r, i = Q) {
|
|
497
476
|
this.key = e, this.profile = t, this.write = n, this.events = r, this.settings = i, this.outgoing = /* @__PURE__ */ new Map(), this.reactions = /* @__PURE__ */ new Map(), this.stopped = !1;
|
|
498
477
|
}
|
|
@@ -500,7 +479,7 @@ var ve = class {
|
|
|
500
479
|
return this.key.publicKey().address().toHex();
|
|
501
480
|
}
|
|
502
481
|
send(e) {
|
|
503
|
-
let { message: t, bytes: n } =
|
|
482
|
+
let { message: t, bytes: n } = u(this.key, {
|
|
504
483
|
...e,
|
|
505
484
|
...this.profile
|
|
506
485
|
}), r = {
|
|
@@ -528,7 +507,7 @@ var ve = class {
|
|
|
528
507
|
let i = this.reactions.get(r);
|
|
529
508
|
this.reactions.delete(r), i && i.taps % 2 == 1 && !this.stopped && this.send({
|
|
530
509
|
topic: e,
|
|
531
|
-
type:
|
|
510
|
+
type: d.REACTION,
|
|
532
511
|
target: t,
|
|
533
512
|
text: n
|
|
534
513
|
});
|
|
@@ -565,41 +544,33 @@ var ve = class {
|
|
|
565
544
|
}
|
|
566
545
|
scheduleNext(e) {
|
|
567
546
|
!this.stopped && this.outgoing.has(e.message.id) && (e.timer = setTimeout(() => {
|
|
568
|
-
|
|
569
|
-
this.scheduleNext(e);
|
|
570
|
-
return;
|
|
571
|
-
}
|
|
572
|
-
if (e.writes > this.settings.maxResends) {
|
|
573
|
-
this.events.failed(e.message, e.lastError ?? /* @__PURE__ */ Error("never seen on the chat feed"));
|
|
574
|
-
return;
|
|
575
|
-
}
|
|
576
|
-
this.attempt(e);
|
|
547
|
+
e.timer = null, this.settings.isLive() ? e.writes > this.settings.maxResends ? this.events.failed(e.message, e.lastError ?? /* @__PURE__ */ Error("never seen on the chat feed")) : this.attempt(e) : this.scheduleNext(e);
|
|
577
548
|
}, this.settings.resendAfterMs));
|
|
578
549
|
}
|
|
579
550
|
clearTimer(e) {
|
|
580
551
|
e.timer &&= (clearTimeout(e.timer), null);
|
|
581
552
|
}
|
|
582
|
-
},
|
|
553
|
+
}, De = [
|
|
583
554
|
1e3,
|
|
584
555
|
2e3,
|
|
585
556
|
4e3,
|
|
586
557
|
8e3
|
|
587
|
-
],
|
|
558
|
+
], Oe = 3;
|
|
588
559
|
function $(e) {
|
|
589
560
|
return (e.startsWith("0x") ? e.slice(2) : e).toLowerCase();
|
|
590
561
|
}
|
|
591
|
-
var
|
|
562
|
+
var ke = class {
|
|
592
563
|
constructor(e, t = {}) {
|
|
593
|
-
this.emitter = new
|
|
564
|
+
this.emitter = new V(), this.seen = /* @__PURE__ */ new Set(), this.status = null, this.generation = 0, this.running = !1, this.starting = null, this.openTimer = null, this.wakeOpen = null;
|
|
594
565
|
let { user: n, infra: r } = e;
|
|
595
|
-
this.key = new
|
|
566
|
+
this.key = new F($(n.privateKey)), this.topic = r.chatTopic, this.profile = {
|
|
596
567
|
name: n.nickname,
|
|
597
568
|
via: r.via,
|
|
598
569
|
...n.binding ? { idb: n.binding } : {},
|
|
599
|
-
...
|
|
600
|
-
}, this.openRetryMs = t.openRetryMs ??
|
|
570
|
+
...n.walletLink ? { wl: n.walletLink } : {}
|
|
571
|
+
}, this.openRetryMs = t.openRetryMs ?? De, this.senderSettings = {
|
|
601
572
|
...Q,
|
|
602
|
-
isLive: () => this.status ===
|
|
573
|
+
isLive: () => this.status === Y.LIVE,
|
|
603
574
|
...t.sender
|
|
604
575
|
};
|
|
605
576
|
let i = {
|
|
@@ -611,28 +582,28 @@ var Ce = class {
|
|
|
611
582
|
...r.noteHeartbeatMs === void 0 ? {} : { heartbeatMs: r.noteHeartbeatMs },
|
|
612
583
|
...t.notes
|
|
613
584
|
};
|
|
614
|
-
this.source = t.source ??
|
|
585
|
+
this.source = t.source ?? ge(new M(r.beeUrl), $(r.chatAddress), r.chatTopic, i, a.slotMs), this.write = t.write ?? ve(new M(r.writeUrl ?? r.beeUrl), r.stamp ? $(r.stamp) : _e, $(r.gsocResourceId), r.gsocTopic, i);
|
|
615
586
|
let o = t.follower?.now ?? (() => Date.now()), s = {
|
|
616
587
|
pollIntervalMs: r.pollingInterval ?? 1e3,
|
|
617
588
|
...t.follower,
|
|
618
589
|
now: o
|
|
619
590
|
}, c = this.source;
|
|
620
|
-
this.notes =
|
|
591
|
+
this.notes = we(c) ? new Z(c, a, o) : null, this.follower = new be(this.source, this.topic, {
|
|
621
592
|
entry: (e) => this.show(e),
|
|
622
|
-
skipped: (e, t, n) => this.emitter.emit(
|
|
593
|
+
skipped: (e, t, n) => this.emitter.emit(L.MESSAGE_SKIPPED, {
|
|
623
594
|
index: e,
|
|
624
595
|
reason: t,
|
|
625
596
|
detail: n
|
|
626
597
|
}),
|
|
627
598
|
status: (e) => this.setStatus(e),
|
|
628
|
-
error: (e) => this.emitter.emit(
|
|
629
|
-
}, s, this.notes), this.history = new
|
|
630
|
-
skipped: (e) => this.emitter.emit(
|
|
599
|
+
error: (e) => this.emitter.emit(L.ERROR, e)
|
|
600
|
+
}, s, this.notes), this.history = new Se(this.source, this.topic, {
|
|
601
|
+
skipped: (e) => this.emitter.emit(L.MESSAGE_SKIPPED, {
|
|
631
602
|
index: -1,
|
|
632
603
|
reason: "history-row",
|
|
633
604
|
detail: `${e} rows of a history file`
|
|
634
605
|
}),
|
|
635
|
-
error: (e) => this.emitter.emit(
|
|
606
|
+
error: (e) => this.emitter.emit(L.ERROR, e)
|
|
636
607
|
}, this.notes), this.sender = this.makeSender();
|
|
637
608
|
}
|
|
638
609
|
getEmitter() {
|
|
@@ -656,11 +627,11 @@ var Ce = class {
|
|
|
656
627
|
this.running = !1, this.generation++, this.openTimer &&= (clearTimeout(this.openTimer), null), this.wakeOpen?.(), this.follower.stop(), this.sender.stop();
|
|
657
628
|
}
|
|
658
629
|
async sendMessage(e, t, n) {
|
|
659
|
-
if (t ===
|
|
630
|
+
if (t === d.REACTION) {
|
|
660
631
|
if (!n) throw Error("a reaction names the message it reacts to");
|
|
661
632
|
return this.sender.react(this.topic, n, e), null;
|
|
662
633
|
}
|
|
663
|
-
return
|
|
634
|
+
return R(this.sender.send({
|
|
664
635
|
topic: this.topic,
|
|
665
636
|
type: t,
|
|
666
637
|
target: n ?? "",
|
|
@@ -671,12 +642,12 @@ var Ce = class {
|
|
|
671
642
|
return this.sender.retry(typeof e == "string" ? e : e.id);
|
|
672
643
|
}
|
|
673
644
|
async fetchPreviousMessages() {
|
|
674
|
-
this.emitter.emit(
|
|
645
|
+
this.emitter.emit(L.LOADING_PREVIOUS_MESSAGES, !0);
|
|
675
646
|
try {
|
|
676
647
|
let e = this.generation, t = await this.history.loadOlder();
|
|
677
648
|
return e === this.generation ? this.showRows(t) : [];
|
|
678
649
|
} finally {
|
|
679
|
-
this.emitter.emit(
|
|
650
|
+
this.emitter.emit(L.LOADING_PREVIOUS_MESSAGES, !1);
|
|
680
651
|
}
|
|
681
652
|
}
|
|
682
653
|
hasPreviousMessages() {
|
|
@@ -686,16 +657,16 @@ var Ce = class {
|
|
|
686
657
|
return [...e].sort((e, t) => e.index >= 0 && t.index >= 0 ? e.index - t.index : e.index >= 0 || t.index >= 0 ? e.index >= 0 ? -1 : 1 : e.timestamp - t.timestamp);
|
|
687
658
|
}
|
|
688
659
|
async open(e) {
|
|
689
|
-
this.emitter.emit(
|
|
660
|
+
this.emitter.emit(L.LOADING_INIT, !0);
|
|
690
661
|
let t = 0;
|
|
691
662
|
for (; e === this.generation;) try {
|
|
692
663
|
let t = await this.history.open();
|
|
693
664
|
if (e !== this.generation) return;
|
|
694
|
-
this.showRows(t.rows), this.follower.start(t.startAt, t.notes), this.emitter.emit(
|
|
665
|
+
this.showRows(t.rows), this.follower.start(t.startAt, t.notes), this.emitter.emit(L.LOADING_INIT, !1);
|
|
695
666
|
return;
|
|
696
667
|
} catch (n) {
|
|
697
668
|
if (e !== this.generation) return;
|
|
698
|
-
t++, this.emitter.emit(
|
|
669
|
+
t++, this.emitter.emit(L.ERROR, n), this.setStatus(Y.RECONNECTING), t === Oe && this.emitter.emit(L.CRITICAL_ERROR, n), await this.waitToOpen(this.openRetryMs[Math.min(t, this.openRetryMs.length) - 1] ?? 8e3);
|
|
699
670
|
}
|
|
700
671
|
}
|
|
701
672
|
waitToOpen(e) {
|
|
@@ -708,31 +679,30 @@ var Ce = class {
|
|
|
708
679
|
});
|
|
709
680
|
}
|
|
710
681
|
makeSender() {
|
|
711
|
-
return new
|
|
712
|
-
pending: (e) => this.emitter.emit(
|
|
713
|
-
written: (e) => this.emitter.emit(
|
|
682
|
+
return new Ee(this.key, this.profile, this.write, {
|
|
683
|
+
pending: (e) => this.emitter.emit(L.MESSAGE_REQUEST_INITIATED, R(e)),
|
|
684
|
+
written: (e) => this.emitter.emit(L.MESSAGE_REQUEST_UPLOADED, R(e)),
|
|
714
685
|
failed: (e, t) => {
|
|
715
|
-
this.emitter.emit(
|
|
686
|
+
this.emitter.emit(L.ERROR, t), this.emitter.emit(L.MESSAGE_REQUEST_ERROR, R(e));
|
|
716
687
|
},
|
|
717
688
|
confirmed: () => {}
|
|
718
689
|
}, this.senderSettings);
|
|
719
690
|
}
|
|
720
691
|
show(e) {
|
|
721
|
-
this.seen.has(e.seq) || (this.seen.add(e.seq), this.sender.confirm(e.msg), this.emitter.emit(
|
|
692
|
+
this.seen.has(e.seq) || (this.seen.add(e.seq), this.sender.confirm(e.msg), this.emitter.emit(L.MESSAGE_RECEIVED, z(e)));
|
|
722
693
|
}
|
|
723
694
|
showRows(e) {
|
|
724
695
|
let t = [];
|
|
725
696
|
for (let n of e) {
|
|
726
697
|
if (this.seen.has(n.seq)) continue;
|
|
727
698
|
this.seen.add(n.seq), this.sender.confirm(n.msg);
|
|
728
|
-
let e =
|
|
729
|
-
t.push(e), this.emitter.emit(
|
|
699
|
+
let e = z(n);
|
|
700
|
+
t.push(e), this.emitter.emit(L.MESSAGE_RECEIVED, e);
|
|
730
701
|
}
|
|
731
702
|
return t;
|
|
732
703
|
}
|
|
733
704
|
setStatus(e) {
|
|
734
|
-
e !== this.status && (this.status = e, this.emitter.emit(
|
|
705
|
+
e !== this.status && (this.status = e, this.emitter.emit(L.STATUS, e));
|
|
735
706
|
}
|
|
736
707
|
};
|
|
737
|
-
|
|
738
|
-
export { M as CHAT_BINDING_TITLE, H as ChatEmitter, p as ChatMessageError, O as DEFAULT_NOTE_HEARTBEAT_MS, C as DEFAULT_NOTE_SLOT_MS, R as EVENTS, X as FeedStatus, G as HeadLookupTimeoutError, t as MAX_BINDING_CHARACTERS, T as MAX_ENTRY_BYTES, n as MAX_MESSAGE_BYTES, se as MAX_NAME_CHARACTERS, E as MAX_NOTE_BYTES, m as MAX_TEXT_CHARACTERS, i as MAX_TOPIC_CHARACTERS, r as MESSAGE_VERSION, u as MessageType, b as MessageVia, ae as NOTE_VERSION, ie as OWN_FEED_TOPIC_PREFIX, Ce as SwarmChat, Z as UnreadableGatewayError, K as UnreadableSlotError, te as chatBindingSchema, e as chatMessageSchema, o as checkChatBinding, oe as countCharacters, l as createChatMessage, ee as encodeChatMessage, re as encodeSlotNote, S as feedEntrySchema, d as hasValidSignature, y as historyFileSchema, v as historyLinkSchema, ne as historyRowSchema, a as newMessageId, w as noteAddress, D as noteIdentifier, h as noteIdentifierText, x as noteSlotEnd, k as noteSlotOf, ce as ownFeedTopic, s as parseChatMessage, A as parseFeedEntry, j as parseHistoryFile, g as parseSlotNote, c as signedBytes, _ as slotNoteSchema, f as verifyChatMessage };
|
|
708
|
+
export { o as CHAT_BINDING_TITLE, V as ChatEmitter, m as ChatMessageError, T as DEFAULT_NOTE_HEARTBEAT_MS, C as DEFAULT_NOTE_SLOT_MS, L as EVENTS, Y as FeedStatus, W as HeadLookupTimeoutError, l as MAX_BINDING_CHARACTERS, pe as MAX_ENTRY_BYTES, n as MAX_MESSAGE_BYTES, O as MAX_NAME_CHARACTERS, he as MAX_NOTE_BYTES, h as MAX_TEXT_CHARACTERS, i as MAX_TOPIC_CHARACTERS, t as MAX_WALLET_LINK_CHARACTERS, r as MESSAGE_VERSION, d as MessageType, ue as MessageVia, ce as NOTE_VERSION, re as OWN_FEED_TOPIC_PREFIX, ke as SwarmChat, X as UnreadableGatewayError, G as UnreadableSlotError, _ as WALLET_LINK_STATEMENT, s as WALLET_LINK_TITLE, me as chatBindingSchema, e as chatMessageSchema, ee as checkChatBinding, g as checkWalletLink, le as countCharacters, u as createChatMessage, ne as displayNameProblem, f as encodeChatMessage, b as encodeSlotNote, de as feedEntrySchema, a as hasValidSignature, se as historyFileSchema, oe as historyLinkSchema, y as historyRowSchema, c as newMessageId, fe as noteAddress, w as noteIdentifier, ie as noteIdentifierText, S as noteSlotEnd, E as noteSlotOf, k as ownFeedTopic, te as parseChatMessage, D as parseFeedEntry, A as parseHistoryFile, x as parseSlotNote, p as signedBytes, ae as slotNoteSchema, j as verifyChatMessage, v as walletLinkSchema };
|
|
@@ -2,15 +2,15 @@ import { z } from 'zod';
|
|
|
2
2
|
/**
|
|
3
3
|
* The Swarm ID chat binding: the account's statement, signed with its own key, that a chat address on one site is its
|
|
4
4
|
* own. The Swarm ID fork (solarpunk-id, `lib/src/utils/chat-binding.ts`) makes it, and this module reads it exactly as
|
|
5
|
-
*
|
|
5
|
+
* Swarm ID's `verifyChatBinding` does, without importing Swarm ID: the same four lines, the same clean site origin,
|
|
6
6
|
* the same EIP-191 personal_sign recovery with v 27 or 28 and a low s.
|
|
7
7
|
*/
|
|
8
8
|
/** The first line, which also versions the binding format. */
|
|
9
9
|
export declare const CHAT_BINDING_TITLE = "Swarm ID chat binding v1";
|
|
10
|
-
/**
|
|
10
|
+
/** Swarm ID's own bound on a binding's text. */
|
|
11
11
|
export declare const MAX_BINDING_CHARACTERS = 512;
|
|
12
12
|
/**
|
|
13
|
-
* A binding as a message carries it. `sig` is spelled as
|
|
13
|
+
* A binding as a message carries it. `sig` is spelled as Swarm ID writes it, `0x` and 130 lowercase hex characters
|
|
14
14
|
* of r, s and v, so one binding has one spelling inside the signed bytes.
|
|
15
15
|
*/
|
|
16
16
|
export declare const chatBindingSchema: z.ZodObject<{
|
|
@@ -26,10 +26,16 @@ export interface ChatIdentity {
|
|
|
26
26
|
site: string;
|
|
27
27
|
/** When the account says it signed, ISO 8601 UTC. */
|
|
28
28
|
date: string;
|
|
29
|
+
/**
|
|
30
|
+
* The wallet the message's Swarm ID wallet link names, `0x` and 40 lowercase hex characters, present only when the
|
|
31
|
+
* message carries a link both the wallet and this account signed. A reader looks its ENS name up itself, and the
|
|
32
|
+
* Swarm ID's `resolveVerifiedEnsName` does that with both the reverse and the forward record.
|
|
33
|
+
*/
|
|
34
|
+
wallet?: string;
|
|
29
35
|
}
|
|
30
36
|
export interface BindingOptions {
|
|
31
|
-
/** The
|
|
32
|
-
|
|
37
|
+
/** The origins the reader runs on, each bare. When given, a binding for a site not among them is refused. */
|
|
38
|
+
origins?: readonly string[];
|
|
33
39
|
/** Accept a binding for `http://localhost`, `http://127.0.0.1` or `http://[::1]`, as only a development build signs. */
|
|
34
40
|
allowLocalHttp?: boolean;
|
|
35
41
|
}
|
|
@@ -42,7 +48,7 @@ export type BindingCheck = {
|
|
|
42
48
|
};
|
|
43
49
|
/**
|
|
44
50
|
* Reads a binding for the chat address `addr` (40 lowercase hex characters, no `0x`). Refuses every text but the four
|
|
45
|
-
* lines
|
|
51
|
+
* lines Swarm ID writes, a binding for another chat address, one for a site not in `origins` when that is given,
|
|
46
52
|
* and a signature nothing recovers an account from. Never throws.
|
|
47
53
|
*/
|
|
48
54
|
export declare function checkChatBinding(binding: ChatBinding, addr: string, options?: BindingOptions): BindingCheck;
|