@fairfox/polly 0.57.0 → 0.59.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.
@@ -21,14 +21,14 @@ export type { EncryptedEnvelope, SealedBytes, } from "./shared/lib/encryption";
21
21
  export { decrypt, decryptOrThrow, EncryptionError, encrypt, generateDocumentKey, KEY_BYTES as ENCRYPTION_KEY_BYTES, NONCE_BYTES as ENCRYPTION_NONCE_BYTES, TAG_BYTES as ENCRYPTION_TAG_BYTES, } from "./shared/lib/encryption";
22
22
  export type { KeyringStorage } from "./shared/lib/keyring-storage";
23
23
  export { deserialiseKeyring, memoryKeyringStorage, serialiseKeyring, } from "./shared/lib/keyring-storage";
24
- export type { CreateMeshClientOptions, MeshClient, MeshClientHandleSnapshot, MeshClientPeerStateSnapshot, } from "./shared/lib/mesh-client";
24
+ export type { CreateMeshClientOptions, MeshClient, MeshClientHandleSnapshot, MeshClientPeerStateSnapshot, MeshStateModuleDiagnostics, } from "./shared/lib/mesh-client";
25
25
  export { createMeshClient } from "./shared/lib/mesh-client";
26
26
  export type { MeshKeyring, MeshNetworkAdapterOptions, } from "./shared/lib/mesh-network-adapter";
27
27
  export { DEFAULT_MESH_KEY_ID, MeshNetworkAdapter, } from "./shared/lib/mesh-network-adapter";
28
28
  export type { MeshSignalingClientOptions, SignalingMessage as MeshSignalingMessage, } from "./shared/lib/mesh-signaling-client";
29
29
  export { MeshSignalingClient } from "./shared/lib/mesh-signaling-client";
30
- export type { MeshStateOptions } from "./shared/lib/mesh-state";
31
- export { $meshCounter, $meshList, $meshState, $meshText, configureMeshState, resetMeshState, } from "./shared/lib/mesh-state";
30
+ export type { MeshStateLoadedRejectionBreadcrumb, MeshStateOptions, } from "./shared/lib/mesh-state";
31
+ export { $meshCounter, $meshList, $meshState, $meshText, configureMeshState, getLastConfiguredRepoPeerId, getLastLoadedRejection, getLazyInvocations, getLazyReachedRepo, getMeshStateModuleId, isMeshStateConfigured, MESH_STATE_MODULE_ID, resetMeshState, wasMeshStateResolved, } from "./shared/lib/mesh-state";
32
32
  export type { HandleSyncSnapshot, InFlightSyncSnapshot, MeshWebRTCAdapterOptions, SlotInitiationDecision, SlotInitiationRejectionReason, SweepSnapshot, SyncHandshakeAttemptSnapshot, SyncProgressEvent, TransportSnapshot, } from "./shared/lib/mesh-webrtc-adapter";
33
33
  export { DEFAULT_ICE_SERVERS, MeshWebRTCAdapter } from "./shared/lib/mesh-webrtc-adapter";
34
34
  export type { CreatePairingTokenOptions, PairingToken, } from "./shared/lib/pairing";
