@waku/sds 0.0.4-006cd41.0 → 0.0.4-01af155.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 +1172 -196
- 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
@@ -5614,11 +5614,17 @@ class TypedEventEmitter extends EventTarget {
|
|
5614
5614
|
}
|
5615
5615
|
|
5616
5616
|
/**
|
5617
|
-
*
|
5617
|
+
* Utilities for hex, bytes, CSPRNG.
|
5618
5618
|
* @module
|
5619
5619
|
*/
|
5620
|
-
|
5621
|
-
|
5620
|
+
/*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
|
5621
|
+
// We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
|
5622
|
+
// node.js versions earlier than v19 don't declare it in global scope.
|
5623
|
+
// For node.js, package.json#exports field mapping rewrites import
|
5624
|
+
// from `crypto` to `cryptoNode`, which imports native module.
|
5625
|
+
// Makes the utils un-importable in browsers without a bundler.
|
5626
|
+
// Once node.js 18 is deprecated (2025-04-30), we can just drop the import.
|
5627
|
+
/** Checks if something is Uint8Array. Be careful: nodejs Buffer will return true. */
|
5622
5628
|
function isBytes(a) {
|
5623
5629
|
return a instanceof Uint8Array || (ArrayBuffer.isView(a) && a.constructor.name === 'Uint8Array');
|
5624
5630
|
}
|
@@ -5644,19 +5650,13 @@ function aoutput(out, instance) {
|
|
5644
5650
|
throw new Error('digestInto() expects output buffer of length at least ' + min);
|
5645
5651
|
}
|
5646
5652
|
}
|
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
|
5653
|
+
/** Zeroize a byte array. Warning: JS provides no guarantees. */
|
5654
|
+
function clean(...arrays) {
|
5655
|
+
for (let i = 0; i < arrays.length; i++) {
|
5656
|
+
arrays[i].fill(0);
|
5657
|
+
}
|
5658
|
+
}
|
5659
|
+
/** Create DataView of an array for easy byte-level manipulation. */
|
5660
5660
|
function createView(arr) {
|
5661
5661
|
return new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
|
5662
5662
|
}
|
@@ -5664,14 +5664,21 @@ function createView(arr) {
|
|
5664
5664
|
function rotr(word, shift) {
|
5665
5665
|
return (word << (32 - shift)) | (word >>> shift);
|
5666
5666
|
}
|
5667
|
+
// Built-in hex conversion https://caniuse.com/mdn-javascript_builtins_uint8array_fromhex
|
5668
|
+
const hasHexBuiltin = /* @__PURE__ */ (() =>
|
5669
|
+
// @ts-ignore
|
5670
|
+
typeof Uint8Array.from([]).toHex === 'function' && typeof Uint8Array.fromHex === 'function')();
|
5667
5671
|
// Array where index 0xf0 (240) is mapped to string 'f0'
|
5668
5672
|
const hexes = /* @__PURE__ */ Array.from({ length: 256 }, (_, i) => i.toString(16).padStart(2, '0'));
|
5669
5673
|
/**
|
5670
|
-
* Convert byte array to hex string.
|
5674
|
+
* Convert byte array to hex string. Uses built-in function, when available.
|
5671
5675
|
* @example bytesToHex(Uint8Array.from([0xca, 0xfe, 0x01, 0x23])) // 'cafe0123'
|
5672
5676
|
*/
|
5673
5677
|
function bytesToHex(bytes) {
|
5674
5678
|
abytes(bytes);
|
5679
|
+
// @ts-ignore
|
5680
|
+
if (hasHexBuiltin)
|
5681
|
+
return bytes.toHex();
|
5675
5682
|
// pre-caching improves the speed 6x
|
5676
5683
|
let hex = '';
|
5677
5684
|
for (let i = 0; i < bytes.length; i++) {
|
@@ -5680,12 +5687,12 @@ function bytesToHex(bytes) {
|
|
5680
5687
|
return hex;
|
5681
5688
|
}
|
5682
5689
|
/**
|
5683
|
-
*
|
5684
|
-
* @example utf8ToBytes('abc') //
|
5690
|
+
* Converts string to bytes using UTF8 encoding.
|
5691
|
+
* @example utf8ToBytes('abc') // Uint8Array.from([97, 98, 99])
|
5685
5692
|
*/
|
5686
5693
|
function utf8ToBytes(str) {
|
5687
5694
|
if (typeof str !== 'string')
|
5688
|
-
throw new Error('
|
5695
|
+
throw new Error('string expected');
|
5689
5696
|
return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
|
5690
5697
|
}
|
5691
5698
|
/**
|
@@ -5701,13 +5708,9 @@ function toBytes(data) {
|
|
5701
5708
|
}
|
5702
5709
|
/** For runtime check if class implements interface */
|
5703
5710
|
class Hash {
|
5704
|
-
// Safe version that clones internal state
|
5705
|
-
clone() {
|
5706
|
-
return this._cloneInto();
|
5707
|
-
}
|
5708
5711
|
}
|
5709
5712
|
/** Wraps hash function, creating an interface on top of it */
|
5710
|
-
function
|
5713
|
+
function createHasher(hashCons) {
|
5711
5714
|
const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
|
5712
5715
|
const tmp = hashCons();
|
5713
5716
|
hashC.outputLen = tmp.outputLen;
|
@@ -5748,21 +5751,22 @@ function Maj(a, b, c) {
|
|
5748
5751
|
class HashMD extends Hash {
|
5749
5752
|
constructor(blockLen, outputLen, padOffset, isLE) {
|
5750
5753
|
super();
|
5751
|
-
this.blockLen = blockLen;
|
5752
|
-
this.outputLen = outputLen;
|
5753
|
-
this.padOffset = padOffset;
|
5754
|
-
this.isLE = isLE;
|
5755
5754
|
this.finished = false;
|
5756
5755
|
this.length = 0;
|
5757
5756
|
this.pos = 0;
|
5758
5757
|
this.destroyed = false;
|
5758
|
+
this.blockLen = blockLen;
|
5759
|
+
this.outputLen = outputLen;
|
5760
|
+
this.padOffset = padOffset;
|
5761
|
+
this.isLE = isLE;
|
5759
5762
|
this.buffer = new Uint8Array(blockLen);
|
5760
5763
|
this.view = createView(this.buffer);
|
5761
5764
|
}
|
5762
5765
|
update(data) {
|
5763
5766
|
aexists(this);
|
5764
|
-
const { view, buffer, blockLen } = this;
|
5765
5767
|
data = toBytes(data);
|
5768
|
+
abytes(data);
|
5769
|
+
const { view, buffer, blockLen } = this;
|
5766
5770
|
const len = data.length;
|
5767
5771
|
for (let pos = 0; pos < len;) {
|
5768
5772
|
const take = Math.min(blockLen - this.pos, len - pos);
|
@@ -5796,7 +5800,7 @@ class HashMD extends Hash {
|
|
5796
5800
|
let { pos } = this;
|
5797
5801
|
// append the bit '1' to the message
|
5798
5802
|
buffer[pos++] = 0b10000000;
|
5799
|
-
this.buffer.subarray(pos)
|
5803
|
+
clean(this.buffer.subarray(pos));
|
5800
5804
|
// we have less than padOffset left in buffer, so we cannot put length in
|
5801
5805
|
// current block, need process it and pad again
|
5802
5806
|
if (this.padOffset > blockLen - pos) {
|
@@ -5834,28 +5838,40 @@ class HashMD extends Hash {
|
|
5834
5838
|
to || (to = new this.constructor());
|
5835
5839
|
to.set(...this.get());
|
5836
5840
|
const { blockLen, buffer, length, finished, destroyed, pos } = this;
|
5841
|
+
to.destroyed = destroyed;
|
5842
|
+
to.finished = finished;
|
5837
5843
|
to.length = length;
|
5838
5844
|
to.pos = pos;
|
5839
|
-
to.finished = finished;
|
5840
|
-
to.destroyed = destroyed;
|
5841
5845
|
if (length % blockLen)
|
5842
5846
|
to.buffer.set(buffer);
|
5843
5847
|
return to;
|
5844
5848
|
}
|
5849
|
+
clone() {
|
5850
|
+
return this._cloneInto();
|
5851
|
+
}
|
5845
5852
|
}
|
5853
|
+
/**
|
5854
|
+
* Initial SHA-2 state: fractional parts of square roots of first 16 primes 2..53.
|
5855
|
+
* Check out `test/misc/sha2-gen-iv.js` for recomputation guide.
|
5856
|
+
*/
|
5857
|
+
/** Initial SHA256 state. Bits 0..32 of frac part of sqrt of primes 2..19 */
|
5858
|
+
const SHA256_IV = /* @__PURE__ */ Uint32Array.from([
|
5859
|
+
0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19,
|
5860
|
+
]);
|
5846
5861
|
|
5847
5862
|
/**
|
5848
|
-
* SHA2
|
5849
|
-
*
|
5850
|
-
*
|
5851
|
-
*
|
5852
|
-
*
|
5853
|
-
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
5863
|
+
* SHA2 hash function. A.k.a. sha256, sha384, sha512, sha512_224, sha512_256.
|
5864
|
+
* SHA256 is the fastest hash implementable in JS, even faster than Blake3.
|
5865
|
+
* Check out [RFC 4634](https://datatracker.ietf.org/doc/html/rfc4634) and
|
5866
|
+
* [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
5854
5867
|
* @module
|
5855
5868
|
*/
|
5856
|
-
/**
|
5869
|
+
/**
|
5870
|
+
* Round constants:
|
5871
|
+
* First 32 bits of fractional parts of the cube roots of the first 64 primes 2..311)
|
5872
|
+
*/
|
5857
5873
|
// prettier-ignore
|
5858
|
-
const SHA256_K = /* @__PURE__ */
|
5874
|
+
const SHA256_K = /* @__PURE__ */ Uint32Array.from([
|
5859
5875
|
0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
|
5860
5876
|
0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
|
5861
5877
|
0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
|
@@ -5865,19 +5881,11 @@ const SHA256_K = /* @__PURE__ */ new Uint32Array([
|
|
5865
5881
|
0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3,
|
5866
5882
|
0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2
|
5867
5883
|
]);
|
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
|
-
*/
|
5884
|
+
/** Reusable temporary buffer. "W" comes straight from spec. */
|
5877
5885
|
const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
|
5878
5886
|
class SHA256 extends HashMD {
|
5879
|
-
constructor() {
|
5880
|
-
super(64,
|
5887
|
+
constructor(outputLen = 32) {
|
5888
|
+
super(64, outputLen, 8, false);
|
5881
5889
|
// We cannot use array here since array allows indexing by variable
|
5882
5890
|
// which means optimizer/compiler cannot use registers.
|
5883
5891
|
this.A = SHA256_IV[0] | 0;
|
@@ -5943,15 +5951,929 @@ class SHA256 extends HashMD {
|
|
5943
5951
|
this.set(A, B, C, D, E, F, G, H);
|
5944
5952
|
}
|
5945
5953
|
roundClean() {
|
5946
|
-
SHA256_W
|
5954
|
+
clean(SHA256_W);
|
5947
5955
|
}
|
5948
5956
|
destroy() {
|
5949
5957
|
this.set(0, 0, 0, 0, 0, 0, 0, 0);
|
5950
|
-
this.buffer
|
5958
|
+
clean(this.buffer);
|
5959
|
+
}
|
5960
|
+
}
|
5961
|
+
/**
|
5962
|
+
* SHA2-256 hash function from RFC 4634.
|
5963
|
+
*
|
5964
|
+
* It is the fastest JS hash, even faster than Blake3.
|
5965
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
5966
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
5967
|
+
*/
|
5968
|
+
const sha256$1 = /* @__PURE__ */ createHasher(() => new SHA256());
|
5969
|
+
|
5970
|
+
/**
|
5971
|
+
* SHA2-256 a.k.a. sha256. In JS, it is the fastest hash, even faster than Blake3.
|
5972
|
+
*
|
5973
|
+
* To break sha256 using birthday attack, attackers need to try 2^128 hashes.
|
5974
|
+
* BTC network is doing 2^70 hashes/sec (2^95 hashes/year) as per 2025.
|
5975
|
+
*
|
5976
|
+
* Check out [FIPS 180-4](https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf).
|
5977
|
+
* @module
|
5978
|
+
* @deprecated
|
5979
|
+
*/
|
5980
|
+
/** @deprecated Use import from `noble/hashes/sha2` module */
|
5981
|
+
const sha256 = sha256$1;
|
5982
|
+
|
5983
|
+
var Protocols;
|
5984
|
+
(function (Protocols) {
|
5985
|
+
Protocols["Relay"] = "relay";
|
5986
|
+
Protocols["Store"] = "store";
|
5987
|
+
Protocols["LightPush"] = "lightpush";
|
5988
|
+
Protocols["Filter"] = "filter";
|
5989
|
+
})(Protocols || (Protocols = {}));
|
5990
|
+
var ProtocolError;
|
5991
|
+
(function (ProtocolError) {
|
5992
|
+
//
|
5993
|
+
// GENERAL ERRORS SECTION
|
5994
|
+
//
|
5995
|
+
/**
|
5996
|
+
* Could not determine the origin of the fault. Best to check connectivity and try again
|
5997
|
+
* */
|
5998
|
+
ProtocolError["GENERIC_FAIL"] = "Generic error";
|
5999
|
+
/**
|
6000
|
+
* The remote peer rejected the message. Information provided by the remote peer
|
6001
|
+
* is logged. Review message validity, or mitigation for `NO_PEER_AVAILABLE`
|
6002
|
+
* or `DECODE_FAILED` can be used.
|
6003
|
+
*/
|
6004
|
+
ProtocolError["REMOTE_PEER_REJECTED"] = "Remote peer rejected";
|
6005
|
+
/**
|
6006
|
+
* Failure to protobuf decode the message. May be due to a remote peer issue,
|
6007
|
+
* ensuring that messages are sent via several peer enable mitigation of this error.
|
6008
|
+
*/
|
6009
|
+
ProtocolError["DECODE_FAILED"] = "Failed to decode";
|
6010
|
+
/**
|
6011
|
+
* Failure to find a peer with suitable protocols. This may due to a connection issue.
|
6012
|
+
* Mitigation can be: retrying after a given time period, display connectivity issue
|
6013
|
+
* to user or listening for `peer:connected:bootstrap` or `peer:connected:peer-exchange`
|
6014
|
+
* on the connection manager before retrying.
|
6015
|
+
*/
|
6016
|
+
ProtocolError["NO_PEER_AVAILABLE"] = "No peer available";
|
6017
|
+
/**
|
6018
|
+
* Failure to find a stream to the peer. This may be because the connection with the peer is not still alive.
|
6019
|
+
* Mitigation can be: retrying after a given time period, or mitigation for `NO_PEER_AVAILABLE` can be used.
|
6020
|
+
*/
|
6021
|
+
ProtocolError["NO_STREAM_AVAILABLE"] = "No stream available";
|
6022
|
+
/**
|
6023
|
+
* The remote peer did not behave as expected. Mitigation for `NO_PEER_AVAILABLE`
|
6024
|
+
* or `DECODE_FAILED` can be used.
|
6025
|
+
*/
|
6026
|
+
ProtocolError["NO_RESPONSE"] = "No response received";
|
6027
|
+
//
|
6028
|
+
// SEND ERRORS SECTION
|
6029
|
+
//
|
6030
|
+
/**
|
6031
|
+
* Failure to protobuf encode the message. This is not recoverable and needs
|
6032
|
+
* further investigation.
|
6033
|
+
*/
|
6034
|
+
ProtocolError["ENCODE_FAILED"] = "Failed to encode";
|
6035
|
+
/**
|
6036
|
+
* The message payload is empty, making the message invalid. Ensure that a non-empty
|
6037
|
+
* payload is set on the outgoing message.
|
6038
|
+
*/
|
6039
|
+
ProtocolError["EMPTY_PAYLOAD"] = "Payload is empty";
|
6040
|
+
/**
|
6041
|
+
* The message size is above the maximum message size allowed on the Waku Network.
|
6042
|
+
* Compressing the message or using an alternative strategy for large messages is recommended.
|
6043
|
+
*/
|
6044
|
+
ProtocolError["SIZE_TOO_BIG"] = "Size is too big";
|
6045
|
+
/**
|
6046
|
+
* The PubsubTopic passed to the send function is not configured on the Waku node.
|
6047
|
+
* Please ensure that the PubsubTopic is used when initializing the Waku node.
|
6048
|
+
*/
|
6049
|
+
ProtocolError["TOPIC_NOT_CONFIGURED"] = "Topic not configured";
|
6050
|
+
/**
|
6051
|
+
* Fails when
|
6052
|
+
*/
|
6053
|
+
ProtocolError["STREAM_ABORTED"] = "Stream aborted";
|
6054
|
+
/**
|
6055
|
+
* General proof generation error message.
|
6056
|
+
* nwaku: https://github.com/waku-org/nwaku/blob/c3cb06ac6c03f0f382d3941ea53b330f6a8dd127/waku/waku_rln_relay/group_manager/group_manager_base.nim#L201C19-L201C42
|
6057
|
+
*/
|
6058
|
+
ProtocolError["RLN_PROOF_GENERATION"] = "Proof generation failed";
|
6059
|
+
//
|
6060
|
+
// RECEIVE ERRORS SECTION
|
6061
|
+
//
|
6062
|
+
/**
|
6063
|
+
* The pubsub topic configured on the decoder does not match the pubsub topic setup on the protocol.
|
6064
|
+
* Ensure that the pubsub topic used for decoder creation is the same as the one used for protocol.
|
6065
|
+
*/
|
6066
|
+
ProtocolError["TOPIC_DECODER_MISMATCH"] = "Topic decoder mismatch";
|
6067
|
+
/**
|
6068
|
+
* The topics passed in the decoders do not match each other, or don't exist at all.
|
6069
|
+
* Ensure that all the pubsub topics used in the decoders are valid and match each other.
|
6070
|
+
*/
|
6071
|
+
ProtocolError["INVALID_DECODER_TOPICS"] = "Invalid decoder topics";
|
6072
|
+
})(ProtocolError || (ProtocolError = {}));
|
6073
|
+
|
6074
|
+
var Tags;
|
6075
|
+
(function (Tags) {
|
6076
|
+
Tags["BOOTSTRAP"] = "bootstrap";
|
6077
|
+
Tags["PEER_EXCHANGE"] = "peer-exchange";
|
6078
|
+
Tags["LOCAL"] = "local-peer-cache";
|
6079
|
+
})(Tags || (Tags = {}));
|
6080
|
+
var EPeersByDiscoveryEvents;
|
6081
|
+
(function (EPeersByDiscoveryEvents) {
|
6082
|
+
EPeersByDiscoveryEvents["PEER_DISCOVERY_BOOTSTRAP"] = "peer:discovery:bootstrap";
|
6083
|
+
EPeersByDiscoveryEvents["PEER_DISCOVERY_PEER_EXCHANGE"] = "peer:discovery:peer-exchange";
|
6084
|
+
EPeersByDiscoveryEvents["PEER_CONNECT_BOOTSTRAP"] = "peer:connected:bootstrap";
|
6085
|
+
EPeersByDiscoveryEvents["PEER_CONNECT_PEER_EXCHANGE"] = "peer:connected:peer-exchange";
|
6086
|
+
})(EPeersByDiscoveryEvents || (EPeersByDiscoveryEvents = {}));
|
6087
|
+
var EConnectionStateEvents;
|
6088
|
+
(function (EConnectionStateEvents) {
|
6089
|
+
EConnectionStateEvents["CONNECTION_STATUS"] = "waku:connection";
|
6090
|
+
})(EConnectionStateEvents || (EConnectionStateEvents = {}));
|
6091
|
+
|
6092
|
+
var HealthStatusChangeEvents;
|
6093
|
+
(function (HealthStatusChangeEvents) {
|
6094
|
+
HealthStatusChangeEvents["StatusChange"] = "health:change";
|
6095
|
+
})(HealthStatusChangeEvents || (HealthStatusChangeEvents = {}));
|
6096
|
+
var HealthStatus;
|
6097
|
+
(function (HealthStatus) {
|
6098
|
+
HealthStatus["Unhealthy"] = "Unhealthy";
|
6099
|
+
HealthStatus["MinimallyHealthy"] = "MinimallyHealthy";
|
6100
|
+
HealthStatus["SufficientlyHealthy"] = "SufficientlyHealthy";
|
6101
|
+
})(HealthStatus || (HealthStatus = {}));
|
6102
|
+
|
6103
|
+
function getDefaultExportFromCjs (x) {
|
6104
|
+
return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, 'default') ? x['default'] : x;
|
6105
|
+
}
|
6106
|
+
|
6107
|
+
var browser = {exports: {}};
|
6108
|
+
|
6109
|
+
/**
|
6110
|
+
* Helpers.
|
6111
|
+
*/
|
6112
|
+
|
6113
|
+
var ms;
|
6114
|
+
var hasRequiredMs;
|
6115
|
+
|
6116
|
+
function requireMs () {
|
6117
|
+
if (hasRequiredMs) return ms;
|
6118
|
+
hasRequiredMs = 1;
|
6119
|
+
var s = 1000;
|
6120
|
+
var m = s * 60;
|
6121
|
+
var h = m * 60;
|
6122
|
+
var d = h * 24;
|
6123
|
+
var w = d * 7;
|
6124
|
+
var y = d * 365.25;
|
6125
|
+
|
6126
|
+
/**
|
6127
|
+
* Parse or format the given `val`.
|
6128
|
+
*
|
6129
|
+
* Options:
|
6130
|
+
*
|
6131
|
+
* - `long` verbose formatting [false]
|
6132
|
+
*
|
6133
|
+
* @param {String|Number} val
|
6134
|
+
* @param {Object} [options]
|
6135
|
+
* @throws {Error} throw an error if val is not a non-empty string or a number
|
6136
|
+
* @return {String|Number}
|
6137
|
+
* @api public
|
6138
|
+
*/
|
6139
|
+
|
6140
|
+
ms = function (val, options) {
|
6141
|
+
options = options || {};
|
6142
|
+
var type = typeof val;
|
6143
|
+
if (type === 'string' && val.length > 0) {
|
6144
|
+
return parse(val);
|
6145
|
+
} else if (type === 'number' && isFinite(val)) {
|
6146
|
+
return options.long ? fmtLong(val) : fmtShort(val);
|
6147
|
+
}
|
6148
|
+
throw new Error(
|
6149
|
+
'val is not a non-empty string or a valid number. val=' +
|
6150
|
+
JSON.stringify(val)
|
6151
|
+
);
|
6152
|
+
};
|
6153
|
+
|
6154
|
+
/**
|
6155
|
+
* Parse the given `str` and return milliseconds.
|
6156
|
+
*
|
6157
|
+
* @param {String} str
|
6158
|
+
* @return {Number}
|
6159
|
+
* @api private
|
6160
|
+
*/
|
6161
|
+
|
6162
|
+
function parse(str) {
|
6163
|
+
str = String(str);
|
6164
|
+
if (str.length > 100) {
|
6165
|
+
return;
|
6166
|
+
}
|
6167
|
+
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(
|
6168
|
+
str
|
6169
|
+
);
|
6170
|
+
if (!match) {
|
6171
|
+
return;
|
6172
|
+
}
|
6173
|
+
var n = parseFloat(match[1]);
|
6174
|
+
var type = (match[2] || 'ms').toLowerCase();
|
6175
|
+
switch (type) {
|
6176
|
+
case 'years':
|
6177
|
+
case 'year':
|
6178
|
+
case 'yrs':
|
6179
|
+
case 'yr':
|
6180
|
+
case 'y':
|
6181
|
+
return n * y;
|
6182
|
+
case 'weeks':
|
6183
|
+
case 'week':
|
6184
|
+
case 'w':
|
6185
|
+
return n * w;
|
6186
|
+
case 'days':
|
6187
|
+
case 'day':
|
6188
|
+
case 'd':
|
6189
|
+
return n * d;
|
6190
|
+
case 'hours':
|
6191
|
+
case 'hour':
|
6192
|
+
case 'hrs':
|
6193
|
+
case 'hr':
|
6194
|
+
case 'h':
|
6195
|
+
return n * h;
|
6196
|
+
case 'minutes':
|
6197
|
+
case 'minute':
|
6198
|
+
case 'mins':
|
6199
|
+
case 'min':
|
6200
|
+
case 'm':
|
6201
|
+
return n * m;
|
6202
|
+
case 'seconds':
|
6203
|
+
case 'second':
|
6204
|
+
case 'secs':
|
6205
|
+
case 'sec':
|
6206
|
+
case 's':
|
6207
|
+
return n * s;
|
6208
|
+
case 'milliseconds':
|
6209
|
+
case 'millisecond':
|
6210
|
+
case 'msecs':
|
6211
|
+
case 'msec':
|
6212
|
+
case 'ms':
|
6213
|
+
return n;
|
6214
|
+
default:
|
6215
|
+
return undefined;
|
6216
|
+
}
|
6217
|
+
}
|
6218
|
+
|
6219
|
+
/**
|
6220
|
+
* Short format for `ms`.
|
6221
|
+
*
|
6222
|
+
* @param {Number} ms
|
6223
|
+
* @return {String}
|
6224
|
+
* @api private
|
6225
|
+
*/
|
6226
|
+
|
6227
|
+
function fmtShort(ms) {
|
6228
|
+
var msAbs = Math.abs(ms);
|
6229
|
+
if (msAbs >= d) {
|
6230
|
+
return Math.round(ms / d) + 'd';
|
6231
|
+
}
|
6232
|
+
if (msAbs >= h) {
|
6233
|
+
return Math.round(ms / h) + 'h';
|
6234
|
+
}
|
6235
|
+
if (msAbs >= m) {
|
6236
|
+
return Math.round(ms / m) + 'm';
|
6237
|
+
}
|
6238
|
+
if (msAbs >= s) {
|
6239
|
+
return Math.round(ms / s) + 's';
|
6240
|
+
}
|
6241
|
+
return ms + 'ms';
|
6242
|
+
}
|
6243
|
+
|
6244
|
+
/**
|
6245
|
+
* Long format for `ms`.
|
6246
|
+
*
|
6247
|
+
* @param {Number} ms
|
6248
|
+
* @return {String}
|
6249
|
+
* @api private
|
6250
|
+
*/
|
6251
|
+
|
6252
|
+
function fmtLong(ms) {
|
6253
|
+
var msAbs = Math.abs(ms);
|
6254
|
+
if (msAbs >= d) {
|
6255
|
+
return plural(ms, msAbs, d, 'day');
|
6256
|
+
}
|
6257
|
+
if (msAbs >= h) {
|
6258
|
+
return plural(ms, msAbs, h, 'hour');
|
6259
|
+
}
|
6260
|
+
if (msAbs >= m) {
|
6261
|
+
return plural(ms, msAbs, m, 'minute');
|
6262
|
+
}
|
6263
|
+
if (msAbs >= s) {
|
6264
|
+
return plural(ms, msAbs, s, 'second');
|
6265
|
+
}
|
6266
|
+
return ms + ' ms';
|
6267
|
+
}
|
6268
|
+
|
6269
|
+
/**
|
6270
|
+
* Pluralization helper.
|
6271
|
+
*/
|
6272
|
+
|
6273
|
+
function plural(ms, msAbs, n, name) {
|
6274
|
+
var isPlural = msAbs >= n * 1.5;
|
6275
|
+
return Math.round(ms / n) + ' ' + name + (isPlural ? 's' : '');
|
6276
|
+
}
|
6277
|
+
return ms;
|
6278
|
+
}
|
6279
|
+
|
6280
|
+
/**
|
6281
|
+
* This is the common logic for both the Node.js and web browser
|
6282
|
+
* implementations of `debug()`.
|
6283
|
+
*/
|
6284
|
+
|
6285
|
+
function setup(env) {
|
6286
|
+
createDebug.debug = createDebug;
|
6287
|
+
createDebug.default = createDebug;
|
6288
|
+
createDebug.coerce = coerce;
|
6289
|
+
createDebug.disable = disable;
|
6290
|
+
createDebug.enable = enable;
|
6291
|
+
createDebug.enabled = enabled;
|
6292
|
+
createDebug.humanize = requireMs();
|
6293
|
+
createDebug.destroy = destroy;
|
6294
|
+
|
6295
|
+
Object.keys(env).forEach(key => {
|
6296
|
+
createDebug[key] = env[key];
|
6297
|
+
});
|
6298
|
+
|
6299
|
+
/**
|
6300
|
+
* The currently active debug mode names, and names to skip.
|
6301
|
+
*/
|
6302
|
+
|
6303
|
+
createDebug.names = [];
|
6304
|
+
createDebug.skips = [];
|
6305
|
+
|
6306
|
+
/**
|
6307
|
+
* Map of special "%n" handling functions, for the debug "format" argument.
|
6308
|
+
*
|
6309
|
+
* Valid key names are a single, lower or upper-case letter, i.e. "n" and "N".
|
6310
|
+
*/
|
6311
|
+
createDebug.formatters = {};
|
6312
|
+
|
6313
|
+
/**
|
6314
|
+
* Selects a color for a debug namespace
|
6315
|
+
* @param {String} namespace The namespace string for the debug instance to be colored
|
6316
|
+
* @return {Number|String} An ANSI color code for the given namespace
|
6317
|
+
* @api private
|
6318
|
+
*/
|
6319
|
+
function selectColor(namespace) {
|
6320
|
+
let hash = 0;
|
6321
|
+
|
6322
|
+
for (let i = 0; i < namespace.length; i++) {
|
6323
|
+
hash = ((hash << 5) - hash) + namespace.charCodeAt(i);
|
6324
|
+
hash |= 0; // Convert to 32bit integer
|
6325
|
+
}
|
6326
|
+
|
6327
|
+
return createDebug.colors[Math.abs(hash) % createDebug.colors.length];
|
6328
|
+
}
|
6329
|
+
createDebug.selectColor = selectColor;
|
6330
|
+
|
6331
|
+
/**
|
6332
|
+
* Create a debugger with the given `namespace`.
|
6333
|
+
*
|
6334
|
+
* @param {String} namespace
|
6335
|
+
* @return {Function}
|
6336
|
+
* @api public
|
6337
|
+
*/
|
6338
|
+
function createDebug(namespace) {
|
6339
|
+
let prevTime;
|
6340
|
+
let enableOverride = null;
|
6341
|
+
let namespacesCache;
|
6342
|
+
let enabledCache;
|
6343
|
+
|
6344
|
+
function debug(...args) {
|
6345
|
+
// Disabled?
|
6346
|
+
if (!debug.enabled) {
|
6347
|
+
return;
|
6348
|
+
}
|
6349
|
+
|
6350
|
+
const self = debug;
|
6351
|
+
|
6352
|
+
// Set `diff` timestamp
|
6353
|
+
const curr = Number(new Date());
|
6354
|
+
const ms = curr - (prevTime || curr);
|
6355
|
+
self.diff = ms;
|
6356
|
+
self.prev = prevTime;
|
6357
|
+
self.curr = curr;
|
6358
|
+
prevTime = curr;
|
6359
|
+
|
6360
|
+
args[0] = createDebug.coerce(args[0]);
|
6361
|
+
|
6362
|
+
if (typeof args[0] !== 'string') {
|
6363
|
+
// Anything else let's inspect with %O
|
6364
|
+
args.unshift('%O');
|
6365
|
+
}
|
6366
|
+
|
6367
|
+
// Apply any `formatters` transformations
|
6368
|
+
let index = 0;
|
6369
|
+
args[0] = args[0].replace(/%([a-zA-Z%])/g, (match, format) => {
|
6370
|
+
// If we encounter an escaped % then don't increase the array index
|
6371
|
+
if (match === '%%') {
|
6372
|
+
return '%';
|
6373
|
+
}
|
6374
|
+
index++;
|
6375
|
+
const formatter = createDebug.formatters[format];
|
6376
|
+
if (typeof formatter === 'function') {
|
6377
|
+
const val = args[index];
|
6378
|
+
match = formatter.call(self, val);
|
6379
|
+
|
6380
|
+
// Now we need to remove `args[index]` since it's inlined in the `format`
|
6381
|
+
args.splice(index, 1);
|
6382
|
+
index--;
|
6383
|
+
}
|
6384
|
+
return match;
|
6385
|
+
});
|
6386
|
+
|
6387
|
+
// Apply env-specific formatting (colors, etc.)
|
6388
|
+
createDebug.formatArgs.call(self, args);
|
6389
|
+
|
6390
|
+
const logFn = self.log || createDebug.log;
|
6391
|
+
logFn.apply(self, args);
|
6392
|
+
}
|
6393
|
+
|
6394
|
+
debug.namespace = namespace;
|
6395
|
+
debug.useColors = createDebug.useColors();
|
6396
|
+
debug.color = createDebug.selectColor(namespace);
|
6397
|
+
debug.extend = extend;
|
6398
|
+
debug.destroy = createDebug.destroy; // XXX Temporary. Will be removed in the next major release.
|
6399
|
+
|
6400
|
+
Object.defineProperty(debug, 'enabled', {
|
6401
|
+
enumerable: true,
|
6402
|
+
configurable: false,
|
6403
|
+
get: () => {
|
6404
|
+
if (enableOverride !== null) {
|
6405
|
+
return enableOverride;
|
6406
|
+
}
|
6407
|
+
if (namespacesCache !== createDebug.namespaces) {
|
6408
|
+
namespacesCache = createDebug.namespaces;
|
6409
|
+
enabledCache = createDebug.enabled(namespace);
|
6410
|
+
}
|
6411
|
+
|
6412
|
+
return enabledCache;
|
6413
|
+
},
|
6414
|
+
set: v => {
|
6415
|
+
enableOverride = v;
|
6416
|
+
}
|
6417
|
+
});
|
6418
|
+
|
6419
|
+
// Env-specific initialization logic for debug instances
|
6420
|
+
if (typeof createDebug.init === 'function') {
|
6421
|
+
createDebug.init(debug);
|
6422
|
+
}
|
6423
|
+
|
6424
|
+
return debug;
|
6425
|
+
}
|
6426
|
+
|
6427
|
+
function extend(namespace, delimiter) {
|
6428
|
+
const newDebug = createDebug(this.namespace + (typeof delimiter === 'undefined' ? ':' : delimiter) + namespace);
|
6429
|
+
newDebug.log = this.log;
|
6430
|
+
return newDebug;
|
6431
|
+
}
|
6432
|
+
|
6433
|
+
/**
|
6434
|
+
* Enables a debug mode by namespaces. This can include modes
|
6435
|
+
* separated by a colon and wildcards.
|
6436
|
+
*
|
6437
|
+
* @param {String} namespaces
|
6438
|
+
* @api public
|
6439
|
+
*/
|
6440
|
+
function enable(namespaces) {
|
6441
|
+
createDebug.save(namespaces);
|
6442
|
+
createDebug.namespaces = namespaces;
|
6443
|
+
|
6444
|
+
createDebug.names = [];
|
6445
|
+
createDebug.skips = [];
|
6446
|
+
|
6447
|
+
const split = (typeof namespaces === 'string' ? namespaces : '')
|
6448
|
+
.trim()
|
6449
|
+
.replace(' ', ',')
|
6450
|
+
.split(',')
|
6451
|
+
.filter(Boolean);
|
6452
|
+
|
6453
|
+
for (const ns of split) {
|
6454
|
+
if (ns[0] === '-') {
|
6455
|
+
createDebug.skips.push(ns.slice(1));
|
6456
|
+
} else {
|
6457
|
+
createDebug.names.push(ns);
|
6458
|
+
}
|
6459
|
+
}
|
6460
|
+
}
|
6461
|
+
|
6462
|
+
/**
|
6463
|
+
* Checks if the given string matches a namespace template, honoring
|
6464
|
+
* asterisks as wildcards.
|
6465
|
+
*
|
6466
|
+
* @param {String} search
|
6467
|
+
* @param {String} template
|
6468
|
+
* @return {Boolean}
|
6469
|
+
*/
|
6470
|
+
function matchesTemplate(search, template) {
|
6471
|
+
let searchIndex = 0;
|
6472
|
+
let templateIndex = 0;
|
6473
|
+
let starIndex = -1;
|
6474
|
+
let matchIndex = 0;
|
6475
|
+
|
6476
|
+
while (searchIndex < search.length) {
|
6477
|
+
if (templateIndex < template.length && (template[templateIndex] === search[searchIndex] || template[templateIndex] === '*')) {
|
6478
|
+
// Match character or proceed with wildcard
|
6479
|
+
if (template[templateIndex] === '*') {
|
6480
|
+
starIndex = templateIndex;
|
6481
|
+
matchIndex = searchIndex;
|
6482
|
+
templateIndex++; // Skip the '*'
|
6483
|
+
} else {
|
6484
|
+
searchIndex++;
|
6485
|
+
templateIndex++;
|
6486
|
+
}
|
6487
|
+
} else if (starIndex !== -1) { // eslint-disable-line no-negated-condition
|
6488
|
+
// Backtrack to the last '*' and try to match more characters
|
6489
|
+
templateIndex = starIndex + 1;
|
6490
|
+
matchIndex++;
|
6491
|
+
searchIndex = matchIndex;
|
6492
|
+
} else {
|
6493
|
+
return false; // No match
|
6494
|
+
}
|
6495
|
+
}
|
6496
|
+
|
6497
|
+
// Handle trailing '*' in template
|
6498
|
+
while (templateIndex < template.length && template[templateIndex] === '*') {
|
6499
|
+
templateIndex++;
|
6500
|
+
}
|
6501
|
+
|
6502
|
+
return templateIndex === template.length;
|
6503
|
+
}
|
6504
|
+
|
6505
|
+
/**
|
6506
|
+
* Disable debug output.
|
6507
|
+
*
|
6508
|
+
* @return {String} namespaces
|
6509
|
+
* @api public
|
6510
|
+
*/
|
6511
|
+
function disable() {
|
6512
|
+
const namespaces = [
|
6513
|
+
...createDebug.names,
|
6514
|
+
...createDebug.skips.map(namespace => '-' + namespace)
|
6515
|
+
].join(',');
|
6516
|
+
createDebug.enable('');
|
6517
|
+
return namespaces;
|
6518
|
+
}
|
6519
|
+
|
6520
|
+
/**
|
6521
|
+
* Returns true if the given mode name is enabled, false otherwise.
|
6522
|
+
*
|
6523
|
+
* @param {String} name
|
6524
|
+
* @return {Boolean}
|
6525
|
+
* @api public
|
6526
|
+
*/
|
6527
|
+
function enabled(name) {
|
6528
|
+
for (const skip of createDebug.skips) {
|
6529
|
+
if (matchesTemplate(name, skip)) {
|
6530
|
+
return false;
|
6531
|
+
}
|
6532
|
+
}
|
6533
|
+
|
6534
|
+
for (const ns of createDebug.names) {
|
6535
|
+
if (matchesTemplate(name, ns)) {
|
6536
|
+
return true;
|
6537
|
+
}
|
6538
|
+
}
|
6539
|
+
|
6540
|
+
return false;
|
6541
|
+
}
|
6542
|
+
|
6543
|
+
/**
|
6544
|
+
* Coerce `val`.
|
6545
|
+
*
|
6546
|
+
* @param {Mixed} val
|
6547
|
+
* @return {Mixed}
|
6548
|
+
* @api private
|
6549
|
+
*/
|
6550
|
+
function coerce(val) {
|
6551
|
+
if (val instanceof Error) {
|
6552
|
+
return val.stack || val.message;
|
6553
|
+
}
|
6554
|
+
return val;
|
6555
|
+
}
|
6556
|
+
|
6557
|
+
/**
|
6558
|
+
* XXX DO NOT USE. This is a temporary stub function.
|
6559
|
+
* XXX It WILL be removed in the next major release.
|
6560
|
+
*/
|
6561
|
+
function destroy() {
|
6562
|
+
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
6563
|
+
}
|
6564
|
+
|
6565
|
+
createDebug.enable(createDebug.load());
|
6566
|
+
|
6567
|
+
return createDebug;
|
6568
|
+
}
|
6569
|
+
|
6570
|
+
var common = setup;
|
6571
|
+
|
6572
|
+
/* eslint-env browser */
|
6573
|
+
|
6574
|
+
(function (module, exports) {
|
6575
|
+
/**
|
6576
|
+
* This is the web browser implementation of `debug()`.
|
6577
|
+
*/
|
6578
|
+
|
6579
|
+
exports.formatArgs = formatArgs;
|
6580
|
+
exports.save = save;
|
6581
|
+
exports.load = load;
|
6582
|
+
exports.useColors = useColors;
|
6583
|
+
exports.storage = localstorage();
|
6584
|
+
exports.destroy = (() => {
|
6585
|
+
let warned = false;
|
6586
|
+
|
6587
|
+
return () => {
|
6588
|
+
if (!warned) {
|
6589
|
+
warned = true;
|
6590
|
+
console.warn('Instance method `debug.destroy()` is deprecated and no longer does anything. It will be removed in the next major version of `debug`.');
|
6591
|
+
}
|
6592
|
+
};
|
6593
|
+
})();
|
6594
|
+
|
6595
|
+
/**
|
6596
|
+
* Colors.
|
6597
|
+
*/
|
6598
|
+
|
6599
|
+
exports.colors = [
|
6600
|
+
'#0000CC',
|
6601
|
+
'#0000FF',
|
6602
|
+
'#0033CC',
|
6603
|
+
'#0033FF',
|
6604
|
+
'#0066CC',
|
6605
|
+
'#0066FF',
|
6606
|
+
'#0099CC',
|
6607
|
+
'#0099FF',
|
6608
|
+
'#00CC00',
|
6609
|
+
'#00CC33',
|
6610
|
+
'#00CC66',
|
6611
|
+
'#00CC99',
|
6612
|
+
'#00CCCC',
|
6613
|
+
'#00CCFF',
|
6614
|
+
'#3300CC',
|
6615
|
+
'#3300FF',
|
6616
|
+
'#3333CC',
|
6617
|
+
'#3333FF',
|
6618
|
+
'#3366CC',
|
6619
|
+
'#3366FF',
|
6620
|
+
'#3399CC',
|
6621
|
+
'#3399FF',
|
6622
|
+
'#33CC00',
|
6623
|
+
'#33CC33',
|
6624
|
+
'#33CC66',
|
6625
|
+
'#33CC99',
|
6626
|
+
'#33CCCC',
|
6627
|
+
'#33CCFF',
|
6628
|
+
'#6600CC',
|
6629
|
+
'#6600FF',
|
6630
|
+
'#6633CC',
|
6631
|
+
'#6633FF',
|
6632
|
+
'#66CC00',
|
6633
|
+
'#66CC33',
|
6634
|
+
'#9900CC',
|
6635
|
+
'#9900FF',
|
6636
|
+
'#9933CC',
|
6637
|
+
'#9933FF',
|
6638
|
+
'#99CC00',
|
6639
|
+
'#99CC33',
|
6640
|
+
'#CC0000',
|
6641
|
+
'#CC0033',
|
6642
|
+
'#CC0066',
|
6643
|
+
'#CC0099',
|
6644
|
+
'#CC00CC',
|
6645
|
+
'#CC00FF',
|
6646
|
+
'#CC3300',
|
6647
|
+
'#CC3333',
|
6648
|
+
'#CC3366',
|
6649
|
+
'#CC3399',
|
6650
|
+
'#CC33CC',
|
6651
|
+
'#CC33FF',
|
6652
|
+
'#CC6600',
|
6653
|
+
'#CC6633',
|
6654
|
+
'#CC9900',
|
6655
|
+
'#CC9933',
|
6656
|
+
'#CCCC00',
|
6657
|
+
'#CCCC33',
|
6658
|
+
'#FF0000',
|
6659
|
+
'#FF0033',
|
6660
|
+
'#FF0066',
|
6661
|
+
'#FF0099',
|
6662
|
+
'#FF00CC',
|
6663
|
+
'#FF00FF',
|
6664
|
+
'#FF3300',
|
6665
|
+
'#FF3333',
|
6666
|
+
'#FF3366',
|
6667
|
+
'#FF3399',
|
6668
|
+
'#FF33CC',
|
6669
|
+
'#FF33FF',
|
6670
|
+
'#FF6600',
|
6671
|
+
'#FF6633',
|
6672
|
+
'#FF9900',
|
6673
|
+
'#FF9933',
|
6674
|
+
'#FFCC00',
|
6675
|
+
'#FFCC33'
|
6676
|
+
];
|
6677
|
+
|
6678
|
+
/**
|
6679
|
+
* Currently only WebKit-based Web Inspectors, Firefox >= v31,
|
6680
|
+
* and the Firebug extension (any Firefox version) are known
|
6681
|
+
* to support "%c" CSS customizations.
|
6682
|
+
*
|
6683
|
+
* TODO: add a `localStorage` variable to explicitly enable/disable colors
|
6684
|
+
*/
|
6685
|
+
|
6686
|
+
// eslint-disable-next-line complexity
|
6687
|
+
function useColors() {
|
6688
|
+
// NB: In an Electron preload script, document will be defined but not fully
|
6689
|
+
// initialized. Since we know we're in Chrome, we'll just detect this case
|
6690
|
+
// explicitly
|
6691
|
+
if (typeof window !== 'undefined' && window.process && (window.process.type === 'renderer' || window.process.__nwjs)) {
|
6692
|
+
return true;
|
6693
|
+
}
|
6694
|
+
|
6695
|
+
// Internet Explorer and Edge do not support colors.
|
6696
|
+
if (typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/(edge|trident)\/(\d+)/)) {
|
6697
|
+
return false;
|
6698
|
+
}
|
6699
|
+
|
6700
|
+
let m;
|
6701
|
+
|
6702
|
+
// Is webkit? http://stackoverflow.com/a/16459606/376773
|
6703
|
+
// document is undefined in react-native: https://github.com/facebook/react-native/pull/1632
|
6704
|
+
// eslint-disable-next-line no-return-assign
|
6705
|
+
return (typeof document !== 'undefined' && document.documentElement && document.documentElement.style && document.documentElement.style.WebkitAppearance) ||
|
6706
|
+
// Is firebug? http://stackoverflow.com/a/398120/376773
|
6707
|
+
(typeof window !== 'undefined' && window.console && (window.console.firebug || (window.console.exception && window.console.table))) ||
|
6708
|
+
// Is firefox >= v31?
|
6709
|
+
// https://developer.mozilla.org/en-US/docs/Tools/Web_Console#Styling_messages
|
6710
|
+
(typeof navigator !== 'undefined' && navigator.userAgent && (m = navigator.userAgent.toLowerCase().match(/firefox\/(\d+)/)) && parseInt(m[1], 10) >= 31) ||
|
6711
|
+
// Double check webkit in userAgent just in case we are in a worker
|
6712
|
+
(typeof navigator !== 'undefined' && navigator.userAgent && navigator.userAgent.toLowerCase().match(/applewebkit\/(\d+)/));
|
6713
|
+
}
|
6714
|
+
|
6715
|
+
/**
|
6716
|
+
* Colorize log arguments if enabled.
|
6717
|
+
*
|
6718
|
+
* @api public
|
6719
|
+
*/
|
6720
|
+
|
6721
|
+
function formatArgs(args) {
|
6722
|
+
args[0] = (this.useColors ? '%c' : '') +
|
6723
|
+
this.namespace +
|
6724
|
+
(this.useColors ? ' %c' : ' ') +
|
6725
|
+
args[0] +
|
6726
|
+
(this.useColors ? '%c ' : ' ') +
|
6727
|
+
'+' + module.exports.humanize(this.diff);
|
6728
|
+
|
6729
|
+
if (!this.useColors) {
|
6730
|
+
return;
|
6731
|
+
}
|
6732
|
+
|
6733
|
+
const c = 'color: ' + this.color;
|
6734
|
+
args.splice(1, 0, c, 'color: inherit');
|
6735
|
+
|
6736
|
+
// The final "%c" is somewhat tricky, because there could be other
|
6737
|
+
// arguments passed either before or after the %c, so we need to
|
6738
|
+
// figure out the correct index to insert the CSS into
|
6739
|
+
let index = 0;
|
6740
|
+
let lastC = 0;
|
6741
|
+
args[0].replace(/%[a-zA-Z%]/g, match => {
|
6742
|
+
if (match === '%%') {
|
6743
|
+
return;
|
6744
|
+
}
|
6745
|
+
index++;
|
6746
|
+
if (match === '%c') {
|
6747
|
+
// We only are interested in the *last* %c
|
6748
|
+
// (the user may have provided their own)
|
6749
|
+
lastC = index;
|
6750
|
+
}
|
6751
|
+
});
|
6752
|
+
|
6753
|
+
args.splice(lastC, 0, c);
|
6754
|
+
}
|
6755
|
+
|
6756
|
+
/**
|
6757
|
+
* Invokes `console.debug()` when available.
|
6758
|
+
* No-op when `console.debug` is not a "function".
|
6759
|
+
* If `console.debug` is not available, falls back
|
6760
|
+
* to `console.log`.
|
6761
|
+
*
|
6762
|
+
* @api public
|
6763
|
+
*/
|
6764
|
+
exports.log = console.debug || console.log || (() => {});
|
6765
|
+
|
6766
|
+
/**
|
6767
|
+
* Save `namespaces`.
|
6768
|
+
*
|
6769
|
+
* @param {String} namespaces
|
6770
|
+
* @api private
|
6771
|
+
*/
|
6772
|
+
function save(namespaces) {
|
6773
|
+
try {
|
6774
|
+
if (namespaces) {
|
6775
|
+
exports.storage.setItem('debug', namespaces);
|
6776
|
+
} else {
|
6777
|
+
exports.storage.removeItem('debug');
|
6778
|
+
}
|
6779
|
+
} catch (error) {
|
6780
|
+
// Swallow
|
6781
|
+
// XXX (@Qix-) should we be logging these?
|
6782
|
+
}
|
6783
|
+
}
|
6784
|
+
|
6785
|
+
/**
|
6786
|
+
* Load `namespaces`.
|
6787
|
+
*
|
6788
|
+
* @return {String} returns the previously persisted debug modes
|
6789
|
+
* @api private
|
6790
|
+
*/
|
6791
|
+
function load() {
|
6792
|
+
let r;
|
6793
|
+
try {
|
6794
|
+
r = exports.storage.getItem('debug');
|
6795
|
+
} catch (error) {
|
6796
|
+
// Swallow
|
6797
|
+
// XXX (@Qix-) should we be logging these?
|
6798
|
+
}
|
6799
|
+
|
6800
|
+
// If debug isn't set in LS, and we're in Electron, try to load $DEBUG
|
6801
|
+
if (!r && typeof process !== 'undefined' && 'env' in process) {
|
6802
|
+
r = process.env.DEBUG;
|
6803
|
+
}
|
6804
|
+
|
6805
|
+
return r;
|
6806
|
+
}
|
6807
|
+
|
6808
|
+
/**
|
6809
|
+
* Localstorage attempts to return the localstorage.
|
6810
|
+
*
|
6811
|
+
* This is necessary because safari throws
|
6812
|
+
* when a user disables cookies/localstorage
|
6813
|
+
* and you attempt to access it.
|
6814
|
+
*
|
6815
|
+
* @return {LocalStorage}
|
6816
|
+
* @api private
|
6817
|
+
*/
|
6818
|
+
|
6819
|
+
function localstorage() {
|
6820
|
+
try {
|
6821
|
+
// TVMLKit (Apple TV JS Runtime) does not have a window object, just localStorage in the global context
|
6822
|
+
// The Browser also has localStorage in the global context.
|
6823
|
+
return localStorage;
|
6824
|
+
} catch (error) {
|
6825
|
+
// Swallow
|
6826
|
+
// XXX (@Qix-) should we be logging these?
|
6827
|
+
}
|
6828
|
+
}
|
6829
|
+
|
6830
|
+
module.exports = common(exports);
|
6831
|
+
|
6832
|
+
const {formatters} = module.exports;
|
6833
|
+
|
6834
|
+
/**
|
6835
|
+
* Map %j to `JSON.stringify()`, since no Web Inspectors do that by default.
|
6836
|
+
*/
|
6837
|
+
|
6838
|
+
formatters.j = function (v) {
|
6839
|
+
try {
|
6840
|
+
return JSON.stringify(v);
|
6841
|
+
} catch (error) {
|
6842
|
+
return '[UnexpectedJSONParseError]: ' + error.message;
|
6843
|
+
}
|
6844
|
+
};
|
6845
|
+
} (browser, browser.exports));
|
6846
|
+
|
6847
|
+
var browserExports = browser.exports;
|
6848
|
+
var debug = /*@__PURE__*/getDefaultExportFromCjs(browserExports);
|
6849
|
+
|
6850
|
+
const APP_NAME = "waku";
|
6851
|
+
class Logger {
|
6852
|
+
_info;
|
6853
|
+
_warn;
|
6854
|
+
_error;
|
6855
|
+
static createDebugNamespace(level, prefix) {
|
6856
|
+
return prefix ? `${APP_NAME}:${level}:${prefix}` : `${APP_NAME}:${level}`;
|
6857
|
+
}
|
6858
|
+
constructor(prefix) {
|
6859
|
+
this._info = debug(Logger.createDebugNamespace("info", prefix));
|
6860
|
+
this._warn = debug(Logger.createDebugNamespace("warn", prefix));
|
6861
|
+
this._error = debug(Logger.createDebugNamespace("error", prefix));
|
6862
|
+
}
|
6863
|
+
get info() {
|
6864
|
+
return this._info;
|
6865
|
+
}
|
6866
|
+
get warn() {
|
6867
|
+
return this._warn;
|
6868
|
+
}
|
6869
|
+
get error() {
|
6870
|
+
return this._error;
|
6871
|
+
}
|
6872
|
+
log(level, ...args) {
|
6873
|
+
const logger = this[level];
|
6874
|
+
logger(...args);
|
5951
6875
|
}
|
5952
6876
|
}
|
5953
|
-
/** SHA2-256 hash function */
|
5954
|
-
const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
|
5955
6877
|
|
5956
6878
|
const DEFAULT_BLOOM_FILTER_OPTIONS = {
|
5957
6879
|
capacity: 10000,
|
@@ -5959,14 +6881,15 @@ const DEFAULT_BLOOM_FILTER_OPTIONS = {
|
|
5959
6881
|
};
|
5960
6882
|
const DEFAULT_CAUSAL_HISTORY_SIZE = 2;
|
5961
6883
|
const DEFAULT_RECEIVED_MESSAGE_TIMEOUT = 1000 * 60 * 5; // 5 minutes
|
6884
|
+
const log = new Logger("sds:message-channel");
|
5962
6885
|
class MessageChannel extends TypedEventEmitter {
|
6886
|
+
channelId;
|
5963
6887
|
lamportTimestamp;
|
5964
6888
|
filter;
|
5965
6889
|
outgoingBuffer;
|
5966
6890
|
acknowledgements;
|
5967
6891
|
incomingBuffer;
|
5968
6892
|
localHistory;
|
5969
|
-
channelId;
|
5970
6893
|
causalHistorySize;
|
5971
6894
|
acknowledgementCount;
|
5972
6895
|
timeReceived;
|
@@ -6002,40 +6925,61 @@ class MessageChannel extends TypedEventEmitter {
|
|
6002
6925
|
this.receivedMessageTimeout =
|
6003
6926
|
options.receivedMessageTimeout ?? DEFAULT_RECEIVED_MESSAGE_TIMEOUT;
|
6004
6927
|
}
|
6005
|
-
|
6006
|
-
|
6928
|
+
static getMessageId(payload) {
|
6929
|
+
return bytesToHex(sha256(payload));
|
6930
|
+
}
|
6931
|
+
/**
|
6932
|
+
* Processes all queued tasks sequentially to ensure proper message ordering.
|
6933
|
+
*
|
6934
|
+
* This method should be called periodically by the library consumer to execute
|
6935
|
+
* queued send/receive operations in the correct sequence.
|
6936
|
+
*
|
6937
|
+
* @example
|
6938
|
+
* ```typescript
|
6939
|
+
* const channel = new MessageChannel("my-channel");
|
6940
|
+
*
|
6941
|
+
* // Queue some operations
|
6942
|
+
* await channel.sendMessage(payload, callback);
|
6943
|
+
* channel.receiveMessage(incomingMessage);
|
6944
|
+
*
|
6945
|
+
* // Process all queued operations
|
6946
|
+
* await channel.processTasks();
|
6947
|
+
* ```
|
6948
|
+
*
|
6949
|
+
* @throws Will emit a 'taskError' event if any task fails, but continues processing remaining tasks
|
6950
|
+
*/
|
6007
6951
|
async processTasks() {
|
6008
6952
|
while (this.tasks.length > 0) {
|
6009
6953
|
const item = this.tasks.shift();
|
6010
6954
|
if (!item) {
|
6011
6955
|
continue;
|
6012
6956
|
}
|
6013
|
-
// Use a generic helper function to ensure type safety
|
6014
6957
|
await this.executeTask(item);
|
6015
6958
|
}
|
6016
6959
|
}
|
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
6960
|
/**
|
6025
|
-
*
|
6961
|
+
* Queues a message to be sent on this channel.
|
6026
6962
|
*
|
6027
|
-
*
|
6028
|
-
*
|
6963
|
+
* The message will be processed sequentially when processTasks() is called.
|
6964
|
+
* This ensures proper lamport timestamp ordering and causal history tracking.
|
6029
6965
|
*
|
6030
|
-
*
|
6031
|
-
*
|
6032
|
-
*
|
6033
|
-
* light push or relay.
|
6966
|
+
* @param payload - The message content as a byte array
|
6967
|
+
* @param callback - Optional callback function called after the message is processed
|
6968
|
+
* @returns Promise that resolves when the message is queued (not sent)
|
6034
6969
|
*
|
6035
|
-
*
|
6970
|
+
* @example
|
6971
|
+
* ```typescript
|
6972
|
+
* const channel = new MessageChannel("chat-room");
|
6973
|
+
* const message = new TextEncoder().encode("Hello, world!");
|
6036
6974
|
*
|
6037
|
-
*
|
6038
|
-
*
|
6975
|
+
* await channel.sendMessage(message, async (processedMessage) => {
|
6976
|
+
* console.log("Message processed:", processedMessage.messageId);
|
6977
|
+
* return { success: true };
|
6978
|
+
* });
|
6979
|
+
*
|
6980
|
+
* // Actually send the message
|
6981
|
+
* await channel.processTasks();
|
6982
|
+
* ```
|
6039
6983
|
*/
|
6040
6984
|
async sendMessage(payload, callback) {
|
6041
6985
|
this.tasks.push({
|
@@ -6046,38 +6990,6 @@ class MessageChannel extends TypedEventEmitter {
|
|
6046
6990
|
}
|
6047
6991
|
});
|
6048
6992
|
}
|
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
6993
|
/**
|
6082
6994
|
* Sends a short-lived message without synchronization or reliability requirements.
|
6083
6995
|
*
|
@@ -6100,32 +7012,24 @@ class MessageChannel extends TypedEventEmitter {
|
|
6100
7012
|
}
|
6101
7013
|
});
|
6102
7014
|
}
|
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
7015
|
/**
|
6117
|
-
*
|
7016
|
+
* Queues a received message for processing.
|
7017
|
+
*
|
7018
|
+
* The message will be processed when processTasks() is called, ensuring
|
7019
|
+
* proper dependency resolution and causal ordering.
|
7020
|
+
*
|
7021
|
+
* @param message - The message to receive and process
|
6118
7022
|
*
|
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.
|
7023
|
+
* @example
|
7024
|
+
* ```typescript
|
7025
|
+
* const channel = new MessageChannel("chat-room");
|
6125
7026
|
*
|
6126
|
-
*
|
7027
|
+
* // Receive a message from the network
|
7028
|
+
* channel.receiveMessage(incomingMessage);
|
6127
7029
|
*
|
6128
|
-
*
|
7030
|
+
* // Process the received message
|
7031
|
+
* await channel.processTasks();
|
7032
|
+
* ```
|
6129
7033
|
*/
|
6130
7034
|
receiveMessage(message) {
|
6131
7035
|
this.tasks.push({
|
@@ -6135,62 +7039,17 @@ class MessageChannel extends TypedEventEmitter {
|
|
6135
7039
|
}
|
6136
7040
|
});
|
6137
7041
|
}
|
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.
|
7042
|
+
/**
|
7043
|
+
* Processes messages in the incoming buffer, delivering those with satisfied dependencies.
|
7044
|
+
*
|
7045
|
+
* @returns Array of history entries for messages still missing dependencies
|
7046
|
+
*/
|
6185
7047
|
sweepIncomingBuffer() {
|
6186
7048
|
const { buffer, missing } = this.incomingBuffer.reduce(({ buffer, missing }, message) => {
|
6187
|
-
// Check each message for missing dependencies
|
6188
7049
|
const missingDependencies = message.causalHistory.filter((messageHistoryEntry) => !this.localHistory.some(({ historyEntry: { messageId } }) => messageId === messageHistoryEntry.messageId));
|
6189
7050
|
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
7051
|
this.deliverMessage(message);
|
6193
|
-
this.
|
7052
|
+
this.safeSendEvent(MessageChannelEvent.MessageDelivered, {
|
6194
7053
|
detail: {
|
6195
7054
|
messageId: message.messageId,
|
6196
7055
|
sentOrReceived: "received"
|
@@ -6207,8 +7066,6 @@ class MessageChannel extends TypedEventEmitter {
|
|
6207
7066
|
return { buffer, missing };
|
6208
7067
|
}
|
6209
7068
|
}
|
6210
|
-
// Any message with missing dependencies stays in the buffer
|
6211
|
-
// and the missing message IDs are returned for processing.
|
6212
7069
|
missingDependencies.forEach((dependency) => {
|
6213
7070
|
missing.add(dependency);
|
6214
7071
|
});
|
@@ -6217,16 +7074,14 @@ class MessageChannel extends TypedEventEmitter {
|
|
6217
7074
|
missing
|
6218
7075
|
};
|
6219
7076
|
}, { buffer: new Array(), missing: new Set() });
|
6220
|
-
// Update the incoming buffer to only include messages with no missing dependencies
|
6221
7077
|
this.incomingBuffer = buffer;
|
6222
|
-
this.
|
7078
|
+
this.safeSendEvent(MessageChannelEvent.MissedMessages, {
|
6223
7079
|
detail: Array.from(missing)
|
6224
7080
|
});
|
6225
7081
|
return Array.from(missing);
|
6226
7082
|
}
|
6227
7083
|
// https://rfc.vac.dev/vac/raw/sds/#periodic-outgoing-buffer-sweep
|
6228
7084
|
sweepOutgoingBuffer() {
|
6229
|
-
// Partition all messages in the outgoing buffer into unacknowledged and possibly acknowledged messages
|
6230
7085
|
return this.outgoingBuffer.reduce(({ unacknowledged, possiblyAcknowledged }, message) => {
|
6231
7086
|
if (this.acknowledgements.has(message.messageId)) {
|
6232
7087
|
return {
|
@@ -6267,13 +7122,136 @@ class MessageChannel extends TypedEventEmitter {
|
|
6267
7122
|
content: emptyMessage
|
6268
7123
|
};
|
6269
7124
|
if (callback) {
|
6270
|
-
|
6271
|
-
|
7125
|
+
try {
|
7126
|
+
await callback(message);
|
7127
|
+
this.safeSendEvent(MessageChannelEvent.SyncSent, {
|
7128
|
+
detail: message
|
7129
|
+
});
|
7130
|
+
return true;
|
7131
|
+
}
|
7132
|
+
catch (error) {
|
7133
|
+
log.error("Callback execution failed in sendSyncMessage:", error);
|
7134
|
+
throw error;
|
7135
|
+
}
|
7136
|
+
}
|
7137
|
+
return false;
|
7138
|
+
}
|
7139
|
+
_receiveMessage(message) {
|
7140
|
+
const isDuplicate = message.content &&
|
7141
|
+
message.content.length > 0 &&
|
7142
|
+
this.timeReceived.has(message.messageId);
|
7143
|
+
if (isDuplicate) {
|
7144
|
+
return;
|
7145
|
+
}
|
7146
|
+
if (!message.lamportTimestamp) {
|
7147
|
+
this.deliverMessage(message);
|
7148
|
+
return;
|
7149
|
+
}
|
7150
|
+
if (message.content?.length === 0) {
|
7151
|
+
this.safeSendEvent(MessageChannelEvent.SyncReceived, {
|
6272
7152
|
detail: message
|
6273
7153
|
});
|
6274
|
-
return true;
|
6275
7154
|
}
|
6276
|
-
|
7155
|
+
else {
|
7156
|
+
this.safeSendEvent(MessageChannelEvent.MessageReceived, {
|
7157
|
+
detail: message
|
7158
|
+
});
|
7159
|
+
}
|
7160
|
+
this.reviewAckStatus(message);
|
7161
|
+
if (message.content?.length && message.content.length > 0) {
|
7162
|
+
this.filter.insert(message.messageId);
|
7163
|
+
}
|
7164
|
+
const dependenciesMet = message.causalHistory.every((historyEntry) => this.localHistory.some(({ historyEntry: { messageId } }) => messageId === historyEntry.messageId));
|
7165
|
+
if (!dependenciesMet) {
|
7166
|
+
this.incomingBuffer.push(message);
|
7167
|
+
this.timeReceived.set(message.messageId, Date.now());
|
7168
|
+
}
|
7169
|
+
else {
|
7170
|
+
this.deliverMessage(message);
|
7171
|
+
this.safeSendEvent(MessageChannelEvent.MessageDelivered, {
|
7172
|
+
detail: {
|
7173
|
+
messageId: message.messageId,
|
7174
|
+
sentOrReceived: "received"
|
7175
|
+
}
|
7176
|
+
});
|
7177
|
+
}
|
7178
|
+
}
|
7179
|
+
async executeTask(item) {
|
7180
|
+
try {
|
7181
|
+
const handler = this.handlers[item.command];
|
7182
|
+
await handler(item.params);
|
7183
|
+
}
|
7184
|
+
catch (error) {
|
7185
|
+
log.error(`Task execution failed for command ${item.command}:`, error);
|
7186
|
+
this.dispatchEvent(new CustomEvent("taskError", {
|
7187
|
+
detail: { command: item.command, error, params: item.params }
|
7188
|
+
}));
|
7189
|
+
}
|
7190
|
+
}
|
7191
|
+
safeSendEvent(event, eventInit) {
|
7192
|
+
try {
|
7193
|
+
this.dispatchEvent(new CustomEvent(event, eventInit));
|
7194
|
+
}
|
7195
|
+
catch (error) {
|
7196
|
+
log.error(`Failed to dispatch event ${event}:`, error);
|
7197
|
+
}
|
7198
|
+
}
|
7199
|
+
async _sendMessage(payload, callback) {
|
7200
|
+
this.lamportTimestamp++;
|
7201
|
+
const messageId = MessageChannel.getMessageId(payload);
|
7202
|
+
const message = {
|
7203
|
+
messageId,
|
7204
|
+
channelId: this.channelId,
|
7205
|
+
lamportTimestamp: this.lamportTimestamp,
|
7206
|
+
causalHistory: this.localHistory
|
7207
|
+
.slice(-this.causalHistorySize)
|
7208
|
+
.map(({ historyEntry }) => historyEntry),
|
7209
|
+
bloomFilter: this.filter.toBytes(),
|
7210
|
+
content: payload
|
7211
|
+
};
|
7212
|
+
this.outgoingBuffer.push(message);
|
7213
|
+
if (callback) {
|
7214
|
+
try {
|
7215
|
+
const { success, retrievalHint } = await callback(message);
|
7216
|
+
if (success) {
|
7217
|
+
this.filter.insert(messageId);
|
7218
|
+
this.localHistory.push({
|
7219
|
+
timestamp: this.lamportTimestamp,
|
7220
|
+
historyEntry: {
|
7221
|
+
messageId,
|
7222
|
+
retrievalHint
|
7223
|
+
}
|
7224
|
+
});
|
7225
|
+
this.timeReceived.set(messageId, Date.now());
|
7226
|
+
this.safeSendEvent(MessageChannelEvent.MessageSent, {
|
7227
|
+
detail: message
|
7228
|
+
});
|
7229
|
+
}
|
7230
|
+
}
|
7231
|
+
catch (error) {
|
7232
|
+
log.error("Callback execution failed in _sendMessage:", error);
|
7233
|
+
throw error;
|
7234
|
+
}
|
7235
|
+
}
|
7236
|
+
}
|
7237
|
+
async _sendEphemeralMessage(payload, callback) {
|
7238
|
+
const message = {
|
7239
|
+
messageId: MessageChannel.getMessageId(payload),
|
7240
|
+
channelId: this.channelId,
|
7241
|
+
content: payload,
|
7242
|
+
lamportTimestamp: undefined,
|
7243
|
+
causalHistory: [],
|
7244
|
+
bloomFilter: undefined
|
7245
|
+
};
|
7246
|
+
if (callback) {
|
7247
|
+
try {
|
7248
|
+
await callback(message);
|
7249
|
+
}
|
7250
|
+
catch (error) {
|
7251
|
+
log.error("Callback execution failed in _sendEphemeralMessage:", error);
|
7252
|
+
throw error;
|
7253
|
+
}
|
7254
|
+
}
|
6277
7255
|
}
|
6278
7256
|
// See https://rfc.vac.dev/vac/raw/sds/#deliver-message
|
6279
7257
|
deliverMessage(message, retrievalHint) {
|
@@ -6311,13 +7289,12 @@ class MessageChannel extends TypedEventEmitter {
|
|
6311
7289
|
// to determine the acknowledgement status of messages in the outgoing buffer.
|
6312
7290
|
// See https://rfc.vac.dev/vac/raw/sds/#review-ack-status
|
6313
7291
|
reviewAckStatus(receivedMessage) {
|
6314
|
-
// the participant MUST mark all messages in the received causal_history as acknowledged.
|
6315
7292
|
receivedMessage.causalHistory.forEach(({ messageId }) => {
|
6316
7293
|
this.outgoingBuffer = this.outgoingBuffer.filter(({ messageId: outgoingMessageId }) => {
|
6317
7294
|
if (outgoingMessageId !== messageId) {
|
6318
7295
|
return true;
|
6319
7296
|
}
|
6320
|
-
this.
|
7297
|
+
this.safeSendEvent(MessageChannelEvent.MessageAcknowledged, {
|
6321
7298
|
detail: messageId
|
6322
7299
|
});
|
6323
7300
|
return false;
|
@@ -6327,7 +7304,6 @@ class MessageChannel extends TypedEventEmitter {
|
|
6327
7304
|
this.filter.insert(messageId);
|
6328
7305
|
}
|
6329
7306
|
});
|
6330
|
-
// the participant MUST mark all messages included in the bloom_filter as possibly acknowledged
|
6331
7307
|
if (!receivedMessage.bloomFilter) {
|
6332
7308
|
return;
|
6333
7309
|
}
|
@@ -6342,7 +7318,7 @@ class MessageChannel extends TypedEventEmitter {
|
|
6342
7318
|
const count = (this.acknowledgements.get(message.messageId) ?? 0) + 1;
|
6343
7319
|
if (count < this.acknowledgementCount) {
|
6344
7320
|
this.acknowledgements.set(message.messageId, count);
|
6345
|
-
this.
|
7321
|
+
this.safeSendEvent(MessageChannelEvent.PartialAcknowledgement, {
|
6346
7322
|
detail: {
|
6347
7323
|
messageId: message.messageId,
|
6348
7324
|
count
|
@@ -6360,4 +7336,4 @@ class MessageChannel extends TypedEventEmitter {
|
|
6360
7336
|
}
|
6361
7337
|
}
|
6362
7338
|
|
6363
|
-
export { BloomFilter,
|
7339
|
+
export { BloomFilter, MessageChannel, MessageChannelEvent, decodeMessage, encodeMessage };
|