@fairfox/polly 0.63.0 → 0.64.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.
@@ -28,7 +28,7 @@ export { DEFAULT_MESH_KEY_ID, MeshNetworkAdapter, } from "./shared/lib/mesh-netw
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
30
  export type { DocIdResolver, LazyWrapperExitReason, MeshStateLazyWrapperRecord, MeshStateLoadedRejectionBreadcrumb, MeshStateOptions, MeshStateStorageOpenError, } from "./shared/lib/mesh-state";
31
- export { $meshCounter, $meshList, $meshState, $meshText, configureMeshState, deriveDocumentId, getDocIdResolver, getLastConfiguredRepoPeerId, getLastLoadedRejection, getLazyInvocations, getLazyReachedRepo, getLazyWrappers, getMeshStateModuleId, getStorageOpenError, isMeshStateConfigured, MESH_STATE_MODULE_ID, registerDocIdResolver, resetMeshState, resolveDocumentId, wasMeshStateResolved, } from "./shared/lib/mesh-state";
31
+ export { $meshCounter, $meshList, $meshState, $meshText, configureMeshState, deriveDocumentId, getDocIdResolver, getLastConfiguredRepoPeerId, getLastLoadedRejection, getLazyInvocations, getLazyReachedRepo, getLazyWrappers, getMeshStateModuleId, getRedirectDetector, getStorageOpenError, isMeshStateConfigured, MESH_STATE_MODULE_ID, registerDocIdResolver, registerRedirectDetector, resetMeshState, resolveDocumentId, 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
@@ -1729,25 +1729,10 @@ function $crdtState(options) {
1729
1729
  const inner = signal2(options.initialValue);
1730
1730
  let updating = false;
1731
1731
  let currentHandle;
1732
- const loaded = (async () => {
1733
- const handle = await options.getHandle();
1734
- await handle.whenReady();
1735
- currentHandle = handle;
1736
- if (options.schemaVersion !== undefined) {
1737
- const targetVersion = options.schemaVersion;
1738
- const migrations = options.migrations ?? {};
1739
- handle.change((doc) => {
1740
- runMigrations(doc, targetVersion, migrations);
1741
- setDocVersion(doc, targetVersion);
1742
- });
1743
- }
1744
- updating = true;
1745
- try {
1746
- inner.value = cloneDoc(handle.doc());
1747
- } finally {
1748
- updating = false;
1749
- }
1750
- handle.on("change", (payload) => {
1732
+ let detachChangeListener;
1733
+ let swapping = false;
1734
+ function attachChangeListener(handle) {
1735
+ const listener = (payload) => {
1751
1736
  if (updating)
1752
1737
  return;
1753
1738
  updating = true;
@@ -1756,7 +1741,75 @@ function $crdtState(options) {
1756
1741
  } finally {
1757
1742
  updating = false;
1758
1743
  }
1744
+ if (options.resolveRedirect && !swapping) {
1745
+ maybeRebind(handle, payload.doc);
1746
+ }
1747
+ };
1748
+ handle.on("change", listener);
1749
+ detachChangeListener = () => {
1750
+ handle.off("change", listener);
1751
+ };
1752
+ }
1753
+ async function maybeRebind(fromHandle, doc) {
1754
+ if (!options.resolveRedirect)
1755
+ return;
1756
+ if (swapping)
1757
+ return;
1758
+ swapping = true;
1759
+ try {
1760
+ const next = await options.resolveRedirect(fromHandle, doc);
1761
+ if (!next)
1762
+ return;
1763
+ if (next === currentHandle)
1764
+ return;
1765
+ if (next.documentId === fromHandle.documentId)
1766
+ return;
1767
+ detachChangeListener?.();
1768
+ detachChangeListener = undefined;
1769
+ currentHandle = next;
1770
+ attachChangeListener(next);
1771
+ updating = true;
1772
+ try {
1773
+ inner.value = cloneDoc(next.doc());
1774
+ } finally {
1775
+ updating = false;
1776
+ }
1777
+ } finally {
1778
+ swapping = false;
1779
+ }
1780
+ }
1781
+ async function followInitialRedirects(start) {
1782
+ if (!options.resolveRedirect)
1783
+ return start;
1784
+ let handle = start;
1785
+ const seen = new Set([handle.documentId]);
1786
+ for (;; ) {
1787
+ const doc = handle.doc();
1788
+ if (!doc)
1789
+ break;
1790
+ const next = await options.resolveRedirect(handle, doc);
1791
+ if (!next || next === handle)
1792
+ break;
1793
+ const nextIdString = next.documentId;
1794
+ if (seen.has(nextIdString))
1795
+ break;
1796
+ seen.add(nextIdString);
1797
+ handle = next;
1798
+ await handle.whenReady();
1799
+ }
1800
+ return handle;
1801
+ }
1802
+ function applyPendingMigrations(handle) {
1803
+ if (options.schemaVersion === undefined)
1804
+ return;
1805
+ const targetVersion = options.schemaVersion;
1806
+ const migrations = options.migrations ?? {};
1807
+ handle.change((doc) => {
1808
+ runMigrations(doc, targetVersion, migrations);
1809
+ setDocVersion(doc, targetVersion);
1759
1810
  });
1811
+ }
1812
+ function bindSignalToHandle() {
1760
1813
  effect2(() => {
1761
1814
  const value = inner.value;
1762
1815
  if (updating)
@@ -1772,6 +1825,21 @@ function $crdtState(options) {
1772
1825
  updating = false;
1773
1826
  }
1774
1827
  });
1828
+ }
1829
+ const loaded = (async () => {
1830
+ const initialHandle = await options.getHandle();
1831
+ await initialHandle.whenReady();
1832
+ const handle = await followInitialRedirects(initialHandle);
1833
+ currentHandle = handle;
1834
+ applyPendingMigrations(handle);
1835
+ updating = true;
1836
+ try {
1837
+ inner.value = cloneDoc(handle.doc());
1838
+ } finally {
1839
+ updating = false;
1840
+ }
1841
+ attachChangeListener(handle);
1842
+ bindSignalToHandle();
1775
1843
  })();
1776
1844
  return {
1777
1845
  key: options.key,
@@ -1951,6 +2019,13 @@ function getDocIdResolver() {
1951
2019
  function resolveDocumentId(key) {
1952
2020
  return docIdResolver?.(key) ?? deriveDocumentId(key);
1953
2021
  }
2022
+ var redirectDetector;
2023
+ function registerRedirectDetector(detector) {
2024
+ redirectDetector = detector;
2025
+ }
2026
+ function getRedirectDetector() {
2027
+ return redirectDetector;
2028
+ }
1954
2029
  function buildHandleFactory(repo, key, initialDoc) {
1955
2030
  const documentId = resolveDocumentId(key);
1956
2031
  return async () => {
@@ -1961,23 +2036,22 @@ function buildHandleFactory(repo, key, initialDoc) {
1961
2036
  const cached = repo.handles[documentId];
1962
2037
  lazyReachedRepo++;
1963
2038
  const docIdString = documentId;
2039
+ let handle;
1964
2040
  if (cached) {
1965
2041
  await withStorageTimeout("whenReady", docIdString, cached.whenReady(["ready", "unavailable"]));
1966
2042
  if (cached.state === "ready") {
1967
2043
  exitReason = "returned-cached";
1968
- return cached;
2044
+ handle = cached;
2045
+ } else {
2046
+ handle = await loadOrSeed(repo, documentId, initialDoc, docIdString, (r) => {
2047
+ exitReason = r;
2048
+ });
1969
2049
  }
2050
+ } else {
2051
+ handle = await loadOrSeed(repo, documentId, initialDoc, docIdString, (r) => {
2052
+ exitReason = r;
2053
+ });
1970
2054
  }
1971
- const loadPromise = repo.storageSubsystem?.loadDoc(documentId);
1972
- const stored = loadPromise ? await withStorageTimeout("loadDoc", docIdString, loadPromise) : undefined;
1973
- if (stored) {
1974
- exitReason = "loaded-from-storage";
1975
- return repo.find(documentId, { allowableStates: ["ready"] });
1976
- }
1977
- const seeded = Automerge.save(Automerge.from(initialDoc));
1978
- const handle = repo.import(seeded, { docId: documentId });
1979
- handle.doneLoading();
1980
- exitReason = "seeded-and-imported";
1981
2055
  return handle;
1982
2056
  } catch (err) {
1983
2057
  errorMessage = err instanceof Error ? err.message : String(err);
@@ -1997,6 +2071,19 @@ function buildHandleFactory(repo, key, initialDoc) {
1997
2071
  }
1998
2072
  };
1999
2073
  }
2074
+ async function loadOrSeed(repo, documentId, initialDoc, docIdString, setExitReason) {
2075
+ const loadPromise = repo.storageSubsystem?.loadDoc(documentId);
2076
+ const stored = loadPromise ? await withStorageTimeout("loadDoc", docIdString, loadPromise) : undefined;
2077
+ if (stored) {
2078
+ setExitReason("loaded-from-storage");
2079
+ return repo.find(documentId, { allowableStates: ["ready"] });
2080
+ }
2081
+ const seeded = Automerge.save(Automerge.from(initialDoc));
2082
+ const handle = repo.import(seeded, { docId: documentId });
2083
+ handle.doneLoading();
2084
+ setExitReason("seeded-and-imported");
2085
+ return handle;
2086
+ }
2000
2087
  function attachLoadedRejectionSink(primitive) {
2001
2088
  primitive.loaded.catch((err) => {
2002
2089
  recordLoadedRejection(err);
@@ -2010,11 +2097,35 @@ function $meshState(key, initialValue, options = {}) {
2010
2097
  primitive: "meshState",
2011
2098
  initialValue,
2012
2099
  getHandle: buildHandleFactory(repo, key, initialValue),
2100
+ resolveRedirect: buildRedirectResolver(repo),
2013
2101
  schemaVersion: options.schemaVersion,
2014
2102
  migrations: options.migrations,
2015
2103
  access: options.access
2016
2104
  }));
2017
2105
  }
2106
+ function buildRedirectResolver(repo) {
2107
+ if (!redirectDetector) {}
2108
+ return async (_handle, doc) => {
2109
+ const detector = redirectDetector;
2110
+ if (!detector)
2111
+ return;
2112
+ let nextId;
2113
+ try {
2114
+ nextId = detector(doc);
2115
+ } catch {
2116
+ return;
2117
+ }
2118
+ if (!nextId)
2119
+ return;
2120
+ try {
2121
+ return await repo.find(nextId, {
2122
+ allowableStates: ["ready", "unavailable"]
2123
+ });
2124
+ } catch {
2125
+ return;
2126
+ }
2127
+ };
2128
+ }
2018
2129
  function $meshText(key, initialValue, options = {}) {
2019
2130
  const repo = resolveRepo(options.repo);
2020
2131
  return attachLoadedRejectionSink($crdtText(key, initialValue, {
@@ -3630,6 +3741,7 @@ export {
3630
3741
  revokePeerLocally,
3631
3742
  resolveDocumentId,
3632
3743
  resetMeshState,
3744
+ registerRedirectDetector,
3633
3745
  registerDocIdResolver,
3634
3746
  parsePairingToken,
3635
3747
  memoryKeyringStorage,
@@ -3637,6 +3749,7 @@ export {
3637
3749
  isMeshStateConfigured,
3638
3750
  isBlobRef,
3639
3751
  getStorageOpenError,
3752
+ getRedirectDetector,
3640
3753
  getMeshStateModuleId,
3641
3754
  getLazyWrappers,
3642
3755
  getLazyReachedRepo,
@@ -3694,4 +3807,4 @@ export {
3694
3807
  $meshCounter
3695
3808
  };
3696
3809
 
3697
- //# debugId=82752400E00815C464756E2164756E21
3810
+ //# debugId=32FAEA2DE6283FD764756E2164756E21