@waku/core 0.0.21 → 0.0.23

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.
Files changed (62) hide show
  1. package/CHANGELOG.md +48 -0
  2. package/bundle/base_protocol-84d9b670.js +1198 -0
  3. package/bundle/index.js +1163 -1281
  4. package/bundle/lib/base_protocol.js +2 -116
  5. package/bundle/lib/message/version_0.js +1 -1
  6. package/bundle/lib/predefined_bootstrap_nodes.js +6 -6
  7. package/bundle/{version_0-86411fdf.js → version_0-74b4b9db.js} +875 -794
  8. package/dist/.tsbuildinfo +1 -0
  9. package/dist/index.d.ts +6 -5
  10. package/dist/index.js +5 -4
  11. package/dist/index.js.map +1 -1
  12. package/dist/lib/base_protocol.d.ts +18 -5
  13. package/dist/lib/base_protocol.js +25 -8
  14. package/dist/lib/base_protocol.js.map +1 -1
  15. package/dist/lib/connection_manager.d.ts +3 -5
  16. package/dist/lib/connection_manager.js +53 -45
  17. package/dist/lib/connection_manager.js.map +1 -1
  18. package/dist/lib/filter/filter_rpc.js +4 -4
  19. package/dist/lib/filter/index.d.ts +4 -0
  20. package/dist/lib/filter/index.js +24 -27
  21. package/dist/lib/filter/index.js.map +1 -1
  22. package/dist/lib/filterPeers.d.ts +10 -0
  23. package/dist/lib/filterPeers.js +31 -0
  24. package/dist/lib/filterPeers.js.map +1 -0
  25. package/dist/lib/keep_alive_manager.d.ts +4 -6
  26. package/dist/lib/keep_alive_manager.js +27 -8
  27. package/dist/lib/keep_alive_manager.js.map +1 -1
  28. package/dist/lib/light_push/index.js +62 -33
  29. package/dist/lib/light_push/index.js.map +1 -1
  30. package/dist/lib/light_push/push_rpc.js +2 -2
  31. package/dist/lib/message/version_0.d.ts +1 -1
  32. package/dist/lib/message/version_0.js +3 -3
  33. package/dist/lib/message/version_0.js.map +1 -1
  34. package/dist/lib/predefined_bootstrap_nodes.js +6 -6
  35. package/dist/lib/store/history_rpc.js +3 -3
  36. package/dist/lib/store/index.d.ts +0 -5
  37. package/dist/lib/store/index.js +54 -37
  38. package/dist/lib/store/index.js.map +1 -1
  39. package/dist/lib/stream_manager.d.ts +15 -0
  40. package/dist/lib/stream_manager.js +53 -0
  41. package/dist/lib/stream_manager.js.map +1 -0
  42. package/dist/lib/to_proto_message.js +1 -1
  43. package/dist/lib/waku.d.ts +2 -2
  44. package/dist/lib/waku.js +1 -1
  45. package/package.json +16 -22
  46. package/src/index.ts +7 -13
  47. package/src/lib/base_protocol.ts +49 -18
  48. package/src/lib/connection_manager.ts +82 -66
  49. package/src/lib/filter/filter_rpc.ts +4 -4
  50. package/src/lib/filter/index.ts +32 -39
  51. package/src/lib/filterPeers.ts +43 -0
  52. package/src/lib/keep_alive_manager.ts +34 -14
  53. package/src/lib/light_push/index.ts +103 -47
  54. package/src/lib/light_push/push_rpc.ts +2 -2
  55. package/src/lib/message/version_0.ts +8 -5
  56. package/src/lib/predefined_bootstrap_nodes.ts +7 -7
  57. package/src/lib/store/history_rpc.ts +4 -4
  58. package/src/lib/store/index.ts +70 -51
  59. package/src/lib/stream_manager.ts +69 -0
  60. package/src/lib/to_proto_message.ts +1 -1
  61. package/src/lib/wait_for_remote_peer.ts +1 -1
  62. package/src/lib/waku.ts +3 -3
package/bundle/index.js CHANGED
@@ -1,251 +1,28 @@
1
+ import { a as allocUnsafe, b as asUint8Array, t as toString$2, f as fromString$1, u as utf8ToBytes$1, T as Tags, E as EPeersByDiscoveryEvents, P as Protocols, c as alloc, B as BaseProtocol, S as SendError, d as concat$1 } from './base_protocol-84d9b670.js';
2
+ export { e as StreamManager } from './base_protocol-84d9b670.js';
1
3
  import { g as getDefaultExportFromCjs, d as debug } from './browser-bde977a3.js';
2
- import { c as createEncoder, v as version_0, M as MessagePush, F as FilterSubscribeRequest, a as FilterSubscribeResponse$1, P as PushRpc$1, b as PushResponse, H as HistoryRpc$1, d as PagingInfo, e as HistoryResponse } from './version_0-86411fdf.js';
3
- export { f as createDecoder } from './version_0-86411fdf.js';
4
- import { BaseProtocol } from './lib/base_protocol.js';
4
+ import { c as createEncoder, v as version_0, M as MessagePush, F as FilterSubscribeRequest, a as FilterSubscribeResponse$1, P as PushRpc$1, b as PushResponse, H as HistoryRpc$1, d as PagingInfo, e as HistoryResponse } from './version_0-74b4b9db.js';
5
+ export { f as createDecoder } from './version_0-74b4b9db.js';
5
6
 
6
7
  const symbol$2 = Symbol.for('@libp2p/peer-id');
7
8
  function isPeerId(other) {
8
9
  return other != null && Boolean(other[symbol$2]);
9
10
  }
10
11
 
