@leofcoin/peernet 1.1.104 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- import { g as getDefaultExportFromCjs } from './identity-nIyW_Xm8.js';
1
+ import { g as getDefaultExportFromCjs } from './identity-B6BHwSTU.js';
2
2
 
3
3
  var browser$2 = {};
4
4
 
@@ -1,4 +1,4 @@
1
- import { g as getDefaultExportFromCjs } from './identity-nIyW_Xm8.js';
1
+ import { g as getDefaultExportFromCjs } from './identity-B6BHwSTU.js';
2
2
 
3
3
  var global;
4
4
  var hasRequiredGlobal;
@@ -1,5 +1,5 @@
1
- import { L as LittlePubSub } from './peernet-BsnqtUsa.js';
2
- import './identity-nIyW_Xm8.js';
1
+ import { L as LittlePubSub, d as deflate_1, c as createDebugger, i as inflate_1 } from './peernet-fcX5oKJJ.js';
2
+ import './identity-B6BHwSTU.js';
3
3
  import './value-C3vAp-wb.js';
4
4
 
5
5
  class Api {
@@ -231,7 +231,7 @@ class SocketRequestClient {
231
231
  const init = async () => {
232
232
  // @ts-ignore
233
233
  if (!globalThis.WebSocket && !this.#experimentalWebsocket)
234
- globalThis.WebSocket = (await import('./browser-CfYI-6aD.js').then(function (n) { return n.b; })).default.w3cwebsocket;
234
+ globalThis.WebSocket = (await import('./browser-DQlwTLRn.js').then(function (n) { return n.b; })).default.w3cwebsocket;
235
235
  const client = new WebSocket(this.#url, this.#protocol);
236
236
  if (this.#experimentalWebsocket) {
237
237
  client.addEventListener('error', this.onerror);
@@ -317,6 +317,17 @@ const defaultOptions = {
317
317
  connectEvent: 'peer:connected'
318
318
  };
319
319
 
320
+ // Simple CRC32 implementation
321
+ const crc32$1 = (data) => {
322
+ let crc = 0xffffffff;
323
+ for (let i = 0; i < data.length; i++) {
324
+ crc ^= data[i];
325
+ for (let j = 0; j < 8; j++) {
326
+ crc = (crc >>> 1) ^ (crc & 1 ? 0xedb88320 : 0);
327
+ }
328
+ }
329
+ return (crc ^ 0xffffffff) >>> 0;
330
+ };
320
331
  const iceServers = [
321
332
  {
322
333
  urls: 'stun:stun.l.google.com:19302' // Google's public STUN server
@@ -335,37 +346,81 @@ const iceServers = [
335
346
  credential: 'openrelayproject'
336
347
  }
337
348
  ];
338
- const SimplePeer = (await import('./index-DTbjK0sK.js').then(function (n) { return n.i; })).default;
349
+ const SimplePeer = (await import('./index-DYdP5D9L.js').then(function (n) { return n.i; })).default;
339
350
  class Peer extends SimplePeer {
340
351
  peerId;
341
352
  channelName;
342
353
  version;
354
+ compressionThreshold = 0.98;
343
355
  bw = { up: 0, down: 0 };
344
356
  get connected() {
345
357
  return super.connected;
346
358
  }
347
359
  constructor(options) {
348
- const { from, to, initiator, trickle, config, version } = options;
360
+ const { from, to, initiator, trickle, config, version, wrtc, compressionThreshold } = options;
349
361
  const channelName = initiator ? `${from}:${to}` : `${to}:${from}`;
350
362
  super({
351
363
  channelName,
352
364
  initiator,
353
- trickle: trickle || true,
365
+ trickle: trickle ?? true,
354
366
  config: { iceServers, ...config },
355
- wrtc: globalThis.wrtc
367
+ wrtc: wrtc ?? globalThis.wrtc
356
368
  });
357
369
  this.version = String(version);
358
370
  this.peerId = to;
359
371
  this.channelName = channelName;
372
+ if (compressionThreshold !== undefined)
373
+ this.compressionThreshold = compressionThreshold;
360
374
  }
361
375
  async #chunkit(data, id) {
362
376
  this.bw.up = data.length;
363
- const size = data.length;
377
+ // attempt compression; use compressed only if beneficial
378
+ let sendData = data;
379
+ try {
380
+ const c = deflate_1(data);
381
+ if (c?.length && c.length < data.length * this.compressionThreshold)
382
+ sendData = c;
383
+ }
384
+ catch (e) {
385
+ // ignore
386
+ }
387
+ const size = sendData.length;
388
+ const encodeFrame = (idStr, totalSize, index, count, payload, flags) => {
389
+ const te = new TextEncoder();
390
+ const idBytes = te.encode(idStr);
391
+ const crc = crc32$1(payload);
392
+ const headerLen = 1 + 1 + 4 + 4 + 4 + 4 + 2 + idBytes.length;
393
+ const buffer = new ArrayBuffer(headerLen + payload.length);
394
+ const view = new DataView(buffer);
395
+ const out = new Uint8Array(buffer);
396
+ let offset = 0;
397
+ view.setUint8(offset, 1); // version
398
+ offset += 1;
399
+ view.setUint8(offset, flags); // flags: bit0 chunked, bit1 compressed
400
+ offset += 1;
401
+ view.setUint32(offset, totalSize, true);
402
+ offset += 4;
403
+ view.setUint32(offset, index, true);
404
+ offset += 4;
405
+ view.setUint32(offset, count, true);
406
+ offset += 4;
407
+ view.setUint32(offset, crc, true); // CRC32
408
+ offset += 4;
409
+ view.setUint16(offset, idBytes.length, true);
410
+ offset += 2;
411
+ out.set(idBytes, offset);
412
+ offset += idBytes.length;
413
+ out.set(payload, offset);
414
+ return out;
415
+ };
364
416
  // no needles chunking, keep it simple, if data is smaller then max size just send it
365
- if (data.length <= MAX_MESSAGE_SIZE) {
366
- return super.send(JSON.stringify({ chunk: data, id, size: data.length }));
417
+ if (size <= MAX_MESSAGE_SIZE) {
418
+ const flags = ((size > MAX_MESSAGE_SIZE ? 1 : 0) << 0) |
419
+ ((sendData !== data ? 1 : 0) << 1);
420
+ super.send(encodeFrame(id, size, 0, 1, sendData, flags));
421
+ return;
367
422
  }
368
- async function* chunks(data) {
423
+ function* chunks(data) {
369
424
  while (data.length !== 0) {
370
425
  const amountToSlice = data.length >= MAX_MESSAGE_SIZE ? MAX_MESSAGE_SIZE : data.length;
371
426
  const subArray = data.subarray(0, amountToSlice);
@@ -381,8 +436,27 @@ class Peer extends SimplePeer {
381
436
  // data = data.subarray(amountToSlice, data.length)
382
437
  // super.send(JSON.stringify({ chunk: subArray, id, size }))
383
438
  // }
384
- for await (const chunk of chunks(data)) {
385
- super.send(JSON.stringify({ chunk, id, size }));
439
+ // backpressure-aware send loop with indexed chunks
440
+ const count = Math.ceil(size / MAX_MESSAGE_SIZE);
441
+ let index = 0;
442
+ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
443
+ const threshold = 4 * 1024 * 1024; // 4MB bufferedAmount threshold
444
+ const flags = (1 << 0) | ((sendData !== data ? 1 : 0) << 1);
445
+ for (const chunk of chunks(sendData)) {
446
+ // wait while channel is congested
447
+ // eslint-disable-next-line no-await-in-loop
448
+ while (
449
+ // @ts-ignore underlying channel is not part of public types
450
+ this._channel?.bufferedAmount > threshold) {
451
+ // if connection closed, abort
452
+ // eslint-disable-next-line no-await-in-loop
453
+ if (!this.connected)
454
+ return;
455
+ // eslint-disable-next-line no-await-in-loop
456
+ await sleep(10);
457
+ }
458
+ super.send(encodeFrame(id, size, index, count, chunk, flags));
459
+ index += 1;
386
460
  }
387
461
  }
388
462
  /**
@@ -402,12 +476,16 @@ class Peer extends SimplePeer {
402
476
  */
403
477
  request(data, id = crypto.randomUUID()) {
404
478
  return new Promise((resolve, reject) => {
405
- const timeout = setTimeout(() => reject(`request for ${id} timed out`), 30_000);
479
+ let timeout;
406
480
  const onrequest = ({ data }) => {
407
481
  clearTimeout(timeout);
408
482
  resolve(data);
409
483
  globalThis.pubsub.unsubscribe(id, onrequest);
410
484
  };
485
+ timeout = setTimeout(() => {
486
+ globalThis.pubsub.unsubscribe(id, onrequest);
487
+ reject(`request for ${id} timed out`);
488
+ }, 30_000);
411
489
  globalThis.pubsub.subscribe(id, onrequest);
412
490
  this.send(data, id);
413
491
  });
@@ -422,7 +500,18 @@ class Peer extends SimplePeer {
422
500
  }
423
501
  }
424
502
 
425
- const debug = globalThis.createDebugger('@netpeer/swarm/client');
503
+ // Simple CRC32 implementation
504
+ const crc32 = (data) => {
505
+ let crc = 0xffffffff;
506
+ for (let i = 0; i < data.length; i++) {
507
+ crc ^= data[i];
508
+ for (let j = 0; j < 8; j++) {
509
+ crc = (crc >>> 1) ^ (crc & 1 ? 0xedb88320 : 0);
510
+ }
511
+ }
512
+ return (crc ^ 0xffffffff) >>> 0;
513
+ };
514
+ const debug = createDebugger('@netpeer/swarm/client');
426
515
  class Client {
427
516
  #peerId;
428
517
  #connections = {};
@@ -527,7 +616,7 @@ class Client {
527
616
  }
528
617
  async _init() {
529
618
  if (!globalThis.RTCPeerConnection)
530
- globalThis.wrtc = (await import('./browser-Qcpp3EKK.js').then(function (n) { return n.b; })).default;
619
+ globalThis.wrtc = (await import('./browser-BHbuEZJu.js').then(function (n) { return n.b; })).default;
531
620
  for (const star of this.starsConfig) {
532
621
  try {
533
622
  await this.setupStar(star);
@@ -705,9 +794,12 @@ class Client {
705
794
  globalThis.pubsub.publishVerbose(this.#connectEvent, peer.peerId);
706
795
  };
707
796
  #noticeMessage = (message, id, from, peer) => {
797
+ const dataOut = message instanceof Uint8Array
798
+ ? message
799
+ : new Uint8Array(Object.values(message));
708
800
  if (globalThis.pubsub.subscribers[id]) {
709
801
  globalThis.pubsub.publish(id, {
710
- data: new Uint8Array(Object.values(message)),
802
+ data: dataOut,
711
803
  id,
712
804
  from,
713
805
  peer
@@ -715,7 +807,7 @@ class Client {
715
807
  }
716
808
  else {
717
809
  globalThis.pubsub.publish('peer:data', {
718
- data: new Uint8Array(Object.values(message)),
810
+ data: dataOut,
719
811
  id,
720
812
  from,
721
813
  peer
@@ -723,22 +815,124 @@ class Client {
723
815
  }
724
816
  };
725
817
  #peerData = (peer, data) => {
726
- const { id, size, chunk } = JSON.parse(new TextDecoder().decode(data));
727
- peer.bw.down += size;
728
- if (size <= MAX_MESSAGE_SIZE) {
729
- this.#noticeMessage(chunk, id, peer.peerId, peer);
818
+ const tryJson = () => {
819
+ const parsed = JSON.parse(new TextDecoder().decode(data));
820
+ const { id, size, chunk, index, count } = parsed;
821
+ chunk ? Object.values(chunk).length : size;
822
+ return {
823
+ id,
824
+ size: Number(size),
825
+ index: Number(index ?? 0),
826
+ count: Number(count ?? 1),
827
+ chunk: new Uint8Array(Object.values(chunk)),
828
+ flags: 0,
829
+ crc: 0
830
+ };
831
+ };
832
+ const decodeBinary = () => {
833
+ let u8;
834
+ if (typeof data === 'string') {
835
+ // should not happen when sending binary, fallback to JSON
836
+ return tryJson();
837
+ }
838
+ else if (data instanceof ArrayBuffer) {
839
+ u8 = new Uint8Array(data);
840
+ }
841
+ else if (ArrayBuffer.isView(data)) {
842
+ const view = data;
843
+ const byteOffset = view.byteOffset || 0;
844
+ const byteLength = view.byteLength || data.length;
845
+ u8 = new Uint8Array(view.buffer, byteOffset, byteLength);
846
+ }
847
+ else if (data?.buffer) {
848
+ u8 = new Uint8Array(data.buffer);
849
+ }
850
+ else {
851
+ // last resort: attempt JSON
852
+ return tryJson();
853
+ }
854
+ const dv = new DataView(u8.buffer, u8.byteOffset, u8.byteLength);
855
+ let offset = 0;
856
+ dv.getUint8(offset);
857
+ offset += 1;
858
+ const flags = dv.getUint8(offset);
859
+ offset += 1;
860
+ const size = dv.getUint32(offset, true);
861
+ offset += 4;
862
+ const index = dv.getUint32(offset, true);
863
+ offset += 4;
864
+ const count = dv.getUint32(offset, true);
865
+ offset += 4;
866
+ const expectedCrc = dv.getUint32(offset, true);
867
+ offset += 4;
868
+ const idLen = dv.getUint16(offset, true);
869
+ offset += 2;
870
+ const idBytes = u8.subarray(offset, offset + idLen);
871
+ offset += idLen;
872
+ const id = new TextDecoder().decode(idBytes);
873
+ const chunk = u8.subarray(offset);
874
+ return { id, size, index, count, chunk, flags, crc: expectedCrc };
875
+ };
876
+ const frame = decodeBinary();
877
+ peer.bw.down += frame.chunk.length;
878
+ // Single frame path: if compressed, inflate before publish
879
+ if (frame.count === 1) {
880
+ let payload = frame.chunk;
881
+ const compressed = Boolean(frame.flags & (1 << 1));
882
+ if (compressed) {
883
+ const actualCrc = crc32(payload);
884
+ if (actualCrc !== frame.crc) {
885
+ console.warn(`CRC mismatch: expected ${frame.crc}, got ${actualCrc}`);
886
+ }
887
+ try {
888
+ payload = inflate_1(payload);
889
+ }
890
+ catch (e) {
891
+ console.warn('inflate failed, passing compressed payload');
892
+ }
893
+ }
894
+ this.#noticeMessage(payload, frame.id, peer.peerId, peer);
895
+ return;
730
896
  }
731
- else {
732
- if (!this.#messagesToHandle[id])
733
- this.#messagesToHandle[id] = [];
734
- this.#messagesToHandle[id] = [
735
- ...this.#messagesToHandle[id],
736
- ...Object.values(chunk)
737
- ];
738
- if (this.#messagesToHandle[id].length === Number(size)) {
739
- this.#noticeMessage(this.#messagesToHandle[id], id, peer.peerId, peer);
740
- delete this.#messagesToHandle[id];
897
+ // Chunked message handling with indexed reassembly
898
+ if (!this.#messagesToHandle[frame.id] ||
899
+ Array.isArray(this.#messagesToHandle[frame.id])) {
900
+ this.#messagesToHandle[frame.id] = {
901
+ chunks: new Array(frame.count),
902
+ receivedBytes: 0,
903
+ expectedSize: Number(frame.size),
904
+ expectedCount: Number(frame.count)
905
+ };
906
+ }
907
+ const state = this.#messagesToHandle[frame.id];
908
+ // Verify CRC for this chunk
909
+ const actualCrc = crc32(frame.chunk);
910
+ if (actualCrc !== frame.crc) {
911
+ console.warn(`Chunk CRC mismatch for ${frame.id}[${frame.index}]: expected ${frame.crc}, got ${actualCrc}`);
912
+ }
913
+ state.chunks[frame.index] = frame.chunk;
914
+ state.receivedBytes += frame.chunk.length;
915
+ // If all chunks present and total size matches, reassemble
916
+ const allPresent = state.chunks.every((c) => c instanceof Uint8Array);
917
+ if (allPresent && state.receivedBytes === state.expectedSize) {
918
+ const result = new Uint8Array(state.expectedSize);
919
+ let offset2 = 0;
920
+ for (const c of state.chunks) {
921
+ result.set(c, offset2);
922
+ offset2 += c.length;
923
+ }
924
+ let payload = result;
925
+ const compressed = Boolean(frame.flags & (1 << 1));
926
+ if (compressed) {
927
+ try {
928
+ payload = inflate_1(result);
929
+ }
930
+ catch (e) {
931
+ console.warn('inflate failed, passing compressed payload');
932
+ }
741
933
  }
934
+ this.#noticeMessage(payload, frame.id, peer.peerId, peer);
935
+ delete this.#messagesToHandle[frame.id];
742
936
  }
743
937
  };
744
938
  #peerError = (peer, error) => {
@@ -17150,7 +17150,7 @@ class Identity {
17150
17150
  this.selectedAccount = new TextDecoder().decode(selected);
17151
17151
  }
17152
17152
  else {
17153
- const importee = await import(/* webpackChunkName: "generate-account" */ './index-ChRjMyiM.js');
17153
+ const importee = await import(/* webpackChunkName: "generate-account" */ '@leofcoin/generate-account');
17154
17154
  const { identity, accounts } = await importee.default(password, this.network);
17155
17155
  await globalThis.accountStore.put('public', JSON.stringify({ walletId: identity.walletId }));
17156
17156
  await globalThis.walletStore.put('version', String(1));
@@ -17196,4 +17196,4 @@ class Identity {
17196
17196
  }
17197
17197
  }
17198
17198
 
17199
- export { Identity as I, MultiWallet as M, base58$1 as a, base$1 as b, index$3 as c, index$2 as d, index$4 as e, encrypt as f, getDefaultExportFromCjs as g, commonjsGlobal as h, index$5 as i, requireInherits_browser as j, require$$3 as r };
17199
+ export { Identity as I, base58$1 as a, base$1 as b, index$3 as c, index$2 as d, index$4 as e, commonjsGlobal as f, getDefaultExportFromCjs as g, requireInherits_browser as h, index$5 as i, require$$3 as r };
@@ -1 +1 @@
1
- export { I as default } from './identity-nIyW_Xm8.js';
1
+ export { I as default } from './identity-B6BHwSTU.js';
@@ -1,4 +1,4 @@
1
- import { h as commonjsGlobal, r as require$$3, j as requireInherits_browser, g as getDefaultExportFromCjs } from './identity-nIyW_Xm8.js';
1
+ import { f as commonjsGlobal, r as require$$3, h as requireInherits_browser, g as getDefaultExportFromCjs } from './identity-B6BHwSTU.js';
2
2
  import require$$0 from 'events';
3
3
 
4
4
  var browser$2 = {exports: {}};
@@ -1,5 +1,5 @@
1
- import { F as FormatInterface } from './peernet-BsnqtUsa.js';
2
- import './identity-nIyW_Xm8.js';
1
+ import { F as FormatInterface } from './peernet-fcX5oKJJ.js';
2
+ import './identity-B6BHwSTU.js';
3
3
  import './value-C3vAp-wb.js';
4
4
 
5
5
  var proto$b = {
@@ -1,42 +1,31 @@
1
- import { b as base, a as base58$1, i as index$2, c as index$3, d as index$4, e as index$5, I as Identity } from './identity-nIyW_Xm8.js';
1
+ import { b as base, a as base58$1, i as index$2, c as index$3, d as index$4, e as index$5, I as Identity } from './identity-B6BHwSTU.js';
2
2
  import { K as KeyPath, a as KeyValue } from './value-C3vAp-wb.js';
3
3
 
4
- if (!globalThis.DEBUG) {
5
- globalThis.DEBUG = [];
6
- if (globalThis.localStorage) {
7
- const DEBUG = globalThis.localStorage.getItem("DEBUG");
8
- if (DEBUG) {
9
- globalThis.DEBUG = DEBUG.startsWith("[")
10
- ? JSON.parse(DEBUG).split(",")
11
- : [DEBUG];
12
- }
13
- }
14
- }
4
+ const getTargets = () => Array.from([]);
5
+ const isEnabled = (target) => {
6
+ return false;
7
+ };
15
8
 
16
9
  const getLogger = (trace) => (trace ? console.trace : console.log);
17
-
18
- const debug$1 = (target, text, trace) => {
19
- const _logger = getLogger(trace);
20
- if (!globalThis.DEBUG || globalThis.DEBUG?.length === 0) return;
21
- if (
22
- globalThis.DEBUG === "true" ||
23
- globalThis.DEBUG === true ||
24
- globalThis.DEBUG?.indexOf(target) !== -1 ||
25
- globalThis.DEBUG?.indexOf("*") !== -1 ||
26
- globalThis.DEBUG?.indexOf(target.split("/")[0]) !== -1
27
- )
28
- if (text) _logger("\x1b[34m\x1b[1m%s", `${target}: ${text}`, "\x1b[0m");
29
- else _logger("\x1b[34m\x1b[1m%s", `${target}`, "\x1b[0m");
10
+ const createDebugger = (target) => {
11
+ // Cache the enabled check on first call
12
+ let enabled = null;
13
+ let lastTargets = undefined;
14
+ return (text, trace) => {
15
+ const targets = getTargets();
16
+ if (lastTargets !== targets) {
17
+ enabled = targets ? isEnabled() : false;
18
+ lastTargets = targets;
19
+ }
20
+ if (!enabled)
21
+ return;
22
+ if (text)
23
+ getLogger(trace)('\x1b[34m\x1b[1m%s', `${target}: ${text}`, '\x1b[0m');
24
+ else
25
+ getLogger(trace)('\x1b[34m\x1b[1m%s', `${target}`, '\x1b[0m');
26
+ };
30
27
  };
31
28
 
32
- const createDebugger = (target) => (text) => debug$1(target, text);
33
-
34
- if (!globalThis.debug) {
35
- globalThis.debug = debug$1;
36
- // todo: deprecate
37
- globalThis.createDebugger = createDebugger;
38
- }
39
-
40
29
  class LittlePubSub {
41
30
  subscribers = {};
42
31
  verbose;
@@ -8222,7 +8211,7 @@ globalThis.LeofcoinStorage = LeofcoinStorage$1;
8222
8211
  globalThis.leofcoin = globalThis.leofcoin || {};
8223
8212
  globalThis.pubsub = globalThis.pubsub || new LittlePubSub();
8224
8213
  globalThis.globalSub = globalThis.globalSub || new LittlePubSub();
8225
- const debug = globalThis.createDebugger('peernet');
8214
+ const debug = createDebugger('peernet');
8226
8215
  /**
8227
8216
  * @access public
8228
8217
  * @example
@@ -8366,7 +8355,7 @@ class Peernet {
8366
8355
  this.root = options.root;
8367
8356
  const { RequestMessage, ResponseMessage, PeerMessage, PeerMessageResponse, PeernetMessage, DHTMessage, DHTMessageResponse, DataMessage, DataMessageResponse, PsMessage, ChatMessage, PeernetFile
8368
8357
  // FolderMessageResponse
8369
- } = await import(/* webpackChunkName: "messages" */ './messages-C22qRxnF.js');
8358
+ } = await import(/* webpackChunkName: "messages" */ './messages-CiR1YiV5.js');
8370
8359
  /**
8371
8360
  * proto Object containing protos
8372
8361
  * @type {Object}
@@ -8460,7 +8449,7 @@ class Peernet {
8460
8449
  if (this.#starting || this.#started)
8461
8450
  return;
8462
8451
  this.#starting = true;
8463
- const importee = await import('./client-Lwke64Zq.js');
8452
+ const importee = await import('./client-DCeU_UX5.js');
8464
8453
  /**
8465
8454
  * @access public
8466
8455
  * @type {PeernetClient}
@@ -8980,4 +8969,4 @@ class Peernet {
8980
8969
  }
8981
8970
  globalThis.Peernet = Peernet;
8982
8971
 
8983
- export { FormatInterface as F, LittlePubSub as L, Peernet as P };
8972
+ export { FormatInterface as F, LittlePubSub as L, Peernet as P, createDebugger as c, deflate_1 as d, inflate_1 as i };
@@ -1,4 +1,3 @@
1
- import '@vandeurenglenn/debug';
2
1
  import PubSub from '@vandeurenglenn/little-pubsub';
3
2
  import PeerDiscovery from './discovery/peer-discovery.js';
4
3
  import DHT from './dht/dht.js';
@@ -1,3 +1,3 @@
1
- export { P as default } from './peernet-BsnqtUsa.js';
2
- import './identity-nIyW_Xm8.js';
1
+ export { P as default } from './peernet-fcX5oKJJ.js';
2
+ import './identity-B6BHwSTU.js';
3
3
  import './value-C3vAp-wb.js';
@@ -1,4 +1,4 @@
1
- import '@vandeurenglenn/debug';
1
+ import { createDebugger } from '@vandeurenglenn/debug';
2
2
  import PubSub from '@vandeurenglenn/little-pubsub';
3
3
  import { Codec } from '@leofcoin/codec-format-interface';
4
4
  import { Storage } from '@leofcoin/storage';
@@ -303,7 +303,7 @@ globalThis.LeofcoinStorage = Storage;
303
303
  globalThis.leofcoin = globalThis.leofcoin || {};
304
304
  globalThis.pubsub = globalThis.pubsub || new PubSub();
305
305
  globalThis.globalSub = globalThis.globalSub || new PubSub();
306
- const debug = globalThis.createDebugger('peernet');
306
+ const debug = createDebugger('peernet');
307
307
  /**
308
308
  * @access public
309
309
  * @example
@@ -1,4 +1,3 @@
1
- import '@vandeurenglenn/debug';
2
1
  import PubSub from '@vandeurenglenn/little-pubsub';
3
2
  import PeerDiscovery from './discovery/peer-discovery.js';
4
3
  import DHT from './dht/dht.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@leofcoin/peernet",
3
- "version": "1.1.104",
3
+ "version": "1.2.0",
4
4
  "description": "",
5
5
  "browser": "./exports/browser/peernet.js",
6
6
  "exports": {
@@ -23,7 +23,7 @@
23
23
  "scripts": {
24
24
  "build": "rollup -c",
25
25
  "watch": "rollup -c -w",
26
- "test": "npx mocha test/peernet.test.ts",
26
+ "test": "node --test test/peernet.test.js",
27
27
  "server": "discovery-swarm-webrtc --port=4000",
28
28
  "demo": "jsproject --serve ./ --port 6868"
29
29
  },
@@ -33,38 +33,25 @@
33
33
  "dependencies": {
34
34
  "@leofcoin/codec-format-interface": "^1.7.14",
35
35
  "@leofcoin/codecs": "^1.0.7",
36
- "@leofcoin/generate-account": "^2.0.3",
37
36
  "@leofcoin/identity-utils": "^1.0.2",
38
37
  "@leofcoin/multi-wallet": "^3.1.8",
39
38
  "@leofcoin/storage": "^3.5.38",
40
- "@netpeer/swarm": "^0.8.32",
41
- "@vandeurenglenn/base32": "^1.2.4",
39
+ "@netpeer/swarm": "^0.9.0",
42
40
  "@vandeurenglenn/base58": "^1.1.9",
43
- "@vandeurenglenn/debug": "^1.2.6",
44
- "@vandeurenglenn/is-hex": "^1.1.1",
41
+ "@vandeurenglenn/debug": "^1.4.0",
45
42
  "@vandeurenglenn/little-pubsub": "^1.5.1",
46
- "inquirer": "^13.0.1",
47
- "multi-signature": "^1.3.1",
43
+ "inquirer": "^13.1.0",
48
44
  "qr-scanner": "^1.4.2",
49
- "qrcode": "^1.5.4",
50
- "socket-request-client": "^2.1.2",
51
- "socket-request-server": "^1.7.2"
45
+ "qrcode": "^1.5.4"
52
46
  },
53
47
  "devDependencies": {
54
- "@jest/globals": "^30.2.0",
55
48
  "@rollup/plugin-commonjs": "^29.0.0",
56
49
  "@rollup/plugin-json": "^6.1.0",
57
50
  "@rollup/plugin-node-resolve": "^16.0.3",
58
51
  "@rollup/plugin-typescript": "^12.3.0",
59
52
  "@rollup/plugin-wasm": "^6.2.2",
60
- "@types/bs58check": "^3.0.1",
61
- "@types/node": "^24.10.1",
53
+ "@types/node": "^25.0.3",
62
54
  "@types/qrcode": "^1.5.6",
63
- "@types/secp256k1": "^4.0.7",
64
- "@types/varint": "^6.0.3",
65
- "chai": "^6.2.1",
66
- "cross-env": "^10.1.0",
67
- "rollup": "^4.53.3",
68
- "sinon": "^21.0.0"
55
+ "rollup": "^4.54.0"
69
56
  }
70
57
  }
package/src/peernet.ts CHANGED
@@ -1,4 +1,4 @@
1
- import '@vandeurenglenn/debug'
1
+ import { createDebugger } from '@vandeurenglenn/debug'
2
2
  import PubSub from '@vandeurenglenn/little-pubsub'
3
3
  import PeerDiscovery from './discovery/peer-discovery.js'
4
4
  import DHT, { DHTProvider, DHTProviderDistanceResult, getAddress } from './dht/dht.js'
@@ -30,7 +30,7 @@ declare global {
30
30
  var chainStore: LeofcoinStorageClass
31
31
  }
32
32
 
33
- const debug = globalThis.createDebugger('peernet')
33
+ const debug = createDebugger('peernet')
34
34
  /**
35
35
  * @access public
36
36
  * @example
@@ -1,159 +1,45 @@
1
+ import test from 'node:test'
2
+ import assert from 'node:assert/strict'
3
+
1
4
  import Peernet from '../exports/peernet.js'
2
5
  import Identity from '../exports/identity.js'
3
- import { expect } from 'chai'
4
- import sinon from 'sinon'
5
- import networks from '@leofcoin/networks'
6
-
7
- const network = networks.leofcoin.peach
8
6
 
9
- let options
10
- let password
11
- options = {
7
+ const options = {
12
8
  network: 'leofcoin:peach',
13
- stars: network.stars,
9
+ stars: [],
14
10
  root: '.testnet',
15
11
  version: '1.0.0',
16
- storePrefix: 'test'
12
+ storePrefix: 'test',
13
+ autoStart: false
17
14
  }
18
- password = 'password'
19
- const peernet = await new Peernet(options, password)
20
-
21
- describe('Peernet', async () => {
22
- // beforeEach(async () => {
23
- // })
24
-
25
- it('should initialize with the correct network', () => {
26
- expect(peernet.network).to.equal('leofcoin:peach')
27
- })
28
-
29
- it('should initialize with the correct version', () => {
30
- expect(peernet.version).to.equal('1.0.0')
31
- })
32
-
33
- it('should initialize with the correct store prefix', () => {
34
- expect(peernet.storePrefix).to.equal('test')
35
- })
36
-
37
- it('should have an identity instance', () => {
38
- expect(peernet.identity).to.be.instanceOf(Identity)
39
- })
40
-
41
- it('should have a DHT instance', () => {
42
- expect(peernet.dht).to.not.be.undefined
43
- })
44
-
45
- it('should start the client', async () => {
46
- const startSpy = sinon.spy(peernet, 'start')
47
- await peernet.start()
48
- expect(startSpy.calledOnce).to.be.true
49
- })
50
-
51
- it('should add a proto', () => {
52
- const protoName = 'test-proto'
53
- const proto = {}
54
- peernet.addProto(protoName, proto)
55
- expect(globalThis.peernet.protos[protoName]).to.equal(proto)
56
- })
57
-
58
- it('should add a codec', () => {
59
- const codec = { name: 'test-codec' }
60
- const addCodecSpy = sinon.spy(peernet, 'addCodec')
61
- peernet.addCodec(codec)
62
- expect(addCodecSpy.calledOnceWith(codec)).to.be.true
63
- })
64
-
65
- it('should select an account', async () => {
66
- const account = 'test-account'
67
- const selectAccountSpy = sinon.spy(peernet.identity, 'selectAccount')
68
- await peernet.selectAccount(account)
69
- expect(selectAccountSpy.calledOnceWith(account)).to.be.true
70
- })
71
15
 
72
- it('should prepare a message', () => {
73
- const data = { message: 'test' }
74
- const prepareMessageSpy = sinon.spy(peernet._messageHandler, 'prepareMessage')
75
- peernet.prepareMessage(data)
76
- expect(prepareMessageSpy.calledOnceWith(data)).to.be.true
77
- })
78
-
79
- it('should get peers', () => {
80
- const peers = peernet.peers
81
- expect(peers).to.be.an('array')
82
- })
83
-
84
- it('should get connections', () => {
85
- const connections = peernet.connections
86
- expect(connections).to.be.an('object')
87
- })
88
-
89
- it('should get a connection by id', () => {
90
- const id = 'test-id'
91
- const connection = peernet.getConnection(id)
92
- expect(connection).to.be.undefined // Assuming no connections are established in the test
93
- })
94
-
95
- // it('should handle DHT', async () => {
96
- // const peer = {}
97
- // const id = 'test-id'
98
- // const proto = { decoded: { hash: 'test-hash', store: 'test-store' } }
99
- // const handleDHTSpy = sinon.spy(peernet, 'handleDHT')
100
- // await peernet.handleDHT(peer, id, proto)
101
- // expect(handleDHTSpy.calledOnceWith(peer, id, proto)).to.be.true
102
- // })
103
-
104
- it('should handle data', async () => {
105
- const peer = {}
106
- const id = 'test-id'
107
- const proto = { decoded: { hash: 'test-hash', store: 'test-store' } }
108
- const handleDataSpy = sinon.spy(peernet, 'handleData')
109
- await peernet.handleData(peer, id, proto)
110
- expect(handleDataSpy.calledOnceWith(peer, id, proto)).to.be.true
111
- })
112
-
113
- it('should handle request', async () => {
114
- const peer = {}
115
- const id = 'test-id'
116
- const proto = { decoded: { request: 'test-request' } }
117
- const handleRequestSpy = sinon.spy(peernet, 'handleRequest')
118
- await peernet.handleRequest(peer, id, proto)
119
- expect(handleRequestSpy.calledOnceWith(peer, id, proto)).to.be.true
120
- })
121
-
122
- it('should walk the network', async () => {
123
- const hash = 'test-hash'
124
- const walkSpy = sinon.spy(peernet, 'walk')
125
- await peernet.walk(hash)
126
- expect(walkSpy.calledOnceWith(hash)).to.be.true
127
- })
16
+ const password = 'password'
17
+ const peernet = await new Peernet(options, password)
128
18
 
129
- // it('should find providers for a hash', async () => {
130
- // const hash = 'test-hash'
131
- // const providers = await peernet.providersFor(hash)
132
- // expect(providers).to.be.undefined // Assuming no providers are found in the test
133
- // })
19
+ test('initializes with provided options', () => {
20
+ assert.equal(peernet.network, options.network)
21
+ assert.equal(peernet.version, options.version)
22
+ assert.equal(peernet.storePrefix, options.storePrefix)
23
+ })
134
24
 
135
- // it('should request data', async () => {
136
- // const hash = 'test-hash'
137
- // const requestDataSpy = sinon.spy(peernet, 'requestData')
138
- // await peernet.requestData(hash, 'data')
139
- // expect(requestDataSpy.calledOnceWith(hash, 'data')).to.be.true
140
- // })
25
+ test('exposes identity instance', () => {
26
+ assert.ok(peernet.identity instanceof Identity)
27
+ })
141
28
 
142
- it('should publish data', async () => {
143
- const topic = 'test-topic'
144
- const data = 'test-data'
145
- const publishSpy = sinon.spy(peernet, 'publish')
146
- await peernet.publish(topic, data)
147
- expect(publishSpy.calledOnceWith(topic, data)).to.be.true
148
- })
29
+ test('has a DHT instance', () => {
30
+ assert.ok(peernet.dht)
31
+ })
149
32
 
150
- it('should subscribe to a topic', async () => {
151
- const topic = 'test-topic'
152
- const callback = sinon.spy()
153
- const subscribeSpy = sinon.spy(peernet, 'subscribe')
154
- await peernet.subscribe(topic, callback)
155
- expect(subscribeSpy.calledOnceWith(topic, callback)).to.be.true
33
+ test('returns peers and connections safely', () => {
34
+ assert.deepEqual(peernet.peers, [])
35
+ assert.deepEqual(peernet.connections, {})
36
+ assert.equal(peernet.getConnection('missing'), undefined)
37
+ })
156
38
 
157
- process.exit()
158
- })
39
+ test('provides callable helpers', () => {
40
+ assert.equal(typeof peernet.addProto, 'function')
41
+ assert.equal(typeof peernet.addCodec, 'function')
42
+ assert.equal(typeof peernet.prepareMessage, 'function')
43
+ assert.equal(typeof peernet.publish, 'function')
44
+ assert.equal(typeof peernet.subscribe, 'function')
159
45
  })
@@ -1,36 +0,0 @@
1
- import { M as MultiWallet, f as encrypt, a as base58$1 } from './identity-nIyW_Xm8.js';
2
-
3
- /**
4
- * @params {String} network
5
- * @return {object} { identity, accounts, config }
6
- */
7
- var index = async (password, network) => {
8
- if (!password)
9
- throw new Error('wallets need to be password protected.');
10
- let wallet = new MultiWallet(network);
11
- /**
12
- * @type {string}
13
- */
14
- let mnemonic = await wallet.generate(password);
15
- wallet = new MultiWallet(network);
16
- await wallet.recover(mnemonic, password, network);
17
- mnemonic = new Uint8Array(await encrypt(password, mnemonic));
18
- const multiWIF = new Uint8Array(await encrypt(password, await wallet.multiWIF));
19
- /**
20
- * @type {object}
21
- */
22
- const external = await wallet.account(1).external(1);
23
- const externalAddress = await external.address;
24
- const internal = await wallet.account(1).internal(1);
25
- const internalAddress = await internal.address;
26
- return {
27
- identity: {
28
- mnemonic: base58$1.encode(mnemonic),
29
- multiWIF: base58$1.encode(multiWIF),
30
- walletId: await external.id
31
- },
32
- accounts: [['main account', externalAddress, internalAddress]]
33
- };
34
- };
35
-
36
- export { index as default };