@fairfox/polly 0.65.0 → 0.67.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.
@@ -164,6 +164,56 @@ export interface CreateMeshClientOptions {
164
164
  * production call site is inside {@link createMeshClient}.
165
165
  */
166
166
  export declare function resolveIceServers(rtc: CreateMeshClientOptions["rtc"]): Promise<RTCIceServer[] | undefined>;
167
+ /** Per-(docId, peerId) view into Automerge's `CollectionSynchronizer`.
168
+ * Built once per snapshot read and consulted from {@link buildHandleEntry}.
169
+ * Structured this way so the docSynchronizer lookup is paid once per
170
+ * docId, not once per (docId × peer). */
171
+ interface PerPeerDocSyncView {
172
+ /** `true` iff Automerge's `CollectionSynchronizer.docSynchronizers`
173
+ * has an entry for this documentId. A handle that exists in
174
+ * `repo.handles` but has no corresponding `docSynchronizer` is the
175
+ * `addDocument`-was-never-called fingerprint — Automerge's
176
+ * NetworkSubsystem can never invoke `send` for it because no
177
+ * synchronizer is wired up. */
178
+ docSynchronizerExists: boolean;
179
+ /** `true` iff the docSynchronizer for this documentId has registered
180
+ * this peer in its internal peer list (`#peers`). `false` with
181
+ * `docSynchronizerExists: true` is the symmetric polly#107 gap: the
182
+ * synchronizer exists (`addDocument` ran) but `addPeer` was never
183
+ * called for this peer on this doc — typically because the handle
184
+ * was created AFTER `peer-candidate` fired and Automerge's
185
+ * `addDocument`-iterates-known-peers path missed it. `undefined`
186
+ * when no docSynchronizer exists. */
187
+ docSynchronizerKnowsPeer: boolean | undefined;
188
+ /** Automerge's `DocSynchronizer.peerStates[peerId]` — one of
189
+ * `"unknown"`, `"has"`, `"unavailable"`, `"wants"`. `"unknown"`
190
+ * with `lastSyncMessageOutAt` set means the local side sent its
191
+ * opening handshake but never advanced past it; this is the
192
+ * wedged-pair fingerprint #112 names. `undefined` when no
193
+ * docSynchronizer exists OR when the synchronizer exists but
194
+ * doesn't track this peer. */
195
+ peerDocumentStatus: string | undefined;
196
+ }
197
+ /** Minimal structural shape we lift off Automerge's hidden
198
+ * `Repo.synchronizer` / `CollectionSynchronizer` types. Kept narrow
199
+ * so a future Automerge bump that renames a private rip doesn't
200
+ * topple the snapshot path. */
201
+ interface SynchronizerStructural {
202
+ docSynchronizers?: Record<string, {
203
+ hasPeer?: (peerId: string) => boolean;
204
+ peerStates?: Record<string, string>;
205
+ }>;
206
+ }
207
+ /** Internal — exported for direct unit-test coverage of the #112
208
+ * structural reader and snapshot wiring. Not part of the public API. */
209
+ export declare const __test__: {
210
+ buildSyncView: (synchronizer: SynchronizerStructural | undefined, docId: string, peerId: string) => PerPeerDocSyncView;
211
+ EMPTY_SYNC_VIEW: PerPeerDocSyncView;
212
+ getCollectionSynchronizer: (repo: Repo) => SynchronizerStructural | undefined;
213
+ enrichPeerSlot: (peer: ReturnType<MeshWebRTCAdapter["getPeerStateSnapshot"]>["peers"][number], knownHandleIds: string[], repoHandles: Record<string, {
214
+ state: unknown;
215
+ } | undefined>, synchronizer: SynchronizerStructural | undefined) => MeshClientPeerStateSnapshot["peers"][number];
216
+ };
167
217
  /** Polly#107 post-v0.60 instrumentation. Walks the lazy-wrapper log
168
218
  * and groups records by `docId`; emits one entry per `docId` that
169
219
  * appears in more than one record. Surfaces the "17 wrappers / 16
@@ -221,6 +271,31 @@ export interface MeshClientHandleSnapshot {
221
271
  * `"sync"` after handshake, `"request"` while the local side is
222
272
  * asking. */
223
273
  lastSyncMessageOutType: string | undefined;
274
+ /** #112 diagnostic. `true` iff Automerge's `CollectionSynchronizer`
275
+ * has a `docSynchronizer` entry for this document. A handle in
276
+ * `repo.handles` with no docSynchronizer is the
277
+ * `addDocument`-never-ran fingerprint: Automerge's NetworkSubsystem
278
+ * can never call `send` for it because no synchronizer is wired up. */
279
+ docSynchronizerExists: boolean;
280
+ /** #112 diagnostic. `true` iff the docSynchronizer for this document
281
+ * has this peer in its internal peer list. `false` with
282
+ * `docSynchronizerExists: true` is the symmetric polly#107 gap —
283
+ * the synchronizer exists but `addPeer` was never invoked on it for
284
+ * this peer, typically because the handle was created AFTER
285
+ * `peer-candidate` fired and Automerge's
286
+ * `addDocument`-iterates-peers path missed it. `undefined` when no
287
+ * docSynchronizer exists. */
288
+ docSynchronizerKnowsPeer: boolean | undefined;
289
+ /** #112 diagnostic. Automerge's
290
+ * `DocSynchronizer.peerStates[peerId]` — one of `"unknown"`,
291
+ * `"has"`, `"unavailable"`, `"wants"`. `"unknown"` together with a
292
+ * set `lastSyncMessageOutAt` is the wedged-pair fingerprint this
293
+ * ticket names: the opening handshake left the wire but the
294
+ * synchronizer never learned whether the remote has the doc, so
295
+ * `generateSyncMessage` quiesces. `undefined` when no
296
+ * docSynchronizer exists OR when the synchronizer does not track
297
+ * this peer. */
298
+ peerDocumentStatus: string | undefined;
224
299
  }
225
300
  /** Polly#107 H5 diagnostics: surfaces the `mesh-state` module
226
301
  * instance identity so a single snapshot read tells the operator
@@ -414,3 +489,4 @@ export interface MeshClient {
414
489
  * peer connections negotiate asynchronously in the background.
415
490
  */
416
491
  export declare function createMeshClient(options: CreateMeshClientOptions): Promise<MeshClient>;
492
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fairfox/polly",
3
- "version": "0.65.0",
3
+ "version": "0.67.0",
4
4
  "private": false,
5
5
  "type": "module",
6
6
  "description": "Multi-execution-context framework with reactive state and cross-context messaging for Chrome extensions, PWAs, and worker-based applications",