@waku/sds 0.0.4-383e0b2.0 → 0.0.4-4c18ca2.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/bundle/index.js +1269 -208
- package/dist/.tsbuildinfo +1 -1
- package/dist/index.d.ts +2 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/message_channel/command_queue.d.ts +1 -1
- package/dist/message_channel/message_channel.d.ts +64 -28
- package/dist/message_channel/message_channel.js +194 -139
- package/dist/message_channel/message_channel.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +13 -1
- package/src/message_channel/command_queue.ts +1 -2
- package/src/message_channel/message_channel.ts +221 -165
package/bundle/index.js
CHANGED
@@ -1864,10 +1864,12 @@ function decodeMessage$1(buf, codec, opts) {
|
|
1864
1864
|
}
|
1865
1865
|
|
1866
1866
|
function coerce(o) {
|
1867
|
-
if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array')
|
1867
|
+
if (o instanceof Uint8Array && o.constructor.name === 'Uint8Array') {
|
1868
1868
|
return o;
|
1869
|
-
|
1869
|
+
}
|
1870
|
+
if (o instanceof ArrayBuffer) {
|
1870
1871
|
return new Uint8Array(o);
|
1872
|
+
}
|
1871
1873
|
if (ArrayBuffer.isView(o)) {
|
1872
1874
|
return new Uint8Array(o.buffer, o.byteOffset, o.byteLength);
|
1873
1875
|
}
|
@@ -2128,7 +2130,6 @@ class ComposedDecoder {
|
|
2128
2130
|
}
|
2129
2131
|
}
|
2130
2132
|
function or(left, right) {
|
2131
|
-
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
2132
2133
|
return new ComposedDecoder({
|
2133
2134
|
...(left.decoders ?? { [left.prefix]: left }),
|
2134
2135
|
...(right.decoders ?? { [right.prefix]: right })
|
@@ -2168,12 +2169,7 @@ function baseX({ name, prefix, alphabet }) {
|
|
2168
2169
|
decode: (text) => coerce(decode(text))
|
2169
2170
|
});
|
2170
2171
|
}
|
2171
|
-
function decode$1(string,
|
2172
|
-
// Build the character lookup table:
|
2173
|
-
const codes = {};
|
2174
|
-
for (let i = 0; i < alphabet.length; ++i) {
|
2175
|
-
codes[alphabet[i]] = i;
|
2176
|
-
}
|
2172
|
+
function decode$1(string, alphabetIdx, bitsPerChar, name) {
|
2177
2173
|
// Count the padding bytes:
|
2178
2174
|
let end = string.length;
|
2179
2175
|
while (string[end - 1] === '=') {
|
@@ -2187,7 +2183,7 @@ function decode$1(string, alphabet, bitsPerChar, name) {
|
|
2187
2183
|
let written = 0; // Next byte to write
|
2188
2184
|
for (let i = 0; i < end; ++i) {
|
2189
2185
|
// Read one character from the string:
|
2190
|
-
const value =
|
2186
|
+
const value = alphabetIdx[string[i]];
|
2191
2187
|
if (value === undefined) {
|
2192
2188
|
throw new SyntaxError(`Non-${name} character`);
|
2193
2189
|
}
|
@@ -2234,10 +2230,19 @@ function encode$1(data, alphabet, bitsPerChar) {
|
|
2234
2230
|
}
|
2235
2231
|
return out;
|
2236
2232
|
}
|
2233
|
+
function createAlphabetIdx(alphabet) {
|
2234
|
+
// Build the character lookup table:
|
2235
|
+
const alphabetIdx = {};
|
2236
|
+
for (let i = 0; i < alphabet.length; ++i) {
|
2237
|
+
alphabetIdx[alphabet[i]] = i;
|
2238
|
+
}
|
2239
|
+
return alphabetIdx;
|
2240
|
+
}
|
2237
2241
|
/**
|
2238
2242
|
* RFC4648 Factory
|
2239
2243
|
*/
|
2240
2244
|
function rfc4648({ name, prefix, bitsPerChar, alphabet }) {
|
2245
|
+
const alphabetIdx = createAlphabetIdx(alphabet);
|
2241
2246
|
return from({
|
2242
2247
|
prefix,
|
2243
2248
|
name,
|
@@ -2245,7 +2250,7 @@ function rfc4648({ name, prefix, bitsPerChar, alphabet }) {
|
|
2245
2250
|
return encode$1(input, alphabet, bitsPerChar);
|
2246
2251
|
},
|
2247
2252
|
decode(input) {
|
2248
|
-
return decode$1(input,
|
2253
|
+
return decode$1(input, alphabetIdx, bitsPerChar, name);
|
2249
2254
|
}
|
2250
2255
|
});
|
2251
2256
|
}
|
@@ -3095,6 +3100,8 @@ class MaxLengthError extends Error {
|
|
3095
3100
|
/* eslint-disable @typescript-eslint/no-namespace */
|
3096
3101
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
3097
3102
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
3103
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
3104
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
3098
3105
|
var RateLimitProof$4;
|
3099
3106
|
(function (RateLimitProof) {
|
3100
3107
|
let _codec;
|
@@ -3298,6 +3305,8 @@ var WakuMessage$4;
|
|
3298
3305
|
/* eslint-disable @typescript-eslint/no-namespace */
|
3299
3306
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
3300
3307
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
3308
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
3309
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
3301
3310
|
var FilterRequest;
|
3302
3311
|
(function (FilterRequest) {
|
3303
3312
|
(function (ContentFilter) {
|
@@ -3736,6 +3745,8 @@ var WakuMessage$3;
|
|
3736
3745
|
/* eslint-disable @typescript-eslint/no-namespace */
|
3737
3746
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
3738
3747
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
3748
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
3749
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
3739
3750
|
var TopicOnlyMessage;
|
3740
3751
|
(function (TopicOnlyMessage) {
|
3741
3752
|
let _codec;
|
@@ -3788,6 +3799,8 @@ var TopicOnlyMessage;
|
|
3788
3799
|
/* eslint-disable @typescript-eslint/no-namespace */
|
3789
3800
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
3790
3801
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
3802
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
3803
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
3791
3804
|
var FilterSubscribeRequest;
|
3792
3805
|
(function (FilterSubscribeRequest) {
|
3793
3806
|
let FilterSubscribeType;
|
@@ -4204,6 +4217,8 @@ var WakuMessage$2;
|
|
4204
4217
|
/* eslint-disable @typescript-eslint/no-namespace */
|
4205
4218
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
4206
4219
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
4220
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
4221
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
4207
4222
|
var PushRequest;
|
4208
4223
|
(function (PushRequest) {
|
4209
4224
|
let _codec;
|
@@ -4583,6 +4598,8 @@ var WakuMessage$1;
|
|
4583
4598
|
/* eslint-disable @typescript-eslint/no-namespace */
|
4584
4599
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
4585
4600
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
4601
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
4602
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
4586
4603
|
var WakuMessageKeyValue;
|
4587
4604
|
(function (WakuMessageKeyValue) {
|
4588
4605
|
let _codec;
|
@@ -5066,6 +5083,8 @@ var WakuMessage;
|
|
5066
5083
|
/* eslint-disable @typescript-eslint/no-namespace */
|
5067
5084
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
5068
5085
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
5086
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
5087
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
5069
5088
|
var PeerInfo;
|
5070
5089
|
(function (PeerInfo) {
|
5071
5090
|
let _codec;
|
@@ -5269,6 +5288,8 @@ var PeerExchangeRPC;
|
|
5269
5288
|
/* eslint-disable @typescript-eslint/no-namespace */
|
5270
5289
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
5271
5290
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
5291
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
5292
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
5272
5293
|
var WakuMetadataRequest;
|
5273
5294
|
(function (WakuMetadataRequest) {
|
5274
5295
|
let _codec;
|
@@ -5393,6 +5414,8 @@ var WakuMetadataResponse;
|
|
5393
5414
|
/* eslint-disable @typescript-eslint/no-namespace */
|
5394
5415
|
/* eslint-disable @typescript-eslint/no-unnecessary-boolean-literal-compare */
|
5395
5416
|
/* eslint-disable @typescript-eslint/no-empty-interface */
|
5417
|
+
/* eslint-disable import/consistent-type-specifier-style */
|
5418
|
+
/* eslint-disable @typescript-eslint/no-unused-vars */
|
5396
5419
|
var HistoryEntry;
|
5397
5420
|
(function (HistoryEntry) {
|
5398
5421
|
let _codec;
|
@@ -5561,9 +5584,71 @@ function decodeMessage(data) {
|
|
5561
5584
|
return SdsMessage.decode(data);
|
5562
5585
|
}
|
5563
5586
|
|
5587
|
+
/**
|
5588
|
+
* @packageDocumentation
|
5589
|
+
*
|
5590
|
+
* Adds types to the EventTarget class.
|
5591
|
+
*
|
5592
|
+
* Hopefully this won't be necessary
|
5593
|
+
* forever:
|
5594
|
+
*
|
5595
|
+
* - https://github.com/microsoft/TypeScript/issues/28357
|
5596
|
+
* - https://github.com/microsoft/TypeScript/issues/43477
|
5597
|
+
* - https://github.com/microsoft/TypeScript/issues/299
|
5598
|
+
* - https://www.npmjs.com/package/typed-events
|
5599
|
+
* - https://www.npmjs.com/package/typed-event-emitter
|
5600
|
+
* - https://www.npmjs.com/package/typed-event-target
|
5601
|
+
* - etc
|
5602
|
+
*
|
5603
|
+
* In addition to types, a `safeDispatchEvent` method is available which
|
5604
|
+
* prevents dispatching events that aren't in the event map, and a
|
5605
|
+
* `listenerCount` method which reports the number of listeners that are
|
5606
|
+
* currently registered for a given event.
|
5607
|
+
*
|
5608
|
+
* @example
|
5609
|
+
*
|
5610
|
+
* ```ts
|
5611
|
+
* import { TypedEventEmitter } from 'main-event'
|
5612
|
+
* import type { TypedEventTarget } from 'main-event'
|
5613
|
+
*
|
5614
|
+
* interface EventTypes {
|
5615
|
+
* 'test': CustomEvent<string>
|
5616
|
+
* }
|
5617
|
+
*
|
5618
|
+
* const target = new TypedEventEmitter<EventTypes>()
|
5619
|
+
*
|
5620
|
+
* // it's a regular EventTarget
|
5621
|
+
* console.info(target instanceof EventTarget) // true
|
5622
|
+
*
|
5623
|
+
* // register listeners normally
|
5624
|
+
* target.addEventListener('test', (evt) => {
|
5625
|
+
* // evt is CustomEvent<string>
|
5626
|
+
* })
|
5627
|
+
*
|
5628
|
+
* // @ts-expect-error 'derp' is not in the event map
|
5629
|
+
* target.addEventListener('derp', () => {})
|
5630
|
+
*
|
5631
|
+
* // use normal dispatchEvent method
|
5632
|
+
* target.dispatchEvent(new CustomEvent('test', {
|
5633
|
+
* detail: 'hello'
|
5634
|
+
* }))
|
5635
|
+
*
|
5636
|
+
* // use type safe dispatch method
|
5637
|
+
* target.safeDispatchEvent('test', {
|
5638
|
+
* detail: 'world'
|
5639
|
+
* })
|
5640
|
+
*
|
5641
|
+
* // report listener count
|
5642
|
+
* console.info(target.listenerCount('test')) // 0
|
5643
|
+
*
|
5644
|
+
* // event emitters can be used purely as interfaces too
|
5645
|
+
* function acceptTarget (target: TypedEventTarget<EventTypes>) {
|
5646
|
+
* // ...
|
5647
|
+
* }
|
5648
|
+
* ```
|
5649
|
+
*/
|
5564
5650
|
/**
|
5565
5651
|
* An implementation of a typed event target
|
5566
|
-
* etc
|
5567
5652
|
*/
|
5568
5653
|
class TypedEventEmitter extends EventTarget {
|
5569
5654
|
#listeners = new Map();
|
@@ -5614,11 +5699,17 @@ class TypedEventEmitter extends EventTarget {
|
|
5614
5699
|
}
|
5615
5700
|
|
5616
5701
|
/**
|
5617
|
-
*
|
5702
|
+
* Utilities for hex, bytes, CSPRNG.
|
5618
5703
|
* @module
|
5619
5704
|
*/
|
5620
|
-
|
5621
|
-
|
5705
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
5706
|
+
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
5707
|
+
// node.js versions earlier than v19 don't declare it in global scope.
|
5708
|
+
// For node.js, package.json#exports field mapping rewrites import
|
5709
|
+
// from `crypto` to `cryptoNode`, which imports native module.
|
5710
|
+
// Makes the utils un-importable in browsers without a bundler.
|
5711
|
+
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
5712
|
+
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
5622
5713
|
function isBytes(a) {
|
5623
5714
|
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
5624
5715
|
}
|
@@ -5644,19 +5735,13 @@ function aoutput(out, instance) {
|
|
5644
5735
|
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
5645
5736
|
}
|
5646
5737
|
}
|
5647
|
-
|
5648
|
-
|
5649
|
-
|
5650
|
-
|
5651
|
-
|
5652
|
-
|
5653
|
-
|
5654
|
-
// node.js versions earlier than v19 don't declare it in global scope.
|
5655
|
-
// For node.js, package.json#exports field mapping rewrites import
|
5656
|
-
// from `crypto` to `cryptoNode`, which imports native module.
|
5657
|
-
// Makes the utils un-importable in browsers without a bundler.
|
5658
|
-
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
5659
|
-
// Cast array to view
|
5738
|
+
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
5739
|
+
function clean(...arrays) {
|
5740
|
+
for (let i = 0; i < arrays.length; i++) {
|
5741
|
+
arrays[i].fill(0);
|
5742
|
+
}
|
5743
|
+
}
|
5744
|
+
/** Create DataView of an array for easy byte-level manipulation. */
|
5660
5745
|
function createView(arr) {
|
5661
5746
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
5662
5747
|
}
|
@@ -5664,14 +5749,21 @@ function createView(arr) {
|
|
5664
5749
|
function rotr(word, shift) {
|
5665
5750
|
return (word << (32 - shift)) | (word >>> shift);
|
5666
5751
|
}
|
5752
|
+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
5753
|
+
const hasHexBuiltin = /* @__PURE__ */ (() =>
|
5754
|
+
// @ts-ignore
|
5755
|
+
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
|
5667
5756
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
5668
5757
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
5669
5758
|
/**
|
5670
|
-
* Convert byte array to hex string.
|
5759
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
5671
5760
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
5672
5761
|
*/
|
5673
5762
|
function bytesToHex(bytes) {
|
5674
5763
|
abytes(bytes);
|
5764
|
+
// @ts-ignore
|
5765
|
+
if (hasHexBuiltin)
|
5766
|
+
return bytes.toHex();
|
5675
5767
|
// pre-caching improves the speed 6x
|
5676
5768
|
let hex = '';
|
5677
5769
|
for (let i = 0; i < bytes.length; i++) {
|
@@ -5680,12 +5772,12 @@ function bytesToHex(bytes) {
|
|
5680
5772
|
return hex;
|
5681
5773
|
}
|
5682
5774
|
/**
|
5683
|
-
*
|
5684
|
-
* @example utf8ToBytes('abc') //
|
5775
|
+
* Converts string to bytes using UTF8 encoding.
|
5776
|
+
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
|
5685
5777
|
*/
|
5686
5778
|
function utf8ToBytes(str) {
|
5687
5779
|
if (typeof str !== 'string')
|
5688
|
-
throw new Error('
|
5780
|
+
throw new Error('string expected');
|
5689
5781
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
5690
5782
|
}
|
5691
5783
|
/**
|
@@ -5701,13 +5793,9 @@ function toBytes(data) {
|
|
5701
5793
|
}
|
5702
5794
|
/** For runtime check if class implements interface */
|
5703
5795
|
class Hash {
|
5704
|
-
// Safe version that clones internal state
|
5705
|
-
clone() {
|
5706
|
-
return this._cloneInto();
|
5707
|
-
}
|
5708
5796
|
}
|
5709
5797
|
/** Wraps hash function, creating an interface on top of it */
|
5710
|
-
function
|
5798
|
+
function createHasher(hashCons) {
|
5711
5799
|
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
5712
5800
|
const tmp = hashCons();
|
5713
5801
|
hashC.outputLen = tmp.outputLen;
|
@@ -5748,21 +5836,22 @@ function Maj(a, b, c) {
|
|
5748
5836
|
class HashMD extends Hash {
|
5749
5837
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
5750
5838
|
super();
|
5751
|
-
this.blockLen = blockLen;
|
5752
|
-
this.outputLen = outputLen;
|
5753
|
-
this.padOffset = padOffset;
|
5754
|
-
this.isLE = isLE;
|
5755
5839
|
this.finished = false;
|
5756
5840
|
this.length = 0;
|
5757
5841
|
this.pos = 0;
|
5758
5842
|
this.destroyed = false;
|
5843
|
+
this.blockLen = blockLen;
|
5844
|
+
this.outputLen = outputLen;
|
5845
|
+
this.padOffset = padOffset;
|
5846
|
+
this.isLE = isLE;
|
5759
5847
|
this.buffer = new Uint8Array(blockLen);
|
5760
5848
|
this.view = createView(this.buffer);
|
5761
5849
|
}
|
5762
5850
|
update(data) {
|
5763
5851
|
aexists(this);
|
5764
|
-
const { view, buffer, blockLen } = this;
|
5765
5852
|
data = toBytes(data);
|
5853
|
+
abytes(data);
|
5854
|
+
const { view, buffer, blockLen } = this;
|
5766
5855
|
const len = data.length;
|
5767
5856
|
for (let pos = 0; pos < len;) {
|
5768
5857
|
const take = Math.min(blockLen - this.pos, len - pos);
|
@@ -5796,7 +5885,7 @@ class HashMD extends Hash {
|
|
5796
5885
|
let { pos } = this;
|
5797
5886
|
// append the bit '1' to the message
|
5798
5887
|
buffer[pos++] = 0b10000000;
|
5799
|
-
this.buffer.subarray(pos)
|
5888
|
+
clean(this.buffer.subarray(pos));
|
5800
5889
|
// we have less than padOffset left in buffer, so we cannot put length in
|
5801
5890
|
// current block, need process it and pad again
|
5802
5891
|
if (this.padOffset > blockLen - pos) {
|
@@ -5834,28 +5923,40 @@ class HashMD extends Hash {
|
|
5834
5923
|
to || (to = new this.constructor());
|
5835
5924
|
to.set(...this.get());
|
5836
5925
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
5926
|
+
to.destroyed = destroyed;
|
5927
|
+
to.finished = finished;
|
5837
5928
|
to.length = length;
|
5838
5929
|
to.pos = pos;
|
5839
|
-
to.finished = finished;
|
5840
|
-
to.destroyed = destroyed;
|
5841
5930
|
if (length % blockLen)
|
5842
5931
|
to.buffer.set(buffer);
|
5843
5932
|
return to;
|
5844
5933
|
}
|
5934
|
+
clone() {
|
5935
|
+
return this._cloneInto();
|
5936
|
+
}
|
5845
5937
|
}
|
5938
|
+
/**
|
5939
|
+
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
|
5940
|
+
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
|
5941
|
+
*/
|
5942
|
+
/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
|
5943
|
+
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
5944
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
5945
|
+
]);
|
5846
5946
|
|
5847
5947
|
/**
|
5848
|
-
* SHA2
|
5849
|
-
*
|
5850
|
-
*
|
5851
|
-
*
|
5852
|
-
*
|
5853
|
-
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
5948
|
+
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
5949
|
+
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
5950
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
5951
|
+
* [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
5854
5952
|
* @module
|
5855
5953
|
*/
|
5856
|
-
/**
|
5954
|
+
/**
|
5955
|
+
* Round constants:
|
5956
|
+
* First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
|
5957
|
+
*/
|
5857
5958
|
// prettier-ignore
|
5858
|
-
const SHA256_K = /* @__PURE__ */
|
5959
|
+
const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
5859
5960
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
5860
5961
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
5861
5962
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
@@ -5865,19 +5966,11 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
5865
5966
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
5866
5967
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
5867
5968
|
]);
|
5868
|
-
/**
|
5869
|
-
// prettier-ignore
|
5870
|
-
const SHA256_IV = /* @__PURE__ */ new Uint32Array([
|
5871
|
-
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
|
5872
|
-
]);
|
5873
|
-
/**
|
5874
|
-
* Temporary buffer, not used to store anything between runs.
|
5875
|
-
* Named this way because it matches specification.
|
5876
|
-
*/
|
5969
|
+
/** Reusable temporary buffer. "W" comes straight from spec. */
|
5877
5970
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
5878
5971
|
class SHA256 extends HashMD {
|
5879
|
-
constructor() {
|
5880
|
-
super(64,
|
5972
|
+
constructor(outputLen = 32) {
|
5973
|
+
super(64, outputLen, 8, false);
|
5881
5974
|
// We cannot use array here since array allows indexing by variable
|
5882
5975
|
// which means optimizer/compiler cannot use registers.
|
5883
5976
|
this.A = SHA256_IV[0] | 0;
|
@@ -5943,15 +6036,929 @@ class SHA256 extends HashMD {
|
|
5943
6036
|
this.set(A, B, C, D, E, F, G, H);
|
5944
6037
|
}
|
5945
6038
|
roundClean() {
|
5946
|
-
SHA256_W
|
6039
|
+
clean(SHA256_W);
|
5947
6040
|
}
|
5948
6041
|
destroy() {
|
5949
6042
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
5950
|
-
this.buffer
|
6043
|
+
clean(this.buffer);
|
6044
|
+
}
|
6045
|
+
}
|
6046
|
+
/**
|
6047
|
+
* SHA2-256 hash function from RFC 4634.
|
6048
|
+
*
|
6049
|
+
* It is the fastest JS hash, even faster than Blake3.
|
6050
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
6051
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
6052
|
+
*/
|
6053
|
+
const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
|
6054
|
+
|
6055
|
+
/**
|
6056
|
+
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
6057
|
+
*
|
6058
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
6059
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
6060
|
+
*
|
6061
|
+
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
6062
|
+
* @module
|
6063
|
+
* @deprecated
|
6064
|
+
*/
|
6065
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
6066
|
+
const sha256 = sha256$1;
|
6067
|
+
|
6068
|
+
var Protocols;
|
6069
|
+
(function (Protocols) {
|
6070
|
+
Protocols["Relay"] = "relay";
|
6071
|
+
Protocols["Store"] = "store";
|
6072
|
+
Protocols["LightPush"] = "lightpush";
|
6073
|
+
Protocols["Filter"] = "filter";
|
6074
|
+
})(Protocols || (Protocols = {}));
|
6075
|
+
var ProtocolError;
|
6076
|
+
(function (ProtocolError) {
|
6077
|
+
//
|
6078
|
+
// GENERAL ERRORS SECTION
|
6079
|
+
//
|
6080
|
+
/**
|
6081
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
6082
|
+
* */
|
6083
|
+
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
6084
|
+
/**
|
6085
|
+
* The remote peer rejected the message. Information provided by the remote peer
|
6086
|
+
* is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
|
6087
|
+
* or `DECODE_FAILED` can be used.
|
6088
|
+
*/
|
6089
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
6090
|
+
/**
|
6091
|
+
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
6092
|
+
* ensuring that messages are sent via several peer enable mitigation of this error.
|
6093
|
+
*/
|
6094
|
+
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
6095
|
+
/**
|
6096
|
+
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
6097
|
+
* Mitigation can be: retrying after a given time period, display connectivity issue
|
6098
|
+
* to user or listening for `peer:connected:bootstrap` or `peer:connected:peer-exchange`
|
6099
|
+
* on the connection manager before retrying.
|
6100
|
+
*/
|
6101
|
+
ProtocolError["NO_PEER_AVAILABLE"] = "No peer available";
|
6102
|
+
/**
|
6103
|
+
* Failure to find a stream to the peer. This may be because the connection with the peer is not still alive.
|
6104
|
+
* Mitigation can be: retrying after a given time period, or mitigation for `NO_PEER_AVAILABLE` can be used.
|
6105
|
+
*/
|
6106
|
+
ProtocolError["NO_STREAM_AVAILABLE"] = "No stream available";
|
6107
|
+
/**
|
6108
|
+
* The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
|
6109
|
+
* or `DECODE_FAILED` can be used.
|
6110
|
+
*/
|
6111
|
+
ProtocolError["NO_RESPONSE"] = "No response received";
|
6112
|
+
//
|
6113
|
+
// SEND ERRORS SECTION
|
6114
|
+
//
|
6115
|
+
/**
|
6116
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
6117
|
+
* further investigation.
|
6118
|
+
*/
|
6119
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
6120
|
+
/**
|
6121
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
6122
|
+
* payload is set on the outgoing message.
|
6123
|
+
*/
|
6124
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
6125
|
+
/**
|
6126
|
+
* The message size is above the maximum message size allowed on the Waku Network.
|
6127
|
+
* Compressing the message or using an alternative strategy for large messages is recommended.
|
6128
|
+
*/
|
6129
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
6130
|
+
/**
|
6131
|
+
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
6132
|
+
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
6133
|
+
*/
|
6134
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
6135
|
+
/**
|
6136
|
+
* Fails when
|
6137
|
+
*/
|
6138
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
6139
|
+
/**
|
6140
|
+
* General proof generation error message.
|
6141
|
+
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
6142
|
+
*/
|
6143
|
+
ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
|
6144
|
+
//
|
6145
|
+
// RECEIVE ERRORS SECTION
|
6146
|
+
//
|
6147
|
+
/**
|
6148
|
+
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
6149
|
+
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
6150
|
+
*/
|
6151
|
+
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
6152
|
+
/**
|
6153
|
+
* The topics passed in the decoders do not match each other, or don't exist at all.
|
6154
|
+
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
6155
|
+
*/
|
6156
|
+
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
6157
|
+
})(ProtocolError || (ProtocolError = {}));
|
6158
|
+
|
6159
|
+
var Tags;
|
6160
|
+
(function (Tags) {
|
6161
|
+
Tags["BOOTSTRAP"] = "bootstrap";
|
6162
|
+
Tags["PEER_EXCHANGE"] = "peer-exchange";
|
6163
|
+
Tags["LOCAL"] = "local-peer-cache";
|
6164
|
+
})(Tags || (Tags = {}));
|
6165
|
+
var EPeersByDiscoveryEvents;
|
6166
|
+
(function (EPeersByDiscoveryEvents) {
|
6167
|
+
EPeersByDiscoveryEvents["PEER_DISCOVERY_BOOTSTRAP"] = "peer:discovery:bootstrap";
|
6168
|
+
EPeersByDiscoveryEvents["PEER_DISCOVERY_PEER_EXCHANGE"] = "peer:discovery:peer-exchange";
|
6169
|
+
EPeersByDiscoveryEvents["PEER_CONNECT_BOOTSTRAP"] = "peer:connected:bootstrap";
|
6170
|
+
EPeersByDiscoveryEvents["PEER_CONNECT_PEER_EXCHANGE"] = "peer:connected:peer-exchange";
|
6171
|
+
})(EPeersByDiscoveryEvents || (EPeersByDiscoveryEvents = {}));
|
6172
|
+
var EConnectionStateEvents;
|
6173
|
+
(function (EConnectionStateEvents) {
|
6174
|
+
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
6175
|
+
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
6176
|
+
|
6177
|
+
var HealthStatusChangeEvents;
|
6178
|
+
(function (HealthStatusChangeEvents) {
|
6179
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
6180
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
6181
|
+
var HealthStatus;
|
6182
|
+
(function (HealthStatus) {
|
6183
|
+
HealthStatus["Unhealthy"] = "Unhealthy";
|
6184
|
+
HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
|
6185
|
+
HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
|
6186
|
+
})(HealthStatus || (HealthStatus = {}));
|
6187
|
+
|
6188
|
+
function getDefaultExportFromCjs (x) {
|
6189
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
6190
|
+
}
|
6191
|
+
|
6192
|
+
var browser = {exports: {}};
|
6193
|
+
|
6194
|
+
/**
|
6195
|
+
* Helpers.
|
6196
|
+
*/
|
6197
|
+
|
6198
|
+
var ms;
|
6199
|
+
var hasRequiredMs;
|
6200
|
+
|
6201
|
+
function requireMs () {
|
6202
|
+
if (hasRequiredMs) return ms;
|
6203
|
+
hasRequiredMs = 1;
|
6204
|
+
var s = 1000;
|
6205
|
+
var m = s * 60;
|
6206
|
+
var h = m * 60;
|
6207
|
+
var d = h * 24;
|
6208
|
+
var w = d * 7;
|
6209
|
+
var y = d * 365.25;
|
6210
|
+
|
6211
|
+
/**
|
6212
|
+
* Parse or format the given `val`.
|
6213
|
+
*
|
6214
|
+
* Options:
|
6215
|
+
*
|
6216
|
+
* - `long` verbose formatting [false]
|
6217
|
+
*
|
6218
|
+
* @param {String|Number} val
|
6219
|
+
* @param {Object} [options]
|
6220
|
+
* @throws {Error} throw an error if val is not a non-empty string or a number
|
6221
|
+
* @return {String|Number}
|
6222
|
+
* @api public
|
6223
|
+
*/
|
6224
|
+
|
6225
|
+
ms = function (val, options) {
|
6226
|
+
options = options || {};
|
6227
|
+
var type = typeof val;
|
6228
|
+
if (type === 'string' && val.length > 0) {
|
6229
|
+
return parse(val);
|
6230
|
+
} else if (type === 'number' && isFinite(val)) {
|
6231
|
+
return options.long ? fmtLong(val) : fmtShort(val);
|
6232
|
+
}
|
6233
|
+
throw new Error(
|
6234
|
+
'val is not a non-empty string or a valid number. val=' +
|
6235
|
+
JSON.stringify(val)
|
6236
|
+
);
|
6237
|
+
};
|
6238
|
+
|
6239
|
+
/**
|
6240
|
+
* Parse the given `str` and return milliseconds.
|
6241
|
+
*
|
6242
|
+
* @param {String} str
|
6243
|
+
* @return {Number}
|
6244
|
+
* @api private
|
6245
|
+
*/
|
6246
|
+
|
6247
|
+
function parse(str) {
|
6248
|
+
str = String(str);
|
6249
|
+
if (str.length > 100) {
|
6250
|
+
return;
|
6251
|
+
}
|
6252
|
+
var match = /^(-?(?:\d+)?\.?\d+) *(milliseconds?|msecs?|ms|seconds?|secs?|s|minutes?|mins?|m|hours?|hrs?|h|days?|d|weeks?|w|years?|yrs?|y)?$/i.exec(
|
6253
|
+
str
|
6254
|
+
);
|
6255
|
+
if (!match) {
|
6256
|
+
return;
|
6257
|
+
}
|
6258
|
+
var n = parseFloat(match[1]);
|
6259
|
+
var type = (match[2] || 'ms').toLowerCase();
|
6260
|
+
switch (type) {
|
6261
|
+
case 'years':
|
6262
|
+
case 'year':
|
6263
|
+
case 'yrs':
|
6264
|
+
case 'yr':
|
6265
|
+
case 'y':
|
6266
|
+
return n * y;
|
6267
|
+
case 'weeks':
|
6268
|
+
case 'week':
|
6269
|
+
case 'w':
|
6270
|
+
return n * w;
|
6271
|
+
case 'days':
|
6272
|
+
case 'day':
|
6273
|
+
case 'd':
|
6274
|
+
return n * d;
|
6275
|
+
case 'hours':
|
6276
|
+
case 'hour':
|
6277
|
+
case 'hrs':
|
6278
|
+
case 'hr':
|
6279
|
+
case 'h':
|
6280
|
+
return n * h;
|
6281
|
+
case 'minutes':
|
6282
|
+
case 'minute':
|
6283
|
+
case 'mins':
|
6284
|
+
case 'min':
|
6285
|
+
case 'm':
|
6286
|
+
return n * m;
|
6287
|
+
case 'seconds':
|
6288
|
+
case 'second':
|
6289
|
+
case 'secs':
|
6290
|
+
case 'sec':
|
6291
|
+
case 's':
|
6292
|
+
return n * s;
|
6293
|
+
case 'milliseconds':
|
6294
|
+
case 'millisecond':
|
6295
|
+
case 'msecs':
|
6296
|
+
case 'msec':
|
6297
|
+
case 'ms':
|
6298
|
+
return n;
|
6299
|
+
default:
|
6300
|
+
return undefined;
|
6301
|
+
}
|
6302
|
+
}
|
6303
|
+
|
6304
|
+
/**
|
6305
|
+
* Short format for `ms`.
|
6306
|
+
*
|
6307
|
+
* @param {Number} ms
|
6308
|
+
* @return {String}
|
6309
|
+
* @api private
|
6310
|
+
*/
|
6311
|
+
|
6312
|
+
function fmtShort(ms) {
|
6313
|
+
var msAbs = Math.abs(ms);
|
6314
|
+
if (msAbs >= d) {
|
6315
|
+
return Math.round(ms / d) + 'd';
|
6316
|
+
}
|
6317
|
+
if (msAbs >= h) {
|
6318
|
+
return Math.round(ms / h) + 'h';
|
6319
|
+
}
|
6320
|
+
if (msAbs >= m) {
|
6321
|
+
return Math.round(ms / m) + 'm';
|
6322
|
+
}
|
6323
|
+
if (msAbs >= s) {
|
6324
|
+
return Math.round(ms / s) + 's';
|
6325
|
+
}
|
6326
|
+
return ms + 'ms';
|
6327
|
+
}
|
6328
|
+
|
6329
|
+
/**
|
6330
|
+
* Long format for `ms`.
|
6331
|
+
*
|
6332
|
+
* @param {Number} ms
|
6333
|
+
* @return {String}
|
6334
|
+
* @api private
|
6335
|
+
*/
|
6336
|
+
|
6337
|
+
function fmtLong(ms) {
|
6338
|
+
var msAbs = Math.abs(ms);
|
6339
|
+
if (msAbs >= d) {
|
6340
|
+
return plural(ms, msAbs, d, 'day');
|
6341
|
+
}
|
6342
|
+
if (msAbs >= h) {
|
6343
|
+
return plural(ms, msAbs, h, 'hour');
|
6344
|
+
}
|
6345
|
+
if (msAbs >= m) {
|
6346
|
+
return plural(ms, msAbs, m, 'minute');
|
6347
|
+
}
|
6348
|
+
if (msAbs >= s) {
|
6349
|
+
return plural(ms, msAbs, s, 'second');
|
6350
|
+
}
|
6351
|
+
return ms + ' ms';
|
6352
|
+
}
|
6353
|
+
|
6354
|
+
/**
|
6355
|
+
* Pluralization helper.
|
6356
|
+
*/
|
6357
|
+
|
6358
|
+
function plural(ms, msAbs, n, name) {
|
6359
|
+
var isPlural = msAbs >= n * 1.5;
|
6360
|
+
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
|
6361
|
+
}
|
6362
|
+
return ms;
|
6363
|
+
}
|
6364
|
+
|
6365
|
+
/**
|
6366
|
+
* This is the common logic for both the Node.js and web browser
|
6367
|
+
* implementations of `debug()`.
|
6368
|
+
*/
|
6369
|
+
|
6370
|
+
function setup(env) {
|
6371
|
+
createDebug.debug = createDebug;
|
6372
|
+
createDebug.default = createDebug;
|
6373
|
+
createDebug.coerce = coerce;
|
6374
|
+
createDebug.disable = disable;
|
6375
|
+
createDebug.enable = enable;
|
6376
|
+
createDebug.enabled = enabled;
|
6377
|
+
createDebug.humanize = requireMs();
|
6378
|
+
createDebug.destroy = destroy;
|
6379
|
+
|
6380
|
+
Object.keys(env).forEach(key => {
|
6381
|
+
createDebug[key] = env[key];
|
6382
|
+
});
|
6383
|
+
|
6384
|
+
/**
|
6385
|
+
* The currently active debug mode names, and names to skip.
|
6386
|
+
*/
|
6387
|
+
|
6388
|
+
createDebug.names = [];
|
6389
|
+
createDebug.skips = [];
|
6390
|
+
|
6391
|
+
/**
|
6392
|
+
* Map of special "%n" handling functions, for the debug "format" argument.
|
6393
|
+
*
|
6394
|
+
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
6395
|
+
*/
|
6396
|
+
createDebug.formatters = {};
|
6397
|
+
|
6398
|
+
/**
|
6399
|
+
* Selects a color for a debug namespace
|
6400
|
+
* @param {String} namespace The namespace string for the debug instance to be colored
|
6401
|
+
* @return {Number|String} An ANSI color code for the given namespace
|
6402
|
+
* @api private
|
6403
|
+
*/
|
6404
|
+
function selectColor(namespace) {
|
6405
|
+
let hash = 0;
|
6406
|
+
|
6407
|
+
for (let i = 0; i < namespace.length; i++) {
|
6408
|
+
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
6409
|
+
hash |= 0; // Convert to 32bit integer
|
6410
|
+
}
|
6411
|
+
|
6412
|
+
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
6413
|
+
}
|
6414
|
+
createDebug.selectColor = selectColor;
|
6415
|
+
|
6416
|
+
/**
|
6417
|
+
* Create a debugger with the given `namespace`.
|
6418
|
+
*
|
6419
|
+
* @param {String} namespace
|
6420
|
+
* @return {Function}
|
6421
|
+
* @api public
|
6422
|
+
*/
|
6423
|
+
function createDebug(namespace) {
|
6424
|
+
let prevTime;
|
6425
|
+
let enableOverride = null;
|
6426
|
+
let namespacesCache;
|
6427
|
+
let enabledCache;
|
6428
|
+
|
6429
|
+
function debug(...args) {
|
6430
|
+
// Disabled?
|
6431
|
+
if (!debug.enabled) {
|
6432
|
+
return;
|
6433
|
+
}
|
6434
|
+
|
6435
|
+
const self = debug;
|
6436
|
+
|
6437
|
+
// Set `diff` timestamp
|
6438
|
+
const curr = Number(new Date());
|
6439
|
+
const ms = curr - (prevTime || curr);
|
6440
|
+
self.diff = ms;
|
6441
|
+
self.prev = prevTime;
|
6442
|
+
self.curr = curr;
|
6443
|
+
prevTime = curr;
|
6444
|
+
|
6445
|
+
args[0] = createDebug.coerce(args[0]);
|
6446
|
+
|
6447
|
+
if (typeof args[0] !== 'string') {
|
6448
|
+
// Anything else let's inspect with %O
|
6449
|
+
args.unshift('%O');
|
6450
|
+
}
|
6451
|
+
|
6452
|
+
// Apply any `formatters` transformations
|
6453
|
+
let index = 0;
|
6454
|
+
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
6455
|
+
// If we encounter an escaped % then don't increase the array index
|
6456
|
+
if (match === '%%') {
|
6457
|
+
return '%';
|
6458
|
+
}
|
6459
|
+
index++;
|
6460
|
+
const formatter = createDebug.formatters[format];
|
6461
|
+
if (typeof formatter === 'function') {
|
6462
|
+
const val = args[index];
|
6463
|
+
match = formatter.call(self, val);
|
6464
|
+
|
6465
|
+
// Now we need to remove `args[index]` since it's inlined in the `format`
|
6466
|
+
args.splice(index, 1);
|
6467
|
+
index--;
|
6468
|
+
}
|
6469
|
+
return match;
|
6470
|
+
});
|
6471
|
+
|
6472
|
+
// Apply env-specific formatting (colors, etc.)
|
6473
|
+
createDebug.formatArgs.call(self, args);
|
6474
|
+
|
6475
|
+
const logFn = self.log || createDebug.log;
|
6476
|
+
logFn.apply(self, args);
|
6477
|
+
}
|
6478
|
+
|
6479
|
+
debug.namespace = namespace;
|
6480
|
+
debug.useColors = createDebug.useColors();
|
6481
|
+
debug.color = createDebug.selectColor(namespace);
|
6482
|
+
debug.extend = extend;
|
6483
|
+
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
|
6484
|
+
|
6485
|
+
Object.defineProperty(debug, 'enabled', {
|
6486
|
+
enumerable: true,
|
6487
|
+
configurable: false,
|
6488
|
+
get: () => {
|
6489
|
+
if (enableOverride !== null) {
|
6490
|
+
return enableOverride;
|
6491
|
+
}
|
6492
|
+
if (namespacesCache !== createDebug.namespaces) {
|
6493
|
+
namespacesCache = createDebug.namespaces;
|
6494
|
+
enabledCache = createDebug.enabled(namespace);
|
6495
|
+
}
|
6496
|
+
|
6497
|
+
return enabledCache;
|
6498
|
+
},
|
6499
|
+
set: v => {
|
6500
|
+
enableOverride = v;
|
6501
|
+
}
|
6502
|
+
});
|
6503
|
+
|
6504
|
+
// Env-specific initialization logic for debug instances
|
6505
|
+
if (typeof createDebug.init === 'function') {
|
6506
|
+
createDebug.init(debug);
|
6507
|
+
}
|
6508
|
+
|
6509
|
+
return debug;
|
6510
|
+
}
|
6511
|
+
|
6512
|
+
function extend(namespace, delimiter) {
|
6513
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
|
6514
|
+
newDebug.log = this.log;
|
6515
|
+
return newDebug;
|
6516
|
+
}
|
6517
|
+
|
6518
|
+
/**
|
6519
|
+
* Enables a debug mode by namespaces. This can include modes
|
6520
|
+
* separated by a colon and wildcards.
|
6521
|
+
*
|
6522
|
+
* @param {String} namespaces
|
6523
|
+
* @api public
|
6524
|
+
*/
|
6525
|
+
function enable(namespaces) {
|
6526
|
+
createDebug.save(namespaces);
|
6527
|
+
createDebug.namespaces = namespaces;
|
6528
|
+
|
6529
|
+
createDebug.names = [];
|
6530
|
+
createDebug.skips = [];
|
6531
|
+
|
6532
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
6533
|
+
.trim()
|
6534
|
+
.replace(/\s+/g, ',')
|
6535
|
+
.split(',')
|
6536
|
+
.filter(Boolean);
|
6537
|
+
|
6538
|
+
for (const ns of split) {
|
6539
|
+
if (ns[0] === '-') {
|
6540
|
+
createDebug.skips.push(ns.slice(1));
|
6541
|
+
} else {
|
6542
|
+
createDebug.names.push(ns);
|
6543
|
+
}
|
6544
|
+
}
|
6545
|
+
}
|
6546
|
+
|
6547
|
+
/**
|
6548
|
+
* Checks if the given string matches a namespace template, honoring
|
6549
|
+
* asterisks as wildcards.
|
6550
|
+
*
|
6551
|
+
* @param {String} search
|
6552
|
+
* @param {String} template
|
6553
|
+
* @return {Boolean}
|
6554
|
+
*/
|
6555
|
+
function matchesTemplate(search, template) {
|
6556
|
+
let searchIndex = 0;
|
6557
|
+
let templateIndex = 0;
|
6558
|
+
let starIndex = -1;
|
6559
|
+
let matchIndex = 0;
|
6560
|
+
|
6561
|
+
while (searchIndex < search.length) {
|
6562
|
+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
|
6563
|
+
// Match character or proceed with wildcard
|
6564
|
+
if (template[templateIndex] === '*') {
|
6565
|
+
starIndex = templateIndex;
|
6566
|
+
matchIndex = searchIndex;
|
6567
|
+
templateIndex++; // Skip the '*'
|
6568
|
+
} else {
|
6569
|
+
searchIndex++;
|
6570
|
+
templateIndex++;
|
6571
|
+
}
|
6572
|
+
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
|
6573
|
+
// Backtrack to the last '*' and try to match more characters
|
6574
|
+
templateIndex = starIndex + 1;
|
6575
|
+
matchIndex++;
|
6576
|
+
searchIndex = matchIndex;
|
6577
|
+
} else {
|
6578
|
+
return false; // No match
|
6579
|
+
}
|
6580
|
+
}
|
6581
|
+
|
6582
|
+
// Handle trailing '*' in template
|
6583
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
6584
|
+
templateIndex++;
|
6585
|
+
}
|
6586
|
+
|
6587
|
+
return templateIndex === template.length;
|
6588
|
+
}
|
6589
|
+
|
6590
|
+
/**
|
6591
|
+
* Disable debug output.
|
6592
|
+
*
|
6593
|
+
* @return {String} namespaces
|
6594
|
+
* @api public
|
6595
|
+
*/
|
6596
|
+
function disable() {
|
6597
|
+
const namespaces = [
|
6598
|
+
...createDebug.names,
|
6599
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
6600
|
+
].join(',');
|
6601
|
+
createDebug.enable('');
|
6602
|
+
return namespaces;
|
6603
|
+
}
|
6604
|
+
|
6605
|
+
/**
|
6606
|
+
* Returns true if the given mode name is enabled, false otherwise.
|
6607
|
+
*
|
6608
|
+
* @param {String} name
|
6609
|
+
* @return {Boolean}
|
6610
|
+
* @api public
|
6611
|
+
*/
|
6612
|
+
function enabled(name) {
|
6613
|
+
for (const skip of createDebug.skips) {
|
6614
|
+
if (matchesTemplate(name, skip)) {
|
6615
|
+
return false;
|
6616
|
+
}
|
6617
|
+
}
|
6618
|
+
|
6619
|
+
for (const ns of createDebug.names) {
|
6620
|
+
if (matchesTemplate(name, ns)) {
|
6621
|
+
return true;
|
6622
|
+
}
|
6623
|
+
}
|
6624
|
+
|
6625
|
+
return false;
|
6626
|
+
}
|
6627
|
+
|
6628
|
+
/**
|
6629
|
+
* Coerce `val`.
|
6630
|
+
*
|
6631
|
+
* @param {Mixed} val
|
6632
|
+
* @return {Mixed}
|
6633
|
+
* @api private
|
6634
|
+
*/
|
6635
|
+
function coerce(val) {
|
6636
|
+
if (val instanceof Error) {
|
6637
|
+
return val.stack || val.message;
|
6638
|
+
}
|
6639
|
+
return val;
|
6640
|
+
}
|
6641
|
+
|
6642
|
+
/**
|
6643
|
+
* XXX DO NOT USE. This is a temporary stub function.
|
6644
|
+
* XXX It WILL be removed in the next major release.
|
6645
|
+
*/
|
6646
|
+
function destroy() {
|
6647
|
+
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
6648
|
+
}
|
6649
|
+
|
6650
|
+
createDebug.enable(createDebug.load());
|
6651
|
+
|
6652
|
+
return createDebug;
|
6653
|
+
}
|
6654
|
+
|
6655
|
+
var common = setup;
|
6656
|
+
|
6657
|
+
/* eslint-env browser */
|
6658
|
+
|
6659
|
+
(function (module, exports) {
|
6660
|
+
/**
|
6661
|
+
* This is the web browser implementation of `debug()`.
|
6662
|
+
*/
|
6663
|
+
|
6664
|
+
exports.formatArgs = formatArgs;
|
6665
|
+
exports.save = save;
|
6666
|
+
exports.load = load;
|
6667
|
+
exports.useColors = useColors;
|
6668
|
+
exports.storage = localstorage();
|
6669
|
+
exports.destroy = (() => {
|
6670
|
+
let warned = false;
|
6671
|
+
|
6672
|
+
return () => {
|
6673
|
+
if (!warned) {
|
6674
|
+
warned = true;
|
6675
|
+
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
6676
|
+
}
|
6677
|
+
};
|
6678
|
+
})();
|
6679
|
+
|
6680
|
+
/**
|
6681
|
+
* Colors.
|
6682
|
+
*/
|
6683
|
+
|
6684
|
+
exports.colors = [
|
6685
|
+
'#0000CC',
|
6686
|
+
'#0000FF',
|
6687
|
+
'#0033CC',
|
6688
|
+
'#0033FF',
|
6689
|
+
'#0066CC',
|
6690
|
+
'#0066FF',
|
6691
|
+
'#0099CC',
|
6692
|
+
'#0099FF',
|
6693
|
+
'#00CC00',
|
6694
|
+
'#00CC33',
|
6695
|
+
'#00CC66',
|
6696
|
+
'#00CC99',
|
6697
|
+
'#00CCCC',
|
6698
|
+
'#00CCFF',
|
6699
|
+
'#3300CC',
|
6700
|
+
'#3300FF',
|
6701
|
+
'#3333CC',
|
6702
|
+
'#3333FF',
|
6703
|
+
'#3366CC',
|
6704
|
+
'#3366FF',
|
6705
|
+
'#3399CC',
|
6706
|
+
'#3399FF',
|
6707
|
+
'#33CC00',
|
6708
|
+
'#33CC33',
|
6709
|
+
'#33CC66',
|
6710
|
+
'#33CC99',
|
6711
|
+
'#33CCCC',
|
6712
|
+
'#33CCFF',
|
6713
|
+
'#6600CC',
|
6714
|
+
'#6600FF',
|
6715
|
+
'#6633CC',
|
6716
|
+
'#6633FF',
|
6717
|
+
'#66CC00',
|
6718
|
+
'#66CC33',
|
6719
|
+
'#9900CC',
|
6720
|
+
'#9900FF',
|
6721
|
+
'#9933CC',
|
6722
|
+
'#9933FF',
|
6723
|
+
'#99CC00',
|
6724
|
+
'#99CC33',
|
6725
|
+
'#CC0000',
|
6726
|
+
'#CC0033',
|
6727
|
+
'#CC0066',
|
6728
|
+
'#CC0099',
|
6729
|
+
'#CC00CC',
|
6730
|
+
'#CC00FF',
|
6731
|
+
'#CC3300',
|
6732
|
+
'#CC3333',
|
6733
|
+
'#CC3366',
|
6734
|
+
'#CC3399',
|
6735
|
+
'#CC33CC',
|
6736
|
+
'#CC33FF',
|
6737
|
+
'#CC6600',
|
6738
|
+
'#CC6633',
|
6739
|
+
'#CC9900',
|
6740
|
+
'#CC9933',
|
6741
|
+
'#CCCC00',
|
6742
|
+
'#CCCC33',
|
6743
|
+
'#FF0000',
|
6744
|
+
'#FF0033',
|
6745
|
+
'#FF0066',
|
6746
|
+
'#FF0099',
|
6747
|
+
'#FF00CC',
|
6748
|
+
'#FF00FF',
|
6749
|
+
'#FF3300',
|
6750
|
+
'#FF3333',
|
6751
|
+
'#FF3366',
|
6752
|
+
'#FF3399',
|
6753
|
+
'#FF33CC',
|
6754
|
+
'#FF33FF',
|
6755
|
+
'#FF6600',
|
6756
|
+
'#FF6633',
|
6757
|
+
'#FF9900',
|
6758
|
+
'#FF9933',
|
6759
|
+
'#FFCC00',
|
6760
|
+
'#FFCC33'
|
6761
|
+
];
|
6762
|
+
|
6763
|
+
/**
|
6764
|
+
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
6765
|
+
* and the Firebug extension (any Firefox version) are known
|
6766
|
+
* to support "%c" CSS customizations.
|
6767
|
+
*
|
6768
|
+
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
6769
|
+
*/
|
6770
|
+
|
6771
|
+
// eslint-disable-next-line complexity
|
6772
|
+
function useColors() {
|
6773
|
+
// NB: In an Electron preload script, document will be defined but not fully
|
6774
|
+
// initialized. Since we know we're in Chrome, we'll just detect this case
|
6775
|
+
// explicitly
|
6776
|
+
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
|
6777
|
+
return true;
|
6778
|
+
}
|
6779
|
+
|
6780
|
+
// Internet Explorer and Edge do not support colors.
|
6781
|
+
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
6782
|
+
return false;
|
6783
|
+
}
|
6784
|
+
|
6785
|
+
let m;
|
6786
|
+
|
6787
|
+
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
6788
|
+
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
6789
|
+
// eslint-disable-next-line no-return-assign
|
6790
|
+
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
6791
|
+
// Is firebug? http://stackoverflow.com/a/398120/376773
|
6792
|
+
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
6793
|
+
// Is firefox >= v31?
|
6794
|
+
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
6795
|
+
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
|
6796
|
+
// Double check webkit in userAgent just in case we are in a worker
|
6797
|
+
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
6798
|
+
}
|
6799
|
+
|
6800
|
+
/**
|
6801
|
+
* Colorize log arguments if enabled.
|
6802
|
+
*
|
6803
|
+
* @api public
|
6804
|
+
*/
|
6805
|
+
|
6806
|
+
function formatArgs(args) {
|
6807
|
+
args[0] = (this.useColors ? '%c' : '') +
|
6808
|
+
this.namespace +
|
6809
|
+
(this.useColors ? ' %c' : ' ') +
|
6810
|
+
args[0] +
|
6811
|
+
(this.useColors ? '%c ' : ' ') +
|
6812
|
+
'+' + module.exports.humanize(this.diff);
|
6813
|
+
|
6814
|
+
if (!this.useColors) {
|
6815
|
+
return;
|
6816
|
+
}
|
6817
|
+
|
6818
|
+
const c = 'color: ' + this.color;
|
6819
|
+
args.splice(1, 0, c, 'color: inherit');
|
6820
|
+
|
6821
|
+
// The final "%c" is somewhat tricky, because there could be other
|
6822
|
+
// arguments passed either before or after the %c, so we need to
|
6823
|
+
// figure out the correct index to insert the CSS into
|
6824
|
+
let index = 0;
|
6825
|
+
let lastC = 0;
|
6826
|
+
args[0].replace(/%[a-zA-Z%]/g, match => {
|
6827
|
+
if (match === '%%') {
|
6828
|
+
return;
|
6829
|
+
}
|
6830
|
+
index++;
|
6831
|
+
if (match === '%c') {
|
6832
|
+
// We only are interested in the *last* %c
|
6833
|
+
// (the user may have provided their own)
|
6834
|
+
lastC = index;
|
6835
|
+
}
|
6836
|
+
});
|
6837
|
+
|
6838
|
+
args.splice(lastC, 0, c);
|
6839
|
+
}
|
6840
|
+
|
6841
|
+
/**
|
6842
|
+
* Invokes `console.debug()` when available.
|
6843
|
+
* No-op when `console.debug` is not a "function".
|
6844
|
+
* If `console.debug` is not available, falls back
|
6845
|
+
* to `console.log`.
|
6846
|
+
*
|
6847
|
+
* @api public
|
6848
|
+
*/
|
6849
|
+
exports.log = console.debug || console.log || (() => {});
|
6850
|
+
|
6851
|
+
/**
|
6852
|
+
* Save `namespaces`.
|
6853
|
+
*
|
6854
|
+
* @param {String} namespaces
|
6855
|
+
* @api private
|
6856
|
+
*/
|
6857
|
+
function save(namespaces) {
|
6858
|
+
try {
|
6859
|
+
if (namespaces) {
|
6860
|
+
exports.storage.setItem('debug', namespaces);
|
6861
|
+
} else {
|
6862
|
+
exports.storage.removeItem('debug');
|
6863
|
+
}
|
6864
|
+
} catch (error) {
|
6865
|
+
// Swallow
|
6866
|
+
// XXX (@Qix-) should we be logging these?
|
6867
|
+
}
|
6868
|
+
}
|
6869
|
+
|
6870
|
+
/**
|
6871
|
+
* Load `namespaces`.
|
6872
|
+
*
|
6873
|
+
* @return {String} returns the previously persisted debug modes
|
6874
|
+
* @api private
|
6875
|
+
*/
|
6876
|
+
function load() {
|
6877
|
+
let r;
|
6878
|
+
try {
|
6879
|
+
r = exports.storage.getItem('debug') || exports.storage.getItem('DEBUG') ;
|
6880
|
+
} catch (error) {
|
6881
|
+
// Swallow
|
6882
|
+
// XXX (@Qix-) should we be logging these?
|
6883
|
+
}
|
6884
|
+
|
6885
|
+
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
6886
|
+
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
6887
|
+
r = process.env.DEBUG;
|
6888
|
+
}
|
6889
|
+
|
6890
|
+
return r;
|
6891
|
+
}
|
6892
|
+
|
6893
|
+
/**
|
6894
|
+
* Localstorage attempts to return the localstorage.
|
6895
|
+
*
|
6896
|
+
* This is necessary because safari throws
|
6897
|
+
* when a user disables cookies/localstorage
|
6898
|
+
* and you attempt to access it.
|
6899
|
+
*
|
6900
|
+
* @return {LocalStorage}
|
6901
|
+
* @api private
|
6902
|
+
*/
|
6903
|
+
|
6904
|
+
function localstorage() {
|
6905
|
+
try {
|
6906
|
+
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
|
6907
|
+
// The Browser also has localStorage in the global context.
|
6908
|
+
return localStorage;
|
6909
|
+
} catch (error) {
|
6910
|
+
// Swallow
|
6911
|
+
// XXX (@Qix-) should we be logging these?
|
6912
|
+
}
|
6913
|
+
}
|
6914
|
+
|
6915
|
+
module.exports = common(exports);
|
6916
|
+
|
6917
|
+
const {formatters} = module.exports;
|
6918
|
+
|
6919
|
+
/**
|
6920
|
+
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
6921
|
+
*/
|
6922
|
+
|
6923
|
+
formatters.j = function (v) {
|
6924
|
+
try {
|
6925
|
+
return JSON.stringify(v);
|
6926
|
+
} catch (error) {
|
6927
|
+
return '[UnexpectedJSONParseError]: ' + error.message;
|
6928
|
+
}
|
6929
|
+
};
|
6930
|
+
} (browser, browser.exports));
|
6931
|
+
|
6932
|
+
var browserExports = browser.exports;
|
6933
|
+
var debug = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
|
6934
|
+
|
6935
|
+
const APP_NAME = "waku";
|
6936
|
+
class Logger {
|
6937
|
+
_info;
|
6938
|
+
_warn;
|
6939
|
+
_error;
|
6940
|
+
static createDebugNamespace(level, prefix) {
|
6941
|
+
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
|
6942
|
+
}
|
6943
|
+
constructor(prefix) {
|
6944
|
+
this._info = debug(Logger.createDebugNamespace("info", prefix));
|
6945
|
+
this._warn = debug(Logger.createDebugNamespace("warn", prefix));
|
6946
|
+
this._error = debug(Logger.createDebugNamespace("error", prefix));
|
6947
|
+
}
|
6948
|
+
get info() {
|
6949
|
+
return this._info;
|
6950
|
+
}
|
6951
|
+
get warn() {
|
6952
|
+
return this._warn;
|
6953
|
+
}
|
6954
|
+
get error() {
|
6955
|
+
return this._error;
|
6956
|
+
}
|
6957
|
+
log(level, ...args) {
|
6958
|
+
const logger = this[level];
|
6959
|
+
logger(...args);
|
5951
6960
|
}
|
5952
6961
|
}
|
5953
|
-
/** SHA2-256 hash function */
|
5954
|
-
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
5955
6962
|
|
5956
6963
|
const DEFAULT_BLOOM_FILTER_OPTIONS = {
|
5957
6964
|
capacity: 10000,
|
@@ -5959,14 +6966,15 @@ const DEFAULT_BLOOM_FILTER_OPTIONS = {
|
|
5959
6966
|
};
|
5960
6967
|
const DEFAULT_CAUSAL_HISTORY_SIZE = 2;
|
5961
6968
|
const DEFAULT_RECEIVED_MESSAGE_TIMEOUT = 1000 * 60 * 5; // 5 minutes
|
6969
|
+
const log = new Logger("sds:message-channel");
|
5962
6970
|
class MessageChannel extends TypedEventEmitter {
|
6971
|
+
channelId;
|
5963
6972
|
lamportTimestamp;
|
5964
6973
|
filter;
|
5965
6974
|
outgoingBuffer;
|
5966
6975
|
acknowledgements;
|
5967
6976
|
incomingBuffer;
|
5968
6977
|
localHistory;
|
5969
|
-
channelId;
|
5970
6978
|
causalHistorySize;
|
5971
6979
|
acknowledgementCount;
|
5972
6980
|
timeReceived;
|
@@ -6002,40 +7010,61 @@ class MessageChannel extends TypedEventEmitter {
|
|
6002
7010
|
this.receivedMessageTimeout =
|
6003
7011
|
options.receivedMessageTimeout ?? DEFAULT_RECEIVED_MESSAGE_TIMEOUT;
|
6004
7012
|
}
|
6005
|
-
|
6006
|
-
|
7013
|
+
static getMessageId(payload) {
|
7014
|
+
return bytesToHex(sha256(payload));
|
7015
|
+
}
|
7016
|
+
/**
|
7017
|
+
* Processes all queued tasks sequentially to ensure proper message ordering.
|
7018
|
+
*
|
7019
|
+
* This method should be called periodically by the library consumer to execute
|
7020
|
+
* queued send/receive operations in the correct sequence.
|
7021
|
+
*
|
7022
|
+
* @example
|
7023
|
+
* ```typescript
|
7024
|
+
* const channel = new MessageChannel("my-channel");
|
7025
|
+
*
|
7026
|
+
* // Queue some operations
|
7027
|
+
* await channel.sendMessage(payload, callback);
|
7028
|
+
* channel.receiveMessage(incomingMessage);
|
7029
|
+
*
|
7030
|
+
* // Process all queued operations
|
7031
|
+
* await channel.processTasks();
|
7032
|
+
* ```
|
7033
|
+
*
|
7034
|
+
* @throws Will emit a 'taskError' event if any task fails, but continues processing remaining tasks
|
7035
|
+
*/
|
6007
7036
|
async processTasks() {
|
6008
7037
|
while (this.tasks.length > 0) {
|
6009
7038
|
const item = this.tasks.shift();
|
6010
7039
|
if (!item) {
|
6011
7040
|
continue;
|
6012
7041
|
}
|
6013
|
-
// Use a generic helper function to ensure type safety
|
6014
7042
|
await this.executeTask(item);
|
6015
7043
|
}
|
6016
7044
|
}
|
6017
|
-
async executeTask(item) {
|
6018
|
-
const handler = this.handlers[item.command];
|
6019
|
-
await handler(item.params);
|
6020
|
-
}
|
6021
|
-
static getMessageId(payload) {
|
6022
|
-
return bytesToHex(sha256(payload));
|
6023
|
-
}
|
6024
7045
|
/**
|
6025
|
-
*
|
7046
|
+
* Queues a message to be sent on this channel.
|
6026
7047
|
*
|
6027
|
-
*
|
6028
|
-
*
|
7048
|
+
* The message will be processed sequentially when processTasks() is called.
|
7049
|
+
* This ensures proper lamport timestamp ordering and causal history tracking.
|
6029
7050
|
*
|
6030
|
-
*
|
6031
|
-
*
|
6032
|
-
*
|
6033
|
-
* light push or relay.
|
7051
|
+
* @param payload - The message content as a byte array
|
7052
|
+
* @param callback - Optional callback function called after the message is processed
|
7053
|
+
* @returns Promise that resolves when the message is queued (not sent)
|
6034
7054
|
*
|
6035
|
-
*
|
7055
|
+
* @example
|
7056
|
+
* ```typescript
|
7057
|
+
* const channel = new MessageChannel("chat-room");
|
7058
|
+
* const message = new TextEncoder().encode("Hello, world!");
|
6036
7059
|
*
|
6037
|
-
*
|
6038
|
-
*
|
7060
|
+
* await channel.sendMessage(message, async (processedMessage) => {
|
7061
|
+
* console.log("Message processed:", processedMessage.messageId);
|
7062
|
+
* return { success: true };
|
7063
|
+
* });
|
7064
|
+
*
|
7065
|
+
* // Actually send the message
|
7066
|
+
* await channel.processTasks();
|
7067
|
+
* ```
|
6039
7068
|
*/
|
6040
7069
|
async sendMessage(payload, callback) {
|
6041
7070
|
this.tasks.push({
|
@@ -6046,38 +7075,6 @@ class MessageChannel extends TypedEventEmitter {
|
|
6046
7075
|
}
|
6047
7076
|
});
|
6048
7077
|
}
|
6049
|
-
async _sendMessage(payload, callback) {
|
6050
|
-
this.lamportTimestamp++;
|
6051
|
-
const messageId = MessageChannel.getMessageId(payload);
|
6052
|
-
const message = {
|
6053
|
-
messageId,
|
6054
|
-
channelId: this.channelId,
|
6055
|
-
lamportTimestamp: this.lamportTimestamp,
|
6056
|
-
causalHistory: this.localHistory
|
6057
|
-
.slice(-this.causalHistorySize)
|
6058
|
-
.map(({ historyEntry }) => historyEntry),
|
6059
|
-
bloomFilter: this.filter.toBytes(),
|
6060
|
-
content: payload
|
6061
|
-
};
|
6062
|
-
this.outgoingBuffer.push(message);
|
6063
|
-
if (callback) {
|
6064
|
-
const { success, retrievalHint } = await callback(message);
|
6065
|
-
if (success) {
|
6066
|
-
this.filter.insert(messageId);
|
6067
|
-
this.localHistory.push({
|
6068
|
-
timestamp: this.lamportTimestamp,
|
6069
|
-
historyEntry: {
|
6070
|
-
messageId,
|
6071
|
-
retrievalHint
|
6072
|
-
}
|
6073
|
-
});
|
6074
|
-
this.timeReceived.set(messageId, Date.now());
|
6075
|
-
this.safeDispatchEvent(MessageChannelEvent.MessageSent, {
|
6076
|
-
detail: message
|
6077
|
-
});
|
6078
|
-
}
|
6079
|
-
}
|
6080
|
-
}
|
6081
7078
|
/**
|
6082
7079
|
* Sends a short-lived message without synchronization or reliability requirements.
|
6083
7080
|
*
|
@@ -6100,32 +7097,24 @@ class MessageChannel extends TypedEventEmitter {
|
|
6100
7097
|
}
|
6101
7098
|
});
|
6102
7099
|
}
|
6103
|
-
async _sendEphemeralMessage(payload, callback) {
|
6104
|
-
const message = {
|
6105
|
-
messageId: MessageChannel.getMessageId(payload),
|
6106
|
-
channelId: this.channelId,
|
6107
|
-
content: payload,
|
6108
|
-
lamportTimestamp: undefined,
|
6109
|
-
causalHistory: [],
|
6110
|
-
bloomFilter: undefined
|
6111
|
-
};
|
6112
|
-
if (callback) {
|
6113
|
-
await callback(message);
|
6114
|
-
}
|
6115
|
-
}
|
6116
7100
|
/**
|
6117
|
-
*
|
7101
|
+
* Queues a received message for processing.
|
7102
|
+
*
|
7103
|
+
* The message will be processed when processTasks() is called, ensuring
|
7104
|
+
* proper dependency resolution and causal ordering.
|
7105
|
+
*
|
7106
|
+
* @param message - The message to receive and process
|
6118
7107
|
*
|
6119
|
-
*
|
6120
|
-
*
|
6121
|
-
*
|
6122
|
-
* If the local history contains every message in the received message's
|
6123
|
-
* causal history, deliver the message. Otherwise, add the message to the
|
6124
|
-
* incoming buffer.
|
7108
|
+
* @example
|
7109
|
+
* ```typescript
|
7110
|
+
* const channel = new MessageChannel("chat-room");
|
6125
7111
|
*
|
6126
|
-
*
|
7112
|
+
* // Receive a message from the network
|
7113
|
+
* channel.receiveMessage(incomingMessage);
|
6127
7114
|
*
|
6128
|
-
*
|
7115
|
+
* // Process the received message
|
7116
|
+
* await channel.processTasks();
|
7117
|
+
* ```
|
6129
7118
|
*/
|
6130
7119
|
receiveMessage(message) {
|
6131
7120
|
this.tasks.push({
|
@@ -6135,62 +7124,17 @@ class MessageChannel extends TypedEventEmitter {
|
|
6135
7124
|
}
|
6136
7125
|
});
|
6137
7126
|
}
|
6138
|
-
|
6139
|
-
|
6140
|
-
|
6141
|
-
|
6142
|
-
|
6143
|
-
return;
|
6144
|
-
}
|
6145
|
-
if (!message.lamportTimestamp) {
|
6146
|
-
// Messages with no timestamp are ephemeral messages and should be delivered immediately
|
6147
|
-
this.deliverMessage(message);
|
6148
|
-
return;
|
6149
|
-
}
|
6150
|
-
if (message.content?.length === 0) {
|
6151
|
-
this.safeDispatchEvent(MessageChannelEvent.SyncReceived, {
|
6152
|
-
detail: message
|
6153
|
-
});
|
6154
|
-
}
|
6155
|
-
else {
|
6156
|
-
this.safeDispatchEvent(MessageChannelEvent.MessageReceived, {
|
6157
|
-
detail: message
|
6158
|
-
});
|
6159
|
-
}
|
6160
|
-
// review ack status
|
6161
|
-
this.reviewAckStatus(message);
|
6162
|
-
// add to bloom filter (skip for messages with empty content)
|
6163
|
-
if (message.content?.length && message.content.length > 0) {
|
6164
|
-
this.filter.insert(message.messageId);
|
6165
|
-
}
|
6166
|
-
// verify causal history
|
6167
|
-
const dependenciesMet = message.causalHistory.every((historyEntry) => this.localHistory.some(({ historyEntry: { messageId } }) => messageId === historyEntry.messageId));
|
6168
|
-
if (!dependenciesMet) {
|
6169
|
-
this.incomingBuffer.push(message);
|
6170
|
-
this.timeReceived.set(message.messageId, Date.now());
|
6171
|
-
}
|
6172
|
-
else {
|
6173
|
-
this.deliverMessage(message);
|
6174
|
-
this.safeDispatchEvent(MessageChannelEvent.MessageDelivered, {
|
6175
|
-
detail: {
|
6176
|
-
messageId: message.messageId,
|
6177
|
-
sentOrReceived: "received"
|
6178
|
-
}
|
6179
|
-
});
|
6180
|
-
}
|
6181
|
-
}
|
6182
|
-
// https://rfc.vac.dev/vac/raw/sds/#periodic-incoming-buffer-sweep
|
6183
|
-
// Note that even though this function has side effects, it is not async
|
6184
|
-
// and does not need to be called through the queue.
|
7127
|
+
/**
|
7128
|
+
* Processes messages in the incoming buffer, delivering those with satisfied dependencies.
|
7129
|
+
*
|
7130
|
+
* @returns Array of history entries for messages still missing dependencies
|
7131
|
+
*/
|
6185
7132
|
sweepIncomingBuffer() {
|
6186
7133
|
const { buffer, missing } = this.incomingBuffer.reduce(({ buffer, missing }, message) => {
|
6187
|
-
// Check each message for missing dependencies
|
6188
7134
|
const missingDependencies = message.causalHistory.filter((messageHistoryEntry) => !this.localHistory.some(({ historyEntry: { messageId } }) => messageId === messageHistoryEntry.messageId));
|
6189
7135
|
if (missingDependencies.length === 0) {
|
6190
|
-
// Any message with no missing dependencies is delivered
|
6191
|
-
// and removed from the buffer (implicitly by not adding it to the new incoming buffer)
|
6192
7136
|
this.deliverMessage(message);
|
6193
|
-
this.
|
7137
|
+
this.safeSendEvent(MessageChannelEvent.MessageDelivered, {
|
6194
7138
|
detail: {
|
6195
7139
|
messageId: message.messageId,
|
6196
7140
|
sentOrReceived: "received"
|
@@ -6207,8 +7151,6 @@ class MessageChannel extends TypedEventEmitter {
|
|
6207
7151
|
return { buffer, missing };
|
6208
7152
|
}
|
6209
7153
|
}
|
6210
|
-
// Any message with missing dependencies stays in the buffer
|
6211
|
-
// and the missing message IDs are returned for processing.
|
6212
7154
|
missingDependencies.forEach((dependency) => {
|
6213
7155
|
missing.add(dependency);
|
6214
7156
|
});
|
@@ -6217,16 +7159,14 @@ class MessageChannel extends TypedEventEmitter {
|
|
6217
7159
|
missing
|
6218
7160
|
};
|
6219
7161
|
}, { buffer: new Array(), missing: new Set() });
|
6220
|
-
// Update the incoming buffer to only include messages with no missing dependencies
|
6221
7162
|
this.incomingBuffer = buffer;
|
6222
|
-
this.
|
7163
|
+
this.safeSendEvent(MessageChannelEvent.MissedMessages, {
|
6223
7164
|
detail: Array.from(missing)
|
6224
7165
|
});
|
6225
7166
|
return Array.from(missing);
|
6226
7167
|
}
|
6227
7168
|
// https://rfc.vac.dev/vac/raw/sds/#periodic-outgoing-buffer-sweep
|
6228
7169
|
sweepOutgoingBuffer() {
|
6229
|
-
// Partition all messages in the outgoing buffer into unacknowledged and possibly acknowledged messages
|
6230
7170
|
return this.outgoingBuffer.reduce(({ unacknowledged, possiblyAcknowledged }, message) => {
|
6231
7171
|
if (this.acknowledgements.has(message.messageId)) {
|
6232
7172
|
return {
|
@@ -6267,13 +7207,136 @@ class MessageChannel extends TypedEventEmitter {
|
|
6267
7207
|
content: emptyMessage
|
6268
7208
|
};
|
6269
7209
|
if (callback) {
|
6270
|
-
|
6271
|
-
|
7210
|
+
try {
|
7211
|
+
await callback(message);
|
7212
|
+
this.safeSendEvent(MessageChannelEvent.SyncSent, {
|
7213
|
+
detail: message
|
7214
|
+
});
|
7215
|
+
return true;
|
7216
|
+
}
|
7217
|
+
catch (error) {
|
7218
|
+
log.error("Callback execution failed in sendSyncMessage:", error);
|
7219
|
+
throw error;
|
7220
|
+
}
|
7221
|
+
}
|
7222
|
+
return false;
|
7223
|
+
}
|
7224
|
+
_receiveMessage(message) {
|
7225
|
+
const isDuplicate = message.content &&
|
7226
|
+
message.content.length > 0 &&
|
7227
|
+
this.timeReceived.has(message.messageId);
|
7228
|
+
if (isDuplicate) {
|
7229
|
+
return;
|
7230
|
+
}
|
7231
|
+
if (!message.lamportTimestamp) {
|
7232
|
+
this.deliverMessage(message);
|
7233
|
+
return;
|
7234
|
+
}
|
7235
|
+
if (message.content?.length === 0) {
|
7236
|
+
this.safeSendEvent(MessageChannelEvent.SyncReceived, {
|
6272
7237
|
detail: message
|
6273
7238
|
});
|
6274
|
-
return true;
|
6275
7239
|
}
|
6276
|
-
|
7240
|
+
else {
|
7241
|
+
this.safeSendEvent(MessageChannelEvent.MessageReceived, {
|
7242
|
+
detail: message
|
7243
|
+
});
|
7244
|
+
}
|
7245
|
+
this.reviewAckStatus(message);
|
7246
|
+
if (message.content?.length && message.content.length > 0) {
|
7247
|
+
this.filter.insert(message.messageId);
|
7248
|
+
}
|
7249
|
+
const dependenciesMet = message.causalHistory.every((historyEntry) => this.localHistory.some(({ historyEntry: { messageId } }) => messageId === historyEntry.messageId));
|
7250
|
+
if (!dependenciesMet) {
|
7251
|
+
this.incomingBuffer.push(message);
|
7252
|
+
this.timeReceived.set(message.messageId, Date.now());
|
7253
|
+
}
|
7254
|
+
else {
|
7255
|
+
this.deliverMessage(message);
|
7256
|
+
this.safeSendEvent(MessageChannelEvent.MessageDelivered, {
|
7257
|
+
detail: {
|
7258
|
+
messageId: message.messageId,
|
7259
|
+
sentOrReceived: "received"
|
7260
|
+
}
|
7261
|
+
});
|
7262
|
+
}
|
7263
|
+
}
|
7264
|
+
async executeTask(item) {
|
7265
|
+
try {
|
7266
|
+
const handler = this.handlers[item.command];
|
7267
|
+
await handler(item.params);
|
7268
|
+
}
|
7269
|
+
catch (error) {
|
7270
|
+
log.error(`Task execution failed for command ${item.command}:`, error);
|
7271
|
+
this.dispatchEvent(new CustomEvent("taskError", {
|
7272
|
+
detail: { command: item.command, error, params: item.params }
|
7273
|
+
}));
|
7274
|
+
}
|
7275
|
+
}
|
7276
|
+
safeSendEvent(event, eventInit) {
|
7277
|
+
try {
|
7278
|
+
this.dispatchEvent(new CustomEvent(event, eventInit));
|
7279
|
+
}
|
7280
|
+
catch (error) {
|
7281
|
+
log.error(`Failed to dispatch event ${event}:`, error);
|
7282
|
+
}
|
7283
|
+
}
|
7284
|
+
async _sendMessage(payload, callback) {
|
7285
|
+
this.lamportTimestamp++;
|
7286
|
+
const messageId = MessageChannel.getMessageId(payload);
|
7287
|
+
const message = {
|
7288
|
+
messageId,
|
7289
|
+
channelId: this.channelId,
|
7290
|
+
lamportTimestamp: this.lamportTimestamp,
|
7291
|
+
causalHistory: this.localHistory
|
7292
|
+
.slice(-this.causalHistorySize)
|
7293
|
+
.map(({ historyEntry }) => historyEntry),
|
7294
|
+
bloomFilter: this.filter.toBytes(),
|
7295
|
+
content: payload
|
7296
|
+
};
|
7297
|
+
this.outgoingBuffer.push(message);
|
7298
|
+
if (callback) {
|
7299
|
+
try {
|
7300
|
+
const { success, retrievalHint } = await callback(message);
|
7301
|
+
if (success) {
|
7302
|
+
this.filter.insert(messageId);
|
7303
|
+
this.localHistory.push({
|
7304
|
+
timestamp: this.lamportTimestamp,
|
7305
|
+
historyEntry: {
|
7306
|
+
messageId,
|
7307
|
+
retrievalHint
|
7308
|
+
}
|
7309
|
+
});
|
7310
|
+
this.timeReceived.set(messageId, Date.now());
|
7311
|
+
this.safeSendEvent(MessageChannelEvent.MessageSent, {
|
7312
|
+
detail: message
|
7313
|
+
});
|
7314
|
+
}
|
7315
|
+
}
|
7316
|
+
catch (error) {
|
7317
|
+
log.error("Callback execution failed in _sendMessage:", error);
|
7318
|
+
throw error;
|
7319
|
+
}
|
7320
|
+
}
|
7321
|
+
}
|
7322
|
+
async _sendEphemeralMessage(payload, callback) {
|
7323
|
+
const message = {
|
7324
|
+
messageId: MessageChannel.getMessageId(payload),
|
7325
|
+
channelId: this.channelId,
|
7326
|
+
content: payload,
|
7327
|
+
lamportTimestamp: undefined,
|
7328
|
+
causalHistory: [],
|
7329
|
+
bloomFilter: undefined
|
7330
|
+
};
|
7331
|
+
if (callback) {
|
7332
|
+
try {
|
7333
|
+
await callback(message);
|
7334
|
+
}
|
7335
|
+
catch (error) {
|
7336
|
+
log.error("Callback execution failed in _sendEphemeralMessage:", error);
|
7337
|
+
throw error;
|
7338
|
+
}
|
7339
|
+
}
|
6277
7340
|
}
|
6278
7341
|
// See https://rfc.vac.dev/vac/raw/sds/#deliver-message
|
6279
7342
|
deliverMessage(message, retrievalHint) {
|
@@ -6311,13 +7374,12 @@ class MessageChannel extends TypedEventEmitter {
|
|
6311
7374
|
// to determine the acknowledgement status of messages in the outgoing buffer.
|
6312
7375
|
// See https://rfc.vac.dev/vac/raw/sds/#review-ack-status
|
6313
7376
|
reviewAckStatus(receivedMessage) {
|
6314
|
-
// the participant MUST mark all messages in the received causal_history as acknowledged.
|
6315
7377
|
receivedMessage.causalHistory.forEach(({ messageId }) => {
|
6316
7378
|
this.outgoingBuffer = this.outgoingBuffer.filter(({ messageId: outgoingMessageId }) => {
|
6317
7379
|
if (outgoingMessageId !== messageId) {
|
6318
7380
|
return true;
|
6319
7381
|
}
|
6320
|
-
this.
|
7382
|
+
this.safeSendEvent(MessageChannelEvent.MessageAcknowledged, {
|
6321
7383
|
detail: messageId
|
6322
7384
|
});
|
6323
7385
|
return false;
|
@@ -6327,7 +7389,6 @@ class MessageChannel extends TypedEventEmitter {
|
|
6327
7389
|
this.filter.insert(messageId);
|
6328
7390
|
}
|
6329
7391
|
});
|
6330
|
-
// the participant MUST mark all messages included in the bloom_filter as possibly acknowledged
|
6331
7392
|
if (!receivedMessage.bloomFilter) {
|
6332
7393
|
return;
|
6333
7394
|
}
|
@@ -6342,7 +7403,7 @@ class MessageChannel extends TypedEventEmitter {
|
|
6342
7403
|
const count = (this.acknowledgements.get(message.messageId) ?? 0) + 1;
|
6343
7404
|
if (count < this.acknowledgementCount) {
|
6344
7405
|
this.acknowledgements.set(message.messageId, count);
|
6345
|
-
this.
|
7406
|
+
this.safeSendEvent(MessageChannelEvent.PartialAcknowledgement, {
|
6346
7407
|
detail: {
|
6347
7408
|
messageId: message.messageId,
|
6348
7409
|
count
|
@@ -6360,4 +7421,4 @@ class MessageChannel extends TypedEventEmitter {
|
|
6360
7421
|
}
|
6361
7422
|
}
|
6362
7423
|
|
6363
|
-
export { BloomFilter,
|
7424
|
+
export { BloomFilter, MessageChannel, MessageChannelEvent, decodeMessage, encodeMessage };
|