@fairfox/polly 0.22.0 → 0.24.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.
Files changed (36) hide show
  1. package/README.md +55 -1
  2. package/dist/src/elysia/index.js +5 -3
  3. package/dist/src/elysia/index.js.map +3 -3
  4. package/dist/src/elysia/peer-repo-plugin.d.ts +1 -1
  5. package/dist/src/mesh-node.d.ts +89 -0
  6. package/dist/src/mesh-node.js +594 -0
  7. package/dist/src/mesh-node.js.map +14 -0
  8. package/dist/src/mesh.d.ts +10 -0
  9. package/dist/src/mesh.js +926 -24
  10. package/dist/src/mesh.js.map +17 -9
  11. package/dist/src/peer.d.ts +1 -0
  12. package/dist/src/peer.js +108 -85
  13. package/dist/src/peer.js.map +11 -10
  14. package/dist/src/shared/lib/blob-cache.d.ts +58 -0
  15. package/dist/src/shared/lib/blob-store-impl.d.ts +33 -0
  16. package/dist/src/shared/lib/blob-store.d.ts +87 -0
  17. package/dist/src/shared/lib/blob-transfer.d.ts +58 -0
  18. package/dist/src/shared/lib/crdt-specialised.d.ts +1 -1
  19. package/dist/src/shared/lib/crdt-state.d.ts +1 -1
  20. package/dist/src/shared/lib/keyring-storage.d.ts +57 -0
  21. package/dist/src/shared/lib/mesh-client.d.ts +91 -0
  22. package/dist/src/shared/lib/mesh-network-adapter.d.ts +1 -1
  23. package/dist/src/shared/lib/mesh-signaling-client.d.ts +6 -0
  24. package/dist/src/shared/lib/mesh-state.d.ts +1 -1
  25. package/dist/src/shared/lib/mesh-webrtc-adapter.d.ts +20 -1
  26. package/dist/src/shared/lib/peer-relay-adapter.d.ts +1 -1
  27. package/dist/src/shared/lib/peer-repo-server.d.ts +1 -1
  28. package/dist/src/shared/lib/peer-state.d.ts +1 -1
  29. package/dist/src/shared/lib/wasm-init.d.ts +17 -0
  30. package/dist/tools/quality/src/cli.js +98 -47
  31. package/dist/tools/quality/src/cli.js.map +4 -4
  32. package/dist/tools/quality/src/index.d.ts +25 -0
  33. package/dist/tools/quality/src/index.js +196 -0
  34. package/dist/tools/quality/src/index.js.map +10 -0
  35. package/dist/tools/quality/src/no-as-casting.d.ts +44 -0
  36. package/package.json +22 -2
@@ -11,6 +11,7 @@
11
11
  * import { $peerState, configurePeerState } from "@fairfox/polly/peer";