package/dist/src/mesh.js CHANGED
@@ -1764,16 +1764,62 @@ function fieldEquals(a, b) {
1764
1764
 
1765
1765
  // src/shared/lib/mesh-state.ts
1766
1766
  var defaultRepo;
1767
+ var MESH_STATE_MODULE_ID = `mesh-state-${typeof crypto !== "undefined" && typeof crypto.randomUUID === "function" ? crypto.randomUUID() : Math.random().toString(36).slice(2) + Date.now().toString(36)}`;
1768
+ function getMeshStateModuleId() {
1769
+ return MESH_STATE_MODULE_ID;
1770
+ }
1771
+ var lastConfiguredRepoPeerId;
1772
+ function getLastConfiguredRepoPeerId() {
1773
+ return lastConfiguredRepoPeerId;
1774
+ }
1767
1775
  function configureMeshState(repo) {
1768
1776
  defaultRepo = repo;
1777
+ lastConfiguredRepoPeerId = repo.peerId;
1769
1778
  }
1770
1779
  function resetMeshState() {
1771
1780
  defaultRepo = undefined;
1781
+ lastConfiguredRepoPeerId = undefined;
1782
+ meshStateEverResolved = false;
1783
+ lazyInvocations = 0;
1784
+ lazyReachedRepo = 0;
1785
+ lastLoadedRejection = undefined;
1786
+ }
1787
+ function isMeshStateConfigured() {
1788
+ return defaultRepo !== undefined;
1789
+ }
1790
+ var meshStateEverResolved = false;
1791
+ function wasMeshStateResolved() {
1792
+ return meshStateEverResolved;
1793
+ }
1794
+ var lazyInvocations = 0;
1795
+ function getLazyInvocations() {
1796
+ return lazyInvocations;
1797
+ }
1798
+ var lazyReachedRepo = 0;
1799
+ function getLazyReachedRepo() {
1800
+ return lazyReachedRepo;
1801
+ }
1802
+ var lastLoadedRejection;
1803
+ function getLastLoadedRejection() {
1804
+ return lastLoadedRejection;
1805
+ }
1806
+ function recordLoadedRejection(thrown) {
1807
+ const err = thrown instanceof Error ? thrown : new Error(typeof thrown === "string" ? thrown : String(thrown));
1808
+ lastLoadedRejection = {
1809
+ name: err.name,
1810
+ message: err.message,
1811
+ stack: err.stack,
1812
+ at: Date.now()
1813
+ };
1772
1814
  }
1773
1815
  function resolveRepo(option) {
1816
+ meshStateEverResolved = true;
1774
1817
  const repo = option ?? defaultRepo;
1775
1818
  if (!repo) {
1776
- throw new Error("Polly $meshState: no Repo configured. Call configureMeshState(repo) at startup or pass { repo } in the primitive options.");
1819
+ if (typeof console !== "undefined" && typeof console.warn === "function") {
1820
+ console.warn(`[polly#107 H5] $meshState resolved against unconfigured module instance ${MESH_STATE_MODULE_ID}. If createMeshClient was called elsewhere, the consumer's wrappers and the mesh client are reaching different module instances — see polly#107.`);
1821
+ }
1822
+ throw new Error(`Polly $meshState: no Repo configured (module instance ${MESH_STATE_MODULE_ID}). Call configureMeshState(repo) at startup or pass { repo } in the primitive options. If you have called configureMeshState elsewhere, the most likely cause is that the call resolved to a different module instance than this one — see polly#107.`);
1777
1823
  }
1778
1824
  return repo;
1779
1825
  }
@@ -1787,26 +1833,39 @@ function deriveDocumentId(key) {
1787
1833
  function buildHandleFactory(repo, key, initialDoc) {
1788
1834
  const documentId = deriveDocumentId(key);
1789
1835
  return async () => {
1790
- const cached = repo.handles[documentId];
1791
- if (cached) {
1792
- await cached.whenReady(["ready", "unavailable"]);
1793
- if (cached.state === "ready") {
1794
- return cached;
1836
+ lazyInvocations++;
1837
+ try {
1838
+ const cached = repo.handles[documentId];
1839
+ lazyReachedRepo++;
1840
+ if (cached) {
1841
+ await cached.whenReady(["ready", "unavailable"]);
1842
+ if (cached.state === "ready") {
1843
+ return cached;
1844
+ }
1795
1845
  }
1846
+ const stored = await repo.storageSubsystem?.loadDoc(documentId);
1847
+ if (stored) {
1848
+ return repo.find(documentId, { allowableStates: ["ready"] });
1849
+ }
1850
+ const seeded = Automerge.save(Automerge.from(initialDoc));
1851
+ const handle = repo.import(seeded, { docId: documentId });
1852
+ handle.doneLoading();
1853
+ return handle;
1854
+ } catch (err) {
1855
+ recordLoadedRejection(err);
1856
+ throw err;
1796
1857
  }
1797
- const stored = await repo.storageSubsystem?.loadDoc(documentId);
1798
- if (stored) {
1799
- return repo.find(documentId, { allowableStates: ["ready"] });
1800
- }
1801
- const seeded = Automerge.save(Automerge.from(initialDoc));
1802
- const handle = repo.import(seeded, { docId: documentId });
1803
- handle.doneLoading();
1804
- return handle;
1805
1858
  };
1806
1859
  }
1860
+ function attachLoadedRejectionSink(primitive) {
1861
+ primitive.loaded.catch((err) => {
1862
+ recordLoadedRejection(err);
1863
+ });
1864
+ return primitive;
1865
+ }
1807
1866
  function $meshState(key, initialValue, options = {}) {
1808
1867
  const repo = resolveRepo(options.repo);
1809
- return $crdtState({
1868
+ return attachLoadedRejectionSink($crdtState({
1810
1869
  key,
1811
1870
  primitive: "meshState",
1812
1871
  initialValue,
@@ -1814,37 +1873,37 @@ function $meshState(key, initialValue, options = {}) {
1814
1873
  schemaVersion: options.schemaVersion,
1815
1874
  migrations: options.migrations,
1816
1875
  access: options.access
1817
- });
1876
+ }));
1818
1877
  }
1819
1878
  function $meshText(key, initialValue, options = {}) {
1820
1879
  const repo = resolveRepo(options.repo);
1821
- return $crdtText(key, initialValue, {
1880
+ return attachLoadedRejectionSink($crdtText(key, initialValue, {
1822
1881
  primitive: "meshState",
1823
1882
  getHandle: buildHandleFactory(repo, key, { text: initialValue }),
1824
1883
  schemaVersion: options.schemaVersion,
1825
1884
  migrations: options.migrations,
1826
1885
  access: options.access
1827
- });
1886
+ }));
1828
1887
  }
1829
1888
  function $meshCounter(key, initialValue, options = {}) {
1830
1889
  const repo = resolveRepo(options.repo);
1831
- return $crdtCounter(key, initialValue, {
1890
+ return attachLoadedRejectionSink($crdtCounter(key, initialValue, {
1832
1891
  primitive: "meshState",
1833
1892
  getHandle: buildHandleFactory(repo, key, {}),
1834
1893
  schemaVersion: options.schemaVersion,
1835
1894
  migrations: options.migrations,
1836
1895
  access: options.access
1837
- });
1896
+ }));
1838
1897
  }
1839
1898
  function $meshList(key, initialValue, options = {}) {
1840
1899
  const repo = resolveRepo(options.repo);
1841
- return $crdtList(key, initialValue, {
1900
+ return attachLoadedRejectionSink($crdtList(key, initialValue, {
1842
1901
  primitive: "meshState",
1843
1902
  getHandle: buildHandleFactory(repo, key, { items: initialValue }),
1844
1903
  schemaVersion: options.schemaVersion,
1845
1904
  migrations: options.migrations,
1846
1905
  access: options.access
1847
- });
1906
+ }));
1848
1907
  }
1849
1908
 
1850
1909
  // src/shared/lib/mesh-webrtc-adapter.ts
@@ -3000,7 +3059,18 @@ async function createMeshClient(options) {
3000
3059
  runCount: 0,
3001
3060
  lastRunAt: undefined
3002
3061
  },
3003
- peers: []
3062
+ peers: [],
3063
+ meshStateModule: {
3064
+ moduleId: getMeshStateModuleId(),
3065
+ configured: isMeshStateConfigured(),
3066
+ lastConfiguredRepoPeerId: getLastConfiguredRepoPeerId(),
3067
+ wasResolved: wasMeshStateResolved(),
3068
+ lazyInvocations: getLazyInvocations(),
3069
+ lazyReachedRepo: getLazyReachedRepo(),
3070
+ lastLoadedRejection: getLastLoadedRejection()
3071
+ },
3072
+ repoHandleCount: Object.keys(repo.handles).length,
3073
+ repoHandleIds: Object.keys(repo.handles)
3004
3074
  };
3005
3075
  }
3006
3076
  const base = webrtcAdapter.getPeerStateSnapshot();
@@ -3012,7 +3082,18 @@ async function createMeshClient(options) {
3012
3082
  knownPeerIds: base.knownPeerIds,
3013
3083
  presentPeerIds: base.presentPeerIds,
3014
3084
  sweep: base.sweep,
3015
- peers: enrichedPeers
3085
+ peers: enrichedPeers,
3086
+ meshStateModule: {
3087
+ moduleId: getMeshStateModuleId(),
3088
+ configured: isMeshStateConfigured(),
3089
+ lastConfiguredRepoPeerId: getLastConfiguredRepoPeerId(),
3090
+ wasResolved: wasMeshStateResolved(),
3091
+ lazyInvocations: getLazyInvocations(),
3092
+ lazyReachedRepo: getLazyReachedRepo(),
3093
+ lastLoadedRejection: getLastLoadedRejection()
3094
+ },
3095
+ repoHandleCount: knownHandleIds.length,
3096
+ repoHandleIds: knownHandleIds
3016
3097
  };
3017
3098
  return out;
3018
3099
  },
@@ -3382,6 +3463,7 @@ function decodeRevocation(bytes, keyring) {
3382
3463
  return record;
3383
3464
  }
3384
3465
  export {
3466
+ wasMeshStateResolved,
3385
3467
  verify,
3386
3468
  signingKeyPairFromSecret,
3387
3469
  sign,
@@ -3392,7 +3474,13 @@ export {
3392
3474
  parsePairingToken,
3393
3475
  memoryKeyringStorage,
3394
3476
  isPairingTokenExpired,
3477
+ isMeshStateConfigured,
3395
3478
  isBlobRef,
3479
+ getMeshStateModuleId,
3480
+ getLazyReachedRepo,
3481
+ getLazyInvocations,
3482
+ getLastLoadedRejection,
3483
+ getLastConfiguredRepoPeerId,
3396
3484
  generateSigningKeyPair,
3397
3485
  generateDocumentKey,
3398
3486
  encrypt,
@@ -3427,6 +3515,7 @@ export {
3427
3515
  MeshSignalingClient,
3428
3516
  MeshNetworkAdapter,
3429
3517
  MemoryBlobCache,
3518
+ MESH_STATE_MODULE_ID,
3430
3519
  IndexedDBBlobCache,
3431
3520
  EncryptionError,
3432
3521
  TAG_BYTES as ENCRYPTION_TAG_BYTES,
@@ -3441,4 +3530,4 @@ export {
3441
3530
  $meshCounter
3442
3531
  };
3443
3532
 
3444
- //# debugId=DAB92455464EE0D864756E2164756E21
3533
+ //# debugId=5E68DFAAE223E09564756E2164756E21