11
- /* eslint-disable @typescript-eslint/no-unsafe-return */
12
- class Parser {
13
- index = 0;
14
- input = "";
15
- new(input) {
16
- this.index = 0;
17
- this.input = input;
18
- return this;
19
- }
20
- /** Run a parser, and restore the pre-parse state if it fails. */
21
- readAtomically(fn) {
22
- const index = this.index;
23
- const result = fn();
24
- if (result === undefined) {
25
- this.index = index;
26
- }
27
- return result;
28
- }
29
- /** Run a parser, but fail if the entire input wasn't consumed. Doesn't run atomically. */
30
- parseWith(fn) {
31
- const result = fn();
32
- if (this.index !== this.input.length) {
33
- return undefined;
34
- }
35
- return result;
36
- }
37
- /** Peek the next character from the input */
38
- peekChar() {
39
- if (this.index >= this.input.length) {
40
- return undefined;
41
- }
42
- return this.input[this.index];
43
- }
44
- /** Read the next character from the input */
45
- readChar() {
46
- if (this.index >= this.input.length) {
47
- return undefined;
48
- }
49
- return this.input[this.index++];
50
- }
51
- /** Read the next character from the input if it matches the target. */
52
- readGivenChar(target) {
53
- return this.readAtomically(() => {
54
- const char = this.readChar();
55
- if (char !== target) {
56
- return undefined;
57
- }
58
- return char;
59
- });
60
- }
61
- /**
62
- * Helper for reading separators in an indexed loop. Reads the separator
63
- * character iff index > 0, then runs the parser. When used in a loop,
64
- * the separator character will only be read on index > 0 (see
65
- * readIPv4Addr for an example)
66
- */
67
- readSeparator(sep, index, inner) {
68
- return this.readAtomically(() => {
69
- if (index > 0) {
70
- if (this.readGivenChar(sep) === undefined) {
71
- return undefined;
72
- }
73
- }
74
- return inner();
75
- });
76
- }
77
- /**
78
- * Read a number off the front of the input in the given radix, stopping
79
- * at the first non-digit character or eof. Fails if the number has more
80
- * digits than max_digits or if there is no number.
81
- */
82
- readNumber(radix, maxDigits, allowZeroPrefix, maxBytes) {
83
- return this.readAtomically(() => {
84
- let result = 0;
85
- let digitCount = 0;
86
- const leadingChar = this.peekChar();
87
- if (leadingChar === undefined) {
88
- return undefined;
89
- }
90
- const hasLeadingZero = leadingChar === "0";
91
- const maxValue = 2 ** (8 * maxBytes) - 1;
92
- // eslint-disable-next-line no-constant-condition
93
- while (true) {
94
- const digit = this.readAtomically(() => {
95
- const char = this.readChar();
96
- if (char === undefined) {
97
- return undefined;
98
- }
99
- const num = Number.parseInt(char, radix);
100
- if (Number.isNaN(num)) {
101
- return undefined;
102
- }
103
- return num;
104
- });
105
- if (digit === undefined) {
106
- break;
107
- }
108
- result *= radix;
109
- result += digit;
110
- if (result > maxValue) {
111
- return undefined;
112
- }
113
- digitCount += 1;
114
- if (maxDigits !== undefined) {
115
- if (digitCount > maxDigits) {
116
- return undefined;
117
- }
118
- }
119
- }
120
- if (digitCount === 0) {
121
- return undefined;
122
- }
123
- else if (!allowZeroPrefix && hasLeadingZero && digitCount > 1) {
124
- return undefined;
125
- }
126
- else {
127
- return result;
128
- }
129
- });
130
- }
131
- /** Read an IPv4 address. */
132
- readIPv4Addr() {
133
- return this.readAtomically(() => {
134
- const out = new Uint8Array(4);
135
- for (let i = 0; i < out.length; i++) {
136
- const ix = this.readSeparator(".", i, () => this.readNumber(10, 3, false, 1));
137
- if (ix === undefined) {
138
- return undefined;
139
- }
140
- out[i] = ix;
141
- }
142
- return out;
143
- });
144
- }
145
- /** Read an IPv6 Address. */
146
- readIPv6Addr() {
147
- /**
148
- * Read a chunk of an IPv6 address into `groups`. Returns the number
149
- * of groups read, along with a bool indicating if an embedded
150
- * trailing IPv4 address was read. Specifically, read a series of
151
- * colon-separated IPv6 groups (0x0000 - 0xFFFF), with an optional
152
- * trailing embedded IPv4 address.
153
- */
154
- const readGroups = (groups) => {
155
- for (let i = 0; i < groups.length / 2; i++) {
156
- const ix = i * 2;
157
- // Try to read a trailing embedded IPv4 address. There must be at least 4 groups left.
158
- if (i < groups.length - 3) {
159
- const ipv4 = this.readSeparator(":", i, () => this.readIPv4Addr());
160
- if (ipv4 !== undefined) {
161
- groups[ix] = ipv4[0];
162
- groups[ix + 1] = ipv4[1];
163
- groups[ix + 2] = ipv4[2];
164
- groups[ix + 3] = ipv4[3];
165
- return [ix + 4, true];
166
- }
167
- }
168
- const group = this.readSeparator(":", i, () => this.readNumber(16, 4, true, 2));
169
- if (group === undefined) {
170
- return [ix, false];
171
- }
172
- groups[ix] = group >> 8;
173
- groups[ix + 1] = group & 255;
174
- }
175
- return [groups.length, false];
176
- };
177
- return this.readAtomically(() => {
178
- // Read the front part of the address; either the whole thing, or up to the first ::
179
- const head = new Uint8Array(16);
180
- const [headSize, headIp4] = readGroups(head);
181
- if (headSize === 16) {
182
- return head;
183
- }
184
- // IPv4 part is not allowed before `::`
185
- if (headIp4) {
186
- return undefined;
187
- }
188
- // Read `::` if previous code parsed less than 8 groups.
189
- // `::` indicates one or more groups of 16 bits of zeros.
190
- if (this.readGivenChar(":") === undefined) {
191
- return undefined;
192
- }
193
- if (this.readGivenChar(":") === undefined) {
194
- return undefined;
195
- }
196
- // Read the back part of the address. The :: must contain at least one
197
- // set of zeroes, so our max length is 7.
198
- const tail = new Uint8Array(14);
199
- const limit = 16 - (headSize + 2);
200
- const [tailSize] = readGroups(tail.subarray(0, limit));
201
- // Concat the head and tail of the IP address
202
- head.set(tail.subarray(0, tailSize), 16 - tailSize);
203
- return head;
204
- });
205
- }
206
- /** Read an IP Address, either IPv4 or IPv6. */
207
- readIPAddr() {
208
- return this.readIPv4Addr() ?? this.readIPv6Addr();
209
- }
210
- }
211
-
212
- // See https://stackoverflow.com/questions/166132/maximum-length-of-the-textual-representation-of-an-ipv6-address
213
- const MAX_IPV6_LENGTH = 45;
214
- const MAX_IPV4_LENGTH = 15;
215
- const parser = new Parser();
216
- /** Parse `input` into IPv4 bytes. */
217
- function parseIPv4(input) {
218
- if (input.length > MAX_IPV4_LENGTH) {
219
- return undefined;
220
- }
221
- return parser.new(input).parseWith(() => parser.readIPv4Addr());
222
- }
223
- /** Parse `input` into IPv6 bytes. */
224
- function parseIPv6(input) {
225
- if (input.length > MAX_IPV6_LENGTH) {
226
- return undefined;
227
- }
228
- return parser.new(input).parseWith(() => parser.readIPv6Addr());
229
- }
230
- /** Parse `input` into IPv4 or IPv6 bytes. */
231
- function parseIP(input) {
232
- if (input.length > MAX_IPV6_LENGTH) {
233
- return undefined;
12
+ /**
13
+ * When this error is thrown it means an operation was aborted,
14
+ * usually in response to the `abort` event being emitted by an
15
+ * AbortSignal.
16
+ */
17
+ class CodeError extends Error {
18
+ code;
19
+ props;
20
+ constructor(message, code, props) {
21
+ super(message);
22
+ this.code = code;
23
+ this.name = props?.name ?? 'CodeError';
24
+ this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
234
25
  }
235
- return parser.new(input).parseWith(() => parser.readIPAddr());
236
- }
237
-
238
- /** Check if `input` is IPv4. */
239
- function isIPv4(input) {
240
- return Boolean(parseIPv4(input));
241
- }
242
- /** Check if `input` is IPv6. */
243
- function isIPv6(input) {
244
- return Boolean(parseIPv6(input));
245
- }
246
- /** Check if `input` is IPv4 or IPv6. */
247
- function isIP(input) {
248
- return Boolean(parseIP(input));
249
26
  }
250
27
 
251
28
  // base-x encoding / decoding
@@ -410,13 +187,13 @@ const coerce = o => {
410
187
  * @param {string} str
411
188
  * @returns {Uint8Array}
412
189
  */
413
- const fromString$2 = str => (new TextEncoder()).encode(str);
190
+ const fromString = str => (new TextEncoder()).encode(str);
414
191
 
415
192
  /**
416
193
  * @param {Uint8Array} b
417
194
  * @returns {string}
418
195
  */
419
- const toString$2 = b => (new TextDecoder()).decode(b);
196
+ const toString$1 = b => (new TextDecoder()).decode(b);
420
197
 
421
198
  /**
422
199
  * Class represents both BaseEncoder and MultibaseEncoder meaning it
@@ -760,180 +537,11 @@ const rfc4648 = ({ name, prefix, bitsPerChar, alphabet }) => {
760
537
  })
761
538
  };
762
539
 
763
- // @ts-check
764
-
765
- const identity = from({
766
- prefix: '\x00',
767
- name: 'identity',
768
- encode: (buf) => toString$2(buf),
769
- decode: (str) => fromString$2(str)
770
- });
771
-
772
- var identityBase = /*#__PURE__*/Object.freeze({
773
- __proto__: null,
774
- identity: identity
775
- });
776
-
777
- // @ts-check
778
-
779
- const base2 = rfc4648({
780
- prefix: '0',
781
- name: 'base2',
782
- alphabet: '01',
783
- bitsPerChar: 1
784
- });
785
-
786
- var base2$1 = /*#__PURE__*/Object.freeze({
787
- __proto__: null,
788
- base2: base2
789
- });
790
-
791
- // @ts-check
792
-
793
- const base8 = rfc4648({
794
- prefix: '7',
795
- name: 'base8',
796
- alphabet: '01234567',
797
- bitsPerChar: 3
798
- });
799
-
800
- var base8$1 = /*#__PURE__*/Object.freeze({
801
- __proto__: null,
802
- base8: base8
803
- });
804
-
805
- const base10 = baseX({
806
- prefix: '9',
807
- name: 'base10',
808
- alphabet: '0123456789'
809
- });
810
-
811
- var base10$1 = /*#__PURE__*/Object.freeze({
812
- __proto__: null,
813
- base10: base10
814
- });
815
-
816
- // @ts-check
817
-
818
- const base16 = rfc4648({
819
- prefix: 'f',
820
- name: 'base16',
821
- alphabet: '0123456789abcdef',
822
- bitsPerChar: 4
823
- });
824
-
825
- const base16upper = rfc4648({
826
- prefix: 'F',
827
- name: 'base16upper',
828
- alphabet: '0123456789ABCDEF',
829
- bitsPerChar: 4
830
- });
831
-
832
- var base16$1 = /*#__PURE__*/Object.freeze({
833
- __proto__: null,
834
- base16: base16,
835
- base16upper: base16upper
836
- });
837
-
838
- const base32 = rfc4648({
839
- prefix: 'b',
840
- name: 'base32',
841
- alphabet: 'abcdefghijklmnopqrstuvwxyz234567',
842
- bitsPerChar: 5
843
- });
844
-
845
- const base32upper = rfc4648({
846
- prefix: 'B',
847
- name: 'base32upper',
848
- alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
849
- bitsPerChar: 5
850
- });
851
-
852
- const base32pad = rfc4648({
853
- prefix: 'c',
854
- name: 'base32pad',
855
- alphabet: 'abcdefghijklmnopqrstuvwxyz234567=',
856
- bitsPerChar: 5
857
- });
858
-
859
- const base32padupper = rfc4648({
860
- prefix: 'C',
861
- name: 'base32padupper',
862
- alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=',
863
- bitsPerChar: 5
864
- });
865
-
866
- const base32hex = rfc4648({
867
- prefix: 'v',
868
- name: 'base32hex',
869
- alphabet: '0123456789abcdefghijklmnopqrstuv',
870
- bitsPerChar: 5
871
- });
872
-
873
- const base32hexupper = rfc4648({
874
- prefix: 'V',
875
- name: 'base32hexupper',
876
- alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV',
877
- bitsPerChar: 5
878
- });
879
-
880
- const base32hexpad = rfc4648({
881
- prefix: 't',
882
- name: 'base32hexpad',
883
- alphabet: '0123456789abcdefghijklmnopqrstuv=',
884
- bitsPerChar: 5
885
- });
886
-
887
- const base32hexpadupper = rfc4648({
888
- prefix: 'T',
889
- name: 'base32hexpadupper',
890
- alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV=',
891
- bitsPerChar: 5
892
- });
893
-
894
- const base32z = rfc4648({
895
- prefix: 'h',
896
- name: 'base32z',
897
- alphabet: 'ybndrfg8ejkmcpqxot1uwisza345h769',
898
- bitsPerChar: 5
899
- });
900
-
901
- var base32$1 = /*#__PURE__*/Object.freeze({
902
- __proto__: null,
903
- base32: base32,
904
- base32hex: base32hex,
905
- base32hexpad: base32hexpad,
906
- base32hexpadupper: base32hexpadupper,
907
- base32hexupper: base32hexupper,
908
- base32pad: base32pad,
909
- base32padupper: base32padupper,
910
- base32upper: base32upper,
911
- base32z: base32z
912
- });
913
-
914
- const base36 = baseX({
915
- prefix: 'k',
916
- name: 'base36',
917
- alphabet: '0123456789abcdefghijklmnopqrstuvwxyz'
918
- });
919
-
920
- const base36upper = baseX({
921
- prefix: 'K',
922
- name: 'base36upper',
923
- alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
924
- });
925
-
926
- var base36$1 = /*#__PURE__*/Object.freeze({
927
- __proto__: null,
928
- base36: base36,
929
- base36upper: base36upper
930
- });
931
-
932
- const base58btc = baseX({
933
- name: 'base58btc',
934
- prefix: 'z',
935
- alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
936
- });
540
+ const base58btc = baseX({
541
+ name: 'base58btc',
542
+ prefix: 'z',
543
+ alphabet: '123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz'
544
+ });
937
545
 
938
546
  const base58flickr = baseX({
939
547
  name: 'base58flickr',
@@ -947,95 +555,14 @@ var base58 = /*#__PURE__*/Object.freeze({
947
555
  base58flickr: base58flickr
948
556
  });
949
557
 
950
- // @ts-check
951
-
952
- const base64 = rfc4648({
953
- prefix: 'm',
954
- name: 'base64',
955
- alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
956
- bitsPerChar: 6
957
- });
958
-
959
- const base64pad = rfc4648({
960
- prefix: 'M',
961
- name: 'base64pad',
962
- alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
963
- bitsPerChar: 6
964
- });
965
-
966
- const base64url = rfc4648({
967
- prefix: 'u',
968
- name: 'base64url',
969
- alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
970
- bitsPerChar: 6
971
- });
972
-
973
- const base64urlpad = rfc4648({
974
- prefix: 'U',
975
- name: 'base64urlpad',
976
- alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=',
977
- bitsPerChar: 6
978
- });
979
-
980
- var base64$1 = /*#__PURE__*/Object.freeze({
981
- __proto__: null,
982
- base64: base64,
983
- base64pad: base64pad,
984
- base64url: base64url,
985
- base64urlpad: base64urlpad
986
- });
987
-
988
- const alphabet = Array.from('🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂');
989
- const alphabetBytesToChars = /** @type {string[]} */ (alphabet.reduce((p, c, i) => { p[i] = c; return p }, /** @type {string[]} */([])));
990
- const alphabetCharsToBytes = /** @type {number[]} */ (alphabet.reduce((p, c, i) => { p[/** @type {number} */ (c.codePointAt(0))] = i; return p }, /** @type {number[]} */([])));
991
-
992
- /**
993
- * @param {Uint8Array} data
994
- * @returns {string}
995
- */
996
- function encode$3 (data) {
997
- return data.reduce((p, c) => {
998
- p += alphabetBytesToChars[c];
999
- return p
1000
- }, '')
1001
- }
1002
-
1003
- /**
1004
- * @param {string} str
1005
- * @returns {Uint8Array}
1006
- */
1007
- function decode$5 (str) {
1008
- const byts = [];
1009
- for (const char of str) {
1010
- const byt = alphabetCharsToBytes[/** @type {number} */ (char.codePointAt(0))];
1011
- if (byt === undefined) {
1012
- throw new Error(`Non-base256emoji character: ${char}`)
1013
- }
1014
- byts.push(byt);
1015
- }
1016
- return new Uint8Array(byts)
1017
- }
1018
-
1019
- const base256emoji = from({
1020
- prefix: '🚀',
1021
- name: 'base256emoji',
1022
- encode: encode$3,
1023
- decode: decode$5
1024
- });
1025
-
1026
- var base256emoji$1 = /*#__PURE__*/Object.freeze({
1027
- __proto__: null,
1028
- base256emoji: base256emoji
1029
- });
1030
-
1031
- var encode_1$1 = encode$2;
558
+ var encode_1$1 = encode$3;
1032
559
 
1033
560
  var MSB$2 = 0x80
1034
561
  , REST$2 = 0x7F
1035
562
  , MSBALL$1 = ~REST$2
1036
563
  , INT$1 = Math.pow(2, 31);
1037
564
 
1038
- function encode$2(num, out, offset) {
565
+ function encode$3(num, out, offset) {
1039
566
  out = out || [];
1040
567
  offset = offset || 0;
1041
568
  var oldOffset = offset;
@@ -1050,12 +577,12 @@ function encode$2(num, out, offset) {
1050
577
  }
1051
578
  out[offset] = num | 0;
1052
579
 
1053
- encode$2.bytes = offset - oldOffset + 1;
580
+ encode$3.bytes = offset - oldOffset + 1;
1054
581
 
1055
582
  return out
1056
583
  }
1057
584
 
1058
- var decode$4 = read$1;
585
+ var decode$5 = read$1;
1059
586
 
1060
587
  var MSB$1$1 = 0x80
1061
588
  , REST$1$1 = 0x7F;
@@ -1112,7 +639,7 @@ var length$1 = function (value) {
1112
639
 
1113
640
  var varint$2 = {
1114
641
  encode: encode_1$1
1115
- , decode: decode$4
642
+ , decode: decode$5
1116
643
  , encodingLength: length$1
1117
644
  };
1118
645
 
@@ -1123,7 +650,7 @@ var _brrp_varint = varint$2;
1123
650
  * @param {number} [offset=0]
1124
651
  * @returns {[number, number]}
1125
652
  */
1126
- const decode$3 = (data, offset = 0) => {
653
+ const decode$4 = (data, offset = 0) => {
1127
654
  const code = _brrp_varint.decode(data, offset);
1128
655
  return [code, _brrp_varint.decode.bytes]
1129
656
  };
@@ -1172,10 +699,10 @@ const create = (code, digest) => {
1172
699
  * @param {Uint8Array} multihash
1173
700
  * @returns {MultihashDigest}
1174
701
  */
1175
- const decode$2 = (multihash) => {
702
+ const decode$3 = (multihash) => {
1176
703
  const bytes = coerce(multihash);
1177
- const [code, sizeOffset] = decode$3(bytes);
1178
- const [size, digestOffset] = decode$3(bytes.subarray(sizeOffset));
704
+ const [code, sizeOffset] = decode$4(bytes);
705
+ const [size, digestOffset] = decode$4(bytes.subarray(sizeOffset));
1179
706
  const digest = bytes.subarray(sizeOffset + digestOffset);
1180
707
 
1181
708
  if (digest.byteLength !== size) {
@@ -1235,15 +762,81 @@ class Digest {
1235
762
  }
1236
763
  }
1237
764
 
1238
- // @ts-check
1239
-
1240
- /**
1241
- * @template T
1242
- * @typedef {import('./interface.js').ByteView<T>} ByteView
1243
- */
765
+ const base32 = rfc4648({
766
+ prefix: 'b',
767
+ name: 'base32',
768
+ alphabet: 'abcdefghijklmnopqrstuvwxyz234567',
769
+ bitsPerChar: 5
770
+ });
1244
771
 
1245
- new TextEncoder();
1246
- new TextDecoder();
772
+ const base32upper = rfc4648({
773
+ prefix: 'B',
774
+ name: 'base32upper',
775
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567',
776
+ bitsPerChar: 5
777
+ });
778
+
779
+ const base32pad = rfc4648({
780
+ prefix: 'c',
781
+ name: 'base32pad',
782
+ alphabet: 'abcdefghijklmnopqrstuvwxyz234567=',
783
+ bitsPerChar: 5
784
+ });
785
+
786
+ const base32padupper = rfc4648({
787
+ prefix: 'C',
788
+ name: 'base32padupper',
789
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ234567=',
790
+ bitsPerChar: 5
791
+ });
792
+
793
+ const base32hex = rfc4648({
794
+ prefix: 'v',
795
+ name: 'base32hex',
796
+ alphabet: '0123456789abcdefghijklmnopqrstuv',
797
+ bitsPerChar: 5
798
+ });
799
+
800
+ const base32hexupper = rfc4648({
801
+ prefix: 'V',
802
+ name: 'base32hexupper',
803
+ alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV',
804
+ bitsPerChar: 5
805
+ });
806
+
807
+ const base32hexpad = rfc4648({
808
+ prefix: 't',
809
+ name: 'base32hexpad',
810
+ alphabet: '0123456789abcdefghijklmnopqrstuv=',
811
+ bitsPerChar: 5
812
+ });
813
+
814
+ const base32hexpadupper = rfc4648({
815
+ prefix: 'T',
816
+ name: 'base32hexpadupper',
817
+ alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUV=',
818
+ bitsPerChar: 5
819
+ });
820
+
821
+ const base32z = rfc4648({
822
+ prefix: 'h',
823
+ name: 'base32z',
824
+ alphabet: 'ybndrfg8ejkmcpqxot1uwisza345h769',
825
+ bitsPerChar: 5
826
+ });
827
+
828
+ var base32$1 = /*#__PURE__*/Object.freeze({
829
+ __proto__: null,
830
+ base32: base32,
831
+ base32hex: base32hex,
832
+ base32hexpad: base32hexpad,
833
+ base32hexpadupper: base32hexpadupper,
834
+ base32hexupper: base32hexupper,
835
+ base32pad: base32pad,
836
+ base32padupper: base32padupper,
837
+ base32upper: base32upper,
838
+ base32z: base32z
839
+ });
1247
840
 
1248
841
  /**
1249
842
  * @template {API.Link<unknown, number, number, API.Version>} T
@@ -1499,7 +1092,7 @@ class CID {
1499
1092
  const { version, multihash, code } = value;
1500
1093
  const digest =
1501
1094
  /** @type {API.MultihashDigest<Alg>} */
1502
- (decode$2(multihash));
1095
+ (decode$3(multihash));
1503
1096
  return CID.create(version, code, digest)
1504
1097
  } else {
1505
1098
  // Otherwise value is not a CID (or an incompatible version of it) in
@@ -1655,7 +1248,7 @@ class CID {
1655
1248
  static inspectBytes (initialBytes) {
1656
1249
  let offset = 0;
1657
1250
  const next = () => {
1658
- const [i, length] = decode$3(initialBytes.subarray(offset));
1251
+ const [i, length] = decode$4(initialBytes.subarray(offset));
1659
1252
  offset += length;
1660
1253
  return i
1661
1254
  };
@@ -1793,126 +1386,595 @@ const toStringV1 = (bytes, cache, base) => {
1793
1386
  }
1794
1387
  };
1795
1388
 
1796
- const DAG_PB_CODE = 0x70;
1797
- const SHA_256_CODE = 0x12;
1389
+ const DAG_PB_CODE = 0x70;
1390
+ const SHA_256_CODE = 0x12;
1391
+
1392
+ /**
1393
+ * @param {API.Version} version
1394
+ * @param {number} code
1395
+ * @param {Uint8Array} multihash
1396
+ * @returns {Uint8Array}
1397
+ */
1398
+ const encodeCID = (version, code, multihash) => {
1399
+ const codeOffset = encodingLength(version);
1400
+ const hashOffset = codeOffset + encodingLength(code);
1401
+ const bytes = new Uint8Array(hashOffset + multihash.byteLength);
1402
+ encodeTo(version, bytes, 0);
1403
+ encodeTo(code, bytes, codeOffset);
1404
+ bytes.set(multihash, hashOffset);
1405
+ return bytes
1406
+ };
1407
+
1408
+ const cidSymbol = Symbol.for('@ipld/js-cid/CID');
1409
+
1410
+ /**
1411
+ * Returns true if the two passed Uint8Arrays have the same content
1412
+ */
1413
+ function equals(a, b) {
1414
+ if (a === b) {
1415
+ return true;
1416
+ }
1417
+ if (a.byteLength !== b.byteLength) {
1418
+ return false;
1419
+ }
1420
+ for (let i = 0; i < a.byteLength; i++) {
1421
+ if (a[i] !== b[i]) {
1422
+ return false;
1423
+ }
1424
+ }
1425
+ return true;
1426
+ }
1427
+
1428
+ /**
1429
+ * Returns a new Uint8Array created by concatenating the passed ArrayLikes
1430
+ */
1431
+ function concat(arrays, length) {
1432
+ if (length == null) {
1433
+ length = arrays.reduce((acc, curr) => acc + curr.length, 0);
1434
+ }
1435
+ const output = allocUnsafe(length);
1436
+ let offset = 0;
1437
+ for (const arr of arrays) {
1438
+ output.set(arr, offset);
1439
+ offset += arr.length;
1440
+ }
1441
+ return asUint8Array(output);
1442
+ }
1443
+
1444
+ var encode_1 = encode$2;
1445
+
1446
+ var MSB$1 = 0x80
1447
+ , REST$1 = 0x7F
1448
+ , MSBALL = ~REST$1
1449
+ , INT = Math.pow(2, 31);
1450
+
1451
+ function encode$2(num, out, offset) {
1452
+ if (Number.MAX_SAFE_INTEGER && num > Number.MAX_SAFE_INTEGER) {
1453
+ encode$2.bytes = 0;
1454
+ throw new RangeError('Could not encode varint')
1455
+ }
1456
+ out = out || [];
1457
+ offset = offset || 0;
1458
+ var oldOffset = offset;
1459
+
1460
+ while(num >= INT) {
1461
+ out[offset++] = (num & 0xFF) | MSB$1;
1462
+ num /= 128;
1463
+ }
1464
+ while(num & MSBALL) {
1465
+ out[offset++] = (num & 0xFF) | MSB$1;
1466
+ num >>>= 7;
1467
+ }
1468
+ out[offset] = num | 0;
1469
+
1470
+ encode$2.bytes = offset - oldOffset + 1;
1471
+
1472
+ return out
1473
+ }
1474
+
1475
+ var decode$2 = read;
1476
+
1477
+ var MSB = 0x80
1478
+ , REST = 0x7F;
1479
+
1480
+ function read(buf, offset) {
1481
+ var res = 0
1482
+ , offset = offset || 0
1483
+ , shift = 0
1484
+ , counter = offset
1485
+ , b
1486
+ , l = buf.length;
1487
+
1488
+ do {
1489
+ if (counter >= l || shift > 49) {
1490
+ read.bytes = 0;
1491
+ throw new RangeError('Could not decode varint')
1492
+ }
1493
+ b = buf[counter++];
1494
+ res += shift < 28
1495
+ ? (b & REST) << shift
1496
+ : (b & REST) * Math.pow(2, shift);
1497
+ shift += 7;
1498
+ } while (b >= MSB)
1499
+
1500
+ read.bytes = counter - offset;
1501
+
1502
+ return res
1503
+ }
1504
+
1505
+ var N1$1 = Math.pow(2, 7);
1506
+ var N2$1 = Math.pow(2, 14);
1507
+ var N3$1 = Math.pow(2, 21);
1508
+ var N4$1 = Math.pow(2, 28);
1509
+ var N5$1 = Math.pow(2, 35);
1510
+ var N6$1 = Math.pow(2, 42);
1511
+ var N7$1 = Math.pow(2, 49);
1512
+ var N8$1 = Math.pow(2, 56);
1513
+ var N9$1 = Math.pow(2, 63);
1514
+
1515
+ var length = function (value) {
1516
+ return (
1517
+ value < N1$1 ? 1
1518
+ : value < N2$1 ? 2
1519
+ : value < N3$1 ? 3
1520
+ : value < N4$1 ? 4
1521
+ : value < N5$1 ? 5
1522
+ : value < N6$1 ? 6
1523
+ : value < N7$1 ? 7
1524
+ : value < N8$1 ? 8
1525
+ : value < N9$1 ? 9
1526
+ : 10
1527
+ )
1528
+ };
1529
+
1530
+ var varint = {
1531
+ encode: encode_1
1532
+ , decode: decode$2
1533
+ , encodingLength: length
1534
+ };
1535
+
1536
+ var varint$1 = /*@__PURE__*/getDefaultExportFromCjs(varint);
1537
+
1538
+ /* eslint-disable @typescript-eslint/no-unsafe-return */
1539
+ class Parser {
1540
+ index = 0;
1541
+ input = "";
1542
+ new(input) {
1543
+ this.index = 0;
1544
+ this.input = input;
1545
+ return this;
1546
+ }
1547
+ /** Run a parser, and restore the pre-parse state if it fails. */
1548
+ readAtomically(fn) {
1549
+ const index = this.index;
1550
+ const result = fn();
1551
+ if (result === undefined) {
1552
+ this.index = index;
1553
+ }
1554
+ return result;
1555
+ }
1556
+ /** Run a parser, but fail if the entire input wasn't consumed. Doesn't run atomically. */
1557
+ parseWith(fn) {
1558
+ const result = fn();
1559
+ if (this.index !== this.input.length) {
1560
+ return undefined;
1561
+ }
1562
+ return result;
1563
+ }
1564
+ /** Peek the next character from the input */
1565
+ peekChar() {
1566
+ if (this.index >= this.input.length) {
1567
+ return undefined;
1568
+ }
1569
+ return this.input[this.index];
1570
+ }
1571
+ /** Read the next character from the input */
1572
+ readChar() {
1573
+ if (this.index >= this.input.length) {
1574
+ return undefined;
1575
+ }
1576
+ return this.input[this.index++];
1577
+ }
1578
+ /** Read the next character from the input if it matches the target. */
1579
+ readGivenChar(target) {
1580
+ return this.readAtomically(() => {
1581
+ const char = this.readChar();
1582
+ if (char !== target) {
1583
+ return undefined;
1584
+ }
1585
+ return char;
1586
+ });
1587
+ }
1588
+ /**
1589
+ * Helper for reading separators in an indexed loop. Reads the separator
1590
+ * character iff index > 0, then runs the parser. When used in a loop,
1591
+ * the separator character will only be read on index > 0 (see
1592
+ * readIPv4Addr for an example)
1593
+ */
1594
+ readSeparator(sep, index, inner) {
1595
+ return this.readAtomically(() => {
1596
+ if (index > 0) {
1597
+ if (this.readGivenChar(sep) === undefined) {
1598
+ return undefined;
1599
+ }
1600
+ }
1601
+ return inner();
1602
+ });
1603
+ }
1604
+ /**
1605
+ * Read a number off the front of the input in the given radix, stopping
1606
+ * at the first non-digit character or eof. Fails if the number has more
1607
+ * digits than max_digits or if there is no number.
1608
+ */
1609
+ readNumber(radix, maxDigits, allowZeroPrefix, maxBytes) {
1610
+ return this.readAtomically(() => {
1611
+ let result = 0;
1612
+ let digitCount = 0;
1613
+ const leadingChar = this.peekChar();
1614
+ if (leadingChar === undefined) {
1615
+ return undefined;
1616
+ }
1617
+ const hasLeadingZero = leadingChar === "0";
1618
+ const maxValue = 2 ** (8 * maxBytes) - 1;
1619
+ // eslint-disable-next-line no-constant-condition
1620
+ while (true) {
1621
+ const digit = this.readAtomically(() => {
1622
+ const char = this.readChar();
1623
+ if (char === undefined) {
1624
+ return undefined;
1625
+ }
1626
+ const num = Number.parseInt(char, radix);
1627
+ if (Number.isNaN(num)) {
1628
+ return undefined;
1629
+ }
1630
+ return num;
1631
+ });
1632
+ if (digit === undefined) {
1633
+ break;
1634
+ }
1635
+ result *= radix;
1636
+ result += digit;
1637
+ if (result > maxValue) {
1638
+ return undefined;
1639
+ }
1640
+ digitCount += 1;
1641
+ if (maxDigits !== undefined) {
1642
+ if (digitCount > maxDigits) {
1643
+ return undefined;
1644
+ }
1645
+ }
1646
+ }
1647
+ if (digitCount === 0) {
1648
+ return undefined;
1649
+ }
1650
+ else if (!allowZeroPrefix && hasLeadingZero && digitCount > 1) {
1651
+ return undefined;
1652
+ }
1653
+ else {
1654
+ return result;
1655
+ }
1656
+ });
1657
+ }
1658
+ /** Read an IPv4 address. */
1659
+ readIPv4Addr() {
1660
+ return this.readAtomically(() => {
1661
+ const out = new Uint8Array(4);
1662
+ for (let i = 0; i < out.length; i++) {
1663
+ const ix = this.readSeparator(".", i, () => this.readNumber(10, 3, false, 1));
1664
+ if (ix === undefined) {
1665
+ return undefined;
1666
+ }
1667
+ out[i] = ix;
1668
+ }
1669
+ return out;
1670
+ });
1671
+ }
1672
+ /** Read an IPv6 Address. */
1673
+ readIPv6Addr() {
1674
+ /**
1675
+ * Read a chunk of an IPv6 address into `groups`. Returns the number
1676
+ * of groups read, along with a bool indicating if an embedded
1677
+ * trailing IPv4 address was read. Specifically, read a series of
1678
+ * colon-separated IPv6 groups (0x0000 - 0xFFFF), with an optional
1679
+ * trailing embedded IPv4 address.
1680
+ */
1681
+ const readGroups = (groups) => {
1682
+ for (let i = 0; i < groups.length / 2; i++) {
1683
+ const ix = i * 2;
1684
+ // Try to read a trailing embedded IPv4 address. There must be at least 4 groups left.
1685
+ if (i < groups.length - 3) {
1686
+ const ipv4 = this.readSeparator(":", i, () => this.readIPv4Addr());
1687
+ if (ipv4 !== undefined) {
1688
+ groups[ix] = ipv4[0];
1689
+ groups[ix + 1] = ipv4[1];
1690
+ groups[ix + 2] = ipv4[2];
1691
+ groups[ix + 3] = ipv4[3];
1692
+ return [ix + 4, true];
1693
+ }
1694
+ }
1695
+ const group = this.readSeparator(":", i, () => this.readNumber(16, 4, true, 2));
1696
+ if (group === undefined) {
1697
+ return [ix, false];
1698
+ }
1699
+ groups[ix] = group >> 8;
1700
+ groups[ix + 1] = group & 255;
1701
+ }
1702
+ return [groups.length, false];
1703
+ };
1704
+ return this.readAtomically(() => {
1705
+ // Read the front part of the address; either the whole thing, or up to the first ::
1706
+ const head = new Uint8Array(16);
1707
+ const [headSize, headIp4] = readGroups(head);
1708
+ if (headSize === 16) {
1709
+ return head;
1710
+ }
1711
+ // IPv4 part is not allowed before `::`
1712
+ if (headIp4) {
1713
+ return undefined;
1714
+ }
1715
+ // Read `::` if previous code parsed less than 8 groups.
1716
+ // `::` indicates one or more groups of 16 bits of zeros.
1717
+ if (this.readGivenChar(":") === undefined) {
1718
+ return undefined;
1719
+ }
1720
+ if (this.readGivenChar(":") === undefined) {
1721
+ return undefined;
1722
+ }
1723
+ // Read the back part of the address. The :: must contain at least one
1724
+ // set of zeroes, so our max length is 7.
1725
+ const tail = new Uint8Array(14);
1726
+ const limit = 16 - (headSize + 2);
1727
+ const [tailSize] = readGroups(tail.subarray(0, limit));
1728
+ // Concat the head and tail of the IP address
1729
+ head.set(tail.subarray(0, tailSize), 16 - tailSize);
1730
+ return head;
1731
+ });
1732
+ }
1733
+ /** Read an IP Address, either IPv4 or IPv6. */
1734
+ readIPAddr() {
1735
+ return this.readIPv4Addr() ?? this.readIPv6Addr();
1736
+ }
1737
+ }
1738
+
1739
+ // See https://stackoverflow.com/questions/166132/maximum-length-of-the-textual-representation-of-an-ipv6-address
1740
+ const MAX_IPV6_LENGTH = 45;
1741
+ const MAX_IPV4_LENGTH = 15;
1742
+ const parser = new Parser();
1743
+ /** Parse `input` into IPv4 bytes. */
1744
+ function parseIPv4(input) {
1745
+ if (input.length > MAX_IPV4_LENGTH) {
1746
+ return undefined;
1747
+ }
1748
+ return parser.new(input).parseWith(() => parser.readIPv4Addr());
1749
+ }
1750
+ /** Parse `input` into IPv6 bytes. */
1751
+ function parseIPv6(input) {
1752
+ // strip zone index if it is present
1753
+ if (input.includes("%")) {
1754
+ input = input.split("%")[0];
1755
+ }
1756
+ if (input.length > MAX_IPV6_LENGTH) {
1757
+ return undefined;
1758
+ }
1759
+ return parser.new(input).parseWith(() => parser.readIPv6Addr());
1760
+ }
1761
+ /** Parse `input` into IPv4 or IPv6 bytes. */
1762
+ function parseIP(input) {
1763
+ // strip zone index if it is present
1764
+ if (input.includes("%")) {
1765
+ input = input.split("%")[0];
1766
+ }
1767
+ if (input.length > MAX_IPV6_LENGTH) {
1768
+ return undefined;
1769
+ }
1770
+ return parser.new(input).parseWith(() => parser.readIPAddr());
1771
+ }
1772
+
1773
+ // @ts-check
1774
+
1775
+
1776
+ const identity = from({
1777
+ prefix: '\x00',
1778
+ name: 'identity',
1779
+ encode: (buf) => toString$1(buf),
1780
+ decode: (str) => fromString(str)
1781
+ });
1782
+
1783
+ var identityBase = /*#__PURE__*/Object.freeze({
1784
+ __proto__: null,
1785
+ identity: identity
1786
+ });
1787
+
1788
+ // @ts-check
1789
+
1790
+
1791
+ const base2 = rfc4648({
1792
+ prefix: '0',
1793
+ name: 'base2',
1794
+ alphabet: '01',
1795
+ bitsPerChar: 1
1796
+ });
1797
+
1798
+ var base2$1 = /*#__PURE__*/Object.freeze({
1799
+ __proto__: null,
1800
+ base2: base2
1801
+ });
1802
+
1803
+ // @ts-check
1804
+
1805
+
1806
+ const base8 = rfc4648({
1807
+ prefix: '7',
1808
+ name: 'base8',
1809
+ alphabet: '01234567',
1810
+ bitsPerChar: 3
1811
+ });
1812
+
1813
+ var base8$1 = /*#__PURE__*/Object.freeze({
1814
+ __proto__: null,
1815
+ base8: base8
1816
+ });
1817
+
1818
+ const base10 = baseX({
1819
+ prefix: '9',
1820
+ name: 'base10',
1821
+ alphabet: '0123456789'
1822
+ });
1823
+
1824
+ var base10$1 = /*#__PURE__*/Object.freeze({
1825
+ __proto__: null,
1826
+ base10: base10
1827
+ });
1828
+
1829
+ // @ts-check
1830
+
1831
+
1832
+ const base16 = rfc4648({
1833
+ prefix: 'f',
1834
+ name: 'base16',
1835
+ alphabet: '0123456789abcdef',
1836
+ bitsPerChar: 4
1837
+ });
1838
+
1839
+ const base16upper = rfc4648({
1840
+ prefix: 'F',
1841
+ name: 'base16upper',
1842
+ alphabet: '0123456789ABCDEF',
1843
+ bitsPerChar: 4
1844
+ });
1845
+
1846
+ var base16$1 = /*#__PURE__*/Object.freeze({
1847
+ __proto__: null,
1848
+ base16: base16,
1849
+ base16upper: base16upper
1850
+ });
1851
+
1852
+ const base36 = baseX({
1853
+ prefix: 'k',
1854
+ name: 'base36',
1855
+ alphabet: '0123456789abcdefghijklmnopqrstuvwxyz'
1856
+ });
1857
+
1858
+ const base36upper = baseX({
1859
+ prefix: 'K',
1860
+ name: 'base36upper',
1861
+ alphabet: '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ'
1862
+ });
1863
+
1864
+ var base36$1 = /*#__PURE__*/Object.freeze({
1865
+ __proto__: null,
1866
+ base36: base36,
1867
+ base36upper: base36upper
1868
+ });
1869
+
1870
+ // @ts-check
1871
+
1798
1872
 
1799
- /**
1800
- * @param {API.Version} version
1801
- * @param {number} code
1802
- * @param {Uint8Array} multihash
1803
- * @returns {Uint8Array}
1804
- */
1805
- const encodeCID = (version, code, multihash) => {
1806
- const codeOffset = encodingLength(version);
1807
- const hashOffset = codeOffset + encodingLength(code);
1808
- const bytes = new Uint8Array(hashOffset + multihash.byteLength);
1809
- encodeTo(version, bytes, 0);
1810
- encodeTo(code, bytes, codeOffset);
1811
- bytes.set(multihash, hashOffset);
1812
- return bytes
1813
- };
1873
+ const base64 = rfc4648({
1874
+ prefix: 'm',
1875
+ name: 'base64',
1876
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
1877
+ bitsPerChar: 6
1878
+ });
1814
1879
 
1815
- const cidSymbol = Symbol.for('@ipld/js-cid/CID');
1880
+ const base64pad = rfc4648({
1881
+ prefix: 'M',
1882
+ name: 'base64pad',
1883
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/=',
1884
+ bitsPerChar: 6
1885
+ });
1816
1886
 
1817
- // @ts-check
1887
+ const base64url = rfc4648({
1888
+ prefix: 'u',
1889
+ name: 'base64url',
1890
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_',
1891
+ bitsPerChar: 6
1892
+ });
1818
1893
 
1819
- const bases = { ...identityBase, ...base2$1, ...base8$1, ...base10$1, ...base16$1, ...base32$1, ...base36$1, ...base58, ...base64$1, ...base256emoji$1 };
1894
+ const base64urlpad = rfc4648({
1895
+ prefix: 'U',
1896
+ name: 'base64urlpad',
1897
+ alphabet: 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_=',
1898
+ bitsPerChar: 6
1899
+ });
1820
1900
 
1821
- /**
1822
- * To guarantee Uint8Array semantics, convert nodejs Buffers
1823
- * into vanilla Uint8Arrays
1824
- */
1825
- function asUint8Array(buf) {
1826
- if (globalThis.Buffer != null) {
1827
- return new Uint8Array(buf.buffer, buf.byteOffset, buf.byteLength);
1828
- }
1829
- return buf;
1830
- }
1901
+ var base64$1 = /*#__PURE__*/Object.freeze({
1902
+ __proto__: null,
1903
+ base64: base64,
1904
+ base64pad: base64pad,
1905
+ base64url: base64url,
1906
+ base64urlpad: base64urlpad
1907
+ });
1908
+
1909
+ const alphabet = Array.from('🚀🪐☄🛰🌌🌑🌒🌓🌔🌕🌖🌗🌘🌍🌏🌎🐉☀💻🖥💾💿😂❤😍🤣😊🙏💕😭😘👍😅👏😁🔥🥰💔💖💙😢🤔😆🙄💪😉☺👌🤗💜😔😎😇🌹🤦🎉💞✌✨🤷😱😌🌸🙌😋💗💚😏💛🙂💓🤩😄😀🖤😃💯🙈👇🎶😒🤭❣😜💋👀😪😑💥🙋😞😩😡🤪👊🥳😥🤤👉💃😳✋😚😝😴🌟😬🙃🍀🌷😻😓⭐✅🥺🌈😈🤘💦✔😣🏃💐☹🎊💘😠☝😕🌺🎂🌻😐🖕💝🙊😹🗣💫💀👑🎵🤞😛🔴😤🌼😫⚽🤙☕🏆🤫👈😮🙆🍻🍃🐶💁😲🌿🧡🎁⚡🌞🎈❌✊👋😰🤨😶🤝🚶💰🍓💢🤟🙁🚨💨🤬✈🎀🍺🤓😙💟🌱😖👶🥴▶➡❓💎💸⬇😨🌚🦋😷🕺⚠🙅😟😵👎🤲🤠🤧📌🔵💅🧐🐾🍒😗🤑🌊🤯🐷☎💧😯💆👆🎤🙇🍑❄🌴💣🐸💌📍🥀🤢👅💡💩👐📸👻🤐🤮🎼🥵🚩🍎🍊👼💍📣🥂');
1910
+ const alphabetBytesToChars = /** @type {string[]} */ (alphabet.reduce((p, c, i) => { p[i] = c; return p }, /** @type {string[]} */([])));
1911
+ const alphabetCharsToBytes = /** @type {number[]} */ (alphabet.reduce((p, c, i) => { p[/** @type {number} */ (c.codePointAt(0))] = i; return p }, /** @type {number[]} */([])));
1831
1912
 
1832
1913
  /**
1833
- * Returns a `Uint8Array` of the requested size. Referenced memory will
1834
- * be initialized to 0.
1914
+ * @param {Uint8Array} data
1915
+ * @returns {string}
1835
1916
  */
1836
- function alloc(size = 0) {
1837
- if (globalThis.Buffer?.alloc != null) {
1838
- return asUint8Array(globalThis.Buffer.alloc(size));
1839
- }
1840
- return new Uint8Array(size);
1917
+ function encode$1 (data) {
1918
+ return data.reduce((p, c) => {
1919
+ p += alphabetBytesToChars[c];
1920
+ return p
1921
+ }, '')
1841
1922
  }
1923
+
1842
1924
  /**
1843
- * Where possible returns a Uint8Array of the requested size that references
1844
- * uninitialized memory. Only use if you are certain you will immediately
1845
- * overwrite every value in the returned `Uint8Array`.
1925
+ * @param {string} str
1926
+ * @returns {Uint8Array}
1846
1927
  */
1847
- function allocUnsafe(size = 0) {
1848
- if (globalThis.Buffer?.allocUnsafe != null) {
1849
- return asUint8Array(globalThis.Buffer.allocUnsafe(size));
1928
+ function decode$1 (str) {
1929
+ const byts = [];
1930
+ for (const char of str) {
1931
+ const byt = alphabetCharsToBytes[/** @type {number} */ (char.codePointAt(0))];
1932
+ if (byt === undefined) {
1933
+ throw new Error(`Non-base256emoji character: ${char}`)
1850
1934
  }
1851
- return new Uint8Array(size);
1935
+ byts.push(byt);
1936
+ }
1937
+ return new Uint8Array(byts)
1852
1938
  }
1853
1939
 
1854
- function createCodec(name, prefix, encode, decode) {
1855
- return {
1856
- name,
1857
- prefix,
1858
- encoder: {
1859
- name,
1860
- prefix,
1861
- encode
1862
- },
1863
- decoder: {
1864
- decode
1865
- }
1866
- };
1867
- }
1868
- const string = createCodec('utf8', 'u', (buf) => {
1869
- const decoder = new TextDecoder('utf8');
1870
- return 'u' + decoder.decode(buf);
1871
- }, (str) => {
1872
- const encoder = new TextEncoder();
1873
- return encoder.encode(str.substring(1));
1940
+ const base256emoji = from({
1941
+ prefix: '🚀',
1942
+ name: 'base256emoji',
1943
+ encode: encode$1,
1944
+ decode: decode$1
1874
1945
  });
1875
- const ascii = createCodec('ascii', 'a', (buf) => {
1876
- let string = 'a';
1877
- for (let i = 0; i < buf.length; i++) {
1878
- string += String.fromCharCode(buf[i]);
1879
- }
1880
- return string;
1881
- }, (str) => {
1882
- str = str.substring(1);
1883
- const buf = allocUnsafe(str.length);
1884
- for (let i = 0; i < str.length; i++) {
1885
- buf[i] = str.charCodeAt(i);
1886
- }
1887
- return buf;
1946
+
1947
+ var base256emoji$1 = /*#__PURE__*/Object.freeze({
1948
+ __proto__: null,
1949
+ base256emoji: base256emoji
1888
1950
  });
1889
- const BASES = {
1890
- utf8: string,
1891
- 'utf-8': string,
1892
- hex: bases.base16,
1893
- latin1: ascii,
1894
- ascii,
1895
- binary: ascii,
1896
- ...bases
1897
- };
1951
+
1952
+ // @ts-check
1898
1953
 
1899
1954
  /**
1900
- * Turns a `Uint8Array` into a string.
1901
- *
1902
- * Supports `utf8`, `utf-8` and any encoding supported by the multibase module.
1903
- *
1904
- * Also `ascii` which is similar to node's 'binary' encoding.
1955
+ * @template T
1956
+ * @typedef {import('./interface.js').ByteView<T>} ByteView
1905
1957
  */
1906
- function toString$1(array, encoding = 'utf8') {
1907
- const base = BASES[encoding];
1908
- if (base == null) {
1909
- throw new Error(`Unsupported encoding "${encoding}"`);
1910
- }
1911
- if ((encoding === 'utf8' || encoding === 'utf-8') && globalThis.Buffer != null && globalThis.Buffer.from != null) {
1912
- return globalThis.Buffer.from(array.buffer, array.byteOffset, array.byteLength).toString('utf8');
1913
- }
1914
- // strip multibase prefix
1915
- return base.encoder.encode(array).substring(1);
1958
+
1959
+ new TextEncoder();
1960
+ new TextDecoder();
1961
+
1962
+ // @ts-check
1963
+
1964
+
1965
+ const bases = { ...identityBase, ...base2$1, ...base8$1, ...base10$1, ...base16$1, ...base32$1, ...base36$1, ...base58, ...base64$1, ...base256emoji$1 };
1966
+
1967
+ /** Check if `input` is IPv4. */
1968
+ function isIPv4(input) {
1969
+ return Boolean(parseIPv4(input));
1970
+ }
1971
+ /** Check if `input` is IPv6. */
1972
+ function isIPv6(input) {
1973
+ return Boolean(parseIPv6(input));
1974
+ }
1975
+ /** Check if `input` is IPv4 or IPv6. */
1976
+ function isIP(input) {
1977
+ return Boolean(parseIP(input));
1916
1978
  }
1917
1979
 
1918
1980
  const isV4 = isIPv4;
@@ -1937,10 +1999,10 @@ const toBytes$1 = function (ip) {
1937
1999
  let v4Buffer;
1938
2000
  if (isv4) {
1939
2001
  v4Buffer = toBytes$1(sections[i]);
1940
- sections[i] = toString$1(v4Buffer.slice(0, 2), 'base16');
2002
+ sections[i] = toString$2(v4Buffer.slice(0, 2), 'base16');
1941
2003
  }
1942
2004
  if (v4Buffer != null && ++i < 8) {
1943
- sections.splice(i, 0, toString$1(v4Buffer.slice(2, 4), 'base16'));
2005
+ sections.splice(i, 0, toString$2(v4Buffer.slice(2, 4), 'base16'));
1944
2006
  }
1945
2007
  }
1946
2008
  if (sections[0] === '') {
@@ -2086,135 +2148,6 @@ function getProtocol(proto) {
2086
2148
  throw new Error(`invalid protocol id type: ${typeof proto}`);
2087
2149
  }
2088
2150
 
2089
- var encode_1 = encode$1;
2090
-
2091
- var MSB$1 = 0x80
2092
- , REST$1 = 0x7F
2093
- , MSBALL = ~REST$1
2094
- , INT = Math.pow(2, 31);
2095
-
2096
- function encode$1(num, out, offset) {
2097
- if (Number.MAX_SAFE_INTEGER && num > Number.MAX_SAFE_INTEGER) {
2098
- encode$1.bytes = 0;
2099
- throw new RangeError('Could not encode varint')
2100
- }
2101
- out = out || [];
2102
- offset = offset || 0;
2103
- var oldOffset = offset;
2104
-
2105
- while(num >= INT) {
2106
- out[offset++] = (num & 0xFF) | MSB$1;
2107
- num /= 128;
2108
- }
2109
- while(num & MSBALL) {
2110
- out[offset++] = (num & 0xFF) | MSB$1;
2111
- num >>>= 7;
2112
- }
2113
- out[offset] = num | 0;
2114
-
2115
- encode$1.bytes = offset - oldOffset + 1;
2116
-
2117
- return out
2118
- }
2119
-
2120
- var decode$1 = read;
2121
-
2122
- var MSB = 0x80
2123
- , REST = 0x7F;
2124
-
2125
- function read(buf, offset) {
2126
- var res = 0
2127
- , offset = offset || 0
2128
- , shift = 0
2129
- , counter = offset
2130
- , b
2131
- , l = buf.length;
2132
-
2133
- do {
2134
- if (counter >= l || shift > 49) {
2135
- read.bytes = 0;
2136
- throw new RangeError('Could not decode varint')
2137
- }
2138
- b = buf[counter++];
2139
- res += shift < 28
2140
- ? (b & REST) << shift
2141
- : (b & REST) * Math.pow(2, shift);
2142
- shift += 7;
2143
- } while (b >= MSB)
2144
-
2145
- read.bytes = counter - offset;
2146
-
2147
- return res
2148
- }
2149
-
2150
- var N1$1 = Math.pow(2, 7);
2151
- var N2$1 = Math.pow(2, 14);
2152
- var N3$1 = Math.pow(2, 21);
2153
- var N4$1 = Math.pow(2, 28);
2154
- var N5$1 = Math.pow(2, 35);
2155
- var N6$1 = Math.pow(2, 42);
2156
- var N7$1 = Math.pow(2, 49);
2157
- var N8$1 = Math.pow(2, 56);
2158
- var N9$1 = Math.pow(2, 63);
2159
-
2160
- var length = function (value) {
2161
- return (
2162
- value < N1$1 ? 1
2163
- : value < N2$1 ? 2
2164
- : value < N3$1 ? 3
2165
- : value < N4$1 ? 4
2166
- : value < N5$1 ? 5
2167
- : value < N6$1 ? 6
2168
- : value < N7$1 ? 7
2169
- : value < N8$1 ? 8
2170
- : value < N9$1 ? 9
2171
- : 10
2172
- )
2173
- };
2174
-
2175
- var varint = {
2176
- encode: encode_1
2177
- , decode: decode$1
2178
- , encodingLength: length
2179
- };
2180
-
2181
- var varint$1 = /*@__PURE__*/getDefaultExportFromCjs(varint);
2182
-
2183
- /**
2184
- * Create a `Uint8Array` from the passed string
2185
- *
2186
- * Supports `utf8`, `utf-8`, `hex`, and any encoding supported by the multiformats module.
2187
- *
2188
- * Also `ascii` which is similar to node's 'binary' encoding.
2189
- */
2190
- function fromString$1(string, encoding = 'utf8') {
2191
- const base = BASES[encoding];
2192
- if (base == null) {
2193
- throw new Error(`Unsupported encoding "${encoding}"`);
2194
- }
2195
- if ((encoding === 'utf8' || encoding === 'utf-8') && globalThis.Buffer != null && globalThis.Buffer.from != null) {
2196
- return asUint8Array(globalThis.Buffer.from(string, 'utf-8'));
2197
- }
2198
- // add multibase prefix
2199
- return base.decoder.decode(`${base.prefix}${string}`); // eslint-disable-line @typescript-eslint/restrict-template-expressions
2200
- }
2201
-
2202
- /**
2203
- * Returns a new Uint8Array created by concatenating the passed ArrayLikes
2204
- */
2205
- function concat$1(arrays, length) {
2206
- if (length == null) {
2207
- length = arrays.reduce((acc, curr) => acc + curr.length, 0);
2208
- }
2209
- const output = allocUnsafe(length);
2210
- let offset = 0;
2211
- for (const arr of arrays) {
2212
- output.set(arr, offset);
2213
- offset += arr.length;
2214
- }
2215
- return asUint8Array(output);
2216
- }
2217
-
2218
2151
  /**
2219
2152
  * @packageDocumentation
2220
2153
  *
@@ -2256,7 +2189,7 @@ function convertToString(proto, buf) {
2256
2189
  case 466: // certhash
2257
2190
  return bytes2mb(buf);
2258
2191
  default:
2259
- return toString$1(buf, 'base16'); // no clue. convert to hex
2192
+ return toString$2(buf, 'base16'); // no clue. convert to hex
2260
2193
  }
2261
2194
  }
2262
2195
  function convertToBytes(proto, str) {
@@ -2328,7 +2261,7 @@ function bytes2port(buf) {
2328
2261
  function str2bytes(str) {
2329
2262
  const buf = fromString$1(str);
2330
2263
  const size = Uint8Array.from(varint$1.encode(buf.length));
2331
- return concat$1([size, buf], size.length + buf.length);
2264
+ return concat([size, buf], size.length + buf.length);
2332
2265
  }
2333
2266
  function bytes2str(buf) {
2334
2267
  const size = varint$1.decode(buf);
@@ -2336,24 +2269,24 @@ function bytes2str(buf) {
2336
2269
  if (buf.length !== size) {
2337
2270
  throw new Error('inconsistent lengths');
2338
2271
  }
2339
- return toString$1(buf);
2272
+ return toString$2(buf);
2340
2273
  }
2341
2274
  function mh2bytes(hash) {
2342
2275
  let mh;
2343
2276
  if (hash[0] === 'Q' || hash[0] === '1') {
2344
- mh = decode$2(base58btc.decode(`z${hash}`)).bytes;
2277
+ mh = decode$3(base58btc.decode(`z${hash}`)).bytes;
2345
2278
  }
2346
2279
  else {
2347
2280
  mh = CID.parse(hash).multihash.bytes;
2348
2281
  }
2349
2282
  // the address is a varint prefixed multihash string representation
2350
2283
  const size = Uint8Array.from(varint$1.encode(mh.length));
2351
- return concat$1([size, mh], size.length + mh.length);
2284
+ return concat([size, mh], size.length + mh.length);
2352
2285
  }
2353
2286
  function mb2bytes(mbstr) {
2354
2287
  const mb = anybaseDecoder.decode(mbstr);
2355
2288
  const size = Uint8Array.from(varint$1.encode(mb.length));
2356
- return concat$1([size, mb], size.length + mb.length);
2289
+ return concat([size, mb], size.length + mb.length);
2357
2290
  }
2358
2291
  function bytes2mb(buf) {
2359
2292
  const size = varint$1.decode(buf);
@@ -2361,7 +2294,7 @@ function bytes2mb(buf) {
2361
2294
  if (hash.length !== size) {
2362
2295
  throw new Error('inconsistent lengths');
2363
2296
  }
2364
- return 'u' + toString$1(hash, 'base64url');
2297
+ return 'u' + toString$2(hash, 'base64url');
2365
2298
  }
2366
2299
  /**
2367
2300
  * Converts bytes to bas58btc string
@@ -2372,7 +2305,7 @@ function bytes2mh(buf) {
2372
2305
  if (address.length !== size) {
2373
2306
  throw new Error('inconsistent lengths');
2374
2307
  }
2375
- return toString$1(address, 'base58btc');
2308
+ return toString$2(address, 'base58btc');
2376
2309
  }
2377
2310
  function onion2bytes(str) {
2378
2311
  const addr = str.split(':');
@@ -2390,7 +2323,7 @@ function onion2bytes(str) {
2390
2323
  throw new Error('Port number is not in range(1, 65536)');
2391
2324
  }
2392
2325
  const portBuf = port2bytes(port);
2393
- return concat$1([buf, portBuf], buf.length + portBuf.length);
2326
+ return concat([buf, portBuf], buf.length + portBuf.length);
2394
2327
  }
2395
2328
  function onion32bytes(str) {
2396
2329
  const addr = str.split(':');
@@ -2408,30 +2341,37 @@ function onion32bytes(str) {
2408
2341
  throw new Error('Port number is not in range(1, 65536)');
2409
2342
  }
2410
2343
  const portBuf = port2bytes(port);
2411
- return concat$1([buf, portBuf], buf.length + portBuf.length);
2344
+ return concat([buf, portBuf], buf.length + portBuf.length);
2412
2345
  }
2413
2346
  function bytes2onion(buf) {
2414
2347
  const addrBytes = buf.slice(0, buf.length - 2);
2415
2348
  const portBytes = buf.slice(buf.length - 2);
2416
- const addr = toString$1(addrBytes, 'base32');
2349
+ const addr = toString$2(addrBytes, 'base32');
2417
2350
  const port = bytes2port(portBytes);
2418
2351
  return `${addr}:${port}`;
2419
2352
  }
2420
2353
 
2421
- /**
2422
- * string -> [[str name, str addr]... ]
2423
- */
2424
- function stringToStringTuples(str) {
2354
+ function stringToMultiaddrParts(str) {
2355
+ str = cleanPath(str);
2425
2356
  const tuples = [];
2426
- const parts = str.split('/').slice(1); // skip first empty elem
2357
+ const stringTuples = [];
2358
+ let path = null;
2359
+ const parts = str.split('/').slice(1);
2427
2360
  if (parts.length === 1 && parts[0] === '') {
2428
- return [];
2361
+ return {
2362
+ bytes: new Uint8Array(),
2363
+ string: '/',
2364
+ tuples: [],
2365
+ stringTuples: [],
2366
+ path: null
2367
+ };
2429
2368
  }
2430
2369
  for (let p = 0; p < parts.length; p++) {
2431
2370
  const part = parts[p];
2432
2371
  const proto = getProtocol(part);
2433
2372
  if (proto.size === 0) {
2434
- tuples.push([part]);
2373
+ tuples.push([proto.code]);
2374
+ stringTuples.push([proto.code]);
2435
2375
  // eslint-disable-next-line no-continue
2436
2376
  continue;
2437
2377
  }
@@ -2441,18 +2381,67 @@ function stringToStringTuples(str) {
2441
2381
  }
2442
2382
  // if it's a path proto, take the rest
2443
2383
  if (proto.path === true) {
2444
- tuples.push([
2445
- part,
2446
- // should we need to check each path part to see if it's a proto?
2447
- // This would allow for other protocols to be added after a unix path,
2448
- // however it would have issues if the path had a protocol name in the path
2449
- cleanPath(parts.slice(p).join('/'))
2450
- ]);
2384
+ // should we need to check each path part to see if it's a proto?
2385
+ // This would allow for other protocols to be added after a unix path,
2386
+ // however it would have issues if the path had a protocol name in the path
2387
+ path = cleanPath(parts.slice(p).join('/'));
2388
+ tuples.push([proto.code, convertToBytes(proto.code, path)]);
2389
+ stringTuples.push([proto.code, path]);
2390
+ break;
2391
+ }
2392
+ const bytes = convertToBytes(proto.code, parts[p]);
2393
+ tuples.push([proto.code, bytes]);
2394
+ stringTuples.push([proto.code, convertToString(proto.code, bytes)]);
2395
+ }
2396
+ return {
2397
+ string: stringTuplesToString(stringTuples),
2398
+ bytes: tuplesToBytes(tuples),
2399
+ tuples,
2400
+ stringTuples,
2401
+ path
2402
+ };
2403
+ }
2404
+ function bytesToMultiaddrParts(bytes) {
2405
+ const tuples = [];
2406
+ const stringTuples = [];
2407
+ let path = null;
2408
+ let i = 0;
2409
+ while (i < bytes.length) {
2410
+ const code = varint$1.decode(bytes, i);
2411
+ const n = varint$1.decode.bytes ?? 0;
2412
+ const p = getProtocol(code);
2413
+ const size = sizeForAddr(p, bytes.slice(i + n));
2414
+ if (size === 0) {
2415
+ tuples.push([code]);
2416
+ stringTuples.push([code]);
2417
+ i += n;
2418
+ // eslint-disable-next-line no-continue
2419
+ continue;
2420
+ }
2421
+ const addr = bytes.slice(i + n, i + n + size);
2422
+ i += (size + n);
2423
+ if (i > bytes.length) { // did not end _exactly_ at buffer.length
2424
+ throw ParseError('Invalid address Uint8Array: ' + toString$2(bytes, 'base16'));
2425
+ }
2426
+ // ok, tuple seems good.
2427
+ tuples.push([code, addr]);
2428
+ const stringAddr = convertToString(code, addr);
2429
+ stringTuples.push([code, stringAddr]);
2430
+ if (p.path === true) {
2431
+ // should we need to check each path part to see if it's a proto?
2432
+ // This would allow for other protocols to be added after a unix path,
2433
+ // however it would have issues if the path had a protocol name in the path
2434
+ path = stringAddr;
2451
2435
  break;
2452
2436
  }
2453
- tuples.push([part, parts[p]]);
2454
2437
  }
2455
- return tuples;
2438
+ return {
2439
+ bytes: Uint8Array.from(bytes),
2440
+ string: stringTuplesToString(stringTuples),
2441
+ tuples,
2442
+ stringTuples,
2443
+ path
2444
+ };
2456
2445
  }
2457
2446
  /**
2458
2447
  * [[str name, str addr]... ] -> string
@@ -2460,7 +2449,7 @@ function stringToStringTuples(str) {
2460
2449
  function stringTuplesToString(tuples) {
2461
2450
  const parts = [];
2462
2451
  tuples.map((tup) => {
2463
- const proto = protoFromTuple(tup);
2452
+ const proto = getProtocol(tup[0]);
2464
2453
  parts.push(proto.name);
2465
2454
  if (tup.length > 1 && tup[1] != null) {
2466
2455
  parts.push(tup[1]);
@@ -2469,47 +2458,18 @@ function stringTuplesToString(tuples) {
2469
2458
  });
2470
2459
  return cleanPath(parts.join('/'));
2471
2460
  }
2472
- /**
2473
- * [[str name, str addr]... ] -> [[int code, Uint8Array]... ]
2474
- */
2475
- function stringTuplesToTuples(tuples) {
2476
- return tuples.map((tup) => {
2477
- if (!Array.isArray(tup)) {
2478
- tup = [tup];
2479
- }
2480
- const proto = protoFromTuple(tup);
2481
- if (tup.length > 1) {
2482
- return [proto.code, convertToBytes(proto.code, tup[1])];
2483
- }
2484
- return [proto.code];
2485
- });
2486
- }
2487
- /**
2488
- * Convert tuples to string tuples
2489
- *
2490
- * [[int code, Uint8Array]... ] -> [[int code, str addr]... ]
2491
- */
2492
- function tuplesToStringTuples(tuples) {
2493
- return tuples.map(tup => {
2494
- const proto = protoFromTuple(tup);
2495
- if (tup[1] != null) {
2496
- return [proto.code, convertToString(proto.code, tup[1])];
2497
- }
2498
- return [proto.code];
2499
- });
2500
- }
2501
2461
  /**
2502
2462
  * [[int code, Uint8Array ]... ] -> Uint8Array
2503
2463
  */
2504
2464
  function tuplesToBytes(tuples) {
2505
- return fromBytes(concat$1(tuples.map((tup) => {
2506
- const proto = protoFromTuple(tup);
2465
+ return concat(tuples.map((tup) => {
2466
+ const proto = getProtocol(tup[0]);
2507
2467
  let buf = Uint8Array.from(varint$1.encode(proto.code));
2508
2468
  if (tup.length > 1 && tup[1] != null) {
2509
- buf = concat$1([buf, tup[1]]); // add address buffer
2469
+ buf = concat([buf, tup[1]]); // add address buffer
2510
2470
  }
2511
2471
  return buf;
2512
- })));
2472
+ }));
2513
2473
  }
2514
2474
  /**
2515
2475
  * For the passed address, return the serialized size
@@ -2526,115 +2486,12 @@ function sizeForAddr(p, addr) {
2526
2486
  return size + (varint$1.decode.bytes ?? 0);
2527
2487
  }
2528
2488
  }
2529
- function bytesToTuples(buf) {
2530
- const tuples = [];
2531
- let i = 0;
2532
- while (i < buf.length) {
2533
- const code = varint$1.decode(buf, i);
2534
- const n = varint$1.decode.bytes ?? 0;
2535
- const p = getProtocol(code);
2536
- const size = sizeForAddr(p, buf.slice(i + n));
2537
- if (size === 0) {
2538
- tuples.push([code]);
2539
- i += n;
2540
- // eslint-disable-next-line no-continue
2541
- continue;
2542
- }
2543
- const addr = buf.slice(i + n, i + n + size);
2544
- i += (size + n);
2545
- if (i > buf.length) { // did not end _exactly_ at buffer.length
2546
- throw ParseError('Invalid address Uint8Array: ' + toString$1(buf, 'base16'));
2547
- }
2548
- // ok, tuple seems good.
2549
- tuples.push([code, addr]);
2550
- }
2551
- return tuples;
2552
- }
2553
- /**
2554
- * Uint8Array -> String
2555
- */
2556
- function bytesToString(buf) {
2557
- const a = bytesToTuples(buf);
2558
- const b = tuplesToStringTuples(a);
2559
- return stringTuplesToString(b);
2560
- }
2561
- /**
2562
- * String -> Uint8Array
2563
- */
2564
- function stringToBytes(str) {
2565
- str = cleanPath(str);
2566
- const a = stringToStringTuples(str);
2567
- const b = stringTuplesToTuples(a);
2568
- return tuplesToBytes(b);
2569
- }
2570
- /**
2571
- * String -> Uint8Array
2572
- */
2573
- function fromString(str) {
2574
- return stringToBytes(str);
2575
- }
2576
- /**
2577
- * Uint8Array -> Uint8Array
2578
- */
2579
- function fromBytes(buf) {
2580
- const err = validateBytes(buf);
2581
- if (err != null) {
2582
- throw err;
2583
- }
2584
- return Uint8Array.from(buf); // copy
2585
- }
2586
- function validateBytes(buf) {
2587
- try {
2588
- bytesToTuples(buf); // try to parse. will throw if breaks
2589
- }
2590
- catch (err) {
2591
- return err;
2592
- }
2593
- }
2594
2489
  function cleanPath(str) {
2595
2490
  return '/' + str.trim().split('/').filter((a) => a).join('/');
2596
2491
  }
2597
2492
  function ParseError(str) {
2598
2493
  return new Error('Error parsing address: ' + str);
2599
2494
  }
2600
- function protoFromTuple(tup) {
2601
- const proto = getProtocol(tup[0]);
2602
- return proto;
2603
- }
2604
-
2605
- /**
2606
- * When this error is thrown it means an operation was aborted,
2607
- * usually in response to the `abort` event being emitted by an
2608
- * AbortSignal.
2609
- */
2610
- class CodeError extends Error {
2611
- code;
2612
- props;
2613
- constructor(message, code, props) {
2614
- super(message);
2615
- this.code = code;
2616
- this.name = props?.name ?? 'CodeError';
2617
- this.props = props ?? {}; // eslint-disable-line @typescript-eslint/consistent-type-assertions
2618
- }
2619
- }
2620
-
2621
- /**
2622
- * Returns true if the two passed Uint8Arrays have the same content
2623
- */
2624
- function equals(a, b) {
2625
- if (a === b) {
2626
- return true;
2627
- }
2628
- if (a.byteLength !== b.byteLength) {
2629
- return false;
2630
- }
2631
- for (let i = 0; i < a.byteLength; i++) {
2632
- if (a[i] !== b[i]) {
2633
- return false;
2634
- }
2635
- }
2636
- return true;
2637
- }
2638
2495
 
2639
2496
  /**
2640
2497
  * @packageDocumentation
@@ -2649,18 +2506,6 @@ function equals(a, b) {
2649
2506
  * const ma = multiaddr('/ip4/127.0.0.1/tcp/1234')
2650
2507
  * ```
2651
2508
  */
2652
- var __classPrivateFieldGet = (undefined && undefined.__classPrivateFieldGet) || function (receiver, state, kind, f) {
2653
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter");
2654
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it");
2655
- return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver);
2656
- };
2657
- var __classPrivateFieldSet = (undefined && undefined.__classPrivateFieldSet) || function (receiver, state, value, kind, f) {
2658
- if (kind === "m") throw new TypeError("Private method is not writable");
2659
- if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter");
2660
- if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
2661
- return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
2662
- };
2663
- var _DefaultMultiaddr_string, _DefaultMultiaddr_tuples, _DefaultMultiaddr_stringTuples, _DefaultMultiaddr_path, _a;
2664
2509
  const inspect = Symbol.for('nodejs.util.inspect.custom');
2665
2510
  const DNS_CODES = [
2666
2511
  getProtocol('dns').code,
@@ -2694,37 +2539,41 @@ function isMultiaddr(value) {
2694
2539
  * Creates a {@link Multiaddr} from a {@link MultiaddrInput}
2695
2540
  */
2696
2541
  class DefaultMultiaddr {
2542
+ bytes;
2543
+ #string;
2544
+ #tuples;
2545
+ #stringTuples;
2546
+ #path;
2547
+ [symbol$1] = true;
2697
2548
  constructor(addr) {
2698
- _DefaultMultiaddr_string.set(this, void 0);
2699
- _DefaultMultiaddr_tuples.set(this, void 0);
2700
- _DefaultMultiaddr_stringTuples.set(this, void 0);
2701
- _DefaultMultiaddr_path.set(this, void 0);
2702
- this[_a] = true;
2703
2549
  // default
2704
2550
  if (addr == null) {
2705
2551
  addr = '';
2706
2552
  }
2553
+ let parts;
2707
2554
  if (addr instanceof Uint8Array) {
2708
- this.bytes = fromBytes(addr);
2555
+ parts = bytesToMultiaddrParts(addr);
2709
2556
  }
2710
2557
  else if (typeof addr === 'string') {
2711
2558
  if (addr.length > 0 && addr.charAt(0) !== '/') {
2712
2559
  throw new Error(`multiaddr "${addr}" must start with a "/"`);
2713
2560
  }
2714
- this.bytes = fromString(addr);
2561
+ parts = stringToMultiaddrParts(addr);
2715
2562
  }
2716
2563
  else if (isMultiaddr(addr)) { // Multiaddr
2717
- this.bytes = fromBytes(addr.bytes); // validate + copy buffer
2564
+ parts = bytesToMultiaddrParts(addr.bytes);
2718
2565
  }
2719
2566
  else {
2720
2567
  throw new Error('addr must be a string, Buffer, or another Multiaddr');
2721
2568
  }
2569
+ this.bytes = parts.bytes;
2570
+ this.#string = parts.string;
2571
+ this.#tuples = parts.tuples;
2572
+ this.#stringTuples = parts.stringTuples;
2573
+ this.#path = parts.path;
2722
2574
  }
2723
2575
  toString() {
2724
- if (__classPrivateFieldGet(this, _DefaultMultiaddr_string, "f") == null) {
2725
- __classPrivateFieldSet(this, _DefaultMultiaddr_string, bytesToString(this.bytes), "f");
2726
- }
2727
- return __classPrivateFieldGet(this, _DefaultMultiaddr_string, "f");
2576
+ return this.#string;
2728
2577
  }
2729
2578
  toJSON() {
2730
2579
  return this.toString();
@@ -2774,36 +2623,19 @@ class DefaultMultiaddr {
2774
2623
  return opts;
2775
2624
  }
2776
2625
  protos() {
2777
- return this.protoCodes().map(code => Object.assign({}, getProtocol(code)));
2626
+ return this.#tuples.map(([code]) => Object.assign({}, getProtocol(code)));
2778
2627
  }
2779
2628
  protoCodes() {
2780
- const codes = [];
2781
- const buf = this.bytes;
2782
- let i = 0;
2783
- while (i < buf.length) {
2784
- const code = varint$1.decode(buf, i);
2785
- const n = varint$1.decode.bytes ?? 0;
2786
- const p = getProtocol(code);
2787
- const size = sizeForAddr(p, buf.slice(i + n));
2788
- i += (size + n);
2789
- codes.push(code);
2790
- }
2791
- return codes;
2629
+ return this.#tuples.map(([code]) => code);
2792
2630
  }
2793
2631
  protoNames() {
2794
- return this.protos().map(proto => proto.name);
2632
+ return this.#tuples.map(([code]) => getProtocol(code).name);
2795
2633
  }
2796
2634
  tuples() {
2797
- if (__classPrivateFieldGet(this, _DefaultMultiaddr_tuples, "f") == null) {
2798
- __classPrivateFieldSet(this, _DefaultMultiaddr_tuples, bytesToTuples(this.bytes), "f");
2799
- }
2800
- return __classPrivateFieldGet(this, _DefaultMultiaddr_tuples, "f");
2635
+ return this.#tuples;
2801
2636
  }
2802
2637
  stringTuples() {
2803
- if (__classPrivateFieldGet(this, _DefaultMultiaddr_stringTuples, "f") == null) {
2804
- __classPrivateFieldSet(this, _DefaultMultiaddr_stringTuples, tuplesToStringTuples(this.tuples()), "f");
2805
- }
2806
- return __classPrivateFieldGet(this, _DefaultMultiaddr_stringTuples, "f");
2638
+ return this.#stringTuples;
2807
2639
  }
2808
2640
  encapsulate(addr) {
2809
2641
  addr = new DefaultMultiaddr(addr);
@@ -2829,23 +2661,28 @@ class DefaultMultiaddr {
2829
2661
  }
2830
2662
  getPeerId() {
2831
2663
  try {
2832
- const tuples = this.stringTuples().filter((tuple) => {
2833
- if (tuple[0] === names.ipfs.code) {
2834
- return true;
2664
+ let tuples = [];
2665
+ this.stringTuples().forEach(([code, name]) => {
2666
+ if (code === names.p2p.code) {
2667
+ tuples.push([code, name]);
2668
+ }
2669
+ // if this is a p2p-circuit address, return the target peer id if present
2670
+ // not the peer id of the relay
2671
+ if (code === names['p2p-circuit'].code) {
2672
+ tuples = [];
2835
2673
  }
2836
- return false;
2837
2674
  });
2838
- // Get the last ipfs tuple ['ipfs', 'peerid string']
2675
+ // Get the last ipfs tuple ['p2p', 'peerid string']
2839
2676
  const tuple = tuples.pop();
2840
2677
  if (tuple?.[1] != null) {
2841
2678
  const peerIdStr = tuple[1];
2842
2679
  // peer id is base58btc encoded string but not multibase encoded so add the `z`
2843
2680
  // prefix so we can validate that it is correctly encoded
2844
2681
  if (peerIdStr[0] === 'Q' || peerIdStr[0] === '1') {
2845
- return toString$1(base58btc.decode(`z${peerIdStr}`), 'base58btc');
2682
+ return toString$2(base58btc.decode(`z${peerIdStr}`), 'base58btc');
2846
2683
  }
2847
2684
  // try to parse peer id as CID
2848
- return toString$1(CID.parse(peerIdStr).multihash.bytes, 'base58btc');
2685
+ return toString$2(CID.parse(peerIdStr).multihash.bytes, 'base58btc');
2849
2686
  }
2850
2687
  return null;
2851
2688
  }
@@ -2854,26 +2691,7 @@ class DefaultMultiaddr {
2854
2691
  }
2855
2692
  }
2856
2693
  getPath() {
2857
- // on initialization, this.#path is undefined
2858
- // after the first call, it is either a string or null
2859
- if (__classPrivateFieldGet(this, _DefaultMultiaddr_path, "f") === undefined) {
2860
- try {
2861
- __classPrivateFieldSet(this, _DefaultMultiaddr_path, this.stringTuples().filter((tuple) => {
2862
- const proto = getProtocol(tuple[0]);
2863
- if (proto.path === true) {
2864
- return true;
2865
- }
2866
- return false;
2867
- })[0][1], "f");
2868
- if (__classPrivateFieldGet(this, _DefaultMultiaddr_path, "f") == null) {
2869
- __classPrivateFieldSet(this, _DefaultMultiaddr_path, null, "f");
2870
- }
2871
- }
2872
- catch {
2873
- __classPrivateFieldSet(this, _DefaultMultiaddr_path, null, "f");
2874
- }
2875
- }
2876
- return __classPrivateFieldGet(this, _DefaultMultiaddr_path, "f");
2694
+ return this.#path;
2877
2695
  }
2878
2696
  equals(addr) {
2879
2697
  return equals(this.bytes, addr.bytes);
@@ -2927,8 +2745,8 @@ class DefaultMultiaddr {
2927
2745
  * // 'Multiaddr(/ip4/127.0.0.1/tcp/4001)'
2928
2746
  * ```
2929
2747
  */
2930
- [(_DefaultMultiaddr_string = new WeakMap(), _DefaultMultiaddr_tuples = new WeakMap(), _DefaultMultiaddr_stringTuples = new WeakMap(), _DefaultMultiaddr_path = new WeakMap(), _a = symbol$1, inspect)]() {
2931
- return `Multiaddr(${bytesToString(this.bytes)})`;
2748
+ [inspect]() {
2749
+ return `Multiaddr(${this.#string})`;
2932
2750
  }
2933
2751
  }
2934
2752
  /**
@@ -2948,41 +2766,6 @@ function multiaddr(addr) {
2948
2766
  return new DefaultMultiaddr(addr);
2949
2767
  }
2950
2768
 
2951
- var Protocols;
2952
- (function (Protocols) {
2953
- Protocols["Relay"] = "relay";
2954
- Protocols["Store"] = "store";
2955
- Protocols["LightPush"] = "lightpush";
2956
- Protocols["Filter"] = "filter";
2957
- })(Protocols || (Protocols = {}));
2958
- var SendError;
2959
- (function (SendError) {
2960
- SendError["GENERIC_FAIL"] = "Generic error";
2961
- SendError["ENCODE_FAILED"] = "Failed to encode";
2962
- SendError["DECODE_FAILED"] = "Failed to decode";
2963
- SendError["SIZE_TOO_BIG"] = "Size is too big";
2964
- SendError["NO_RPC_RESPONSE"] = "No RPC response";
2965
- })(SendError || (SendError = {}));
2966
-
2967
- var PageDirection$1;
2968
- (function (PageDirection) {
2969
- PageDirection["BACKWARD"] = "backward";
2970
- PageDirection["FORWARD"] = "forward";
2971
- })(PageDirection$1 || (PageDirection$1 = {}));
2972
-
2973
- var Tags;
2974
- (function (Tags) {
2975
- Tags["BOOTSTRAP"] = "bootstrap";
2976
- Tags["PEER_EXCHANGE"] = "peer-exchange";
2977
- })(Tags || (Tags = {}));
2978
- var EPeersByDiscoveryEvents;
2979
- (function (EPeersByDiscoveryEvents) {
2980
- EPeersByDiscoveryEvents["PEER_DISCOVERY_BOOTSTRAP"] = "peer:discovery:bootstrap";
2981
- EPeersByDiscoveryEvents["PEER_DISCOVERY_PEER_EXCHANGE"] = "peer:discovery:peer-exchange";
2982
- EPeersByDiscoveryEvents["PEER_CONNECT_BOOTSTRAP"] = "peer:connected:bootstrap";
2983
- EPeersByDiscoveryEvents["PEER_CONNECT_PEER_EXCHANGE"] = "peer:connected:peer-exchange";
2984
- })(EPeersByDiscoveryEvents || (EPeersByDiscoveryEvents = {}));
2985
-
2986
2769
  /**
2987
2770
  * Adds types to the EventTarget class. Hopefully this won't be necessary forever.
2988
2771
  *
@@ -3066,16 +2849,34 @@ class KeepAliveManager {
3066
2849
  this.options = options;
3067
2850
  this.relay = relay;
3068
2851
  }
3069
- start(peerId, libp2pPing) {
3070
- // Just in case a timer already exist for this peer
2852
+ start(peerId, libp2pPing, peerStore) {
2853
+ // Just in case a timer already exists for this peer
3071
2854
  this.stop(peerId);
3072
2855
  const { pingKeepAlive: pingPeriodSecs, relayKeepAlive: relayPeriodSecs } = this.options;
3073
2856
  const peerIdStr = peerId.toString();
3074
2857
  if (pingPeriodSecs !== 0) {
3075
2858
  const interval = setInterval(() => {
3076
- libp2pPing.ping(peerId).catch((e) => {
3077
- log$6(`Ping failed (${peerIdStr})`, e);
3078
- });
2859
+ void (async () => {
2860
+ try {
2861
+ // ping the peer for keep alive
2862
+ // also update the peer store with the latency
2863
+ const ping = await libp2pPing.ping(peerId);
2864
+ log$6(`Ping succeeded (${peerIdStr})`, ping);
2865
+ try {
2866
+ await peerStore.patch(peerId, {
2867
+ metadata: {
2868
+ ping: utf8ToBytes$1(ping.toString())
2869
+ }
2870
+ });
2871
+ }
2872
+ catch (e) {
2873
+ log$6("Failed to update ping", e);
2874
+ }
2875
+ }
2876
+ catch (e) {
2877
+ log$6(`Ping failed (${peerIdStr})`, e);
2878
+ }
2879
+ })();
3079
2880
  }, pingPeriodSecs * 1000);
3080
2881
  this.pingKeepAliveTimers.set(peerIdStr, interval);
3081
2882
  }
@@ -3083,7 +2884,7 @@ class KeepAliveManager {
3083
2884
  if (relay && relayPeriodSecs !== 0) {
3084
2885
  const encoder = createEncoder({
3085
2886
  contentTopic: RelayPingContentTopic,
3086
- ephemeral: true,
2887
+ ephemeral: true
3087
2888
  });
3088
2889
  const interval = setInterval(() => {
3089
2890
  log$6("Sending Waku Relay ping message");
@@ -3108,7 +2909,7 @@ class KeepAliveManager {
3108
2909
  stopAll() {
3109
2910
  for (const timer of [
3110
2911
  ...Object.values(this.pingKeepAliveTimers),
3111
- ...Object.values(this.relayKeepAliveTimers),
2912
+ ...Object.values(this.relayKeepAliveTimers)
3112
2913
  ]) {
3113
2914
  clearInterval(timer);
3114
2915
  }
@@ -3169,12 +2970,12 @@ class ConnectionManager extends EventEmitter {
3169
2970
  return {
3170
2971
  DISCOVERED: {
3171
2972
  [Tags.BOOTSTRAP]: peersDiscoveredByBootstrap,
3172
- [Tags.PEER_EXCHANGE]: peersDiscoveredByPeerExchange,
2973
+ [Tags.PEER_EXCHANGE]: peersDiscoveredByPeerExchange
3173
2974
  },
3174
2975
  CONNECTED: {
3175
2976
  [Tags.BOOTSTRAP]: peersConnectedByBootstrap,
3176
- [Tags.PEER_EXCHANGE]: peersConnectedByPeerExchange,
3177
- },
2977
+ [Tags.PEER_EXCHANGE]: peersConnectedByPeerExchange
2978
+ }
3178
2979
  };
3179
2980
  }
3180
2981
  constructor(libp2p, keepAliveOptions, relay, options) {
@@ -3184,7 +2985,7 @@ class ConnectionManager extends EventEmitter {
3184
2985
  maxDialAttemptsForPeer: DEFAULT_MAX_DIAL_ATTEMPTS_FOR_PEER,
3185
2986
  maxBootstrapPeersAllowed: DEFAULT_MAX_BOOTSTRAP_PEERS_ALLOWED,
3186
2987
  maxParallelDials: DEFAULT_MAX_PARALLEL_DIALS,
3187
- ...options,
2988
+ ...options
3188
2989
  };
3189
2990
  this.keepAliveManager = new KeepAliveManager(keepAliveOptions, relay);
3190
2991
  this.run()
@@ -3225,42 +3026,55 @@ class ConnectionManager extends EventEmitter {
3225
3026
  async dialPeer(peerId) {
3226
3027
  this.currentActiveDialCount += 1;
3227
3028
  let dialAttempt = 0;
3228
- while (dialAttempt <= this.options.maxDialAttemptsForPeer) {
3029
+ while (dialAttempt < this.options.maxDialAttemptsForPeer) {
3229
3030
  try {
3230
- log$5(`Dialing peer ${peerId.toString()}`);
3031
+ log$5(`Dialing peer ${peerId.toString()} on attempt ${dialAttempt + 1}`);
3231
3032
  await this.libp2p.dial(peerId);
3232
3033
  const tags = await this.getTagNamesForPeer(peerId);
3233
3034
  // add tag to connection describing discovery mechanism
3234
3035
  // don't add duplicate tags
3235
- this.libp2p
3236
- .getConnections(peerId)
3237
- .forEach((conn) => (conn.tags = Array.from(new Set([...conn.tags, ...tags]))));
3036
+ this.libp2p.getConnections(peerId).forEach((conn) => {
3037
+ conn.tags = Array.from(new Set([...conn.tags, ...tags]));
3038
+ });
3238
3039
  this.dialAttemptsForPeer.delete(peerId.toString());
3239
- return;
3040
+ // Dialing succeeded, break the loop
3041
+ break;
3240
3042
  }
3241
- catch (e) {
3242
- const error = e;
3243
- this.dialErrorsForPeer.set(peerId.toString(), error);
3244
- log$5(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
3245
- dialAttempt = this.dialAttemptsForPeer.get(peerId.toString()) ?? 1;
3246
- this.dialAttemptsForPeer.set(peerId.toString(), dialAttempt + 1);
3247
- if (dialAttempt <= this.options.maxDialAttemptsForPeer) {
3248
- log$5(`Reattempting dial (${dialAttempt})`);
3043
+ catch (error) {
3044
+ if (error instanceof AggregateError) {
3045
+ // Handle AggregateError
3046
+ log$5(`Error dialing peer ${peerId.toString()} - ${error.errors}`);
3249
3047
  }
3048
+ else {
3049
+ // Handle generic error
3050
+ log$5(`Error dialing peer ${peerId.toString()} - ${error.message}`);
3051
+ }
3052
+ this.dialErrorsForPeer.set(peerId.toString(), error);
3053
+ dialAttempt++;
3054
+ this.dialAttemptsForPeer.set(peerId.toString(), dialAttempt);
3250
3055
  }
3251
3056
  }
3252
- try {
3253
- log$5(`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${JSON.stringify(this.dialErrorsForPeer.get(peerId.toString()).errors[0])}
3254
- }`);
3255
- this.dialErrorsForPeer.delete(peerId.toString());
3256
- return await this.libp2p.peerStore.delete(peerId);
3257
- }
3258
- catch (error) {
3259
- throw `Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`;
3260
- }
3261
- finally {
3262
- this.currentActiveDialCount -= 1;
3263
- this.processDialQueue();
3057
+ // Always decrease the active dial count and process the dial queue
3058
+ this.currentActiveDialCount--;
3059
+ this.processDialQueue();
3060
+ // If max dial attempts reached and dialing failed, delete the peer
3061
+ if (dialAttempt === this.options.maxDialAttemptsForPeer) {
3062
+ try {
3063
+ const error = this.dialErrorsForPeer.get(peerId.toString());
3064
+ let errorMessage;
3065
+ if (error instanceof AggregateError) {
3066
+ errorMessage = JSON.stringify(error.errors[0]);
3067
+ }
3068
+ else {
3069
+ errorMessage = error.message;
3070
+ }
3071
+ log$5(`Deleting undialable peer ${peerId.toString()} from peer store. Error: ${errorMessage}`);
3072
+ this.dialErrorsForPeer.delete(peerId.toString());
3073
+ await this.libp2p.peerStore.delete(peerId);
3074
+ }
3075
+ catch (error) {
3076
+ throw new Error(`Error deleting undialable peer ${peerId.toString()} from peer store - ${error}`);
3077
+ }
3264
3078
  }
3265
3079
  }
3266
3080
  async dropConnection(peerId) {
@@ -3321,16 +3135,11 @@ class ConnectionManager extends EventEmitter {
3321
3135
  void (async () => {
3322
3136
  const { id: peerId } = evt.detail;
3323
3137
  const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(Tags.BOOTSTRAP);
3324
- if (isBootstrap) {
3325
- this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP, {
3326
- detail: peerId,
3327
- }));
3328
- }
3329
- else {
3330
- this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE, {
3331
- detail: peerId,
3332
- }));
3333
- }
3138
+ this.dispatchEvent(new CustomEvent(isBootstrap
3139
+ ? EPeersByDiscoveryEvents.PEER_DISCOVERY_BOOTSTRAP
3140
+ : EPeersByDiscoveryEvents.PEER_DISCOVERY_PEER_EXCHANGE, {
3141
+ detail: peerId
3142
+ }));
3334
3143
  try {
3335
3144
  await this.attemptDial(peerId);
3336
3145
  }
@@ -3342,7 +3151,7 @@ class ConnectionManager extends EventEmitter {
3342
3151
  "peer:connect": (evt) => {
3343
3152
  void (async () => {
3344
3153
  const peerId = evt.detail;
3345
- this.keepAliveManager.start(peerId, this.libp2p.services.ping);
3154
+ this.keepAliveManager.start(peerId, this.libp2p.services.ping, this.libp2p.peerStore);
3346
3155
  const isBootstrap = (await this.getTagNamesForPeer(peerId)).includes(Tags.BOOTSTRAP);
3347
3156
  if (isBootstrap) {
3348
3157
  const bootstrapConnections = this.libp2p
@@ -3354,13 +3163,13 @@ class ConnectionManager extends EventEmitter {
3354
3163
  }
3355
3164
  else {
3356
3165
  this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_CONNECT_BOOTSTRAP, {
3357
- detail: peerId,
3166
+ detail: peerId
3358
3167
  }));
3359
3168
  }
3360
3169
  }
3361
3170
  else {
3362
3171
  this.dispatchEvent(new CustomEvent(EPeersByDiscoveryEvents.PEER_CONNECT_PEER_EXCHANGE, {
3363
- detail: peerId,
3172
+ detail: peerId
3364
3173
  }));
3365
3174
  }
3366
3175
  })();
@@ -3369,7 +3178,7 @@ class ConnectionManager extends EventEmitter {
3369
3178
  return (evt) => {
3370
3179
  this.keepAliveManager.stop(evt.detail);
3371
3180
  };
3372
- },
3181
+ }
3373
3182
  };
3374
3183
  /**
3375
3184
  * Checks if the peer is dialable based on the following conditions:
@@ -3569,13 +3378,13 @@ const FRAME_RATE = 60;
3569
3378
  * @param iteratorOptions - optional configuration for iterator;
3570
3379
  * @returns iterator and stop function to terminate it.
3571
3380
  */
3572
- async function toAsyncIterator(receiver, decoder, options, iteratorOptions) {
3381
+ async function toAsyncIterator(receiver, decoder, iteratorOptions) {
3573
3382
  const iteratorDelay = iteratorOptions?.iteratorDelay ?? FRAME_RATE;
3574
3383
  const messages = [];
3575
3384
  let unsubscribe;
3576
3385
  unsubscribe = await receiver.subscribe(decoder, (message) => {
3577
3386
  messages.push(message);
3578
- }, options);
3387
+ });
3579
3388
  const isWithTimeout = Number.isInteger(iteratorOptions?.timeoutMs);
3580
3389
  const timeoutMs = iteratorOptions?.timeoutMs ?? 0;
3581
3390
  const startTime = Date.now();
@@ -3602,7 +3411,7 @@ async function toAsyncIterator(receiver, decoder, options, iteratorOptions) {
3602
3411
  await unsubscribe();
3603
3412
  unsubscribe = undefined;
3604
3413
  }
3605
- },
3414
+ }
3606
3415
  };
3607
3416
  }
3608
3417
  function wait(ms) {
@@ -3811,7 +3620,7 @@ class Uint8ArrayList {
3811
3620
  */
3812
3621
  slice(beginInclusive, endExclusive) {
3813
3622
  const { bufs, length } = this._subList(beginInclusive, endExclusive);
3814
- return concat$1(bufs, length);
3623
+ return concat(bufs, length);
3815
3624
  }
3816
3625
  /**
3817
3626
  * Returns a alloc from the given start and end element index.
@@ -3824,7 +3633,7 @@ class Uint8ArrayList {
3824
3633
  if (bufs.length === 1) {
3825
3634
  return bufs[0];
3826
3635
  }
3827
- return concat$1(bufs, length);
3636
+ return concat(bufs, length);
3828
3637
  }
3829
3638
  /**
3830
3639
  * Returns a allocList from the given start and end element index.
@@ -4626,8 +4435,24 @@ decode.fromReader = (reader, options) => {
4626
4435
  });
4627
4436
  };
4628
4437
 
4438
+ function pDefer() {
4439
+ const deferred = {};
4440
+
4441
+ deferred.promise = new Promise((resolve, reject) => {
4442
+ deferred.resolve = resolve;
4443
+ deferred.reject = reject;
4444
+ });
4445
+
4446
+ return deferred;
4447
+ }
4448
+
4629
4449
  // ported from https://www.npmjs.com/package/fast-fifo
4630
4450
  class FixedFIFO {
4451
+ buffer;
4452
+ mask;
4453
+ top;
4454
+ btm;
4455
+ next;
4631
4456
  constructor(hwm) {
4632
4457
  if (!(hwm > 0) || ((hwm - 1) & hwm) !== 0) {
4633
4458
  throw new Error('Max size for a FixedFIFO should be a power of two');
@@ -4660,6 +4485,10 @@ class FixedFIFO {
4660
4485
  }
4661
4486
  }
4662
4487
  class FIFO {
4488
+ size;
4489
+ hwm;
4490
+ head;
4491
+ tail;
4663
4492
  constructor(options = {}) {
4664
4493
  this.hwm = options.splitLimit ?? 16;
4665
4494
  this.head = new FixedFIFO(this.hwm);
@@ -4748,6 +4577,15 @@ class FIFO {
4748
4577
  * // [ [1, 2, 3] ]
4749
4578
  * ```
4750
4579
  */
4580
+ let AbortError$1 = class AbortError extends Error {
4581
+ type;
4582
+ code;
4583
+ constructor(message, code) {
4584
+ super(message ?? 'The operation was aborted');
4585
+ this.type = 'aborted';
4586
+ this.code = code ?? 'ABORT_ERR';
4587
+ }
4588
+ };
4751
4589
  function pushable(options = {}) {
4752
4590
  const getNext = (buffer) => {
4753
4591
  const next = buffer.shift();
@@ -4759,7 +4597,7 @@ function pushable(options = {}) {
4759
4597
  }
4760
4598
  return {
4761
4599
  done: next.done === true,
4762
- // @ts-expect-error
4600
+ // @ts-expect-error if done is false, value will be present
4763
4601
  value: next.value
4764
4602
  };
4765
4603
  };
@@ -4772,26 +4610,39 @@ function _pushable(getNext, options) {
4772
4610
  let pushable;
4773
4611
  let onNext;
4774
4612
  let ended;
4613
+ let drain = pDefer();
4775
4614
  const waitNext = async () => {
4776
- if (!buffer.isEmpty()) {
4777
- return getNext(buffer);
4615
+ try {
4616
+ if (!buffer.isEmpty()) {
4617
+ return getNext(buffer);
4618
+ }
4619
+ if (ended) {
4620
+ return { done: true };
4621
+ }
4622
+ return await new Promise((resolve, reject) => {
4623
+ onNext = (next) => {
4624
+ onNext = null;
4625
+ buffer.push(next);
4626
+ try {
4627
+ resolve(getNext(buffer));
4628
+ }
4629
+ catch (err) {
4630
+ reject(err);
4631
+ }
4632
+ return pushable;
4633
+ };
4634
+ });
4778
4635
  }
4779
- if (ended) {
4780
- return { done: true };
4636
+ finally {
4637
+ if (buffer.isEmpty()) {
4638
+ // settle promise in the microtask queue to give consumers a chance to
4639
+ // await after calling .push
4640
+ queueMicrotask(() => {
4641
+ drain.resolve();
4642
+ drain = pDefer();
4643
+ });
4644
+ }
4781
4645
  }
4782
- return await new Promise((resolve, reject) => {
4783
- onNext = (next) => {
4784
- onNext = null;
4785
- buffer.push(next);
4786
- try {
4787
- resolve(getNext(buffer));
4788
- }
4789
- catch (err) {
4790
- reject(err);
4791
- }
4792
- return pushable;
4793
- };
4794
- });
4795
4646
  };
4796
4647
  const bufferNext = (next) => {
4797
4648
  if (onNext != null) {
@@ -4842,6 +4693,34 @@ function _pushable(getNext, options) {
4842
4693
  end,
4843
4694
  get readableLength() {
4844
4695
  return buffer.size;
4696
+ },
4697
+ onEmpty: async (options) => {
4698
+ const signal = options?.signal;
4699
+ signal?.throwIfAborted();
4700
+ if (buffer.isEmpty()) {
4701
+ return;
4702
+ }
4703
+ let cancel;
4704
+ let listener;
4705
+ if (signal != null) {
4706
+ cancel = new Promise((resolve, reject) => {
4707
+ listener = () => {
4708
+ reject(new AbortError$1());
4709
+ };
4710
+ signal.addEventListener('abort', listener);
4711
+ });
4712
+ }
4713
+ try {
4714
+ await Promise.race([
4715
+ drain.promise,
4716
+ cancel
4717
+ ]);
4718
+ }
4719
+ finally {
4720
+ if (listener != null && signal != null) {
4721
+ signal?.removeEventListener('abort', listener);
4722
+ }
4723
+ }
4845
4724
  }
4846
4725
  };
4847
4726
  if (onEnd == null) {
@@ -5111,7 +4990,7 @@ class FilterSubscribeRpc {
5111
4990
  requestId: v4(),
5112
4991
  filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.SUBSCRIBE,
5113
4992
  pubsubTopic,
5114
- contentTopics,
4993
+ contentTopics
5115
4994
  });
5116
4995
  }
5117
4996
  static createUnsubscribeRequest(pubsubTopic, contentTopics) {
@@ -5119,7 +4998,7 @@ class FilterSubscribeRpc {
5119
4998
  requestId: v4(),
5120
4999
  filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.UNSUBSCRIBE,
5121
5000
  pubsubTopic,
5122
- contentTopics,
5001
+ contentTopics
5123
5002
  });
5124
5003
  }
5125
5004
  static createUnsubscribeAllRequest(pubsubTopic) {
@@ -5127,7 +5006,7 @@ class FilterSubscribeRpc {
5127
5006
  requestId: v4(),
5128
5007
  filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.UNSUBSCRIBE_ALL,
5129
5008
  pubsubTopic,
5130
- contentTopics: [],
5009
+ contentTopics: []
5131
5010
  });
5132
5011
  }
5133
5012
  static createSubscriberPingRequest() {
@@ -5135,7 +5014,7 @@ class FilterSubscribeRpc {
5135
5014
  requestId: v4(),
5136
5015
  filterSubscribeType: FilterSubscribeRequest.FilterSubscribeType.SUBSCRIBER_PING,
5137
5016
  pubsubTopic: "",
5138
- contentTopics: [],
5017
+ contentTopics: []
5139
5018
  });
5140
5019
  }
5141
5020
  static decode(bytes) {
@@ -5184,7 +5063,7 @@ class FilterSubscribeResponse {
5184
5063
  const log$3 = debug("waku:filter:v2");
5185
5064
  const FilterCodecs = {
5186
5065
  SUBSCRIBE: "/vac/waku/filter-subscribe/2.0.0-beta1",
5187
- PUSH: "/vac/waku/filter-push/2.0.0-beta1",
5066
+ PUSH: "/vac/waku/filter-push/2.0.0-beta1"
5188
5067
  };
5189
5068
  class Subscription {
5190
5069
  peer;
@@ -5227,7 +5106,7 @@ class Subscription {
5227
5106
  // Decoder that decode to different implementations of `IDecodedMessage`
5228
5107
  const subscriptionCallback = {
5229
5108
  decoders,
5230
- callback,
5109
+ callback
5231
5110
  };
5232
5111
  // The callback and decoder may override previous values, this is on
5233
5112
  // purpose as the user may call `subscribe` to refresh the subscription
@@ -5292,6 +5171,7 @@ class Subscription {
5292
5171
  class Filter extends BaseProtocol {
5293
5172
  options;
5294
5173
  activeSubscriptions = new Map();
5174
+ NUM_PEERS_PROTOCOL = 1;
5295
5175
  getActiveSubscription(pubSubTopic, peerIdStr) {
5296
5176
  return this.activeSubscriptions.get(`${pubSubTopic}_${peerIdStr}`);
5297
5177
  }
@@ -5307,15 +5187,18 @@ class Filter extends BaseProtocol {
5307
5187
  this.activeSubscriptions = new Map();
5308
5188
  this.options = options ?? {};
5309
5189
  }
5310
- async createSubscription(pubSubTopic, peerId) {
5190
+ async createSubscription(pubSubTopic) {
5311
5191
  const _pubSubTopic = pubSubTopic ?? this.options.pubSubTopic ?? DefaultPubSubTopic;
5312
- const peer = await this.getPeer(peerId);
5192
+ const peer = (await this.getPeers({
5193
+ maxBootstrapPeers: 1,
5194
+ numPeers: this.NUM_PEERS_PROTOCOL
5195
+ }))[0];
5313
5196
  const subscription = this.getActiveSubscription(_pubSubTopic, peer.id.toString()) ??
5314
- this.setActiveSubscription(_pubSubTopic, peer.id.toString(), new Subscription(_pubSubTopic, peer, this.newStream.bind(this, peer)));
5197
+ this.setActiveSubscription(_pubSubTopic, peer.id.toString(), new Subscription(_pubSubTopic, peer, this.getStream.bind(this, peer)));
5315
5198
  return subscription;
5316
5199
  }
5317
- toSubscriptionIterator(decoders, opts) {
5318
- return toAsyncIterator(this, decoders, opts);
5200
+ toSubscriptionIterator(decoders) {
5201
+ return toAsyncIterator(this, decoders);
5319
5202
  }
5320
5203
  /**
5321
5204
  * This method is used to satisfy the `IReceiver` interface.
@@ -5332,8 +5215,8 @@ class Filter extends BaseProtocol {
5332
5215
  * This method should not be used directly.
5333
5216
  * Instead, use `createSubscription` to create a new subscription.
5334
5217
  */
5335
- async subscribe(decoders, callback, opts) {
5336
- const subscription = await this.createSubscription(undefined, opts?.peerId);
5218
+ async subscribe(decoders, callback) {
5219
+ const subscription = await this.createSubscription();
5337
5220
  await subscription.subscribe(decoders, callback);
5338
5221
  const contentTopics = Array.from(groupByContentTopic(Array.isArray(decoders) ? decoders : [decoders]).keys());
5339
5222
  return async () => {
@@ -5384,27 +5267,21 @@ async function pushMessage(subscriptionCallback, pubSubTopic, message) {
5384
5267
  log$3("Message has no content topic, skipping");
5385
5268
  return;
5386
5269
  }
5387
- let didDecodeMsg = false;
5388
- // We don't want to wait for decoding failure, just attempt to decode
5389
- // all messages and do the call back on the one that works
5390
- // noinspection ES6MissingAwait
5391
- for (const dec of decoders) {
5392
- if (didDecodeMsg)
5393
- break;
5394
- const decoded = await dec.fromProtoObj(pubSubTopic, message);
5395
- if (!decoded) {
5396
- log$3("Not able to decode message");
5397
- continue;
5398
- }
5399
- // This is just to prevent more decoding attempt
5400
- // TODO: Could be better if we were to abort promises
5401
- didDecodeMsg = Boolean(decoded);
5402
- await callback(decoded);
5270
+ try {
5271
+ const decodePromises = decoders.map((dec) => dec
5272
+ .fromProtoObj(pubSubTopic, message)
5273
+ .then((decoded) => decoded || Promise.reject("Decoding failed")));
5274
+ const decodedMessage = await Promise.any(decodePromises);
5275
+ await callback(decodedMessage);
5276
+ }
5277
+ catch (e) {
5278
+ log$3("Error decoding message", e);
5403
5279
  }
5404
5280
  }
5405
5281
 
5406
5282
  var index$2 = /*#__PURE__*/Object.freeze({
5407
5283
  __proto__: null,
5284
+ FilterCodecs: FilterCodecs,
5408
5285
  wakuFilter: wakuFilter
5409
5286
  });
5410
5287
 
@@ -5418,9 +5295,9 @@ class PushRpc {
5418
5295
  requestId: v4(),
5419
5296
  request: {
5420
5297
  message: message,
5421
- pubsubTopic: pubSubTopic,
5298
+ pubsubTopic: pubSubTopic
5422
5299
  },
5423
- response: undefined,
5300
+ response: undefined
5424
5301
  });
5425
5302
  }
5426
5303
  static decode(bytes) {
@@ -5445,60 +5322,89 @@ const LightPushCodec = "/vac/waku/lightpush/2.0.0-beta1";
5445
5322
  */
5446
5323
  class LightPush extends BaseProtocol {
5447
5324
  options;
5325
+ NUM_PEERS_PROTOCOL = 1;
5448
5326
  constructor(libp2p, options) {
5449
5327
  super(LightPushCodec, libp2p.components);
5450
5328
  this.options = options || {};
5451
5329
  }
5452
- async send(encoder, message, opts) {
5453
- const { pubSubTopic = DefaultPubSubTopic } = this.options;
5454
- const peer = await this.getPeer(opts?.peerId);
5455
- const stream = await this.newStream(peer);
5456
- const recipients = [];
5457
- let error = undefined;
5330
+ async preparePushMessage(encoder, message, pubSubTopic) {
5458
5331
  try {
5459
5332
  if (!isSizeValid(message.payload)) {
5460
- log$2("Failed to send waku light push: message is bigger that 1MB");
5461
- return {
5462
- recipients,
5463
- error: SendError.SIZE_TOO_BIG,
5464
- };
5333
+ log$2("Failed to send waku light push: message is bigger than 1MB");
5334
+ return { query: null, error: SendError.SIZE_TOO_BIG };
5465
5335
  }
5466
5336
  const protoMessage = await encoder.toProtoObj(message);
5467
5337
  if (!protoMessage) {
5468
5338
  log$2("Failed to encode to protoMessage, aborting push");
5469
5339
  return {
5470
- recipients,
5471
- error: SendError.ENCODE_FAILED,
5340
+ query: null,
5341
+ error: SendError.ENCODE_FAILED
5472
5342
  };
5473
5343
  }
5474
5344
  const query = PushRpc.createRequest(protoMessage, pubSubTopic);
5475
- const res = await pipe([query.encode()], encode, stream, decode, async (source) => await all(source));
5345
+ return { query, error: null };
5346
+ }
5347
+ catch (error) {
5348
+ log$2("Failed to prepare push message", error);
5349
+ return {
5350
+ query: null,
5351
+ error: SendError.GENERIC_FAIL
5352
+ };
5353
+ }
5354
+ }
5355
+ async send(encoder, message) {
5356
+ const { pubSubTopic = DefaultPubSubTopic } = this.options;
5357
+ const recipients = [];
5358
+ const { query, error: preparationError } = await this.preparePushMessage(encoder, message, pubSubTopic);
5359
+ if (preparationError || !query) {
5360
+ return {
5361
+ recipients,
5362
+ errors: [preparationError]
5363
+ };
5364
+ }
5365
+ const peers = await this.getPeers({
5366
+ maxBootstrapPeers: 1,
5367
+ numPeers: this.NUM_PEERS_PROTOCOL
5368
+ });
5369
+ const promises = peers.map(async (peer) => {
5370
+ let error;
5371
+ const stream = await this.getStream(peer);
5476
5372
  try {
5477
- const bytes = new Uint8ArrayList();
5478
- res.forEach((chunk) => {
5479
- bytes.append(chunk);
5480
- });
5481
- const response = PushRpc.decode(bytes).response;
5482
- if (response?.isSuccess) {
5483
- recipients.push(peer.id);
5373
+ const res = await pipe([query.encode()], encode, stream, decode, async (source) => await all(source));
5374
+ try {
5375
+ const bytes = new Uint8ArrayList();
5376
+ res.forEach((chunk) => {
5377
+ bytes.append(chunk);
5378
+ });
5379
+ const response = PushRpc.decode(bytes).response;
5380
+ if (response?.isSuccess) {
5381
+ recipients.some((recipient) => recipient.equals(peer.id)) ||
5382
+ recipients.push(peer.id);
5383
+ }
5384
+ else {
5385
+ log$2("No response in PushRPC");
5386
+ error = SendError.NO_RPC_RESPONSE;
5387
+ }
5484
5388
  }
5485
- else {
5486
- log$2("No response in PushRPC");
5487
- error = SendError.NO_RPC_RESPONSE;
5389
+ catch (err) {
5390
+ log$2("Failed to decode push reply", err);
5391
+ error = SendError.DECODE_FAILED;
5488
5392
  }
5489
5393
  }
5490
5394
  catch (err) {
5491
- log$2("Failed to decode push reply", err);
5492
- error = SendError.DECODE_FAILED;
5395
+ log$2("Failed to send waku light push request", err);
5396
+ error = SendError.GENERIC_FAIL;
5493
5397
  }
5494
- }
5495
- catch (err) {
5496
- log$2("Failed to send waku light push request", err);
5497
- error = SendError.GENERIC_FAIL;
5498
- }
5398
+ return { recipients, error };
5399
+ });
5400
+ const results = await Promise.allSettled(promises);
5401
+ const errors = results
5402
+ .filter((result) => result.status === "fulfilled")
5403
+ .map((result) => result.value.error)
5404
+ .filter((error) => error !== undefined);
5499
5405
  return {
5500
- error,
5501
5406
  recipients,
5407
+ errors
5502
5408
  };
5503
5409
  }
5504
5410
  }
@@ -5513,25 +5419,11 @@ var index$1 = /*#__PURE__*/Object.freeze({
5513
5419
  wakuLightPush: wakuLightPush
5514
5420
  });
5515
5421
 
5516
- function number(n) {
5517
- if (!Number.isSafeInteger(n) || n < 0)
5518
- throw new Error(`Wrong positive integer: ${n}`);
5519
- }
5520
- function bool(b) {
5521
- if (typeof b !== 'boolean')
5522
- throw new Error(`Expected boolean, not ${b}`);
5523
- }
5524
5422
  function bytes(b, ...lengths) {
5525
5423
  if (!(b instanceof Uint8Array))
5526
- throw new TypeError('Expected Uint8Array');
5424
+ throw new Error('Expected Uint8Array');
5527
5425
  if (lengths.length > 0 && !lengths.includes(b.length))
5528
- throw new TypeError(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
5529
- }
5530
- function hash(hash) {
5531
- if (typeof hash !== 'function' || typeof hash.create !== 'function')
5532
- throw new Error('Hash should be wrapped by utils.wrapConstructor');
5533
- number(hash.outputLen);
5534
- number(hash.blockLen);
5426
+ throw new Error(`Expected Uint8Array of length ${lengths}, not of length=${b.length}`);
5535
5427
  }
5536
5428
  function exists(instance, checkFinished = true) {
5537
5429
  if (instance.destroyed)
@@ -5546,16 +5438,15 @@ function output(out, instance) {
5546
5438
  throw new Error(`digestInto() expects output buffer of length at least ${min}`);
5547
5439
  }
5548
5440
  }
5549
- const assert = {
5550
- number,
5551
- bool,
5552
- bytes,
5553
- hash,
5554
- exists,
5555
- output,
5556
- };
5557
5441
 
5558
5442
  /*! noble-hashes - MIT License (c) 2022 Paul Miller (paulmillr.com) */
5443
+ // We use WebCrypto aka globalThis.crypto, which exists in browsers and node.js 16+.
5444
+ // node.js versions earlier than v19 don't declare it in global scope.
5445
+ // For node.js, package.json#exports field mapping rewrites import
5446
+ // from `crypto` to `cryptoNode`, which imports native module.
5447
+ // Makes the utils un-importable in browsers without a bundler.
5448
+ // Once node.js 18 is deprecated, we can just drop the import.
5449
+ const u8a = (a) => a instanceof Uint8Array;
5559
5450
  // Cast array to view
5560
5451
  const createView = (arr) => new DataView(arr.buffer, arr.byteOffset, arr.byteLength);
5561
5452
  // The rotate right (circular right shift) operation for uint32
@@ -5565,18 +5456,24 @@ const rotr = (word, shift) => (word << (32 - shift)) | (word >>> shift);
5565
5456
  const isLE = new Uint8Array(new Uint32Array([0x11223344]).buffer)[0] === 0x44;
5566
5457
  if (!isLE)
5567
5458
  throw new Error('Non little-endian hardware is not supported');
5568
- Array.from({ length: 256 }, (v, i) => i.toString(16).padStart(2, '0'));
5569
- function utf8ToBytes$1(str) {
5570
- if (typeof str !== 'string') {
5571
- throw new TypeError(`utf8ToBytes expected string, got ${typeof str}`);
5572
- }
5573
- return new TextEncoder().encode(str);
5459
+ /**
5460
+ * @example utf8ToBytes('abc') // new Uint8Array([97, 98, 99])
5461
+ */
5462
+ function utf8ToBytes(str) {
5463
+ if (typeof str !== 'string')
5464
+ throw new Error(`utf8ToBytes expected string, got ${typeof str}`);
5465
+ return new Uint8Array(new TextEncoder().encode(str)); // https://bugzil.la/1681809
5574
5466
  }
5467
+ /**
5468
+ * Normalizes (non-hex) string or Uint8Array to Uint8Array.
5469
+ * Warning: when Uint8Array is passed, it would NOT get copied.
5470
+ * Keep in mind for future mutable operations.
5471
+ */
5575
5472
  function toBytes(data) {
5576
5473
  if (typeof data === 'string')
5577
- data = utf8ToBytes$1(data);
5578
- if (!(data instanceof Uint8Array))
5579
- throw new TypeError(`Expected input type is Uint8Array (got ${typeof data})`);
5474
+ data = utf8ToBytes(data);
5475
+ if (!u8a(data))
5476
+ throw new Error(`expected Uint8Array, got ${typeof data}`);
5580
5477
  return data;
5581
5478
  }
5582
5479
  // For runtime check if class implements interface
@@ -5586,12 +5483,12 @@ class Hash {
5586
5483
  return this._cloneInto();
5587
5484
  }
5588
5485
  }
5589
- function wrapConstructor(hashConstructor) {
5590
- const hashC = (message) => hashConstructor().update(toBytes(message)).digest();
5591
- const tmp = hashConstructor();
5486
+ function wrapConstructor(hashCons) {
5487
+ const hashC = (msg) => hashCons().update(toBytes(msg)).digest();
5488
+ const tmp = hashCons();
5592
5489
  hashC.outputLen = tmp.outputLen;
5593
5490
  hashC.blockLen = tmp.blockLen;
5594
- hashC.create = () => hashConstructor();
5491
+ hashC.create = () => hashCons();
5595
5492
  return hashC;
5596
5493
  }
5597
5494
 
@@ -5624,7 +5521,7 @@ class SHA2 extends Hash {
5624
5521
  this.view = createView(this.buffer);
5625
5522
  }
5626
5523
  update(data) {
5627
- assert.exists(this);
5524
+ exists(this);
5628
5525
  const { view, buffer, blockLen } = this;
5629
5526
  data = toBytes(data);
5630
5527
  const len = data.length;
@@ -5650,8 +5547,8 @@ class SHA2 extends Hash {
5650
5547
  return this;
5651
5548
  }
5652
5549
  digestInto(out) {
5653
- assert.exists(this);
5654
- assert.output(out, this);
5550
+ exists(this);
5551
+ output(out, this);
5655
5552
  this.finished = true;
5656
5553
  // Padding
5657
5554
  // We can avoid allocation of buffer for padding completely if it
@@ -5707,6 +5604,8 @@ class SHA2 extends Hash {
5707
5604
  }
5708
5605
  }
5709
5606
 
5607
+ // SHA2-256 need to try 2^128 hashes to execute birthday attack.
5608
+ // BTC network is doing 2^67 hashes/sec as per early 2023.
5710
5609
  // Choice: a ? b : c
5711
5610
  const Chi = (a, b, c) => (a & b) ^ (~a & c);
5712
5611
  // Majority function, true if any two inpust is true
@@ -5714,7 +5613,7 @@ const Maj = (a, b, c) => (a & b) ^ (a & c) ^ (b & c);
5714
5613
  // Round constants:
5715
5614
  // first 32 bits of the fractional parts of the cube roots of the first 64 primes 2..311)
5716
5615
  // prettier-ignore
5717
- const SHA256_K = new Uint32Array([
5616
+ const SHA256_K = /* @__PURE__ */ new Uint32Array([
5718
5617
  0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5,
5719
5618
  0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174,
5720
5619
  0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da,
@@ -5726,12 +5625,12 @@ const SHA256_K = new Uint32Array([
5726
5625
  ]);
5727
5626
  // Initial state (first 32 bits of the fractional parts of the square roots of the first 8 primes 2..19):
5728
5627
  // prettier-ignore
5729
- const IV = new Uint32Array([
5628
+ const IV = /* @__PURE__ */ new Uint32Array([
5730
5629
  0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19
5731
5630
  ]);
5732
5631
  // Temporary buffer, not used to store anything between runs
5733
5632
  // Named this way because it matches specification.
5734
- const SHA256_W = new Uint32Array(64);
5633
+ const SHA256_W = /* @__PURE__ */ new Uint32Array(64);
5735
5634
  class SHA256 extends SHA2 {
5736
5635
  constructor() {
5737
5636
  super(64, 32, 8, false);
@@ -5807,45 +5706,11 @@ class SHA256 extends SHA2 {
5807
5706
  this.buffer.fill(0);
5808
5707
  }
5809
5708
  }
5810
- // Constants from https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.180-4.pdf
5811
- class SHA224 extends SHA256 {
5812
- constructor() {
5813
- super();
5814
- this.A = 0xc1059ed8 | 0;
5815
- this.B = 0x367cd507 | 0;
5816
- this.C = 0x3070dd17 | 0;
5817
- this.D = 0xf70e5939 | 0;
5818
- this.E = 0xffc00b31 | 0;
5819
- this.F = 0x68581511 | 0;
5820
- this.G = 0x64f98fa7 | 0;
5821
- this.H = 0xbefa4fa4 | 0;
5822
- this.outputLen = 28;
5823
- }
5824
- }
5825
5709
  /**
5826
5710
  * SHA2-256 hash function
5827
5711
  * @param message - data that would be hashed
5828
5712
  */
5829
- const sha256 = wrapConstructor(() => new SHA256());
5830
- wrapConstructor(() => new SHA224());
5831
-
5832
- /**
5833
- * Encode utf-8 string to byte array.
5834
- */
5835
- const utf8ToBytes = (s) => fromString$1(s, "utf8");
5836
- /**
5837
- * Concatenate using Uint8Arrays as `Buffer` has a different behavior with `DataView`
5838
- */
5839
- function concat(byteArrays, totalLength) {
5840
- const len = totalLength ?? byteArrays.reduce((acc, curr) => acc + curr.length, 0);
5841
- const res = new Uint8Array(len);
5842
- let offset = 0;
5843
- for (const bytes of byteArrays) {
5844
- res.set(bytes, offset);
5845
- offset += bytes.length;
5846
- }
5847
- return res;
5848
- }
5713
+ const sha256 = /* @__PURE__ */ wrapConstructor(() => new SHA256());
5849
5714
 
5850
5715
  const EmptyMessage = {
5851
5716
  payload: new Uint8Array(),
@@ -5854,7 +5719,7 @@ const EmptyMessage = {
5854
5719
  timestamp: undefined,
5855
5720
  meta: undefined,
5856
5721
  rateLimitProof: undefined,
5857
- ephemeral: undefined,
5722
+ ephemeral: undefined
5858
5723
  };
5859
5724
  function toProtoMessage(wire) {
5860
5725
  return { ...EmptyMessage, ...wire };
@@ -5888,7 +5753,7 @@ class HistoryRpc {
5888
5753
  const pagingInfo = {
5889
5754
  pageSize: BigInt(params.pageSize),
5890
5755
  cursor: params.cursor,
5891
- direction,
5756
+ direction
5892
5757
  };
5893
5758
  let startTime, endTime;
5894
5759
  if (params.startTime) {
@@ -5906,9 +5771,9 @@ class HistoryRpc {
5906
5771
  contentFilters,
5907
5772
  pagingInfo,
5908
5773
  startTime,
5909
- endTime,
5774
+ endTime
5910
5775
  },
5911
- response: undefined,
5776
+ response: undefined
5912
5777
  });
5913
5778
  }
5914
5779
  decode(bytes) {
@@ -5941,10 +5806,45 @@ const DefaultPageSize = 10;
5941
5806
  */
5942
5807
  class Store extends BaseProtocol {
5943
5808
  options;
5809
+ NUM_PEERS_PROTOCOL = 1;
5944
5810
  constructor(libp2p, options) {
5945
5811
  super(StoreCodec, libp2p.components);
5946
5812
  this.options = options ?? {};
5947
5813
  }
5814
+ /**
5815
+ * Processes messages based on the provided callback and options.
5816
+ * @private
5817
+ */
5818
+ async processMessages(messages, callback, options) {
5819
+ let abort = false;
5820
+ const messagesOrUndef = await Promise.all(messages);
5821
+ let processedMessages = messagesOrUndef.filter(isDefined);
5822
+ if (this.shouldReverseOrder(options)) {
5823
+ processedMessages = processedMessages.reverse();
5824
+ }
5825
+ await Promise.all(processedMessages.map(async (msg) => {
5826
+ if (msg && !abort) {
5827
+ abort = Boolean(await callback(msg));
5828
+ }
5829
+ }));
5830
+ return abort;
5831
+ }
5832
+ /**
5833
+ * Determines whether to reverse the order of messages based on the provided options.
5834
+ *
5835
+ * Messages in pages are ordered from oldest (first) to most recent (last).
5836
+ * https://github.com/vacp2p/rfc/issues/533
5837
+ *
5838
+ * @private
5839
+ */
5840
+ shouldReverseOrder(options) {
5841
+ return (typeof options?.pageDirection === "undefined" ||
5842
+ options?.pageDirection === PageDirection.BACKWARD);
5843
+ }
5844
+ /**
5845
+ * @deprecated Use `queryWithOrderedCallback` instead
5846
+ **/
5847
+ queryOrderedCallback = this.queryWithOrderedCallback;
5948
5848
  /**
5949
5849
  * Do a query to a Waku Store to retrieve historical/missed messages.
5950
5850
  *
@@ -5962,31 +5862,16 @@ class Store extends BaseProtocol {
5962
5862
  * or if an error is encountered when processing the reply,
5963
5863
  * or if two decoders with the same content topic are passed.
5964
5864
  */
5965
- async queryOrderedCallback(decoders, callback, options) {
5966
- let abort = false;
5865
+ async queryWithOrderedCallback(decoders, callback, options) {
5967
5866
  for await (const promises of this.queryGenerator(decoders, options)) {
5968
- if (abort)
5867
+ if (await this.processMessages(promises, callback, options))
5969
5868
  break;
5970
- const messagesOrUndef = await Promise.all(promises);
5971
- let messages = messagesOrUndef.filter(isDefined);
5972
- // Messages in pages are ordered from oldest (first) to most recent (last).
5973
- // https://github.com/vacp2p/rfc/issues/533
5974
- if (typeof options?.pageDirection === "undefined" ||
5975
- options?.pageDirection === PageDirection.BACKWARD) {
5976
- messages = messages.reverse();
5977
- }
5978
- await Promise.all(messages.map(async (msg) => {
5979
- if (msg && !abort) {
5980
- abort = Boolean(await callback(msg));
5981
- }
5982
- }));
5983
5869
  }
5984
5870
  }
5985
5871
  /**
5986
5872
  * Do a query to a Waku Store to retrieve historical/missed messages.
5987
- *
5988
5873
  * The callback function takes a `Promise<WakuMessage>` in input,
5989
- * useful if messages needs to be decrypted and performance matters.
5874
+ * useful if messages need to be decrypted and performance matters.
5990
5875
  *
5991
5876
  * The order of the messages passed to the callback is as follows:
5992
5877
  * - within a page, messages are expected to be ordered from oldest to most recent
@@ -6000,18 +5885,18 @@ class Store extends BaseProtocol {
6000
5885
  * or if an error is encountered when processing the reply,
6001
5886
  * or if two decoders with the same content topic are passed.
6002
5887
  */
6003
- async queryCallbackOnPromise(decoders, callback, options) {
5888
+ async queryWithPromiseCallback(decoders, callback, options) {
6004
5889
  let abort = false;
6005
- let promises = [];
6006
5890
  for await (const page of this.queryGenerator(decoders, options)) {
6007
- const _promises = page.map(async (msg) => {
6008
- if (!abort) {
6009
- abort = Boolean(await callback(msg));
6010
- }
5891
+ const _promises = page.map(async (msgPromise) => {
5892
+ if (abort)
5893
+ return;
5894
+ abort = Boolean(await callback(msgPromise));
6011
5895
  });
6012
- promises = promises.concat(_promises);
5896
+ await Promise.all(_promises);
5897
+ if (abort)
5898
+ break;
6013
5899
  }
6014
- await Promise.all(promises);
6015
5900
  }
6016
5901
  /**
6017
5902
  * Do a query to a Waku Store to retrieve historical/missed messages.
@@ -6023,9 +5908,6 @@ class Store extends BaseProtocol {
6023
5908
  * as follows:
6024
5909
  * - within a page, messages SHOULD be ordered from oldest to most recent
6025
5910
  * - pages direction depends on { @link QueryOptions.pageDirection }
6026
- *
6027
- * However, there is no way to guarantee the behavior of the remote node.
6028
- *
6029
5911
  * @throws If not able to reach a Waku Store peer to query,
6030
5912
  * or if an error is encountered when processing the reply,
6031
5913
  * or if two decoders with the same content topic are passed.
@@ -6048,14 +5930,14 @@ class Store extends BaseProtocol {
6048
5930
  const queryOpts = Object.assign({
6049
5931
  pubSubTopic: pubSubTopic,
6050
5932
  pageDirection: PageDirection.BACKWARD,
6051
- pageSize: DefaultPageSize,
5933
+ pageSize: DefaultPageSize
6052
5934
  }, options, { contentTopics, startTime, endTime });
6053
- log$1("Querying history with the following options", {
6054
- ...options,
6055
- peerId: options?.peerId?.toString(),
6056
- });
6057
- const peer = await this.getPeer(options?.peerId);
6058
- for await (const messages of paginate(this.newStream.bind(this, peer), queryOpts, decodersAsMap, options?.cursor)) {
5935
+ log$1("Querying history with the following options", options);
5936
+ const peer = (await this.getPeers({
5937
+ numPeers: this.NUM_PEERS_PROTOCOL,
5938
+ maxBootstrapPeers: 1
5939
+ }))[0];
5940
+ for await (const messages of paginate(this.getStream.bind(this, peer), queryOpts, decodersAsMap, options?.cursor)) {
6059
5941
  yield messages;
6060
5942
  }
6061
5943
  }
@@ -6126,14 +6008,14 @@ async function createCursor(message, pubsubTopic = DefaultPubSubTopic) {
6126
6008
  !message.contentTopic) {
6127
6009
  throw new Error("Message is missing required fields");
6128
6010
  }
6129
- const contentTopicBytes = utf8ToBytes(message.contentTopic);
6130
- const digest = sha256(concat([contentTopicBytes, message.payload]));
6011
+ const contentTopicBytes = utf8ToBytes$1(message.contentTopic);
6012
+ const digest = sha256(concat$1([contentTopicBytes, message.payload]));
6131
6013
  const messageTime = BigInt(message.timestamp.getTime()) * BigInt(1000000);
6132
6014
  return {
6133
6015
  digest,
6134
6016
  pubsubTopic,
6135
6017
  senderTime: messageTime,
6136
- receiverTime: messageTime,
6018
+ receiverTime: messageTime
6137
6019
  };
6138
6020
  }
6139
6021
  function wakuStore(init = {}) {
@@ -6467,4 +6349,4 @@ function getEnabledProtocols(waku) {
6467
6349
  return protocols;
6468
6350
  }
6469
6351
 
6470
- export { ConnectionManager, DefaultPubSubTopic, DefaultUserAgent, KeepAliveManager, LightPushCodec, PageDirection, StoreCodec, WakuNode, createCursor, createEncoder, index$3 as message, waitForRemotePeer, waku, wakuFilter, wakuLightPush, wakuStore, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };
6352
+ export { ConnectionManager, DefaultPubSubTopic, DefaultUserAgent, FilterCodecs, KeepAliveManager, PageDirection, WakuNode, createCursor, createEncoder, index$3 as message, waitForRemotePeer, waku, wakuFilter, wakuLightPush, wakuStore, index$2 as waku_filter, index$1 as waku_light_push, index as waku_store };