12
12
  * ```
13
13
  */
14
+ import "./shared/lib/wasm-init";
14
15
  export type { CounterDoc, CrdtCounterOptions, CrdtListOptions, CrdtTextOptions, ListDoc, SpecialisedPrimitive, TextDoc, } from "./shared/lib/crdt-specialised";
15
16
  export { $crdtCounter, $crdtList, $crdtText } from "./shared/lib/crdt-specialised";
16
17
  export type { CrdtPrimitive, CrdtStateOptions } from "./shared/lib/crdt-state";
package/dist/src/peer.js CHANGED
@@ -44,8 +44,107 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
44
44
  throw Error('Dynamic require of "' + x + '" is not supported');
45
45
  });
46
46
 
47
+ // src/shared/lib/encryption.ts
48
+ var exports_encryption = {};
49
+ __export(exports_encryption, {
50
+ sealEnvelope: () => sealEnvelope,
51
+ openEnvelope: () => openEnvelope,
52
+ generateDocumentKey: () => generateDocumentKey,
53
+ encrypt: () => encrypt,
54
+ encodeEncryptedEnvelope: () => encodeEncryptedEnvelope,
55
+ decryptOrThrow: () => decryptOrThrow,
56
+ decrypt: () => decrypt,
57
+ decodeEncryptedEnvelope: () => decodeEncryptedEnvelope,
58
+ TAG_BYTES: () => TAG_BYTES,
59
+ NONCE_BYTES: () => NONCE_BYTES,
60
+ KEY_BYTES: () => KEY_BYTES,
61
+ EncryptionError: () => EncryptionError
62
+ });
63
+ import nacl from "tweetnacl";
64
+ function generateDocumentKey() {
65
+ return nacl.randomBytes(KEY_BYTES);
66
+ }
67
+ function encrypt(payload, key) {
68
+ if (key.length !== KEY_BYTES) {
69
+ throw new EncryptionError(`secretbox key must be ${KEY_BYTES} bytes, got ${key.length}.`, "invalid-key-length");
70
+ }
71
+ const nonce = nacl.randomBytes(NONCE_BYTES);
72
+ const ciphertext = nacl.secretbox(payload, nonce, key);
73
+ const out = new Uint8Array(NONCE_BYTES + ciphertext.length);
74
+ out.set(nonce, 0);
75
+ out.set(ciphertext, NONCE_BYTES);
76
+ return out;
77
+ }
78
+ function decrypt(sealed, key) {
79
+ if (key.length !== KEY_BYTES) {
80
+ throw new EncryptionError(`secretbox key must be ${KEY_BYTES} bytes, got ${key.length}.`, "invalid-key-length");
81
+ }
82
+ if (sealed.length < NONCE_BYTES + TAG_BYTES) {
83
+ return;
84
+ }
85
+ const nonce = sealed.subarray(0, NONCE_BYTES);
86
+ const ciphertext = sealed.subarray(NONCE_BYTES);
87
+ const opened = nacl.secretbox.open(ciphertext, nonce, key);
88
+ return opened ?? undefined;
89
+ }
90
+ function decryptOrThrow(sealed, key) {
91
+ const opened = decrypt(sealed, key);
92
+ if (!opened) {
93
+ throw new EncryptionError(`Failed to decrypt sealed blob: wrong key, malformed input, or tampered ciphertext.`, "decrypt-failed");
94
+ }
95
+ return opened;
96
+ }
97
+ function sealEnvelope(payload, documentId, key) {
98
+ return {
99
+ documentId,
100
+ sealed: encrypt(payload, key)
101
+ };
102
+ }
103
+ function openEnvelope(envelope, key) {
104
+ return decryptOrThrow(envelope.sealed, key);
105
+ }
106
+ function encodeEncryptedEnvelope(envelope) {
107
+ const idBytes = new TextEncoder().encode(envelope.documentId);
108
+ const out = new Uint8Array(4 + idBytes.length + envelope.sealed.length);
109
+ const view = new DataView(out.buffer);
110
+ view.setUint32(0, idBytes.length, false);
111
+ out.set(idBytes, 4);
112
+ out.set(envelope.sealed, 4 + idBytes.length);
113
+ return out;
114
+ }
115
+ function decodeEncryptedEnvelope(bytes) {
116
+ if (bytes.length < 4) {
117
+ throw new EncryptionError(`Encrypted envelope too short: ${bytes.length} bytes.`, "envelope-malformed");
118
+ }
119
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
120
+ const idLen = view.getUint32(0, false);
121
+ if (bytes.length < 4 + idLen) {
122
+ throw new EncryptionError(`Encrypted envelope truncated: declared id length ${idLen}, total ${bytes.length}.`, "envelope-malformed");
123
+ }
124
+ const documentId = new TextDecoder().decode(bytes.subarray(4, 4 + idLen));
125
+ const sealed = bytes.slice(4 + idLen);
126
+ return { documentId, sealed };
127
+ }
128
+ var KEY_BYTES = 32, NONCE_BYTES = 24, TAG_BYTES = 16, EncryptionError;
129
+ var init_encryption = __esm(() => {
130
+ EncryptionError = class EncryptionError extends Error {
131
+ code;
132
+ constructor(message, code) {
133
+ super(message);
134
+ this.name = "EncryptionError";
135
+ this.code = code;
136
+ }
137
+ };
138
+ });
139
+
140
+ // src/shared/lib/wasm-init.ts
141
+ import wasmPath from "@automerge/automerge/automerge.wasm";
142
+ import { initializeWasm } from "@automerge/automerge-repo/slim";
143
+ var wasmUrl = new URL(wasmPath, import.meta.url).href;
144
+ await initializeWasm(wasmUrl);
145
+
47
146
  // src/shared/lib/crdt-specialised.ts
48
- import { Counter, updateText } from "@automerge/automerge-repo";
147
+ import { Counter, updateText } from "@automerge/automerge-repo/slim";
49
148
  import { effect, signal } from "@preact/signals";
50
149
 
51
150
  // src/shared/lib/migrate-primitive.ts
@@ -418,93 +517,15 @@ function applyTopLevel(doc, value) {
418
517
  }
419
518
  }
420
519
  // src/shared/lib/peer-relay-adapter.ts
421
- import { Repo } from "@automerge/automerge-repo";
520
+ import { Repo } from "@automerge/automerge-repo/slim";
422
521
  import { WebSocketClientAdapter } from "@automerge/automerge-repo-network-websocket";
423
522
  import { signal as signal3 } from "@preact/signals";
424
523
 
425
524
  // src/shared/lib/mesh-network-adapter.ts
525
+ init_encryption();
426
526
  import {
427
527
  NetworkAdapter
428
- } from "@automerge/automerge-repo";
429
-
430
- // src/shared/lib/encryption.ts
431
- import nacl from "tweetnacl";
432
- var KEY_BYTES = 32;
433
- var NONCE_BYTES = 24;
434
- var TAG_BYTES = 16;
435
-
436
- class EncryptionError extends Error {
437
- code;
438
- constructor(message, code) {
439
- super(message);
440
- this.name = "EncryptionError";
441
- this.code = code;
442
- }
443
- }
444
- function generateDocumentKey() {
445
- return nacl.randomBytes(KEY_BYTES);
446
- }
447
- function encrypt(payload, key) {
448
- if (key.length !== KEY_BYTES) {
449
- throw new EncryptionError(`secretbox key must be ${KEY_BYTES} bytes, got ${key.length}.`, "invalid-key-length");
450
- }
451
- const nonce = nacl.randomBytes(NONCE_BYTES);
452
- const ciphertext = nacl.secretbox(payload, nonce, key);
453
- const out = new Uint8Array(NONCE_BYTES + ciphertext.length);
454
- out.set(nonce, 0);
455
- out.set(ciphertext, NONCE_BYTES);
456
- return out;
457
- }
458
- function decrypt(sealed, key) {
459
- if (key.length !== KEY_BYTES) {
460
- throw new EncryptionError(`secretbox key must be ${KEY_BYTES} bytes, got ${key.length}.`, "invalid-key-length");
461
- }
462
- if (sealed.length < NONCE_BYTES + TAG_BYTES) {
463
- return;
464
- }
465
- const nonce = sealed.subarray(0, NONCE_BYTES);
466
- const ciphertext = sealed.subarray(NONCE_BYTES);
467
- const opened = nacl.secretbox.open(ciphertext, nonce, key);
468
- return opened ?? undefined;
469
- }
470
- function decryptOrThrow(sealed, key) {
471
- const opened = decrypt(sealed, key);
472
- if (!opened) {
473
- throw new EncryptionError(`Failed to decrypt sealed blob: wrong key, malformed input, or tampered ciphertext.`, "decrypt-failed");
474
- }
475
- return opened;
476
- }
477
- function sealEnvelope(payload, documentId, key) {
478
- return {
479
- documentId,
480
- sealed: encrypt(payload, key)
481
- };
482
- }
483
- function openEnvelope(envelope, key) {
484
- return decryptOrThrow(envelope.sealed, key);
485
- }
486
- function encodeEncryptedEnvelope(envelope) {
487
- const idBytes = new TextEncoder().encode(envelope.documentId);
488
- const out = new Uint8Array(4 + idBytes.length + envelope.sealed.length);
489
- const view = new DataView(out.buffer);
490
- view.setUint32(0, idBytes.length, false);
491
- out.set(idBytes, 4);
492
- out.set(envelope.sealed, 4 + idBytes.length);
493
- return out;
494
- }
495
- function decodeEncryptedEnvelope(bytes) {
496
- if (bytes.length < 4) {
497
- throw new EncryptionError(`Encrypted envelope too short: ${bytes.length} bytes.`, "envelope-malformed");
498
- }
499
- const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
500
- const idLen = view.getUint32(0, false);
501
- if (bytes.length < 4 + idLen) {
502
- throw new EncryptionError(`Encrypted envelope truncated: declared id length ${idLen}, total ${bytes.length}.`, "envelope-malformed");
503
- }
504
- const documentId = new TextDecoder().decode(bytes.subarray(4, 4 + idLen));
505
- const sealed = bytes.slice(4 + idLen);
506
- return { documentId, sealed };
507
- }
528
+ } from "@automerge/automerge-repo/slim";
508
529
 
509
530
  // src/shared/lib/signing.ts
510
531
  import nacl2 from "tweetnacl";
@@ -771,7 +792,7 @@ function createPeerStateClient(options) {
771
792
  };
772
793
  }
773
794
  // src/shared/lib/peer-repo-server.ts
774
- import { Repo as Repo2 } from "@automerge/automerge-repo";
795
+ import { Repo as Repo2 } from "@automerge/automerge-repo/slim";
775
796
  import { WebSocketServerAdapter } from "@automerge/automerge-repo-network-websocket";
776
797
  import { NodeFSStorageAdapter } from "@automerge/automerge-repo-storage-nodefs";
777
798
  import * as ws from "ws";
@@ -801,7 +822,9 @@ async function createPeerRepoServer(options) {
801
822
  client.terminate();
802
823
  } catch {}
803
824
  }
804
- repo.shutdown();
825
+ try {
826
+ await repo.shutdown();
827
+ } catch {}
805
828
  try {
806
829
  wss.close();
807
830
  } catch {}
@@ -925,4 +948,4 @@ export {
925
948
  $crdtCounter
926
949
  };
927
950
 
928
- //# debugId=81EED7520484C6A364756E2164756E21
951
+ //# debugId=5ABAA75081B5AC5A64756E2164756E21