@wovin/connect-web3storage 0.1.36 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/chunk-6224SQ5A.js +2 -0
- package/dist/chunk-6224SQ5A.js.map +1 -0
- package/dist/chunk-LDGLUYRV.js +2 -0
- package/dist/chunk-LDGLUYRV.js.map +1 -0
- package/dist/chunk-SW4VIQUZ.js +2 -0
- package/dist/{chunk-XCHCNDQW.min.js.map → chunk-SW4VIQUZ.js.map} +1 -1
- package/dist/{chunk-BFHWRINC.min.js → chunk-U6PL7AYU.js} +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/dist/ipns.js +2 -0
- package/dist/retrieve.js +2 -0
- package/dist/store.js +1 -0
- package/dist/utils.js +2 -0
- package/dist/watch.js +2 -0
- package/package.json +13 -12
- package/src/index.ts +5 -0
- package/src/ipns.ts +103 -0
- package/src/retrieve.ts +97 -0
- package/src/store.ts +20 -0
- package/src/utils.ts +5 -0
- package/src/watch.ts +572 -0
- package/dist/chunk-6K4NRK7Q.min.js +0 -2
- package/dist/chunk-6K4NRK7Q.min.js.map +0 -1
- package/dist/chunk-D2SZILOK.min.js +0 -2
- package/dist/chunk-L7VH6KZJ.min.js +0 -3
- package/dist/chunk-L7VH6KZJ.min.js.map +0 -1
- package/dist/chunk-UKHFBNOE.min.js +0 -29
- package/dist/chunk-UKHFBNOE.min.js.map +0 -1
- package/dist/chunk-W6NJ5ZSK.min.js +0 -33
- package/dist/chunk-W6NJ5ZSK.min.js.map +0 -1
- package/dist/chunk-XCHCNDQW.min.js +0 -2
- package/dist/index.min.js +0 -2
- package/dist/ipns.min.js +0 -2
- package/dist/retrieve.min.js +0 -2
- package/dist/store.min.js +0 -1
- package/dist/utils.min.js +0 -2
- package/dist/watch.min.js +0 -2
- package/dist/watch.min.js.map +0 -1
- /package/dist/{chunk-BFHWRINC.min.js.map → chunk-U6PL7AYU.js.map} +0 -0
- /package/dist/{chunk-D2SZILOK.min.js.map → index.js.map} +0 -0
- /package/dist/{index.min.js.map → ipns.js.map} +0 -0
- /package/dist/{ipns.min.js.map → retrieve.js.map} +0 -0
- /package/dist/{retrieve.min.js.map → store.js.map} +0 -0
- /package/dist/{store.min.js.map → utils.js.map} +0 -0
- /package/dist/{utils.min.js.map → watch.js.map} +0 -0
package/src/watch.ts
ADDED
|
@@ -0,0 +1,572 @@
|
|
|
1
|
+
import { Logger } from 'besonders-logger'
|
|
2
|
+
import { CID } from 'multiformats/cid'
|
|
3
|
+
import ReconnectingWebSocket, { type Options as PartysocketOptions } from 'partysocket/ws'
|
|
4
|
+
|
|
5
|
+
export type { PartysocketOptions }
|
|
6
|
+
|
|
7
|
+
const { WARN, LOG, DEBUG, ERROR } = Logger.setup(Logger.INFO) // eslint-disable-line unused-imports/no-unused-vars
|
|
8
|
+
|
|
9
|
+
const NAME_WS_URL = 'wss://name.web3.storage/name'
|
|
10
|
+
const NAME_HTTP_URL = 'https://name.web3.storage/name'
|
|
11
|
+
|
|
12
|
+
export interface W3NameRecord {
|
|
13
|
+
value: string // e.g. "/ipfs/bafybeigdyrzt5sfp7udm7hu76uh7y26nf3efuylqabf3oclgtqy55fbzdi"
|
|
14
|
+
seq?: number
|
|
15
|
+
validity?: string
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
/**
|
|
19
|
+
* Debug info provided when a stale WebSocket connection is detected.
|
|
20
|
+
*/
|
|
21
|
+
export interface StaleConnectionInfo {
|
|
22
|
+
/** When the WebSocket connection was established */
|
|
23
|
+
connectedAt: Date
|
|
24
|
+
/** When we last received a WebSocket message */
|
|
25
|
+
lastMessageAt: Date | null
|
|
26
|
+
/** How long since last message (ms) */
|
|
27
|
+
silenceDuration: number
|
|
28
|
+
/** The stale value from WebSocket */
|
|
29
|
+
staleValue: string | null
|
|
30
|
+
/** The current value from HTTP */
|
|
31
|
+
currentValue: string
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
/**
|
|
35
|
+
* Enriched IPNS update with parsed CID and change detection.
|
|
36
|
+
* Backwards compatible - `.value` still works as before.
|
|
37
|
+
*/
|
|
38
|
+
export interface IpnsUpdate {
|
|
39
|
+
/** Raw IPNS value string (e.g. '/ipfs/bafy...') — same as W3NameRecord.value */
|
|
40
|
+
value: string
|
|
41
|
+
/** Parsed CID if value is valid IPFS path, null otherwise */
|
|
42
|
+
cid: CID | null
|
|
43
|
+
/** Previous value (null on first update) */
|
|
44
|
+
lastValue: string | null
|
|
45
|
+
/** Whether this is a change from lastValue */
|
|
46
|
+
isNew: boolean
|
|
47
|
+
/** Original W3NameRecord for access to seq/validity */
|
|
48
|
+
record: W3NameRecord
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
/**
|
|
52
|
+
* Parse CID from IPNS value string (e.g. "/ipfs/bafybeig...")
|
|
53
|
+
* @returns CID if valid, null otherwise
|
|
54
|
+
*/
|
|
55
|
+
function parseCidFromIpnsValue(value: string): CID | null {
|
|
56
|
+
try {
|
|
57
|
+
// Strip /ipfs/ prefix if present
|
|
58
|
+
const cidStr = value.startsWith('/ipfs/') ? value.slice(6) : value
|
|
59
|
+
return CID.parse(cidStr)
|
|
60
|
+
} catch {
|
|
61
|
+
DEBUG('[parseCidFromIpnsValue] failed to parse:', value)
|
|
62
|
+
return null
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
export interface WatchRawOptions {
|
|
67
|
+
/** Called when the IPNS record is updated */
|
|
68
|
+
onUpdate: (record: W3NameRecord) => void
|
|
69
|
+
/** Called when an error occurs */
|
|
70
|
+
onError?: (error: Event | Error) => void
|
|
71
|
+
/** Called when the connection is opened */
|
|
72
|
+
onOpen?: () => void
|
|
73
|
+
/** Called when the connection is closed */
|
|
74
|
+
onClose?: (event: CloseEvent) => void
|
|
75
|
+
}
|
|
76
|
+
|
|
77
|
+
export interface WatchRawSubscription {
|
|
78
|
+
/** Close the WebSocket connection */
|
|
79
|
+
close: () => void
|
|
80
|
+
/** The underlying WebSocket instance */
|
|
81
|
+
ws: WebSocket
|
|
82
|
+
}
|
|
83
|
+
|
|
84
|
+
/**
|
|
85
|
+
* Low-level WebSocket watcher for IPNS (no reconnect logic).
|
|
86
|
+
* Use this when you want full control over connection lifecycle.
|
|
87
|
+
* For most cases, prefer `watchName` or `IpnsWatcher` which handle reconnection.
|
|
88
|
+
*
|
|
89
|
+
* @param name - The IPNS name/key to watch
|
|
90
|
+
* @param options - Callback options
|
|
91
|
+
* @returns Subscription with close() and ws
|
|
92
|
+
*
|
|
93
|
+
* @example
|
|
94
|
+
* ```ts
|
|
95
|
+
* const sub = watchNameRaw('k51qzi5u...', {
|
|
96
|
+
* onUpdate: (record) => console.log('Update:', record.value),
|
|
97
|
+
* onClose: () => console.log('Disconnected - handle reconnect yourself'),
|
|
98
|
+
* })
|
|
99
|
+
* ```
|
|
100
|
+
*/
|
|
101
|
+
export function watchNameRaw(name: string, options: WatchRawOptions): WatchRawSubscription {
|
|
102
|
+
const url = `${NAME_WS_URL}/${name}/watch`
|
|
103
|
+
DEBUG('[watchNameRaw] connecting to', url)
|
|
104
|
+
|
|
105
|
+
const ws = new WebSocket(url)
|
|
106
|
+
|
|
107
|
+
ws.onopen = () => {
|
|
108
|
+
LOG('[watchNameRaw] connected to', name)
|
|
109
|
+
options.onOpen?.()
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
ws.onmessage = (event) => {
|
|
113
|
+
try {
|
|
114
|
+
const record: W3NameRecord = JSON.parse(event.data)
|
|
115
|
+
DEBUG('[watchNameRaw] received update for', name, record)
|
|
116
|
+
options.onUpdate(record)
|
|
117
|
+
} catch (err) {
|
|
118
|
+
WARN('[watchNameRaw] failed to parse message:', event.data, err)
|
|
119
|
+
options.onError?.(err instanceof Error ? err : new Error(String(err)))
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
ws.onerror = (event) => {
|
|
124
|
+
WARN('[watchNameRaw] error for', name, event)
|
|
125
|
+
options.onError?.(event)
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
ws.onclose = (event) => {
|
|
129
|
+
DEBUG('[watchNameRaw] closed for', name, 'code:', event.code)
|
|
130
|
+
options.onClose?.(event)
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return {
|
|
134
|
+
close: () => {
|
|
135
|
+
DEBUG('[watchNameRaw] closing connection for', name)
|
|
136
|
+
ws.close()
|
|
137
|
+
},
|
|
138
|
+
ws,
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
|
|
142
|
+
export interface IpnsWatcherOptions {
|
|
143
|
+
/** Called when the IPNS record is updated (enriched payload with CID and change detection) */
|
|
144
|
+
onUpdate: (update: IpnsUpdate) => void | Promise<void>
|
|
145
|
+
/** Called when an error occurs */
|
|
146
|
+
onError?: (error: Error | Event) => void
|
|
147
|
+
/** Called when the connection is opened/reconnected */
|
|
148
|
+
onConnected?: () => void
|
|
149
|
+
/** Called when the connection is closed */
|
|
150
|
+
onDisconnected?: () => void
|
|
151
|
+
/** Fetch current IPNS state on first connect (default: false) */
|
|
152
|
+
fetchInitialState?: boolean
|
|
153
|
+
/** Fetch current IPNS state on reconnect to catch missed updates (default: true) */
|
|
154
|
+
catchUpOnReconnect?: boolean
|
|
155
|
+
/** If true, call onUpdate even when value hasn't changed (default: false) */
|
|
156
|
+
includeUnchanged?: boolean
|
|
157
|
+
/**
|
|
158
|
+
* Enable periodic liveness checks via HTTP to detect zombie connections (default: true).
|
|
159
|
+
* When enabled, periodically fetches current IPNS value and forces reconnect if it
|
|
160
|
+
* differs from the last WebSocket update.
|
|
161
|
+
*/
|
|
162
|
+
livenessCheck?: boolean
|
|
163
|
+
/**
|
|
164
|
+
* Liveness check interval in milliseconds (default: 3600000 = 1 hour).
|
|
165
|
+
* Only used when livenessCheck is enabled.
|
|
166
|
+
*/
|
|
167
|
+
livenessCheckInterval?: number
|
|
168
|
+
/**
|
|
169
|
+
* Called when a stale connection is detected (WebSocket missed updates).
|
|
170
|
+
* Provides debug info about the connection state.
|
|
171
|
+
*/
|
|
172
|
+
onStaleConnection?: (info: StaleConnectionInfo) => void
|
|
173
|
+
/**
|
|
174
|
+
* Partysocket options (passed through to ReconnectingWebSocket).
|
|
175
|
+
* Useful options: startClosed, maxReconnectionDelay, minReconnectionDelay, etc.
|
|
176
|
+
* @see https://github.com/partykit/partykit/tree/main/packages/partysocket
|
|
177
|
+
*/
|
|
178
|
+
wsOptions?: PartysocketOptions
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
/**
|
|
182
|
+
* Robust IPNS watcher with auto-reconnect and catch-up logic.
|
|
183
|
+
* Uses partysocket for reliable WebSocket reconnection.
|
|
184
|
+
*
|
|
185
|
+
* @example
|
|
186
|
+
* ```ts
|
|
187
|
+
* const watcher = new IpnsWatcher('k51qzi5uqu...', {
|
|
188
|
+
* onUpdate: (update) => console.log('New CID:', update.cid?.toString()),
|
|
189
|
+
* onError: (err) => console.error('Error:', err),
|
|
190
|
+
* })
|
|
191
|
+
*
|
|
192
|
+
* // Later, to stop watching:
|
|
193
|
+
* watcher.close()
|
|
194
|
+
* ```
|
|
195
|
+
*/
|
|
196
|
+
const DEFAULT_LIVENESS_INTERVAL = 3600000 // 1 hour
|
|
197
|
+
|
|
198
|
+
export class IpnsWatcher {
|
|
199
|
+
private name: string
|
|
200
|
+
private ws: ReconnectingWebSocket
|
|
201
|
+
private lastKnownValue: string | null = null
|
|
202
|
+
private options: IpnsWatcherOptions
|
|
203
|
+
private isFirstConnect = true
|
|
204
|
+
private livenessTimer: ReturnType<typeof setInterval> | null = null
|
|
205
|
+
private connectedAt: Date | null = null
|
|
206
|
+
private lastMessageAt: Date | null = null
|
|
207
|
+
|
|
208
|
+
constructor(name: string, options: IpnsWatcherOptions) {
|
|
209
|
+
this.name = name
|
|
210
|
+
this.options = options
|
|
211
|
+
|
|
212
|
+
const url = `${NAME_WS_URL}/${name}/watch`
|
|
213
|
+
DEBUG('[IpnsWatcher] creating for', name)
|
|
214
|
+
|
|
215
|
+
this.ws = new ReconnectingWebSocket(url, [], {
|
|
216
|
+
maxReconnectionDelay: 900000, // 15min
|
|
217
|
+
minReconnectionDelay: 5000,
|
|
218
|
+
reconnectionDelayGrowFactor: 2,
|
|
219
|
+
maxRetries: Infinity,
|
|
220
|
+
...options.wsOptions,
|
|
221
|
+
})
|
|
222
|
+
|
|
223
|
+
this.ws.onopen = () => {
|
|
224
|
+
LOG('[IpnsWatcher] connected to', name)
|
|
225
|
+
this.connectedAt = new Date()
|
|
226
|
+
options.onConnected?.()
|
|
227
|
+
|
|
228
|
+
// Check for current state on first connect if requested
|
|
229
|
+
if (this.isFirstConnect && (options.fetchInitialState ?? false)) {
|
|
230
|
+
this.checkForMissedUpdates()
|
|
231
|
+
}
|
|
232
|
+
// Check for missed updates on reconnect
|
|
233
|
+
else if (!this.isFirstConnect && (options.catchUpOnReconnect ?? true)) {
|
|
234
|
+
this.checkForMissedUpdates()
|
|
235
|
+
}
|
|
236
|
+
|
|
237
|
+
this.isFirstConnect = false
|
|
238
|
+
|
|
239
|
+
// Start liveness checking (default: enabled)
|
|
240
|
+
if (options.livenessCheck !== false) {
|
|
241
|
+
this.startLivenessCheck()
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
|
|
245
|
+
this.ws.onmessage = (event) => {
|
|
246
|
+
this.lastMessageAt = new Date()
|
|
247
|
+
try {
|
|
248
|
+
const record: W3NameRecord = JSON.parse(event.data as string)
|
|
249
|
+
DEBUG('[IpnsWatcher] received update for', name, record)
|
|
250
|
+
|
|
251
|
+
const lastValue = this.lastKnownValue
|
|
252
|
+
const isNew = record.value !== lastValue
|
|
253
|
+
const cid = parseCidFromIpnsValue(record.value)
|
|
254
|
+
|
|
255
|
+
// Skip unchanged values unless includeUnchanged is set
|
|
256
|
+
if (!isNew && !options.includeUnchanged) {
|
|
257
|
+
DEBUG('[IpnsWatcher] skipping unchanged value for', name)
|
|
258
|
+
return
|
|
259
|
+
}
|
|
260
|
+
|
|
261
|
+
// Update lastKnownValue after the skip check
|
|
262
|
+
this.lastKnownValue = record.value
|
|
263
|
+
|
|
264
|
+
const update: IpnsUpdate = {
|
|
265
|
+
value: record.value,
|
|
266
|
+
cid,
|
|
267
|
+
lastValue,
|
|
268
|
+
isNew,
|
|
269
|
+
record,
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
void options.onUpdate(update)
|
|
273
|
+
} catch (err) {
|
|
274
|
+
WARN('[IpnsWatcher] failed to parse message:', event.data, err)
|
|
275
|
+
options.onError?.(err instanceof Error ? err : new Error(String(err)))
|
|
276
|
+
}
|
|
277
|
+
}
|
|
278
|
+
|
|
279
|
+
this.ws.onerror = (event) => {
|
|
280
|
+
// Extract meaningful error info instead of logging entire ErrorEvent
|
|
281
|
+
const errorMsg = event instanceof ErrorEvent ? event.message : 'WebSocket error'
|
|
282
|
+
|
|
283
|
+
// "Unexpected EOF" is a normal disconnection - partysocket will auto-reconnect
|
|
284
|
+
// Log at INFO level as it's expected behavior, not an error
|
|
285
|
+
if (errorMsg === 'Unexpected EOF') {
|
|
286
|
+
LOG('[IpnsWatcher] error for', name, ':', errorMsg, '(auto-reconnect enabled)')
|
|
287
|
+
} else {
|
|
288
|
+
WARN('[IpnsWatcher] error for', name, ':', errorMsg)
|
|
289
|
+
}
|
|
290
|
+
|
|
291
|
+
// Still call the error handler for unexpected errors
|
|
292
|
+
if (errorMsg !== 'Unexpected EOF') {
|
|
293
|
+
options.onError?.(event)
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
|
|
297
|
+
this.ws.onclose = () => {
|
|
298
|
+
DEBUG('[IpnsWatcher] disconnected from', name)
|
|
299
|
+
this.stopLivenessCheck()
|
|
300
|
+
this.connectedAt = null
|
|
301
|
+
this.lastMessageAt = null
|
|
302
|
+
options.onDisconnected?.()
|
|
303
|
+
}
|
|
304
|
+
}
|
|
305
|
+
|
|
306
|
+
/**
|
|
307
|
+
* Resolve current IPNS value via HTTP API to catch missed updates
|
|
308
|
+
*/
|
|
309
|
+
private async checkForMissedUpdates(): Promise<void> {
|
|
310
|
+
try {
|
|
311
|
+
DEBUG('[IpnsWatcher] checking for missed updates for', this.name)
|
|
312
|
+
const response = await fetch(`${NAME_HTTP_URL}/${this.name}`)
|
|
313
|
+
|
|
314
|
+
if (!response.ok) {
|
|
315
|
+
if (response.status === 404) {
|
|
316
|
+
DEBUG('[IpnsWatcher] IPNS not yet published:', this.name)
|
|
317
|
+
return
|
|
318
|
+
}
|
|
319
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const record: W3NameRecord = await response.json()
|
|
323
|
+
const lastValue = this.lastKnownValue
|
|
324
|
+
const isNew = record.value !== lastValue
|
|
325
|
+
const cid = parseCidFromIpnsValue(record.value)
|
|
326
|
+
|
|
327
|
+
// Skip unchanged values unless includeUnchanged is set
|
|
328
|
+
if (!isNew && !this.options.includeUnchanged) {
|
|
329
|
+
DEBUG('[IpnsWatcher] no new updates for', this.name)
|
|
330
|
+
return
|
|
331
|
+
}
|
|
332
|
+
|
|
333
|
+
const logMsg = lastValue === null
|
|
334
|
+
? '[IpnsWatcher] fetched initial state for'
|
|
335
|
+
: '[IpnsWatcher] caught missed update for'
|
|
336
|
+
LOG(logMsg, this.name, {
|
|
337
|
+
previous: lastValue,
|
|
338
|
+
current: record.value,
|
|
339
|
+
})
|
|
340
|
+
|
|
341
|
+
// Update lastKnownValue after the skip check
|
|
342
|
+
this.lastKnownValue = record.value
|
|
343
|
+
|
|
344
|
+
const update: IpnsUpdate = {
|
|
345
|
+
value: record.value,
|
|
346
|
+
cid,
|
|
347
|
+
lastValue,
|
|
348
|
+
isNew,
|
|
349
|
+
record,
|
|
350
|
+
}
|
|
351
|
+
|
|
352
|
+
void this.options.onUpdate(update)
|
|
353
|
+
} catch (err) {
|
|
354
|
+
WARN('[IpnsWatcher] failed to check for missed updates:', this.name, err)
|
|
355
|
+
this.options.onError?.(err instanceof Error ? err : new Error(String(err)))
|
|
356
|
+
}
|
|
357
|
+
}
|
|
358
|
+
|
|
359
|
+
/**
|
|
360
|
+
* Start periodic liveness checks to detect zombie connections.
|
|
361
|
+
*/
|
|
362
|
+
private startLivenessCheck(): void {
|
|
363
|
+
this.stopLivenessCheck() // Clear any existing timer
|
|
364
|
+
const interval = this.options.livenessCheckInterval ?? DEFAULT_LIVENESS_INTERVAL
|
|
365
|
+
DEBUG('[IpnsWatcher] starting liveness check for', this.name, 'interval:', interval)
|
|
366
|
+
|
|
367
|
+
this.livenessTimer = setInterval(() => {
|
|
368
|
+
void this.performLivenessCheck()
|
|
369
|
+
}, interval)
|
|
370
|
+
}
|
|
371
|
+
|
|
372
|
+
/**
|
|
373
|
+
* Stop periodic liveness checks.
|
|
374
|
+
*/
|
|
375
|
+
private stopLivenessCheck(): void {
|
|
376
|
+
if (this.livenessTimer !== null) {
|
|
377
|
+
DEBUG('[IpnsWatcher] stopping liveness check for', this.name)
|
|
378
|
+
clearInterval(this.livenessTimer)
|
|
379
|
+
this.livenessTimer = null
|
|
380
|
+
}
|
|
381
|
+
}
|
|
382
|
+
|
|
383
|
+
/**
|
|
384
|
+
* Perform a single liveness check via HTTP.
|
|
385
|
+
* If the HTTP value differs from lastKnownValue, the connection is stale.
|
|
386
|
+
*/
|
|
387
|
+
private async performLivenessCheck(): Promise<void> {
|
|
388
|
+
try {
|
|
389
|
+
DEBUG('[IpnsWatcher] performing liveness check for', this.name)
|
|
390
|
+
const response = await fetch(`${NAME_HTTP_URL}/${this.name}`)
|
|
391
|
+
|
|
392
|
+
if (!response.ok) {
|
|
393
|
+
if (response.status === 404) {
|
|
394
|
+
// IPNS not published - if we also have null, that's consistent
|
|
395
|
+
if (this.lastKnownValue === null) {
|
|
396
|
+
DEBUG('[IpnsWatcher] liveness check OK (both null) for', this.name)
|
|
397
|
+
return
|
|
398
|
+
}
|
|
399
|
+
// We have a value but HTTP says 404 - this shouldn't happen normally
|
|
400
|
+
WARN('[IpnsWatcher] liveness check inconsistent (we have value, HTTP 404) for', this.name)
|
|
401
|
+
return
|
|
402
|
+
}
|
|
403
|
+
throw new Error(`HTTP ${response.status}: ${response.statusText}`)
|
|
404
|
+
}
|
|
405
|
+
|
|
406
|
+
const record: W3NameRecord = await response.json()
|
|
407
|
+
|
|
408
|
+
// Check if values match
|
|
409
|
+
if (record.value === this.lastKnownValue) {
|
|
410
|
+
DEBUG('[IpnsWatcher] liveness check OK for', this.name)
|
|
411
|
+
return
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
// Stale connection detected!
|
|
415
|
+
const now = new Date()
|
|
416
|
+
const silenceDuration = this.lastMessageAt
|
|
417
|
+
? now.getTime() - this.lastMessageAt.getTime()
|
|
418
|
+
: this.connectedAt
|
|
419
|
+
? now.getTime() - this.connectedAt.getTime()
|
|
420
|
+
: 0
|
|
421
|
+
|
|
422
|
+
const staleInfo: StaleConnectionInfo = {
|
|
423
|
+
connectedAt: this.connectedAt ?? now,
|
|
424
|
+
lastMessageAt: this.lastMessageAt,
|
|
425
|
+
silenceDuration,
|
|
426
|
+
staleValue: this.lastKnownValue,
|
|
427
|
+
currentValue: record.value,
|
|
428
|
+
}
|
|
429
|
+
|
|
430
|
+
WARN('[IpnsWatcher] stale connection detected for', this.name, {
|
|
431
|
+
connectedAt: staleInfo.connectedAt.toISOString(),
|
|
432
|
+
lastMessageAt: staleInfo.lastMessageAt?.toISOString() ?? 'never',
|
|
433
|
+
silenceDuration: `${Math.round(silenceDuration / 1000)}s`,
|
|
434
|
+
staleValue: staleInfo.staleValue,
|
|
435
|
+
currentValue: staleInfo.currentValue,
|
|
436
|
+
})
|
|
437
|
+
|
|
438
|
+
// Notify via callback
|
|
439
|
+
this.options.onStaleConnection?.(staleInfo)
|
|
440
|
+
|
|
441
|
+
// Fire immediate update with the current value
|
|
442
|
+
const lastValue = this.lastKnownValue
|
|
443
|
+
const cid = parseCidFromIpnsValue(record.value)
|
|
444
|
+
this.lastKnownValue = record.value
|
|
445
|
+
|
|
446
|
+
const update: IpnsUpdate = {
|
|
447
|
+
value: record.value,
|
|
448
|
+
cid,
|
|
449
|
+
lastValue,
|
|
450
|
+
isNew: true,
|
|
451
|
+
record,
|
|
452
|
+
}
|
|
453
|
+
void this.options.onUpdate(update)
|
|
454
|
+
|
|
455
|
+
// Force reconnect to get a fresh connection
|
|
456
|
+
LOG('[IpnsWatcher] forcing reconnect due to stale connection for', this.name)
|
|
457
|
+
this.ws.reconnect()
|
|
458
|
+
} catch (err) {
|
|
459
|
+
// Don't treat HTTP errors as stale - could be network issue
|
|
460
|
+
WARN('[IpnsWatcher] liveness check failed for', this.name, err)
|
|
461
|
+
}
|
|
462
|
+
}
|
|
463
|
+
|
|
464
|
+
/**
|
|
465
|
+
* Manually start/reconnect the WebSocket.
|
|
466
|
+
* Only needed if you used `wsOptions: { startClosed: true }`.
|
|
467
|
+
*/
|
|
468
|
+
start(): void {
|
|
469
|
+
LOG('[IpnsWatcher] starting watcher for', this.name)
|
|
470
|
+
this.ws.reconnect()
|
|
471
|
+
}
|
|
472
|
+
|
|
473
|
+
/**
|
|
474
|
+
* Alias for close() - for backward compatibility
|
|
475
|
+
*/
|
|
476
|
+
stop(): void {
|
|
477
|
+
this.close()
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
/**
|
|
481
|
+
* Close the WebSocket connection and stop watching
|
|
482
|
+
*/
|
|
483
|
+
close(): void {
|
|
484
|
+
LOG('[IpnsWatcher] closing watcher for', this.name)
|
|
485
|
+
this.stopLivenessCheck()
|
|
486
|
+
this.ws.close()
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
/**
|
|
490
|
+
* Get the last known IPNS value
|
|
491
|
+
*/
|
|
492
|
+
get lastValue(): string | null {
|
|
493
|
+
return this.lastKnownValue
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
/**
|
|
497
|
+
* Get the WebSocket ready state
|
|
498
|
+
*/
|
|
499
|
+
get readyState(): number {
|
|
500
|
+
return this.ws.readyState
|
|
501
|
+
}
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
/**
|
|
505
|
+
* Create an IPNS watcher with auto-reconnect and catch-up logic.
|
|
506
|
+
* Convenience function that creates and returns an IpnsWatcher instance.
|
|
507
|
+
*
|
|
508
|
+
* @param name - The IPNS name/key to watch (e.g. "k51qzi5u...")
|
|
509
|
+
* @param options - Callback options for handling events
|
|
510
|
+
* @returns An IpnsWatcher instance with close() method
|
|
511
|
+
*/
|
|
512
|
+
export function watchName(name: string, options: IpnsWatcherOptions): IpnsWatcher {
|
|
513
|
+
return new IpnsWatcher(name, options)
|
|
514
|
+
}
|
|
515
|
+
|
|
516
|
+
/**
|
|
517
|
+
* Watch an IPNS name and return updates as an async iterator.
|
|
518
|
+
* Includes auto-reconnect - iterator continues through disconnections.
|
|
519
|
+
*
|
|
520
|
+
* @param name - The IPNS name/key to watch
|
|
521
|
+
* @param signal - Optional AbortSignal to stop the watch
|
|
522
|
+
*
|
|
523
|
+
* @example
|
|
524
|
+
* ```ts
|
|
525
|
+
* const controller = new AbortController()
|
|
526
|
+
* for await (const update of watchNameIterator('k51qzi5u...', controller.signal)) {
|
|
527
|
+
* console.log('Update:', update.cid?.toString())
|
|
528
|
+
* }
|
|
529
|
+
* ```
|
|
530
|
+
*/
|
|
531
|
+
export async function* watchNameIterator(
|
|
532
|
+
name: string,
|
|
533
|
+
signal?: AbortSignal,
|
|
534
|
+
): AsyncGenerator<IpnsUpdate, void, unknown> {
|
|
535
|
+
const queue: IpnsUpdate[] = []
|
|
536
|
+
let resolve: (() => void) | null = null
|
|
537
|
+
let error: Error | null = null
|
|
538
|
+
|
|
539
|
+
const watcher = new IpnsWatcher(name, {
|
|
540
|
+
onUpdate: (update) => {
|
|
541
|
+
queue.push(update)
|
|
542
|
+
resolve?.()
|
|
543
|
+
},
|
|
544
|
+
onError: (err) => {
|
|
545
|
+
error = err instanceof Error ? err : new Error('WebSocket error')
|
|
546
|
+
resolve?.()
|
|
547
|
+
},
|
|
548
|
+
})
|
|
549
|
+
|
|
550
|
+
signal?.addEventListener('abort', () => {
|
|
551
|
+
watcher.close()
|
|
552
|
+
})
|
|
553
|
+
|
|
554
|
+
try {
|
|
555
|
+
while (!signal?.aborted) {
|
|
556
|
+
if (queue.length > 0) {
|
|
557
|
+
yield queue.shift()!
|
|
558
|
+
} else if (error) {
|
|
559
|
+
// Log error but continue - partysocket will reconnect
|
|
560
|
+
WARN('[watchNameIterator] error occurred, continuing:', error)
|
|
561
|
+
error = null
|
|
562
|
+
} else {
|
|
563
|
+
await new Promise<void>((r) => {
|
|
564
|
+
resolve = r
|
|
565
|
+
})
|
|
566
|
+
resolve = null
|
|
567
|
+
}
|
|
568
|
+
}
|
|
569
|
+
} finally {
|
|
570
|
+
watcher.close()
|
|
571
|
+
}
|
|
572
|
+
}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var I=new Uint8Array(0);function J(r,e){if(r===e)return!0;if(r.byteLength!==e.byteLength)return!1;for(let t=0;t<r.byteLength;t++)if(r[t]!==e[t])return!1;return!0}function N(r){if(r instanceof Uint8Array&&r.constructor.name==="Uint8Array")return r;if(r instanceof ArrayBuffer)return new Uint8Array(r);if(ArrayBuffer.isView(r))return new Uint8Array(r.buffer,r.byteOffset,r.byteLength);throw new Error("Unknown type, must be binary type")}function R(r,e){if(r.length>=255)throw new TypeError("Alphabet too long");for(var t=new Uint8Array(256),o=0;o<t.length;o++)t[o]=255;for(var i=0;i<r.length;i++){var d=r.charAt(i),s=d.charCodeAt(0);if(t[s]!==255)throw new TypeError(d+" is ambiguous");t[s]=i}var f=r.length,h=r.charAt(0),m=Math.log(f)/Math.log(256),w=Math.log(256)/Math.log(f);function U(n){if(n instanceof Uint8Array||(ArrayBuffer.isView(n)?n=new Uint8Array(n.buffer,n.byteOffset,n.byteLength):Array.isArray(n)&&(n=Uint8Array.from(n))),!(n instanceof Uint8Array))throw new TypeError("Expected Uint8Array");if(n.length===0)return"";for(var a=0,A=0,u=0,p=n.length;u!==p&&n[u]===0;)u++,a++;for(var y=(p-u)*w+1>>>0,c=new Uint8Array(y);u!==p;){for(var g=n[u],x=0,l=y-1;(g!==0||x<A)&&l!==-1;l--,x++)g+=256*c[l]>>>0,c[l]=g%f>>>0,g=g/f>>>0;if(g!==0)throw new Error("Non-zero carry");A=x,u++}for(var v=y-A;v!==y&&c[v]===0;)v++;for(var b=h.repeat(a);v<y;++v)b+=r.charAt(c[v]);return b}function O(n){if(typeof n!="string")throw new TypeError("Expected String");if(n.length===0)return new Uint8Array;var a=0;if(n[a]!==" "){for(var A=0,u=0;n[a]===h;)A++,a++;for(var p=(n.length-a)*m+1>>>0,y=new Uint8Array(p);n[a];){var c=t[n.charCodeAt(a)];if(c===255)return;for(var g=0,x=p-1;(c!==0||g<u)&&x!==-1;x--,g++)c+=f*y[x]>>>0,y[x]=c%256>>>0,c=c/256>>>0;if(c!==0)throw new Error("Non-zero carry");u=g,a++}if(n[a]!==" "){for(var l=p-u;l!==p&&y[l]===0;)l++;for(var v=new Uint8Array(A+(p-l)),b=A;l!==p;)v[b++]=y[l++];return v}}}function D(n){var a=O(n);if(a)return a;throw new Error(`Non-${e} character`)}return{encode:U,decodeUnsafe:O,decode:D}}var B=R,T=B,_=T;var E=class{name;prefix;baseEncode;constructor(e,t,o){this.name=e,this.prefix=t,this.baseEncode=o}encode(e){if(e instanceof Uint8Array)return`${this.prefix}${this.baseEncode(e)}`;throw Error("Unknown type, must be binary type")}},S=class{name;prefix;baseDecode;prefixCodePoint;constructor(e,t,o){if(this.name=e,this.prefix=t,t.codePointAt(0)===void 0)throw new Error("Invalid prefix character");this.prefixCodePoint=t.codePointAt(0),this.baseDecode=o}decode(e){if(typeof e=="string"){if(e.codePointAt(0)!==this.prefixCodePoint)throw Error(`Unable to decode multibase string ${JSON.stringify(e)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`);return this.baseDecode(e.slice(this.prefix.length))}else throw Error("Can only multibase decode strings")}or(e){return M(this,e)}},$=class{decoders;constructor(e){this.decoders=e}or(e){return M(this,e)}decode(e){let t=e[0],o=this.decoders[t];if(o!=null)return o.decode(e);throw RangeError(`Unable to decode multibase string ${JSON.stringify(e)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`)}};function M(r,e){return new $({...r.decoders??{[r.prefix]:r},...e.decoders??{[e.prefix]:e}})}var z=class{name;prefix;baseEncode;baseDecode;encoder;decoder;constructor(e,t,o,i){this.name=e,this.prefix=t,this.baseEncode=o,this.baseDecode=i,this.encoder=new E(e,t,o),this.decoder=new S(e,t,i)}encode(e){return this.encoder.encode(e)}decode(e){return this.decoder.decode(e)}};function k({name:r,prefix:e,encode:t,decode:o}){return new z(r,e,t,o)}function G({name:r,prefix:e,alphabet:t}){let{encode:o,decode:i}=_(t,r);return k({prefix:e,name:r,encode:o,decode:d=>N(i(d))})}function V(r,e,t,o){let i={};for(let w=0;w<e.length;++w)i[e[w]]=w;let d=r.length;for(;r[d-1]==="=";)--d;let s=new Uint8Array(d*t/8|0),f=0,h=0,m=0;for(let w=0;w<d;++w){let U=i[r[w]];if(U===void 0)throw new SyntaxError(`Non-${o} character`);h=h<<t|U,f+=t,f>=8&&(f-=8,s[m++]=255&h>>f)}if(f>=t||255&h<<8-f)throw new SyntaxError("Unexpected end of data");return s}function F(r,e,t){let o=e[e.length-1]==="=",i=(1<<t)-1,d="",s=0,f=0;for(let h=0;h<r.length;++h)for(f=f<<8|r[h],s+=8;s>t;)s-=t,d+=e[i&f>>s];if(s!==0&&(d+=e[i&f<<t-s]),o)for(;d.length*t&7;)d+="=";return d}function K({name:r,prefix:e,bitsPerChar:t,alphabet:o}){return k({prefix:e,name:r,encode(i){return F(i,o,t)},decode(i){return V(i,o,t,r)}})}export{J as a,N as b,G as c,K as d};
|
|
2
|
-
//# sourceMappingURL=chunk-6K4NRK7Q.min.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../node_modules/.pnpm/multiformats@13.0.1/node_modules/multiformats/src/bytes.ts","../../../../node_modules/.pnpm/multiformats@13.0.1/node_modules/multiformats/src/vendor/base-x.js","../../../../node_modules/.pnpm/multiformats@13.0.1/node_modules/multiformats/src/bases/base.ts"],"sourcesContent":["export const empty = new Uint8Array(0)\n\nexport function toHex (d: Uint8Array): string {\n return d.reduce((hex, byte) => hex + byte.toString(16).padStart(2, '0'), '')\n}\n\nexport function fromHex (hex: string): Uint8Array {\n const hexes = hex.match(/../g)\n return hexes != null ? new Uint8Array(hexes.map(b => parseInt(b, 16))) : empty\n}\n\nexport function equals (aa: Uint8Array, bb: Uint8Array): boolean {\n if (aa === bb) return true\n if (aa.byteLength !== bb.byteLength) {\n return false\n }\n\n for (let ii = 0; ii < aa.byteLength; ii++) {\n if (aa[ii] !== bb[ii]) {\n return false\n }\n }\n\n return true\n}\n\nexport function coerce (o: ArrayBufferView | ArrayBuffer | Uint8Array): Uint8Array {\n if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') return o\n if (o instanceof ArrayBuffer) return new Uint8Array(o)\n if (ArrayBuffer.isView(o)) {\n return new Uint8Array(o.buffer, o.byteOffset, o.byteLength)\n }\n throw new Error('Unknown type, must be binary type')\n}\n\nexport function isBinary (o: unknown): o is ArrayBuffer | ArrayBufferView {\n return o instanceof ArrayBuffer || ArrayBuffer.isView(o)\n}\n\nexport function fromString (str: string): Uint8Array {\n return new TextEncoder().encode(str)\n}\n\nexport function toString (b: Uint8Array): string {\n return new TextDecoder().decode(b)\n}\n","/* eslint-disable */\n// base-x encoding / decoding\n// Copyright (c) 2018 base-x contributors\n// Copyright (c) 2014-2018 The Bitcoin Core developers (base58.cpp)\n// Distributed under the MIT software license, see the accompanying\n// file LICENSE or http://www.opensource.org/licenses/mit-license.php.\n/**\n * @param {string} ALPHABET\n * @param {any} name\n */\nfunction base (ALPHABET, name) {\n if (ALPHABET.length >= 255) { throw new TypeError('Alphabet too long') }\n var BASE_MAP = new Uint8Array(256);\n for (var j = 0; j < BASE_MAP.length; j++) {\n BASE_MAP[j] = 255;\n }\n for (var i = 0; i < ALPHABET.length; i++) {\n var x = ALPHABET.charAt(i);\n var xc = x.charCodeAt(0);\n if (BASE_MAP[xc] !== 255) { throw new TypeError(x + ' is ambiguous') }\n BASE_MAP[xc] = i;\n }\n var BASE = ALPHABET.length;\n var LEADER = ALPHABET.charAt(0);\n var FACTOR = Math.log(BASE) / Math.log(256); // log(BASE) / log(256), rounded up\n var iFACTOR = Math.log(256) / Math.log(BASE); // log(256) / log(BASE), rounded up\n /**\n * @param {any[] | Iterable<number>} source\n */\n function encode (source) {\n // @ts-ignore\n if (source instanceof Uint8Array) ; else if (ArrayBuffer.isView(source)) {\n source = new Uint8Array(source.buffer, source.byteOffset, source.byteLength);\n } else if (Array.isArray(source)) {\n source = Uint8Array.from(source);\n }\n if (!(source instanceof Uint8Array)) { throw new TypeError('Expected Uint8Array') }\n if (source.length === 0) { return '' }\n // Skip & count leading zeroes.\n var zeroes = 0;\n var length = 0;\n var pbegin = 0;\n var pend = source.length;\n while (pbegin !== pend && source[pbegin] === 0) {\n pbegin++;\n zeroes++;\n }\n // Allocate enough space in big-endian base58 representation.\n var size = ((pend - pbegin) * iFACTOR + 1) >>> 0;\n var b58 = new Uint8Array(size);\n // Process the bytes.\n while (pbegin !== pend) {\n var carry = source[pbegin];\n // Apply \"b58 = b58 * 256 + ch\".\n var i = 0;\n for (var it1 = size - 1; (carry !== 0 || i < length) && (it1 !== -1); it1--, i++) {\n carry += (256 * b58[it1]) >>> 0;\n b58[it1] = (carry % BASE) >>> 0;\n carry = (carry / BASE) >>> 0;\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i;\n pbegin++;\n }\n // Skip leading zeroes in base58 result.\n var it2 = size - length;\n while (it2 !== size && b58[it2] === 0) {\n it2++;\n }\n // Translate the result into a string.\n var str = LEADER.repeat(zeroes);\n for (; it2 < size; ++it2) { str += ALPHABET.charAt(b58[it2]); }\n return str\n }\n /**\n * @param {string | string[]} source\n */\n function decodeUnsafe (source) {\n if (typeof source !== 'string') { throw new TypeError('Expected String') }\n if (source.length === 0) { return new Uint8Array() }\n var psz = 0;\n // Skip leading spaces.\n if (source[psz] === ' ') { return }\n // Skip and count leading '1's.\n var zeroes = 0;\n var length = 0;\n while (source[psz] === LEADER) {\n zeroes++;\n psz++;\n }\n // Allocate enough space in big-endian base256 representation.\n var size = (((source.length - psz) * FACTOR) + 1) >>> 0; // log(58) / log(256), rounded up.\n var b256 = new Uint8Array(size);\n // Process the characters.\n while (source[psz]) {\n // Decode character\n var carry = BASE_MAP[source.charCodeAt(psz)];\n // Invalid character\n if (carry === 255) { return }\n var i = 0;\n for (var it3 = size - 1; (carry !== 0 || i < length) && (it3 !== -1); it3--, i++) {\n carry += (BASE * b256[it3]) >>> 0;\n b256[it3] = (carry % 256) >>> 0;\n carry = (carry / 256) >>> 0;\n }\n if (carry !== 0) { throw new Error('Non-zero carry') }\n length = i;\n psz++;\n }\n // Skip trailing spaces.\n if (source[psz] === ' ') { return }\n // Skip leading zeroes in b256.\n var it4 = size - length;\n while (it4 !== size && b256[it4] === 0) {\n it4++;\n }\n var vch = new Uint8Array(zeroes + (size - it4));\n var j = zeroes;\n while (it4 !== size) {\n vch[j++] = b256[it4++];\n }\n return vch\n }\n /**\n * @param {string | string[]} string\n */\n function decode (string) {\n var buffer = decodeUnsafe(string);\n if (buffer) { return buffer }\n throw new Error(`Non-${name} character`)\n }\n return {\n encode: encode,\n decodeUnsafe: decodeUnsafe,\n decode: decode\n }\n}\nvar src = base;\n\nvar _brrp__multiformats_scope_baseX = src;\n\nexport default _brrp__multiformats_scope_baseX;\n","import { coerce } from '../bytes.js'\nimport basex from '../vendor/base-x.js'\nimport type { BaseCodec, BaseDecoder, BaseEncoder, CombobaseDecoder, Multibase, MultibaseCodec, MultibaseDecoder, MultibaseEncoder, UnibaseDecoder } from './interface.js'\n\ninterface EncodeFn { (bytes: Uint8Array): string }\ninterface DecodeFn { (text: string): Uint8Array }\n\n/**\n * Class represents both BaseEncoder and MultibaseEncoder meaning it\n * can be used to encode to multibase or base encode without multibase\n * prefix.\n */\nclass Encoder<Base extends string, Prefix extends string> implements MultibaseEncoder<Prefix>, BaseEncoder {\n readonly name: Base\n readonly prefix: Prefix\n readonly baseEncode: EncodeFn\n\n constructor (name: Base, prefix: Prefix, baseEncode: EncodeFn) {\n this.name = name\n this.prefix = prefix\n this.baseEncode = baseEncode\n }\n\n encode (bytes: Uint8Array): Multibase<Prefix> {\n if (bytes instanceof Uint8Array) {\n return `${this.prefix}${this.baseEncode(bytes)}`\n } else {\n throw Error('Unknown type, must be binary type')\n }\n }\n}\n\n/**\n * Class represents both BaseDecoder and MultibaseDecoder so it could be used\n * to decode multibases (with matching prefix) or just base decode strings\n * with corresponding base encoding.\n */\nclass Decoder<Base extends string, Prefix extends string> implements MultibaseDecoder<Prefix>, UnibaseDecoder<Prefix>, BaseDecoder {\n readonly name: Base\n readonly prefix: Prefix\n readonly baseDecode: DecodeFn\n private readonly prefixCodePoint: number\n\n constructor (name: Base, prefix: Prefix, baseDecode: DecodeFn) {\n this.name = name\n this.prefix = prefix\n /* c8 ignore next 3 */\n if (prefix.codePointAt(0) === undefined) {\n throw new Error('Invalid prefix character')\n }\n this.prefixCodePoint = prefix.codePointAt(0) as number\n this.baseDecode = baseDecode\n }\n\n decode (text: string): Uint8Array {\n if (typeof text === 'string') {\n if (text.codePointAt(0) !== this.prefixCodePoint) {\n throw Error(`Unable to decode multibase string ${JSON.stringify(text)}, ${this.name} decoder only supports inputs prefixed with ${this.prefix}`)\n }\n return this.baseDecode(text.slice(this.prefix.length))\n } else {\n throw Error('Can only multibase decode strings')\n }\n }\n\n or<OtherPrefix extends string> (decoder: UnibaseDecoder<OtherPrefix> | ComposedDecoder<OtherPrefix>): ComposedDecoder<Prefix | OtherPrefix> {\n return or(this, decoder)\n }\n}\n\ntype Decoders<Prefix extends string> = Record<Prefix, UnibaseDecoder<Prefix>>\n\nclass ComposedDecoder<Prefix extends string> implements MultibaseDecoder<Prefix>, CombobaseDecoder<Prefix> {\n readonly decoders: Decoders<Prefix>\n\n constructor (decoders: Decoders<Prefix>) {\n this.decoders = decoders\n }\n\n or <OtherPrefix extends string> (decoder: UnibaseDecoder<OtherPrefix> | ComposedDecoder<OtherPrefix>): ComposedDecoder<Prefix | OtherPrefix> {\n return or(this, decoder)\n }\n\n decode (input: string): Uint8Array {\n const prefix = input[0] as Prefix\n const decoder = this.decoders[prefix]\n if (decoder != null) {\n return decoder.decode(input)\n } else {\n throw RangeError(`Unable to decode multibase string ${JSON.stringify(input)}, only inputs prefixed with ${Object.keys(this.decoders)} are supported`)\n }\n }\n}\n\nexport function or <L extends string, R extends string> (left: UnibaseDecoder<L> | CombobaseDecoder<L>, right: UnibaseDecoder<R> | CombobaseDecoder<R>): ComposedDecoder<L | R> {\n // eslint-disable-next-line @typescript-eslint/consistent-type-assertions\n return new ComposedDecoder({\n ...(left.decoders ?? { [(left as UnibaseDecoder<L>).prefix]: left }),\n ...(right.decoders ?? { [(right as UnibaseDecoder<R>).prefix]: right })\n } as Decoders<L | R>)\n}\n\nexport class Codec<Base extends string, Prefix extends string> implements MultibaseCodec<Prefix>, MultibaseEncoder<Prefix>, MultibaseDecoder<Prefix>, BaseCodec, BaseEncoder, BaseDecoder {\n readonly name: Base\n readonly prefix: Prefix\n readonly baseEncode: EncodeFn\n readonly baseDecode: DecodeFn\n readonly encoder: Encoder<Base, Prefix>\n readonly decoder: Decoder<Base, Prefix>\n\n constructor (name: Base, prefix: Prefix, baseEncode: EncodeFn, baseDecode: DecodeFn) {\n this.name = name\n this.prefix = prefix\n this.baseEncode = baseEncode\n this.baseDecode = baseDecode\n this.encoder = new Encoder(name, prefix, baseEncode)\n this.decoder = new Decoder(name, prefix, baseDecode)\n }\n\n encode (input: Uint8Array): string {\n return this.encoder.encode(input)\n }\n\n decode (input: string): Uint8Array {\n return this.decoder.decode(input)\n }\n}\n\nexport function from <Base extends string, Prefix extends string> ({ name, prefix, encode, decode }: { name: Base, prefix: Prefix, encode: EncodeFn, decode: DecodeFn }): Codec<Base, Prefix> {\n return new Codec(name, prefix, encode, decode)\n}\n\nexport function baseX <Base extends string, Prefix extends string> ({ name, prefix, alphabet }: { name: Base, prefix: Prefix, alphabet: string }): Codec<Base, Prefix> {\n const { encode, decode } = basex(alphabet, name)\n return from({\n prefix,\n name,\n encode,\n decode: (text: string): Uint8Array => coerce(decode(text))\n })\n}\n\nfunction decode (string: string, alphabet: string, bitsPerChar: number, name: string): Uint8Array {\n // Build the character lookup table:\n const codes: Record<string, number> = {}\n for (let i = 0; i < alphabet.length; ++i) {\n codes[alphabet[i]] = i\n }\n\n // Count the padding bytes:\n let end = string.length\n while (string[end - 1] === '=') {\n --end\n }\n\n // Allocate the output:\n const out = new Uint8Array((end * bitsPerChar / 8) | 0)\n\n // Parse the data:\n let bits = 0 // Number of bits currently in the buffer\n let buffer = 0 // Bits waiting to be written out, MSB first\n let written = 0 // Next byte to write\n for (let i = 0; i < end; ++i) {\n // Read one character from the string:\n const value = codes[string[i]]\n if (value === undefined) {\n throw new SyntaxError(`Non-${name} character`)\n }\n\n // Append the bits to the buffer:\n buffer = (buffer << bitsPerChar) | value\n bits += bitsPerChar\n\n // Write out some bits if the buffer has a byte's worth:\n if (bits >= 8) {\n bits -= 8\n out[written++] = 0xff & (buffer >> bits)\n }\n }\n\n // Verify that we have received just enough bits:\n if (bits >= bitsPerChar || (0xff & (buffer << (8 - bits))) !== 0) {\n throw new SyntaxError('Unexpected end of data')\n }\n\n return out\n}\n\nfunction encode (data: Uint8Array, alphabet: string, bitsPerChar: number): string {\n const pad = alphabet[alphabet.length - 1] === '='\n const mask = (1 << bitsPerChar) - 1\n let out = ''\n\n let bits = 0 // Number of bits currently in the buffer\n let buffer = 0 // Bits waiting to be written out, MSB first\n for (let i = 0; i < data.length; ++i) {\n // Slurp data into the buffer:\n buffer = (buffer << 8) | data[i]\n bits += 8\n\n // Write out as much as we can:\n while (bits > bitsPerChar) {\n bits -= bitsPerChar\n out += alphabet[mask & (buffer >> bits)]\n }\n }\n\n // Partial character:\n if (bits !== 0) {\n out += alphabet[mask & (buffer << (bitsPerChar - bits))]\n }\n\n // Add padding characters until we hit a byte boundary:\n if (pad) {\n while (((out.length * bitsPerChar) & 7) !== 0) {\n out += '='\n }\n }\n\n return out\n}\n\n/**\n * RFC4648 Factory\n */\nexport function rfc4648 <Base extends string, Prefix extends string> ({ name, prefix, bitsPerChar, alphabet }: { name: Base, prefix: Prefix, bitsPerChar: number, alphabet: string }): Codec<Base, Prefix> {\n return from({\n prefix,\n name,\n encode (input: Uint8Array): string {\n return encode(input, alphabet, bitsPerChar)\n },\n decode (input: string): Uint8Array {\n return decode(input, alphabet, bitsPerChar, name)\n }\n })\n}\n"],"mappings":"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","names":["empty","equals","aa","bb","ii","coerce","o","base","ALPHABET","name","BASE_MAP","j","x","xc","BASE","LEADER","FACTOR","iFACTOR","encode","source","zeroes","length","pbegin","pend","size","b58","carry","i","it1","it2","str","decodeUnsafe","psz","b256","it3","it4","vch","decode","string","buffer","src","_brrp__multiformats_scope_baseX","base_x_default","Encoder","name","prefix","baseEncode","bytes","Decoder","baseDecode","text","decoder","or","ComposedDecoder","decoders","input","left","right","Codec","from","encode","decode","baseX","alphabet","base_x_default","coerce","string","bitsPerChar","codes","i","end","out","bits","buffer","written","value","data","pad","mask","rfc4648"]}
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
var g=Object.create;var e=Object.defineProperty;var h=Object.getOwnPropertyDescriptor;var i=Object.getOwnPropertyNames;var j=Object.getPrototypeOf,k=Object.prototype.hasOwnProperty;var m=(b,a)=>()=>(a||b((a={exports:{}}).exports,a),a.exports),n=(b,a)=>{for(var c in a)e(b,c,{get:a[c],enumerable:!0})},l=(b,a,c,f)=>{if(a&&typeof a=="object"||typeof a=="function")for(let d of i(a))!k.call(b,d)&&d!==c&&e(b,d,{get:()=>a[d],enumerable:!(f=h(a,d))||f.enumerable});return b};var o=(b,a,c)=>(c=b!=null?g(j(b)):{},l(a||!b||!b.__esModule?e(c,"default",{value:b,enumerable:!0}):c,b));export{m as a,n as b,o as c};
|
|
2
|
-
//# sourceMappingURL=chunk-D2SZILOK.min.js.map
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
import{a as h,c as b}from"./chunk-D2SZILOK.min.js";var L=h(f=>{"use strict";Object.defineProperty(f,"__esModule",{value:!0});var B=typeof Symbol=="function"&&typeof Symbol.iterator=="symbol"?function(i){return typeof i}:function(i){return i&&typeof Symbol=="function"&&i.constructor===Symbol&&i!==Symbol.prototype?"symbol":typeof i},I=typeof window<"u"&&typeof window.document<"u",j=typeof process<"u"&&process.versions!=null&&process.versions.node!=null,x=(typeof self>"u"?"undefined":B(self))==="object"&&self.constructor&&self.constructor.name==="DedicatedWorkerGlobalScope",A=typeof window<"u"&&window.name==="nodejs"||typeof navigator<"u"&&(navigator.userAgent.includes("Node.js")||navigator.userAgent.includes("jsdom")),J=typeof Deno<"u"&&typeof Deno.version<"u"&&typeof Deno.version.deno<"u";f.isBrowser=I;f.isWebWorker=x;f.isNode=j;f.isJsDom=A;f.isDeno=J});var S=h((_,E)=>{"use strict";E.exports=function(i,e){e||(e={}),typeof e=="function"&&(e={cmp:e});var t=typeof e.cycles=="boolean"?e.cycles:!1,o=e.cmp&&function(c){return function(r){return function(a,n){var g={key:a,value:r[a]},u={key:n,value:r[n]};return c(g,u)}}}(e.cmp),s=[];return function c(r){if(r&&r.toJSON&&typeof r.toJSON=="function"&&(r=r.toJSON()),r!==void 0){if(typeof r=="number")return isFinite(r)?""+r:"null";if(typeof r!="object")return JSON.stringify(r);var a,n;if(Array.isArray(r)){for(n="[",a=0;a<r.length;a++)a&&(n+=","),n+=c(r[a])||"null";return n+"]"}if(r===null)return"null";if(s.indexOf(r)!==-1){if(t)return JSON.stringify("__cycle__");throw new TypeError("Converting circular structure to JSON")}var g=s.push(r)-1,u=Object.keys(r).sort(o&&o(r));for(n="",a=0;a<u.length;a++){var m=u[a],d=c(r[m]);d&&(n&&(n+=","),n+=JSON.stringify(m)+":"+d)}return s.splice(g,1),"{"+n+"}"}}(i)}});var p=b(L(),1),F=b(S(),1),R=!1,D=!1;p.isNode&&(process?.env?.LOGGER_TIME_PREFIX&&(R=process?.env?.LOGGER_TIME_PREFIX==="true"),process?.env?.LOGGER_PERF_PREFIX&&(D=process?.env?.LOGGER_PERF_PREFIX==="true"));var k={prefix:void 0,time:R,delta:D,dimDebugOnServer:!0,printOriginOnServer:!0,serverInspectOptions:{},customFormattersOnServer:!0,printStackLinesOnServer:!1,dim:!0},w=[],G=class{sinceFirst=0;sinceLast=0;time=!1;delta=!1;constructor(i,e,t,o){Object.assign(this,{sinceFirst:i,sinceLast:e,time:t,delta:o})}toString(){let i=this.sinceFirst*.001,e=i.toFixed(i<5?2:1),t=this.sinceLast<1e3?`${this.sinceLast.toFixed(0)}`.padStart(5," "):`${`${(this.sinceLast*.001).toFixed(this.sinceLast<1e4?1:0)}`.padStart(4," ")}s`;return`[${[this.time?e:null,this.delta?t:null].filter(o=>o!=null).join(",")}]`}},N=class{constructor(i,e){Object.assign(this,{style:i,string:e})}},y=!1,P=class l{static ERROR=2;static WARN=4;static INFO=6;static LOG=6;static DEBUG=8;static VERBOSE=10;static firstLog=0;static lastLog=0;static setup(e=l.INFO,t={}){t=Object.assign({},k,t),e>10&&console.debug("setup logger",{config:t});let o=this.wrapLog(console.debug,{...t,dim:t.dimDebugOnServer}),s=(...n)=>{typeof window<"u"&&window?.FORCE_DISABLE_LOGLEVEL&&o(...n)};s.isDisabled=!0,s.isEnabled=!1;let c=this.wrapLog(console.groupCollapsed,t),r=(n,g)=>{function u(...d){let v=d[d.length-1];return v===s?v():(c(...d.slice(0,-1)),(async()=>{try{let O=v();return O instanceof Promise?await O:O}finally{console.groupEnd()}})())}let m=Object.assign(g.bind({}),{isEnabled:n,isDisabled:!n,group:u,force:g});return n?m:Object.assign(s.bind({}),{isEnabled:n,isDisabled:!n,group:u,force:m})},a=r(e>=l.ERROR,this.wrapLog(console.error,t));return{ERROR:(...n)=>(a(...n),new Error((0,F.default)(n))),WARN:r(e>=l.WARN,this.wrapLog(console.warn,t)),LOG:r(e>=l.INFO,this.wrapLog(console.log,t)),DEBUG:r(e>=l.DEBUG,this.wrapLog(console.log,{...t,dim:t.dimDebugOnServer})),VERBOSE:r(e>=l.VERBOSE,this.wrapLog(console.debug,{...t,dim:t.dimDebugOnServer}))}}static wrapLog(e,t){if(p.isNode)return e.bind(console);{let o=[];if(t.time||t.delta){let s=p.isBrowser&&navigator.userAgent.includes("Chrome")?["",l.timeStr(!!t.time,!!t.delta)]:[];o.push(...s)}return t.prefix&&(y?o.push(new N("dim",t.prefix)):o.push(t.prefix)),e.bind(console,...o)}}static timeStr(e,t,o=0){if(!performance.now)return;let s=performance.now();l.firstLog||(l.firstLog=s,l.lastLog=s);let c=new G(s-l.firstLog,s-l.lastLog,e,t);return l.lastLog=s,o?c.toString():c}static getOriginFromStack(e){let t=!1;for(let o of e.split(`
|
|
2
|
-
`)){let s=o.match(/^\s+at\s+(.*)/);if(s){if(t)return s[1].trim().replace(__dirname,"");t=!0}}}};p.isBrowser&&(window.devtoolsFormatters=window.devtoolsFormatters??[],window.devtoolsFormatters.push({header:i=>{if(w&&w.length){for(let e of w)if(e.match(i))return["span",{},e.format(i)]}return null},hasBody:()=>!0},{header:i=>{if(!(i instanceof G))return null;y||(y=!0);let e=P.timeStr(i.time,i.delta);return["span",{style:"font-weight: light; color: grey"},e?.toString()]},hasBody:()=>!1},{header:i=>i instanceof N?(y||(y=!0),["span",{style:"font-weight: light; color: grey; "},i.string]):null,hasBody:()=>!1}));export{P as a};
|
|
3
|
-
//# sourceMappingURL=chunk-L7VH6KZJ.min.js.map
|