@abraca/dabra 1.9.1 → 2.0.1

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.
package/dist/index.d.ts CHANGED
@@ -232,6 +232,23 @@ declare class DocumentCache {
232
232
  }
233
233
  //#endregion
234
234
  //#region packages/provider/src/AbracadabraClient.d.ts
235
+ /**
236
+ * Reason classifications surfaced to `onAuthFailed`. Consumers can decide
237
+ * whether to silently re-register the keypair (`user_not_found`) or
238
+ * surface a hard block (`account_revoked`, `forbidden`).
239
+ */
240
+ type AuthFailureReason = "user_not_found" | "account_revoked" | "forbidden" | "unauthorized";
241
+ interface AuthFailureContext {
242
+ /** HTTP status code from the failed request. */
243
+ status: number;
244
+ /** Server-provided error message verbatim. */
245
+ message: string;
246
+ /** Best-guess classification from the message text. */
247
+ reason: AuthFailureReason;
248
+ /** Method + path of the failed request, useful for debugging. */
249
+ method: string;
250
+ path: string;
251
+ }
235
252
  interface AbracadabraClientConfig {
236
253
  /** Server base URL (http or https). WebSocket URL is derived automatically. */
237
254
  url: string;
@@ -250,6 +267,19 @@ interface AbracadabraClientConfig {
250
267
  * cache entries automatically.
251
268
  */
252
269
  cache?: DocumentCache;
270
+ /**
271
+ * Called whenever a REST call returns 401/403 with a recoverable reason
272
+ * (typically "user not found" — server's DB was wiped or repointed).
273
+ * Consumers wire this to their reauth path (in cou-sh: `_reauthFn`)
274
+ * so silently-failing background fetches still trigger key re-registration
275
+ * without waiting for the next WS action to surface the problem.
276
+ *
277
+ * The callback runs OUT-OF-BAND of the failing request — the original
278
+ * Promise still rejects so callers handle their own error path.
279
+ * Long-running auth handlers should debounce or short-circuit duplicate
280
+ * concurrent invocations.
281
+ */
282
+ onAuthFailed?: (ctx: AuthFailureContext) => void;
253
283
  }
254
284
  declare class AbracadabraClient {
255
285
  private _token;
@@ -258,6 +288,7 @@ declare class AbracadabraClient {
258
288
  private readonly storageKey;
259
289
  private readonly _fetch;
260
290
  readonly cache: DocumentCache | null;
291
+ private readonly _onAuthFailed;
261
292
  constructor(config: AbracadabraClientConfig);
262
293
  get token(): string | null;
263
294
  set token(value: string | null);
@@ -397,8 +428,89 @@ declare class AbracadabraClient {
397
428
  seq: number;
398
429
  data: Uint8Array;
399
430
  }[]>;
400
- /** Clear token from memory and storage. */
431
+ /**
432
+ * Clear token from memory and storage. Local-only; does NOT notify the
433
+ * server. Use {@link logoutServer} or {@link logoutAll} when you also
434
+ * want the JWT to land in the server's revocation cache.
435
+ */
401
436
  logout(): void;
437
+ /**
438
+ * Revoke the current JWT server-side and clear local state. Adds the
439
+ * token's `jti` to the server's revocation cache so subsequent requests
440
+ * with this token return 401, even if the JWT signature still verifies
441
+ * and `exp` hasn't passed. Safe to call when no token is set — degrades
442
+ * to a local clear.
443
+ *
444
+ * Network errors are swallowed (the local state is always cleared) so
445
+ * a sign-out flow can't get stuck on a flaky connection. The endpoint
446
+ * itself is idempotent.
447
+ */
448
+ logoutServer(): Promise<void>;
449
+ /**
450
+ * Bump the user's `tokens_invalid_before` watermark, revoking every
451
+ * outstanding JWT for this user — every device, every browser, every
452
+ * pending background tab. The current token is required (this is the
453
+ * user's "I am who I say I am" assertion). After the call returns,
454
+ * future authenticated requests with any pre-existing token return 401.
455
+ */
456
+ logoutAll(): Promise<void>;
457
+ /**
458
+ * Request an email verification message be sent to the current user's
459
+ * registered email address. Requires authentication. Server enforces a
460
+ * per-user rate limit (1/min, 10/day). Returns 404 if email
461
+ * verification is disabled in `[auth.email_verification]`.
462
+ */
463
+ requestEmailVerification(): Promise<void>;
464
+ /**
465
+ * Confirm an email verification token (typically opened from a link in
466
+ * the verification email). On success the server sets
467
+ * `users.email_verified_at`. No auth required — the token itself is
468
+ * the proof.
469
+ */
470
+ confirmEmailVerification(token: string): Promise<void>;
471
+ /**
472
+ * Initiate a password reset for a user identified by username or
473
+ * email. The server always returns 202 to avoid leaking whether the
474
+ * identifier exists; a real reset email is only sent if the lookup
475
+ * matched. Heavily rate-limited per-identifier and per-IP.
476
+ */
477
+ requestPasswordReset(opts: {
478
+ identifier: string;
479
+ }): Promise<void>;
480
+ /**
481
+ * Complete a password reset using the token from the reset email.
482
+ * On success the user's password is updated and every existing JWT for
483
+ * the account is invalidated (the `tokens_invalid_before` watermark
484
+ * bumps). The caller is NOT auto-logged-in — call {@link login} after.
485
+ */
486
+ confirmPasswordReset(opts: {
487
+ token: string;
488
+ newPassword: string;
489
+ }): Promise<void>;
490
+ /**
491
+ * Change the current user's password. Requires the current password —
492
+ * a stolen JWT alone can't pivot to "I now own this account forever"
493
+ * because the lockout counter (shared with `/auth/login`) trips after
494
+ * a few wrong tries. The endpoint also bumps `tokens_invalid_before`,
495
+ * so other sessions are forced to re-auth.
496
+ */
497
+ changePassword(opts: {
498
+ currentPassword: string;
499
+ newPassword: string;
500
+ }): Promise<void>;
501
+ /**
502
+ * Add a password to an account that doesn't have one yet — for example,
503
+ * a key-based soft identity opting into a recovery credential. Requires
504
+ * the caller to be authenticated. The server checks
505
+ * `users.password_hash IS NULL` and returns 409 if a password is already
506
+ * set — use {@link changePassword} in that case.
507
+ *
508
+ * Setting a password does not bump `tokens_invalid_before`: it adds an
509
+ * orthogonal credential rather than rotating an existing one. Other
510
+ * devices keep their sessions; this just unlocks the password-login
511
+ * code path for future logins on new devices.
512
+ */
513
+ setPassword(newPassword: string): Promise<void>;
402
514
  /** Get the current user's profile. */
403
515
  getMe(): Promise<UserProfile>;
404
516
  /** Update the current user's display name. */
@@ -413,13 +525,51 @@ declare class AbracadabraClient {
413
525
  getDoc(docId: string): Promise<DocumentMeta>;
414
526
  /** Delete a document (requires Owner role). Cascades to children and uploads. */
415
527
  deleteDoc(docId: string): Promise<void>;
416
- /** List immediate child documents. */
417
- listChildren(docId: string): Promise<string[]>;
418
- /** Create a child document under a parent (requires write permission). */
528
+ /**
529
+ * Restore a soft-deleted document (and its descendants). Requires the
530
+ * same `manage` permission as {@link deleteDoc}, and works even when
531
+ * the doc currently has `deleted_at` set — the cascade resolver walks
532
+ * the ancestor chain regardless of soft-delete state. Returns the
533
+ * number of restored rows in the audit log; the SDK call returns
534
+ * `void` because the wire response is 204.
535
+ */
536
+ restoreDoc(docId: string): Promise<void>;
537
+ /**
538
+ * Full-text search over document labels via `GET /docs/search`. The
539
+ * server filters each candidate hit through the cascade resolver, so
540
+ * results only include docs the caller can read at viewer or above.
541
+ * Anonymous callers are permitted but only see public docs.
542
+ *
543
+ * `limit` is clamped to `[1, 50]` server-side; the default is 20.
544
+ * Hits arrive in best-first order. `snippet` is HTML with `<mark>`
545
+ * markers around matched tokens — sanitize before injecting.
546
+ */
547
+ searchDocs(query: string, opts?: {
548
+ limit?: number;
549
+ }): Promise<DocSearchHit[]>;
550
+ /**
551
+ * List the direct children of a document, returning full metadata. Pass
552
+ * no argument to list the children of the server root — what the
553
+ * dashboard renders as the Spaces sidebar.
554
+ *
555
+ * The cache (when configured) stores the bare `id[]` topology used by
556
+ * recursive tree walks; callers that need it can read `meta.id` from
557
+ * the returned metas.
558
+ */
559
+ listChildren(parentId?: string): Promise<DocumentMeta[]>;
560
+ /**
561
+ * Create a child document under a parent (requires write permission).
562
+ *
563
+ * `kind` is the well-known tag (`Kind.Channel`, `Kind.Page`, etc.); the
564
+ * server stores it in `documents.kind` but does not enforce semantics.
565
+ * `description` is freeform metadata.
566
+ */
419
567
  createChild(docId: string, opts?: {
420
568
  child_id?: string;
421
569
  doc_type?: string;
422
570
  label?: string;
571
+ kind?: string;
572
+ description?: string;
423
573
  }): Promise<DocumentMeta>;
424
574
  /** Broadcast a stateless message to all connected clients on a document (requires manage permission). */
425
575
  broadcast(docId: string, payload: string): Promise<void>;
@@ -456,10 +606,6 @@ declare class AbracadabraClient {
456
606
  revokeInvite(code: string): Promise<void>;
457
607
  /** Redeem an invite code for the currently authenticated user. */
458
608
  redeemInvite(code: string): Promise<void>;
459
- /** List root documents (replaces listSpaces for new code). */
460
- listRootDocuments(): Promise<DocumentMeta[]>;
461
- /** Get the hub document, or null if none is configured. */
462
- getHubDocument(): Promise<DocumentMeta | null>;
463
609
  /** Set the public_access level for a document. Pass null to inherit from parent. */
464
610
  setDocumentAccess(docId: string, publicAccess: string | null): Promise<void>;
465
611
  /** Get the public_access info for a document. */
@@ -467,47 +613,77 @@ declare class AbracadabraClient {
467
613
  public_access: string | null;
468
614
  effective_public_access: string | null;
469
615
  }>;
470
- /** Update document metadata (label, description, is_hub). Requires manage permission. */
616
+ /** Update document metadata (label, description, kind). Requires manage permission. */
471
617
  updateDocumentMeta(docId: string, opts: {
472
- label?: string;
618
+ label?: string | null;
473
619
  description?: string | null;
474
- is_hub?: boolean;
620
+ kind?: string | null;
475
621
  }): Promise<void>;
476
622
  /**
477
- * List spaces visible to the caller. No auth required for public spaces.
478
- * @deprecated Use {@link listRootDocuments} instead.
623
+ * List Spaces visible to the caller top-level docs (children of the
624
+ * server root) tagged with `kind: "space"`. Authenticated users see
625
+ * spaces resolving to any role; anonymous users see public ones.
479
626
  */
480
- listSpaces(): Promise<SpaceMeta[]>;
627
+ listSpaces(): Promise<DocumentMeta[]>;
481
628
  /**
482
- * Get a single space by ID.
483
- * @deprecated Use {@link getDoc} instead.
484
- */
485
- getSpace(spaceId: string): Promise<SpaceMeta>;
486
- /**
487
- * Get the hub space, or null if none is configured.
488
- * @deprecated Use {@link getHubDocument} instead.
489
- */
490
- getHubSpace(): Promise<SpaceMeta | null>;
491
- /**
492
- * Create a new space (auth required).
493
- * @deprecated Use {@link createDoc} + {@link updateDocumentMeta} instead.
629
+ * Create a new top-level Space. Equivalent to a `POST /docs` with
630
+ * `kind: "space"` plus the supplied metadata in one round trip.
631
+ *
632
+ * `visibility: "public"` sets `public_access = "observer"` (anonymous
633
+ * read, no awareness or writes). `"private"` (the default) leaves
634
+ * `public_access` unset so only explicit grants apply.
494
635
  */
495
636
  createSpace(opts: {
496
637
  name: string;
497
638
  description?: string;
498
- visibility?: SpaceMeta["visibility"];
639
+ visibility?: "public" | "private";
499
640
  id?: string;
500
- }): Promise<SpaceMeta>;
641
+ }): Promise<DocumentMeta>;
501
642
  /**
502
- * Update an existing space (Owner or admin required).
503
- * @deprecated Use {@link updateDocumentMeta} + {@link setDocumentAccess} instead.
643
+ * Update a Space's metadata. `visibility` flips `public_access` between
644
+ * `"observer"` (public) and `"none"` (private). To leave visibility
645
+ * untouched, omit it. Pass any property as `null` to clear it.
646
+ */
647
+ updateSpace(docId: string, opts: {
648
+ name?: string | null;
649
+ description?: string | null;
650
+ visibility?: "public" | "private";
651
+ }): Promise<void>;
652
+ /** Delete a Space (and every doc nested under it). Requires manage permission. */
653
+ deleteSpace(docId: string): Promise<void>;
654
+ /**
655
+ * Look up the DM doc between the calling user and `otherUserPk`, or
656
+ * create it if none exists. The doc id is deterministically derived from
657
+ * the sorted pubkey pair (see {@link deriveDmDocId}) so both sides
658
+ * compute the same target — race-tolerant by construction. The created
659
+ * doc has `kind = "dm"`, `public_access = "none"`, and explicit Editor
660
+ * permissions for both participants.
661
+ *
662
+ * The cascade resolver enforces that no other user can read the DM,
663
+ * because:
664
+ * - `public_access = "none"` blocks anonymous + falls through to the
665
+ * server-wide `[access].authenticated` floor for everyone else;
666
+ * - the explicit Editor rows only exist for the two participants, so
667
+ * non-participants get only the (capped) authenticated floor;
668
+ * - the doc lives at server root, so there's no ancestor that could
669
+ * leak via a higher cascade grant.
670
+ *
671
+ * Note: when `[access].authenticated >= "viewer"` is set server-wide,
672
+ * non-participants would still be able to *read* the DM via the
673
+ * authenticated floor. That's the documented "private docs need
674
+ * authenticated=none" caveat from REDESIGN.md §9 — operators wanting
675
+ * sealed DMs configure the server accordingly.
676
+ *
677
+ * @param otherUserPk Base64url-encoded Ed25519 public key of the other party.
678
+ * @returns The DM doc's id (existing or newly created).
504
679
  */
505
- updateSpace(spaceId: string, opts: Partial<Pick<SpaceMeta, "name" | "description" | "visibility" | "is_hub">>): Promise<SpaceMeta>;
680
+ findOrCreateDmDoc(otherUserPk: string): Promise<string>;
506
681
  /**
507
- * Delete a space and its root document (Owner or admin required).
508
- * @deprecated Use {@link deleteDoc} instead.
682
+ * The reserved server root document id. Convenience accessor for the
683
+ * client; identical to {@link SERVER_ROOT_ID}. Use this as the parent for
684
+ * top-level docs / Spaces.
509
685
  */
510
- deleteSpace(spaceId: string): Promise<void>;
686
+ get rootDocId(): string;
511
687
  /** List all users (requires elevated role: admin or service). */
512
688
  adminListUsers(): Promise<{
513
689
  users: (UserProfile & {
@@ -528,13 +704,87 @@ declare class AbracadabraClient {
528
704
  refCountsRepaired: number;
529
705
  blobsSwept: number;
530
706
  }>;
707
+ /**
708
+ * Clear the lockout state on a user account: zeroes the failed-login
709
+ * counter and `locked_until`. Requires elevated role (Admin or
710
+ * Service). The action is recorded in the audit log under
711
+ * `admin.user_unlock`.
712
+ */
713
+ adminUnlockUser(userId: string): Promise<void>;
714
+ /**
715
+ * Page through the audit log. Filters AND-combine; `limit` defaults to
716
+ * 100 server-side. Requires elevated role.
717
+ */
718
+ adminAuditList(opts?: AuditQueryOpts): Promise<AuditLogEntry[]>;
719
+ /**
720
+ * Stream the audit log as NDJSON (one JSON object per line) for SIEM
721
+ * ingestion. Filters mirror {@link adminAuditList} minus `limit`/`offset`.
722
+ * The server pages internally so memory usage is bounded; this method
723
+ * buffers the full response into a string and is therefore best for
724
+ * moderate exports — large dumps should consume `/admin/audit/export`
725
+ * directly with a streaming HTTP client.
726
+ */
727
+ adminAuditExport(opts?: Omit<AuditQueryOpts, "limit" | "offset">): Promise<string>;
728
+ /**
729
+ * Verify the integrity of the audit-log hash chain. Returns the result
730
+ * unchanged: `status: "ok"` when the chain is intact, `status: "broken"`
731
+ * with a `break` payload identifying the first divergent row when
732
+ * tampering is detected. Wraps `GET /admin/audit/verify`. Requires
733
+ * elevated role.
734
+ *
735
+ * Note: the server returns HTTP 409 on a broken chain — this method
736
+ * special-cases the 409 status and returns the body as a successful
737
+ * result rather than throwing, because "broken" is a valid answer
738
+ * from the verifier, not an error.
739
+ */
740
+ adminAuditVerify(): Promise<AuditVerifyResult>;
741
+ /**
742
+ * Download a tar archive of the schema-meaningful tables (users,
743
+ * documents, permissions, invites, optionally audit log). Requires
744
+ * elevated role. The server gzips the response when the client sends
745
+ * `Accept-Encoding: gzip` — `fetch` handles that transparently, so
746
+ * the returned Blob is the raw tar bytes.
747
+ */
748
+ adminBackupDump(opts?: {
749
+ includeAudit?: boolean;
750
+ }): Promise<Blob>;
751
+ /**
752
+ * List every registered config field with current value + origin
753
+ * (`default` / `env` / `global_override` / `route_override`). Requires
754
+ * elevated role.
755
+ */
756
+ adminConfigList(): Promise<AdminConfigField[]>;
757
+ /** Read a single config field by dotted path (e.g. `"access.authenticated"`). */
758
+ adminConfigGet(path: string): Promise<AdminConfigField>;
759
+ /**
760
+ * Set a runtime override on a config field. The field must be marked
761
+ * `runtime_mutable = true` in the registry; immutable fields return a
762
+ * schema error. Persists to the `settings_overrides` table.
763
+ */
764
+ adminConfigSet(path: string, value: unknown): Promise<AdminConfigField>;
765
+ /**
766
+ * Clear a runtime override and revert the field to its env/TOML/default
767
+ * base value. Returns `true` when an override was actually removed.
768
+ */
769
+ adminConfigUnset(path: string): Promise<boolean>;
770
+ /**
771
+ * Diagnostic dump of every `ABRA_*` env var the running process saw at
772
+ * boot, mapped to its config path. Use this to debug
773
+ * "I set this in `.env` but the server reports a different value".
774
+ * Secrets are redacted (`value: null`, `redacted: true`).
775
+ */
776
+ adminConfigEnvSnapshot(): Promise<EnvSnapshotResponse>;
531
777
  /** List snapshot metadata for a document. */
532
778
  listSnapshots(docId: string, opts?: {
533
779
  limit?: number;
534
780
  offset?: number;
535
781
  }): Promise<SnapshotMeta[]>;
536
- /** Fetch a single snapshot including its base64-encoded data blob. */
537
- getSnapshot(docId: string, version: number): Promise<SnapshotData>;
782
+ /** Fetch a single snapshot including its base64-encoded data blob.
783
+ * Pass `{ include: "files" }` to also receive the joined upload list
784
+ * (each `fileBlock` / `coverUploadId` resolved against `uploads`). */
785
+ getSnapshot(docId: string, version: number, opts?: {
786
+ include?: "files" | string;
787
+ }): Promise<SnapshotData>;
538
788
  /** Create a manual snapshot of the current document state. */
539
789
  createSnapshot(docId: string, opts?: {
540
790
  label?: string;
@@ -548,7 +798,18 @@ declare class AbracadabraClient {
548
798
  /** Health check — no auth required. */
549
799
  health(): Promise<HealthStatus>;
550
800
  /**
551
- * Fetch server metadata including the optional `index_doc_id` entry point.
801
+ * Readiness probe pings the database. Returns 200 with
802
+ * `status: "ready"` only when the server can serve traffic, 503 with
803
+ * `status: "unready"` otherwise (load balancers / Kubernetes probes
804
+ * use the status code; the body is informational).
805
+ *
806
+ * The 503 case is special-cased here: instead of throwing, the method
807
+ * returns the unready body so callers can react to the state without
808
+ * try/catch boilerplate.
809
+ */
810
+ readyz(): Promise<ReadyzStatus>;
811
+ /**
812
+ * Fetch server metadata including `root_doc_id` and the `[access]` policy.
552
813
  * No auth required.
553
814
  */
554
815
  serverInfo(): Promise<ServerInfo>;
@@ -782,6 +1043,14 @@ interface AbracadabraProviderConfiguration extends Omit<AbracadabraBaseProviderC
782
1043
  * sharing one local store. Used for the identity doc.
783
1044
  */
784
1045
  serverAgnostic?: boolean;
1046
+ /**
1047
+ * Maximum number of simultaneously cached child providers before LRU
1048
+ * eviction reclaims the least-recently-used unpinned ones. Default 20.
1049
+ * Apps that legitimately need more docs alive (e.g. background-sync of
1050
+ * a working set) should raise this; pin individual children with
1051
+ * `pinChild()` to make them eviction-immune regardless of cap.
1052
+ */
1053
+ maxChildren?: number;
785
1054
  }
786
1055
  /**
787
1056
  * AbracadabraProvider extends AbracadabraBaseProvider with:
@@ -815,8 +1084,9 @@ declare class AbracadabraProvider extends AbracadabraBaseProvider {
815
1084
  private childAccessTimes;
816
1085
  /** Pinned children that must not be evicted (e.g. actively viewed docs) */
817
1086
  private pinnedChildren;
818
- /** Max simultaneously cached child providers before LRU eviction kicks in */
819
- private static readonly MAX_CHILDREN;
1087
+ /** Default cap on simultaneously cached child providers; configurable per-instance via `maxChildren`. */
1088
+ private static readonly DEFAULT_MAX_CHILDREN;
1089
+ private readonly maxChildren;
820
1090
  private abracadabraConfig;
821
1091
  private readonly boundHandleYSubdocsChange;
822
1092
  /**
@@ -937,7 +1207,7 @@ declare class AbracadabraProvider extends AbracadabraBaseProvider {
937
1207
  destroy(): void;
938
1208
  }
939
1209
  //#endregion
940
- //#region packages/provider/node_modules/lib0/encoding.d.ts
1210
+ //#region node_modules/lib0/encoding.d.ts
941
1211
  /**
942
1212
  * A BinaryEncoder handles the encoding to an Uint8Array.
943
1213
  */
@@ -981,7 +1251,7 @@ declare const Forbidden: CloseEvent;
981
1251
  */
982
1252
  declare const ConnectionTimeout: CloseEvent;
983
1253
  //#endregion
984
- //#region packages/provider/node_modules/lib0/decoding.d.ts
1254
+ //#region node_modules/lib0/decoding.d.ts
985
1255
  /**
986
1256
  * A Decoder handles the decoding of an Uint8Array.
987
1257
  * @template {ArrayBufferLike} [Buf=ArrayBufferLike]
@@ -1208,18 +1478,57 @@ interface UserProfile {
1208
1478
  role: string;
1209
1479
  /** Account-level Ed25519 public key (base64url). Canonical user identity. */
1210
1480
  publicKey: string | null;
1481
+ /**
1482
+ * Whether the user has a password set. `false` for key-based soft
1483
+ * identities until they opt in via {@link AbracadabraClient.setPassword}.
1484
+ * Drives the UI's "Set password" vs "Change password" branching.
1485
+ */
1486
+ hasPassword?: boolean;
1211
1487
  }
1212
1488
  interface DocumentMeta {
1213
1489
  id: string;
1214
1490
  parent_id: string | null;
1491
+ /**
1492
+ * Renderer hint — `"kanban"`, `"checklist"`, `"outline"`, `"graph"`,
1493
+ * `"sheet"`, `"mindmap"`, `"doc"`, etc. Drives the dashboard's choice of
1494
+ * Vue component for this doc. Orthogonal to {@link kind}.
1495
+ */
1215
1496
  doc_type?: string | null;
1216
1497
  label?: string | null;
1217
1498
  description?: string | null;
1218
1499
  public_access?: string | null;
1219
1500
  owner_id?: string | null;
1220
- is_hub?: boolean;
1501
+ /**
1502
+ * Structural role hint — `"server"` for the reserved server-root doc,
1503
+ * `"space"` for top-level workspace containers, `null`/absent otherwise.
1504
+ * Distinct from {@link doc_type}: a Space (`kind: "space"`) can contain
1505
+ * many Kanban boards (each `doc_type: "kanban"`).
1506
+ */
1507
+ kind?: string | null;
1221
1508
  updated_at?: number | null;
1222
1509
  }
1510
+ /**
1511
+ * Well-known structural roles for the {@link DocumentMeta.kind} field. These
1512
+ * are conventions only — the server treats `kind` as an opaque string. Use
1513
+ * these constants instead of string literals to avoid typos.
1514
+ */
1515
+ declare const Kind: {
1516
+ /** The reserved server root document. There is exactly one per server. */readonly Server: "server"; /** A top-level workspace container — what the dashboard calls a "Space". */
1517
+ readonly Space: "space"; /** A regular content page rendered by the editor. */
1518
+ readonly Page: "page"; /** A group chat container under a Space. */
1519
+ readonly Channel: "channel"; /** A direct-message container at the server root with two-member permissions. */
1520
+ readonly Dm: "dm"; /** A child of channel/dm holding the messages Y.Array. */
1521
+ readonly ChannelPeriod: "channel-period"; /** A per-user inbox doc holding inbox entries; child of server root. */
1522
+ readonly Inbox: "inbox";
1523
+ };
1524
+ type Kind = typeof Kind[keyof typeof Kind];
1525
+ /**
1526
+ * Hardcoded UUID of the reserved server root document. Every doc in the tree
1527
+ * chains up to this row, so a permission grant on this doc cascades into
1528
+ * every descendant. Mirrors the constant in the Rust crate
1529
+ * (`crate::types::SERVER_ROOT_ID_STR`).
1530
+ */
1531
+ declare const SERVER_ROOT_ID = "00000000-0000-0000-0000-000000000000";
1223
1532
  interface UploadMeta {
1224
1533
  id: string;
1225
1534
  doc_id: string;
@@ -1265,9 +1574,28 @@ interface SnapshotMeta {
1265
1574
  label?: string | null;
1266
1575
  created_by?: string | null;
1267
1576
  created_at: number;
1577
+ /** Number of uploads referenced by this snapshot's CRDT state.
1578
+ * Always 0 on servers older than the `snapshot_files` migration, or for
1579
+ * snapshots created before that migration ran (until the operator runs
1580
+ * `POST /admin/snapshots/backfill-refs`). */
1581
+ file_count?: number;
1582
+ /** Signed byte delta vs. the previous-version snapshot for this doc.
1583
+ * `null` for the first snapshot of a doc (or when the previous version
1584
+ * has been pruned). Lets the UI render `+12 KB` / `−3 KB`. */
1585
+ delta_bytes?: number | null;
1586
+ }
1587
+ interface SnapshotFileEntry {
1588
+ id: string;
1589
+ doc_id: string;
1590
+ filename: string;
1591
+ mime_type?: string | null;
1592
+ size?: number | null;
1268
1593
  }
1269
1594
  interface SnapshotData extends SnapshotMeta {
1270
1595
  data: string;
1596
+ /** Populated only when fetched with `?include=files`. Each entry is an
1597
+ * upload referenced by this snapshot's CRDT state. */
1598
+ files?: SnapshotFileEntry[];
1271
1599
  }
1272
1600
  interface SnapshotCreateResult {
1273
1601
  version: number;
@@ -1297,10 +1625,21 @@ interface ServerInfo {
1297
1625
  version?: string;
1298
1626
  /** Hocuspocus wire protocol version (currently 2). */
1299
1627
  protocol_version?: number;
1300
- /** Entry-point document ID advertised by the server, if configured. */
1301
- index_doc_id?: string;
1302
- /** Default role assigned to users without explicit permissions. */
1303
- default_role?: string;
1628
+ /**
1629
+ * The reserved server root document id. Every doc in the tree chains up
1630
+ * to this row; granting Admin here cascades to every doc. Hardcoded by
1631
+ * the server — clients can also use {@link SERVER_ROOT_ID} directly.
1632
+ */
1633
+ root_doc_id?: string;
1634
+ /**
1635
+ * Server-wide access policy. Drives client-side decisions like "show the
1636
+ * sign-up CTA?" (anonymous mode) or "warn before publishing?" (anonymous
1637
+ * grants).
1638
+ */
1639
+ access?: {
1640
+ /** `"none"` rejects unauthenticated requests; `"observer"` allows public read. */anonymous?: "none" | "observer"; /** Server-wide floor for authed users with no explicit grant. */
1641
+ authenticated?: "none" | "observer" | "viewer" | "editor";
1642
+ };
1304
1643
  /** Enabled auth methods (e.g. ["crypto", "jwt"]). */
1305
1644
  auth_methods?: string[];
1306
1645
  /** Whether open registration is enabled. */
@@ -1312,23 +1651,143 @@ interface ServerInfo {
1312
1651
  default_mode?: string;
1313
1652
  minimum_mode?: string;
1314
1653
  };
1654
+ /**
1655
+ * Ed25519 public key (base64url, no padding) the server uses to sign every
1656
+ * accepted `messages:*` record (`server_sig`). Clients can verify message
1657
+ * placement / ordering by checking each record's `server_sig` against this
1658
+ * key over the canonical `{ msg_id, period_id, ts, client_sig }` payload.
1659
+ */
1660
+ messages_signer_pubkey?: string;
1315
1661
  }
1316
1662
  interface SearchResult {
1317
1663
  docId: string;
1318
1664
  /** Number of matching trigrams — higher is better. */
1319
1665
  score: number;
1320
1666
  }
1321
- interface SpaceMeta {
1322
- id: string;
1667
+ /**
1668
+ * A single hit returned by the server's full-text search endpoint
1669
+ * (`GET /docs/search`). Distinct from {@link SearchResult}, which is the
1670
+ * client-side trigram index in `SearchIndex.ts`.
1671
+ *
1672
+ * `snippet` is server-rendered HTML with `<mark>` wrappers around the
1673
+ * matched tokens — safe to inject after standard sanitization. `rank` is
1674
+ * a backend-specific score (SQLite bm25 vs Postgres ts_rank); the only
1675
+ * guarantee is that hits arrive in best-first order.
1676
+ */
1677
+ interface DocSearchHit {
1323
1678
  doc_id: string;
1324
- name: string;
1325
- description: string | null;
1326
- visibility: "public" | "private" | "invite";
1327
- is_hub: boolean;
1328
- owner_id: string | null;
1329
- created_at: number;
1330
- updated_at: number;
1331
- public_access?: string | null;
1679
+ parent_id: string | null;
1680
+ label: string | null;
1681
+ kind: string | null;
1682
+ /** HTML-safe snippet with `<mark>` markers around the matched tokens. */
1683
+ snippet: string;
1684
+ rank: number;
1685
+ }
1686
+ /**
1687
+ * A single row from `GET /admin/audit`. Mirrors the server's audit log
1688
+ * row format (see `audit::AuditLogRow`). `metadata` is the parsed JSON
1689
+ * object the server stored, or `null` if the row had no metadata. Each
1690
+ * row carries an internal `prev_hash` / `row_hash` chain that admins
1691
+ * verify with {@link AuditVerifyResult}.
1692
+ */
1693
+ interface AuditLogEntry {
1694
+ id: string;
1695
+ ts: number;
1696
+ event_type: string;
1697
+ actor_user_id: string | null;
1698
+ actor_ip: string | null;
1699
+ request_id: string | null;
1700
+ target_type: string | null;
1701
+ target_id: string | null;
1702
+ metadata: Record<string, unknown> | null;
1703
+ outcome: string;
1704
+ }
1705
+ /** Filters for `GET /admin/audit`. All optional and AND-combined. */
1706
+ interface AuditQueryOpts {
1707
+ event_type?: string;
1708
+ actor_user_id?: string;
1709
+ target_type?: string;
1710
+ target_id?: string;
1711
+ since_ts?: number;
1712
+ until_ts?: number;
1713
+ limit?: number;
1714
+ offset?: number;
1715
+ }
1716
+ /** Response of `GET /admin/audit/verify`. `status: "broken"` carries `break`. */
1717
+ interface AuditVerifyResult {
1718
+ status: "ok" | "broken";
1719
+ message?: string;
1720
+ break?: {
1721
+ rows_checked: number;
1722
+ row_id: string;
1723
+ reason: string;
1724
+ };
1725
+ }
1726
+ /**
1727
+ * Where the current value of a config field came from.
1728
+ *
1729
+ * * `default` — compiled-in default; nobody touched it.
1730
+ * * `env` — set at startup by an `ABRA_*` env var.
1731
+ * * `global_override` — admin runtime override via `/admin/config`.
1732
+ * * `route_override` — per-route override (Phase 3).
1733
+ */
1734
+ type AdminConfigOriginKind = "default" | "env" | "global_override" | "route_override";
1735
+ /** One entry returned by `GET /admin/config` and `GET /admin/config/fields/:path`. */
1736
+ interface AdminConfigField {
1737
+ path: string;
1738
+ section: string;
1739
+ description: string;
1740
+ env_var: string;
1741
+ runtime_mutable: boolean;
1742
+ value: unknown;
1743
+ origin_kind: AdminConfigOriginKind;
1744
+ /** Provenance — present only when origin_kind is a `*_override`. */
1745
+ set_at?: number;
1746
+ set_by?: string;
1747
+ route?: string;
1748
+ }
1749
+ /**
1750
+ * One row from `GET /admin/config/env-snapshot.items[]`. Reports whether
1751
+ * each registry-known `ABRA_*` env var was set in the running process at
1752
+ * boot, with secrets reported as `value: null` and `redacted: true`.
1753
+ */
1754
+ interface EnvSnapshotItem {
1755
+ env_var: string;
1756
+ path: string;
1757
+ section: string;
1758
+ present: boolean;
1759
+ /** Verbatim env value, or `null` for redacted (secrets) or unset. */
1760
+ value: string | null;
1761
+ redacted: boolean;
1762
+ }
1763
+ /**
1764
+ * One row from `GET /admin/config/env-snapshot.extensions[]`. Extension
1765
+ * overrides (`ABRA_EXT_<name>_<field>`) sit outside the registry and are
1766
+ * reported by name with values inline.
1767
+ */
1768
+ interface EnvSnapshotExtension {
1769
+ env_var: string;
1770
+ value: string;
1771
+ }
1772
+ /**
1773
+ * `GET /admin/config/env-snapshot` response.
1774
+ *
1775
+ * `unknown` lists `ABRA_*` env vars present in the process that don't map
1776
+ * to any registered field — i.e. typos. Operators that see their tweak
1777
+ * land here instead of in `items` know they misspelled the var.
1778
+ */
1779
+ interface EnvSnapshotResponse {
1780
+ items: EnvSnapshotItem[];
1781
+ extensions: EnvSnapshotExtension[];
1782
+ unknown: string[];
1783
+ }
1784
+ /** Response of `GET /readyz`. HTTP 200 when ready, 503 when not. */
1785
+ interface ReadyzStatus {
1786
+ status: "ready" | "unready";
1787
+ version: string;
1788
+ checks: {
1789
+ database: "ok" | "error";
1790
+ };
1332
1791
  }
1333
1792
  interface InviteRow {
1334
1793
  code: string;
@@ -1567,6 +2026,193 @@ declare const HocuspocusProviderWebsocket: typeof AbracadabraWS;
1567
2026
  /** @deprecated Use AbracadabraWS */
1568
2027
  type HocuspocusProviderWebsocket = AbracadabraWS;
1569
2028
  //#endregion
2029
+ //#region packages/provider/src/RpcClient.d.ts
2030
+ /**
2031
+ * RPC v1 — request/response over `MSG_STATELESS`.
2032
+ *
2033
+ * Mirrors `docs/rpc-v1.md` in the abracadabra-rs server. Frames travel as
2034
+ * `MSG_STATELESS` payloads with the literal prefix `rpc:v1:` followed by a
2035
+ * JSON envelope. The provider's existing `sendStateless` / `stateless` event
2036
+ * stream is the only transport surface this layer touches; everything else
2037
+ * (state machine, deadlines, handler registry, dedupe of self-replies) lives
2038
+ * here.
2039
+ */
2040
+ declare const RPC_PREFIX = "rpc:v1:";
2041
+ type RpcKind = "req" | "ack" | "nack" | "progress" | "result" | "cancel" | "hb" | "register" | "unregister";
2042
+ interface RpcFrame {
2043
+ kind: RpcKind;
2044
+ id: string;
2045
+ ts?: number;
2046
+ from?: string;
2047
+ to?: string;
2048
+ method?: string;
2049
+ args?: unknown;
2050
+ deadline_ms?: number;
2051
+ data?: unknown;
2052
+ error?: RpcErrorPayload;
2053
+ by?: "server" | "runner";
2054
+ runner_id?: string;
2055
+ seq?: number;
2056
+ methods?: string[];
2057
+ }
2058
+ interface RpcErrorPayload {
2059
+ code: string;
2060
+ message: string;
2061
+ details?: unknown;
2062
+ }
2063
+ type RpcErrorCode = "NO_HANDLER" | "HANDLER_GONE" | "TIMEOUT" | "CANCELLED" | "RATE_LIMITED" | "UNAUTHORIZED" | "SCHEMA" | "INTERNAL" | "APP" | string;
2064
+ /** Thrown by `rpc.call(...)` on terminal nack / error / timeout. */
2065
+ declare class RpcError extends Error {
2066
+ code: RpcErrorCode;
2067
+ details?: unknown;
2068
+ constructor(code: RpcErrorCode, message: string, details?: unknown);
2069
+ }
2070
+ /**
2071
+ * Minimal provider surface RpcClient needs. The base provider already
2072
+ * satisfies it; the indirection is here so handlers can be tested against
2073
+ * a stub without booting a Y.Doc.
2074
+ */
2075
+ interface RpcTransport {
2076
+ sendStateless(payload: string): void;
2077
+ on(event: string, fn: Function): unknown;
2078
+ off(event: string, fn?: Function): unknown;
2079
+ }
2080
+ type RpcTarget = {
2081
+ kind: "role";
2082
+ role: "service";
2083
+ } | {
2084
+ kind: "user";
2085
+ userId: string;
2086
+ } | {
2087
+ kind: "runner";
2088
+ sessionId: string;
2089
+ };
2090
+ interface RpcCallOptions {
2091
+ /** Defaults to `{ kind: "role", role: "service" }`. */
2092
+ target?: RpcTarget;
2093
+ /** Wall-clock deadline in ms. Server clamps to its own ceiling. */
2094
+ deadline?: number;
2095
+ /** Abort the call (sends `rpc:cancel` to the runner). */
2096
+ signal?: AbortSignal;
2097
+ /** Fired when a runner claims the call (after the server ack). */
2098
+ onClaim?: (runnerId: string) => void;
2099
+ /** Fired for every `rpc:progress` frame the runner emits. */
2100
+ onProgress?: (data: unknown, seq: number) => void;
2101
+ }
2102
+ interface RpcCallHandle<T = unknown> extends Promise<T> {
2103
+ /** RPC id (UUID v7) — useful for log correlation. */
2104
+ readonly id: string;
2105
+ /** Runner session id, populated once a runner has claimed the call. */
2106
+ readonly claimedBy: string | undefined;
2107
+ /** Cancel the call. Equivalent to `signal.abort()` if a signal was passed. */
2108
+ cancel(reason?: string): void;
2109
+ }
2110
+ /**
2111
+ * Handler signature for a runner-side RPC handler.
2112
+ *
2113
+ * Returning a value emits `rpc:result(ok)`. Throwing emits
2114
+ * `rpc:result(err)` — `RpcError` instances pass through their `code` and
2115
+ * `details`; any other thrown value becomes `INTERNAL`.
2116
+ *
2117
+ * Returning an async generator turns each `yield` into a `rpc:progress`
2118
+ * frame (with monotonic `seq`); the generator's return value is the final
2119
+ * `result.data`.
2120
+ */
2121
+ type RpcHandler = (args: unknown, ctx: RpcHandlerContext) => unknown | Promise<unknown> | AsyncGenerator<unknown, unknown, void>;
2122
+ interface RpcHandlerContext {
2123
+ id: string;
2124
+ method: string;
2125
+ /** Server-stamped caller user id. Trusted. */
2126
+ from: string;
2127
+ /** Aborted when the caller cancels or the deadline is reached. */
2128
+ signal: AbortSignal;
2129
+ }
2130
+ /**
2131
+ * Per-provider RPC layer. Construct one and attach by passing the provider
2132
+ * (or any `RpcTransport`). Disposes on `destroy()`.
2133
+ *
2134
+ * Caller side: `rpc.call('ai.summarize@1', { docId }, { onProgress })`.
2135
+ *
2136
+ * Runner side: `rpc.handle('ai.summarize@1', async (args, ctx) => …)`.
2137
+ */
2138
+ declare class RpcClient extends EventEmitter {
2139
+ private readonly transport;
2140
+ private readonly pending;
2141
+ private readonly handlers;
2142
+ /** Tracks live runner-side invocations so we can route `rpc:cancel`. */
2143
+ private readonly runningHandlers;
2144
+ /** Pending register frames awaiting server ack — resolved by id. */
2145
+ private readonly pendingRegistrations;
2146
+ /** Grace timer armed on `disconnect`; cancelled on `connect`. Fires
2147
+ * `HANDLER_GONE` on every pending RPC if the WS is still down after
2148
+ * the grace window. v1 used to wait `deadline + 5s` which could be
2149
+ * 35s on default deadlines — way too long for a definitively-dead
2150
+ * connection. */
2151
+ private disconnectGrace;
2152
+ private static readonly DISCONNECT_GRACE_MS;
2153
+ private readonly onStatelessBound;
2154
+ /**
2155
+ * Replays all live `register` frames whenever the underlying provider
2156
+ * (re)syncs — covers WebSocket reconnects where the server allocated a
2157
+ * new session id and the old capability entries were freed.
2158
+ */
2159
+ private readonly onSyncedBound;
2160
+ private readonly onDisconnectBound;
2161
+ private readonly onConnectBound;
2162
+ private destroyed;
2163
+ constructor(transport: RpcTransport);
2164
+ private armDisconnectGrace;
2165
+ private cancelDisconnectGrace;
2166
+ /**
2167
+ * Called when the WS has been down for the full grace window. Every
2168
+ * in-flight call is dead from the server's perspective (its `close_session`
2169
+ * already fired `HANDLER_GONE` to a now-disconnected caller; on reconnect
2170
+ * the server-side session is fresh, so any cached cancel/result frames
2171
+ * the server tried to deliver were lost). Fail pending immediately.
2172
+ */
2173
+ private failPendingOnDisconnect;
2174
+ /**
2175
+ * Re-emit a `register` frame for every locally-known handler. Called on
2176
+ * every `synced` event from the provider, since a reconnected WS gets a
2177
+ * fresh server-side session with empty capability state.
2178
+ */
2179
+ private replayRegistrations;
2180
+ destroy(): void;
2181
+ /**
2182
+ * Send an RPC and return a handle that resolves with the runner's result.
2183
+ * Throws `RpcError` on nack / handler error / timeout / cancellation.
2184
+ */
2185
+ call<T = unknown>(method: string, args?: unknown, options?: RpcCallOptions): RpcCallHandle<T>;
2186
+ private abortInFlight;
2187
+ /**
2188
+ * Register a handler for `method` and advertise it to the server so
2189
+ * incoming `to: role:service` calls resolve here. Returns an unsubscribe
2190
+ * function. Calling `register` twice for the same method replaces the
2191
+ * handler and re-advertises.
2192
+ *
2193
+ * The advertise is fire-and-forget; if you need to wait until the server
2194
+ * has acknowledged registration (typical in tests with a separate caller
2195
+ * connection), `await rpc.ready()` after registering all handlers.
2196
+ */
2197
+ handle(method: string, handler: RpcHandler): () => void;
2198
+ /**
2199
+ * Resolve once every outstanding `register` frame has been acknowledged
2200
+ * by the server. Useful when a separate connection is about to issue
2201
+ * `rpc.call(...)` and you need the capability registry to be live first.
2202
+ * Resolves immediately if there's nothing pending.
2203
+ */
2204
+ ready(): Promise<void>;
2205
+ private send;
2206
+ private receive;
2207
+ private onAck;
2208
+ private onProgress;
2209
+ private onResult;
2210
+ private onNack;
2211
+ private settle;
2212
+ private onReq;
2213
+ private onCancel;
2214
+ }
2215
+ //#endregion
1570
2216
  //#region packages/provider/src/AbracadabraBaseProvider.d.ts
1571
2217
  type AbracadabraBaseProviderConfiguration = Required<Pick<CompleteAbracadabraBaseProviderConfiguration, "name">> & Partial<CompleteAbracadabraBaseProviderConfiguration> & ((Required<Pick<CompleteAbracadabraWSConfiguration, "url">> & Partial<Pick<CompleteAbracadabraWSConfiguration, "preserveTrailingSlash">>) | Required<Pick<CompleteAbracadabraBaseProviderConfiguration, "websocketProvider">>);
1572
2218
  /** @deprecated Use AbracadabraBaseProviderConfiguration */
@@ -1637,6 +2283,13 @@ declare class AbracadabraBaseProvider extends EventEmitter {
1637
2283
  intervals: {
1638
2284
  forceSync: ReturnType<typeof setInterval> | null;
1639
2285
  };
2286
+ /**
2287
+ * Lazily-constructed RPC v1 client. See `RpcClient`/`docs/rpc-v1.md`.
2288
+ * Bound to this provider's stateless transport, so calls and handlers
2289
+ * ride the doc this provider is subscribed to.
2290
+ */
2291
+ private _rpc;
2292
+ get rpc(): RpcClient;
1640
2293
  constructor(configuration: AbracadabraBaseProviderConfiguration);
1641
2294
  boundDocumentUpdateHandler: (update: Uint8Array, origin: any) => void;
1642
2295
  boundAwarenessUpdateHandler: ({
@@ -1732,7 +2385,7 @@ declare const awarenessStatesToArray: (states: Map<number, Record<string, any>>)
1732
2385
  declare class SubdocMessage extends OutgoingMessage {
1733
2386
  type: MessageType;
1734
2387
  description: string;
1735
- get(args: Partial<OutgoingMessageArguments>): Encoder;
2388
+ get(args: Partial<AbracadabraOutgoingMessageArguments>): Encoder;
1736
2389
  }
1737
2390
  //#endregion
1738
2391
  //#region packages/provider/src/SearchIndex.d.ts
@@ -1986,18 +2639,15 @@ declare function makeEncryptedYText(ydoc: Y.Doc, fieldName: string, docKey: Cryp
1986
2639
  * Attach an observer that writes `updatedAt` to the root doc-tree entry for
1987
2640
  * `childDocId` whenever the child doc receives a non-offline update.
1988
2641
  *
1989
- * Writes are throttled: the first qualifying update records the timestamp;
1990
- * a trailing-edge timer flushes it to the tree map after `throttleMs`.
1991
- *
1992
2642
  * @param treeMap The root doc's "doc-tree" Y.Map.
1993
2643
  * @param childDocId The child document's UUID (key in treeMap).
1994
2644
  * @param childDoc The child Y.Doc to observe.
1995
2645
  * @param offlineStore The child provider's OfflineStore (used to detect
1996
2646
  * offline-replay origins and skip them). Pass null when
1997
2647
  * the offline store is disabled.
1998
- * @param options Optional config. `throttleMs` controls the write
1999
- * interval (default 5000).
2000
- * @returns Cleanup function — call on provider destroy. Flushes
2648
+ * @param options Optional config. `throttleMs` controls the throttle
2649
+ * window (default 5000).
2650
+ * @returns Cleanup function — call on provider destroy. Flushes
2001
2651
  * any pending write before detaching.
2002
2652
  */
2003
2653
  declare function attachUpdatedAtObserver(treeMap: Y.Map<any>, childDocId: string, childDoc: Y.Doc, offlineStore: OfflineStore | null, options?: {
@@ -2375,6 +3025,10 @@ declare class FileTransferHandle extends EventEmitter {
2375
3025
  _setProgress(p: number): void;
2376
3026
  /** @internal */
2377
3027
  _setStatus(s: FileTransferStatus): void;
3028
+ /** @internal — public alias for the protected emit so the parent
3029
+ * `FileTransferChannel` (a different class instance) can dispatch events
3030
+ * on this handle. Protected access is by-class, not by-hierarchy. */
3031
+ _emit(event: string, ...args: unknown[]): void;
2378
3032
  }
2379
3033
  /**
2380
3034
  * Chunked binary file transfer over a dedicated WebRTC data channel.
@@ -2988,7 +3642,6 @@ declare class DeviceRegistrationService {
2988
3642
  //#region packages/provider/src/ChatClient.d.ts
2989
3643
  /**
2990
3644
  * Minimal provider surface ChatClient needs. Matches `AbracadabraBaseProvider`.
2991
- * Kept as an interface so consumers can pass any compatible transport.
2992
3645
  */
2993
3646
  interface ChatClientTransport {
2994
3647
  sendStateless(payload: string): void;
@@ -2996,98 +3649,305 @@ interface ChatClientTransport {
2996
3649
  off(event: string, fn?: Function): unknown;
2997
3650
  }
2998
3651
  /**
2999
- * Typed client for the Abracadabra chat feature.
3652
+ * Send a chat message into a channel doc.
3653
+ *
3654
+ * `channel_doc_id` is the UUID of the channel/dm doc — `documents.id` for
3655
+ * a row with `kind = "channel"` or `kind = "dm"`. Group channels under a
3656
+ * Space pass the channel doc's id; DMs pass the DM doc's id (callers
3657
+ * resolve "the DM doc between user A and user B" via their own path —
3658
+ * typically `client.listChildren(serverRootId)` filtered by `kind === "dm"`
3659
+ * with both pubkeys in `permissions`).
3660
+ */
3661
+ interface SendMessageInput {
3662
+ channel_doc_id: string;
3663
+ content: string;
3664
+ /** Cleartext recipient pubkeys for server-side mention fan-out. */
3665
+ mentions?: string[];
3666
+ /** Message id this is a reply to. */
3667
+ reply_to?: string;
3668
+ /**
3669
+ * Optional Ed25519 signature over the canonical envelope, base64url. When
3670
+ * server config `[messages].require_client_sig = true`, sends without a
3671
+ * sig are rejected. Default-config servers accept unsigned sends — the
3672
+ * threat model relies on JWT-bound session auth + the server's own
3673
+ * `server_sig` over `(msg_id, period_id, ts, sig)`.
3674
+ */
3675
+ sig?: string;
3676
+ /** Client-side timestamp (ms) for skew-tolerance check. Optional. */
3677
+ ts_hint?: number;
3678
+ }
3679
+ interface SendMessageResult {
3680
+ message_id: string;
3681
+ period_id: string;
3682
+ ts: number;
3683
+ server_sig: string;
3684
+ }
3685
+ interface EditMessageInput {
3686
+ channel_doc_id: string;
3687
+ message_id: string;
3688
+ content: string;
3689
+ sig?: string;
3690
+ }
3691
+ interface DeleteMessageInput {
3692
+ channel_doc_id: string;
3693
+ message_id: string;
3694
+ }
3695
+ interface MarkReadInput {
3696
+ channel_doc_id: string;
3697
+ period_id: string;
3698
+ message_id: string;
3699
+ /** Unix milliseconds. Defaults to server time. */
3700
+ ts?: number;
3701
+ }
3702
+ /**
3703
+ * Thin façade over the `messages:*` stateless protocol.
3000
3704
  *
3001
- * Wraps a connected provider (or base provider) and translates JSON envelopes
3002
- * on the stateless channel into typed method calls and events.
3705
+ * The unified messages model stores chat history as Y.Array entries on
3706
+ * `kind = "channel-period"` child docs of channel/dm docs (and notifications
3707
+ * as entries on a per-user `kind = "inbox"` doc). Reading history, listing
3708
+ * channels, observing real-time messages, and tracking read cursors are all
3709
+ * Y.Doc-shaped operations that the SDK consumer performs via
3710
+ * `AbracadabraClient` + `AbracadabraProvider` directly — not through this
3711
+ * façade. ChatClient handles only the *write-and-validate* path (sends,
3712
+ * edits, deletes, typing, mark-read), where the server is the sole authority
3713
+ * over the channel-period Y.Array.
3003
3714
  *
3004
3715
  * Events emitted:
3005
- * - `message` ChatMessage (new message broadcast)
3006
- * - `typing` → ChatTypingEvent (typing indicator broadcast)
3007
- * - `readReceipt` → ChatReadReceipt (mark_read broadcast)
3716
+ * - `typing` ChatTypingEvent (typing broadcast on the channel doc)
3717
+ *
3718
+ * For incoming-message observation, the consumer opens an
3719
+ * `AbracadabraProvider` on the active period doc and observes its
3720
+ * `messages` Y.Array directly. The dashboard's `useChat` composable does
3721
+ * this; the integration tests do this; external consumers should mirror
3722
+ * the pattern.
3008
3723
  */
3009
3724
  declare class ChatClient extends EventEmitter {
3010
3725
  private readonly provider;
3011
3726
  private readonly responseTimeoutMs;
3012
3727
  private readonly pending;
3013
3728
  private readonly boundOnStateless;
3729
+ private readonly boundOnServerError;
3014
3730
  constructor(provider: ChatClientTransport, options?: {
3015
3731
  responseTimeoutMs?: number;
3016
3732
  });
3017
- /** Stop listening for chat messages. Does not disconnect the underlying provider. */
3018
3733
  destroy(): void;
3019
- /** Send a chat message on a channel. Fire-and-forget (the server broadcasts). */
3020
- sendMessage(input: SendChatMessageInput): void;
3021
- /** Fetch historical messages for a channel. Resolves with the server response. */
3022
- getHistory(input: GetChatHistoryInput): Promise<{
3023
- channel: string;
3024
- messages: ChatMessage[];
3025
- }>;
3026
- /** Broadcast a typing indicator on a channel. */
3027
- sendTyping(channel: string): void;
3028
- /** List the current user's channels (ordered by last activity). */
3029
- listChannels(): Promise<{
3030
- channels: ChatChannel[];
3031
- }>;
3032
- /** Mark a channel read up to `timestamp` (unix ms). */
3033
- markRead(channel: string, timestamp: number): void;
3034
- /** Fetch per-user read cursors for a channel. */
3035
- getReadCursors(channel: string): Promise<{
3036
- channel: string;
3037
- cursors: ChatReadCursor[];
3038
- }>;
3039
- onMessage(fn: (m: ChatMessage) => void): this;
3734
+ /** Send a chat message. Resolves with the server-assigned id, ts, and signatures. */
3735
+ send(input: SendMessageInput): Promise<SendMessageResult>;
3736
+ /** Edit a previously-sent message. Append-only server records an `edit` entry. */
3737
+ edit(input: EditMessageInput): Promise<void>;
3738
+ /** Delete a message. Append-only — server records a `tombstone` entry. */
3739
+ delete(input: DeleteMessageInput): Promise<void>;
3740
+ /** Broadcast a typing indicator on a channel. Fire-and-forget. */
3741
+ typing(channel_doc_id: string): void;
3742
+ /** Mark a (period, message) position as read for the calling user. Fire-and-forget. */
3743
+ markRead(input: MarkReadInput): void;
3744
+ /** Observe typing broadcasts. */
3040
3745
  onTyping(fn: (e: ChatTypingEvent) => void): this;
3041
- onReadReceipt(fn: (e: ChatReadReceipt) => void): this;
3042
3746
  private enqueue;
3043
3747
  private removePending;
3044
3748
  private resolveNext;
3749
+ private rejectNext;
3045
3750
  private handleStateless;
3751
+ private handleServerError;
3752
+ }
3753
+ //#endregion
3754
+ //#region packages/provider/src/EncryptedChatClient.d.ts
3755
+ /**
3756
+ * Returns true if `content` is wrapped by this module (i.e. an `e2e:1:`
3757
+ * envelope). Cleartext content always returns false.
3758
+ */
3759
+ declare function isEncryptedContent(content: string): boolean;
3760
+ /**
3761
+ * Decrypt an `e2e:1:` envelope back to cleartext using the channel's
3762
+ * DocKey. Returns null if the envelope is malformed (don't surface
3763
+ * partial decryption — show the user a placeholder instead).
3764
+ */
3765
+ declare function decryptChatContent(content: string, docKey: CryptoKey): Promise<string | null>;
3766
+ /**
3767
+ * Encrypt cleartext into an `e2e:1:` envelope ready to send as the
3768
+ * stateless `messages:send` `content` field.
3769
+ */
3770
+ declare function encryptChatContent(content: string, docKey: CryptoKey): Promise<string>;
3771
+ /**
3772
+ * Per-channel encryption-mode + DocKey resolver. Caches the encryption
3773
+ * mode lookup for `cacheTtlMs`; the DocKey itself is cached inside
3774
+ * `DocKeyManager`. Returns `null` for non-E2E channels.
3775
+ */
3776
+ declare class ChannelKeyResolver {
3777
+ private readonly client;
3778
+ private readonly docKeys;
3779
+ private readonly keystore;
3780
+ private readonly options;
3781
+ private modeCache;
3782
+ private static readonly DEFAULT_TTL_MS;
3783
+ constructor(client: AbracadabraClient, docKeys: DocKeyManager, keystore: CryptoIdentityKeystore, options?: {
3784
+ cacheTtlMs?: number;
3785
+ });
3786
+ modeFor(channelDocId: string): Promise<"none" | "cse" | "e2e">;
3787
+ /**
3788
+ * Returns the DocKey for an E2E channel, or null for cleartext channels
3789
+ * (no envelope to fetch). Throws if the channel is E2E but no envelope
3790
+ * exists for the current user — the caller should let the send fail
3791
+ * loudly rather than fall back to cleartext, which would silently
3792
+ * downgrade the threat model.
3793
+ */
3794
+ docKeyFor(channelDocId: string): Promise<CryptoKey | null>;
3795
+ /** Drop the cached encryption mode for `channelDocId` (or all). */
3796
+ clearCache(channelDocId?: string): void;
3797
+ }
3798
+ /**
3799
+ * Drop-in wrapper around an existing ChatClient that intercepts the
3800
+ * write side (`send` / `edit`) and encrypts content for E2E channels.
3801
+ * Reading is handled separately — the consumer pumps the period's Y.Array
3802
+ * directly and calls `decryptChatContent` per record.
3803
+ *
3804
+ * Channels in `none` or `cse` mode are passed through untouched.
3805
+ */
3806
+ declare class EncryptedChatClient {
3807
+ private readonly inner;
3808
+ private readonly resolver;
3809
+ constructor(inner: ChatClient, resolver: ChannelKeyResolver);
3810
+ send(input: SendMessageInput): Promise<SendMessageResult>;
3811
+ edit(input: EditMessageInput): Promise<void>;
3812
+ delete(...args: Parameters<ChatClient["delete"]>): Promise<void>;
3813
+ markRead(...args: Parameters<ChatClient["markRead"]>): void;
3814
+ typing(...args: Parameters<ChatClient["typing"]>): void;
3815
+ destroy(): void;
3816
+ }
3817
+ //#endregion
3818
+ //#region packages/provider/src/messageRecord.d.ts
3819
+ /**
3820
+ * Decode + fold message records from a period doc's `messages` Y.Array
3821
+ * into the flat `ChatMessage[]` shape the dashboard renders.
3822
+ *
3823
+ * The server appends three kinds of records to the array (see
3824
+ * `abracadabra-rs/crates/abracadabra/src/messages.rs`):
3825
+ *
3826
+ * - `record_kind: "message"` — a real message (default kind).
3827
+ * - `record_kind: "edit"` — an updated version of `target_id`.
3828
+ * - `record_kind: "tombstone"` — `target_id` is deleted.
3829
+ *
3830
+ * Folding rules:
3831
+ * - For each `target_id`, apply edits in `ts` order; the *last* edit's
3832
+ * content wins. The original message's id, sender_id, and ts stay.
3833
+ * `editedAt` is the latest edit's ts.
3834
+ * - Any target_id with a tombstone is dropped from the output entirely.
3835
+ * - Records without record_kind default to "message" (back-compat).
3836
+ *
3837
+ * Cross-period folding: edits and tombstones can in principle target a
3838
+ * message in a *prior* period (e.g. user edits a message that lived on
3839
+ * the previous period after rollover). Callers that paginate across
3840
+ * periods should fold the joined list, not each period independently.
3841
+ */
3842
+ interface MessageRecord {
3843
+ record_kind?: 'message' | 'edit' | 'tombstone';
3844
+ id: string;
3845
+ target_id?: string;
3846
+ sender_id: string;
3847
+ channel_doc_id: string;
3848
+ period_id: string;
3849
+ ts: number;
3850
+ content: string;
3851
+ mentions?: string[];
3852
+ reply_to?: string | null;
3853
+ sig?: string;
3854
+ server_sig?: string;
3855
+ }
3856
+ interface FoldedMessage {
3857
+ id: string;
3858
+ channel: string;
3859
+ senderId: string;
3860
+ senderName?: string;
3861
+ content: string;
3862
+ createdAt: number;
3863
+ /** Set if the message has been edited at least once. */
3864
+ editedAt?: number;
3865
+ /** Reply target message id, if any. */
3866
+ replyTo?: string;
3046
3867
  }
3868
+ /**
3869
+ * Fold an ordered list of records (oldest-first) into the visible
3870
+ * messages a UI should render. Records may come from one period or
3871
+ * across multiple periods concatenated in time order.
3872
+ */
3873
+ declare function foldRecords(records: MessageRecord[]): FoldedMessage[];
3874
+ /**
3875
+ * Decode whatever the Y.Array stored for an entry into a MessageRecord.
3876
+ * Note: the server stamps `ts` server-side via `Any::BigInt(now_ts_ms())`,
3877
+ * so on the wire it round-trips as a JS BigInt — `typeof` is `'bigint'`,
3878
+ * not `'number'`. Accept both and coerce.
3879
+ */
3880
+ declare function recordFromYAny(any: unknown): MessageRecord | null;
3047
3881
  //#endregion
3048
3882
  //#region packages/provider/src/NotificationsClient.d.ts
3883
+ /** Per-user inbox doc entry. Mirrors `InboxEntry` on the server. */
3884
+ interface InboxEntry {
3885
+ id: string;
3886
+ /** "mention" | "reply" | "dm" | "system". */
3887
+ kind: string;
3888
+ channel_doc_id: string;
3889
+ message_id?: string | null;
3890
+ sender_id?: string | null;
3891
+ sender_name?: string | null;
3892
+ /** Empty for E2E channels (server can't read body). Filled otherwise. */
3893
+ preview?: string | null;
3894
+ ts: number;
3895
+ /** Synthesized client-side from the inbox doc's `read` Y.Map. */
3896
+ read: boolean;
3897
+ }
3898
+ interface FetchInboxInput {
3899
+ before?: number;
3900
+ limit?: number;
3901
+ unread_only?: boolean;
3902
+ }
3903
+ interface MarkReadInput$1 {
3904
+ id?: string;
3905
+ ids?: string[];
3906
+ source_id?: string;
3907
+ all?: boolean;
3908
+ }
3049
3909
  /**
3050
- * Typed client for the Abracadabra notifications feature.
3910
+ * Thin façade over the `messages:inbox_*` stateless protocol.
3911
+ *
3912
+ * Per-user notifications live as Y.Array entries on the user's inbox doc
3913
+ * (`kind = "inbox"`, owned by the user, child of the server root, server-only
3914
+ * writer). Real-time observation of new entries is a Y.Array observer the
3915
+ * consumer attaches via `AbracadabraProvider` on the inbox doc.
3916
+ *
3917
+ * This client handles only the request/response layer:
3918
+ * - `fetch()` issues `messages:inbox_fetch`, returns the entry list.
3919
+ * - `markRead()` issues `messages:inbox_mark_read` (id / ids / source_id /
3920
+ * all variants).
3051
3921
  *
3052
- * Emits:
3053
- * - `new` NotificationRecord (incoming notify:new broadcast)
3054
- * - `readUpdate` NotificationReadUpdate (broadcast after mark_read / mark_all_read)
3922
+ * For incoming notification observation, open an AbracadabraProvider on the
3923
+ * inbox doc and observe its `entries` Y.Array directly. The dashboard's
3924
+ * `useNotifications` composable does this.
3055
3925
  */
3056
3926
  declare class NotificationsClient extends EventEmitter {
3057
3927
  private readonly provider;
3058
3928
  private readonly responseTimeoutMs;
3059
3929
  private readonly pending;
3060
3930
  private readonly boundOnStateless;
3931
+ private readonly boundOnServerError;
3061
3932
  constructor(provider: ChatClientTransport, options?: {
3062
3933
  responseTimeoutMs?: number;
3063
3934
  });
3064
3935
  destroy(): void;
3936
+ /** Fetch a slice of the calling user's inbox. Resolves with the entries. */
3937
+ fetch(input?: FetchInboxInput): Promise<{
3938
+ entries: InboxEntry[];
3939
+ }>;
3065
3940
  /**
3066
- * Create a notification targeting a specific recipient. Requires elevated role
3067
- * (service or admin); a `server:error` event with code `forbidden` is emitted
3068
- * by the underlying provider if the caller lacks permission.
3941
+ * Mark inbox entries read. One of `id`, `ids`, `source_id`, or `all`.
3942
+ * Returns when the server has acked.
3069
3943
  */
3070
- create(input: CreateNotificationInput): void;
3071
- /** Fetch notification history for the current user. */
3072
- fetch(input?: FetchNotificationsInput): Promise<{
3073
- notifications: NotificationRecord[];
3074
- }>;
3075
- /** Mark a single notification, or a batch, as read. */
3076
- markRead(target: {
3077
- id: string;
3078
- } | {
3079
- ids: string[];
3080
- }): void;
3081
- /** Mark every notification for the current user as read. */
3082
- markAllRead(): void;
3083
- /** Mark all notifications generated by the given source (e.g. a chat channel) as read. */
3084
- markReadBySource(sourceId: string): void;
3085
- onNew(fn: (n: NotificationRecord) => void): this;
3086
- onReadUpdate(fn: (u: NotificationReadUpdate) => void): this;
3944
+ markRead(input: MarkReadInput$1): Promise<void>;
3087
3945
  private enqueue;
3088
3946
  private removePending;
3089
3947
  private resolveNext;
3948
+ private rejectNext;
3090
3949
  private handleStateless;
3950
+ private handleServerError;
3091
3951
  }
3092
3952
  //#endregion
3093
3953
  //#region node_modules/@scure/bip39/esm/wordlists/english.d.ts
@@ -3157,4 +4017,536 @@ declare function wrapSeed(seed: Uint8Array, wrappingKeyBytes: Uint8Array): Promi
3157
4017
  */
3158
4018
  declare function unwrapSeed(ciphertext: ArrayBuffer, iv: Uint8Array, wrappingKeyBytes: Uint8Array): Promise<Uint8Array>;
3159
4019
  //#endregion
3160
- export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebRTC, type AbracadabraWebRTCConfiguration, AbracadabraWebSocketConn, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, type ChatChannel, ChatClient, type ChatClientTransport, type ChatMessage, type ChatReadCursor, type ChatReadReceipt, type ChatTypingEvent, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, type CreateNotificationInput, CryptoIdentity, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, DevicePairingChannel, type DevicePairingConfig, DeviceRegistrationService, type DeviceServerStatus, type DeviceTier, type DocEncryptionInfo, DocKeyManager, type DocSyncState, DocumentCache, type DocumentCacheOptions, DocumentMeta, E2EAbracadabraProvider, E2EEChannel, type E2EEIdentity, E2EOfflineStore, EffectivePermissionEntry, EffectivePermissionsResponse, EffectiveRole, EncryptedYMap, EncryptedYText, type FetchNotificationsInput, FileBlobStore, FileTransferChannel, FileTransferHandle, type FileTransferMeta, type FileTransferStatus, Forbidden, type GetChatHistoryInput, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, type IdentityDeviceEntry, type IdentityDocConfiguration, IdentityDocProvider, type IdentityProfile, type IdentityServerEntry, type IdentitySpaceEntry, InviteRow, KEY_EXCHANGE_CHANNEL, ManualSignaling, type ManualSignalingBlob, MessageTooBig, MessageType, type NotificationReadUpdate, type NotificationRecord, NotificationsClient, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, type PairingRequest, type PairingResult, PeerConnection, type PeerInfo, type PeerState, PendingSubdoc, PermissionEntry, PublicKeyInfo, ResetConnection, SearchIndex, SearchResult, type SendChatMessageInput, ServerInfo, type SignalingIncoming, type SignalingOutgoing, SignalingSocket, SnapshotCreateResult, SnapshotData, SnapshotForkResult, SnapshotMeta, SnapshotRestoreResult, SpaceMeta, StatesArray, SubdocMessage, SubdocRegisteredEvent, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserProfile, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptField, generateMnemonic, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onCompactedParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onServerErrorParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, readAuthMessage, unwrapSeed, validateMnemonic, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest };
4020
+ //#region packages/provider/src/DocTypes.d.ts
4021
+ /**
4022
+ * Canonical type definitions for Abracadabra document tree entries, page
4023
+ * metadata, and the static page-type catalog.
4024
+ *
4025
+ * These types were previously scattered across `mcp/converters/types.ts` and
4026
+ * `mcp/converters/page-types.ts`. By living in the provider package they
4027
+ * become first-class SDK types that any consumer (`@abraca/dabra`) can import
4028
+ * directly, removing the need for fragile relative-path re-exports.
4029
+ */
4030
+ type MetaFieldType = 'datetimerange' | 'daterange' | 'timerange' | 'datetime' | 'date' | 'time' | 'slider' | 'number' | 'toggle' | 'select' | 'multiselect' | 'colorPreset' | 'colorPicker' | 'location' | 'icon' | 'textarea' | 'url' | 'rating' | 'tags' | 'members';
4031
+ interface UserMetaField {
4032
+ id: string;
4033
+ type: string;
4034
+ label?: string;
4035
+ key?: string;
4036
+ latKey?: string;
4037
+ lngKey?: string;
4038
+ startKey?: string;
4039
+ endKey?: string;
4040
+ allDayKey?: string;
4041
+ presets?: string[];
4042
+ options?: string[];
4043
+ min?: number;
4044
+ max?: number;
4045
+ step?: number;
4046
+ unit?: string;
4047
+ default?: boolean;
4048
+ }
4049
+ interface PageMeta extends Record<string, unknown> {
4050
+ color?: string;
4051
+ icon?: string;
4052
+ subtitle?: string;
4053
+ note?: string;
4054
+ datetimeStart?: string;
4055
+ datetimeEnd?: string;
4056
+ allDay?: boolean;
4057
+ dateStart?: string;
4058
+ dateEnd?: string;
4059
+ timeStart?: string;
4060
+ timeEnd?: string;
4061
+ dateTaken?: string;
4062
+ checked?: boolean;
4063
+ priority?: number;
4064
+ status?: string;
4065
+ taskProgress?: number;
4066
+ rating?: number;
4067
+ tags?: string[];
4068
+ members?: {
4069
+ id: string;
4070
+ label: string;
4071
+ }[];
4072
+ url?: string;
4073
+ email?: string;
4074
+ phone?: string;
4075
+ number?: number;
4076
+ unit?: string;
4077
+ coverUploadId?: string;
4078
+ coverDocId?: string;
4079
+ coverMimeType?: string;
4080
+ geoType?: 'marker' | 'line' | 'measure';
4081
+ geoLat?: number;
4082
+ geoLng?: number;
4083
+ geoDescription?: string;
4084
+ deskX?: number;
4085
+ deskY?: number;
4086
+ deskZ?: number;
4087
+ deskMode?: string;
4088
+ mmX?: number;
4089
+ mmY?: number;
4090
+ graphX?: number;
4091
+ graphY?: number;
4092
+ graphPinned?: boolean;
4093
+ spShape?: string;
4094
+ spOpacity?: number;
4095
+ spX?: number;
4096
+ spY?: number;
4097
+ spZ?: number;
4098
+ spRX?: number;
4099
+ spRY?: number;
4100
+ spRZ?: number;
4101
+ spSX?: number;
4102
+ spSY?: number;
4103
+ spSZ?: number;
4104
+ spModelUploadId?: string;
4105
+ spModelDocId?: string;
4106
+ slidesTransition?: string;
4107
+ slidesTheme?: string;
4108
+ mediaDuration?: number;
4109
+ mediaWidth?: number;
4110
+ mediaHeight?: number;
4111
+ mediaCamera?: string;
4112
+ mediaLens?: string;
4113
+ mediaIso?: number;
4114
+ mediaFocalLength?: number;
4115
+ mediaAperture?: number;
4116
+ mediaShutterSpeed?: string;
4117
+ mediaArtist?: string;
4118
+ mediaAlbum?: string;
4119
+ mediaGenre?: string;
4120
+ mediaYear?: number;
4121
+ bold?: boolean;
4122
+ italic?: boolean;
4123
+ textColor?: string;
4124
+ bgColor?: string;
4125
+ align?: string;
4126
+ formula?: string;
4127
+ fileType?: string;
4128
+ entry?: boolean;
4129
+ kanbanColumnWidth?: string;
4130
+ galleryColumns?: number;
4131
+ galleryAspect?: string;
4132
+ galleryCardStyle?: string;
4133
+ galleryShowLabels?: boolean;
4134
+ gallerySortBy?: string;
4135
+ calendarView?: string;
4136
+ calendarWeekStart?: string;
4137
+ calendarShowWeekNumbers?: boolean;
4138
+ tableMode?: string;
4139
+ tableSortKey?: string;
4140
+ tableSortDir?: string;
4141
+ tableColumns?: any[];
4142
+ tableColumnWidths?: Record<string, number>;
4143
+ tableColumnOrder?: string[];
4144
+ timelineZoom?: string;
4145
+ timelinePixelsPerDay?: number;
4146
+ timelineCenterDate?: string;
4147
+ checklistFilter?: string;
4148
+ checklistSort?: string;
4149
+ mapShowLabels?: boolean;
4150
+ spatialGridVisible?: boolean;
4151
+ graphSpacing?: string;
4152
+ graphShowLabels?: boolean;
4153
+ graphEdgeThickness?: string;
4154
+ mmSpacing?: string;
4155
+ showRefEdges?: boolean;
4156
+ chartType?: string;
4157
+ chartMetric?: string;
4158
+ chartColorScheme?: string;
4159
+ chartLimit?: number;
4160
+ chartShowLegend?: boolean;
4161
+ chartShowValues?: boolean;
4162
+ mediaRepeat?: string;
4163
+ mediaShuffle?: boolean;
4164
+ sheetsDefaultColWidth?: number;
4165
+ sheetsDefaultRowHeight?: number;
4166
+ sheetsShowGridlines?: boolean;
4167
+ sheetsColumnWidths?: Record<string, number>;
4168
+ sheetsRowHeights?: Record<string, number>;
4169
+ sheetsFreezeRows?: number;
4170
+ sheetsFreezeCols?: number;
4171
+ _metaFields?: UserMetaField[];
4172
+ _metaInitialized?: boolean;
4173
+ }
4174
+ interface TreeEntry {
4175
+ id: string;
4176
+ label: string;
4177
+ parentId: string | null;
4178
+ order: number;
4179
+ type?: string;
4180
+ meta?: PageMeta;
4181
+ createdAt?: number;
4182
+ updatedAt?: number;
4183
+ }
4184
+ interface TreeNode {
4185
+ id: string;
4186
+ label: string;
4187
+ type?: string;
4188
+ meta?: PageMeta;
4189
+ order: number;
4190
+ children: TreeNode[];
4191
+ }
4192
+ interface TreeSearchResult {
4193
+ id: string;
4194
+ label: string;
4195
+ type?: string;
4196
+ meta?: PageMeta;
4197
+ /** Ancestor labels from root → parent. */
4198
+ path: string[];
4199
+ }
4200
+ interface PageTypeMetaField {
4201
+ type: MetaFieldType;
4202
+ label?: string;
4203
+ /** single-value fields */
4204
+ key?: string;
4205
+ /** location */
4206
+ latKey?: string;
4207
+ lngKey?: string;
4208
+ /** ranges */
4209
+ startKey?: string;
4210
+ endKey?: string;
4211
+ allDayKey?: string;
4212
+ /** color preset */
4213
+ presets?: string[];
4214
+ /** icon / select / tags */
4215
+ options?: string[];
4216
+ /** slider / number */
4217
+ min?: number;
4218
+ max?: number;
4219
+ step?: number;
4220
+ unit?: string;
4221
+ /** toggle default */
4222
+ default?: boolean;
4223
+ }
4224
+ interface PageTypeInfo {
4225
+ key: string;
4226
+ label: string;
4227
+ icon: string;
4228
+ description?: string;
4229
+ /** true = core type (always available); false = requires plugin */
4230
+ core: boolean;
4231
+ plugin?: string;
4232
+ supportsChildren: boolean;
4233
+ childLabel?: string;
4234
+ grandchildLabel?: string;
4235
+ /** -1 = unlimited depth */
4236
+ defaultDepth?: number;
4237
+ /** Fields that apply to this doc's descendants (children, grandchildren, ...) */
4238
+ metaSchema?: PageTypeMetaField[];
4239
+ /** Fields written to this doc's own meta on first render (renderer config) */
4240
+ defaultMetaFields?: PageTypeMetaField[];
4241
+ }
4242
+ declare const GEO_TYPE_META_SCHEMAS: Record<string, PageTypeMetaField[]>;
4243
+ declare const PAGE_TYPES: Record<string, PageTypeInfo>;
4244
+ declare const TYPE_ALIASES: Record<string, string>;
4245
+ declare function resolvePageType(key: string | undefined): PageTypeInfo | undefined;
4246
+ //#endregion
4247
+ //#region packages/provider/src/TreeManager.d.ts
4248
+ declare class TreeManager {
4249
+ private dm;
4250
+ constructor(dm: DocumentManager);
4251
+ /** Read all tree entries as plain objects. */
4252
+ readEntries(): TreeEntry[];
4253
+ /** Get immediate children of a parent (sorted by order). */
4254
+ childrenOf(parentId: string | null): TreeEntry[];
4255
+ /** Get all descendants recursively. */
4256
+ descendantsOf(parentId: string | null): TreeEntry[];
4257
+ /** Build nested tree JSON. */
4258
+ buildTree(rootId?: string | null, maxDepth?: number): TreeNode[];
4259
+ private _buildTree;
4260
+ /** Find a single entry by ID. */
4261
+ get(docId: string): TreeEntry | null;
4262
+ /** Search by label (case-insensitive substring match). */
4263
+ find(query: string, rootId?: string | null): TreeSearchResult[];
4264
+ /** Create a new document in the tree. Returns the new entry. */
4265
+ create(opts: {
4266
+ parentId?: string | null;
4267
+ label: string;
4268
+ type?: string;
4269
+ meta?: Partial<PageMeta>;
4270
+ }): TreeEntry;
4271
+ /**
4272
+ * Create a document and auto-apply renderer defaults from the page type's
4273
+ * `defaultMetaFields` (toggle fields with `default` values).
4274
+ */
4275
+ createWithTypeDefaults(opts: {
4276
+ parentId?: string | null;
4277
+ label: string;
4278
+ type: string;
4279
+ extraMeta?: Partial<PageMeta>;
4280
+ }): TreeEntry;
4281
+ /** Rename a document. */
4282
+ rename(docId: string, label: string): void;
4283
+ /** Move a document to a new parent. */
4284
+ move(docId: string, newParentId?: string | null, order?: number): void;
4285
+ /** Change the page type of a document. */
4286
+ changeType(docId: string, type: string): void;
4287
+ /**
4288
+ * Soft-delete a document and descendants (move to trash).
4289
+ * @returns count of deleted documents
4290
+ */
4291
+ delete(docId: string): number;
4292
+ /** Duplicate a document (shallow clone). Returns the new entry. */
4293
+ duplicate(docId: string): TreeEntry;
4294
+ /** Restore a document from trash back into the tree. */
4295
+ restore(docId: string): void;
4296
+ /** List trashed documents. */
4297
+ listTrash(): TreeEntry[];
4298
+ /** Get enabled plugin names from space-plugins map. */
4299
+ getEnabledPlugins(): string[];
4300
+ private _descendantIds;
4301
+ }
4302
+ //#endregion
4303
+ //#region packages/provider/src/DocConverters.d.ts
4304
+ /**
4305
+ * Converts a Y.XmlFragment (TipTap document) to markdown.
4306
+ * Extracts the title from the documentHeader element.
4307
+ *
4308
+ * @returns `{ title, markdown }` where title is the H1/header text
4309
+ */
4310
+ declare function yjsToMarkdown(fragment: Y.XmlFragment): {
4311
+ title: string;
4312
+ markdown: string;
4313
+ };
4314
+ declare function filenameToLabel(raw: string): string;
4315
+ interface FrontmatterResult {
4316
+ title?: string;
4317
+ meta: Partial<PageMeta>;
4318
+ body: string;
4319
+ }
4320
+ declare function parseFrontmatter(markdown: string): FrontmatterResult;
4321
+ declare function populateYDocFromMarkdown(fragment: Y.XmlFragment, markdown: string, fallbackTitle?: string): void;
4322
+ declare function buildHeadingElement(text: string, level?: 1 | 2 | 3 | 4 | 5 | 6): Y.XmlElement;
4323
+ declare function buildParagraphElement(text: string): Y.XmlElement;
4324
+ declare function buildBulletListElement(items: string[]): Y.XmlElement;
4325
+ declare function buildOrderedListElement(items: string[]): Y.XmlElement;
4326
+ declare function buildTaskListElement(items: Array<{
4327
+ text: string;
4328
+ checked?: boolean;
4329
+ }>): Y.XmlElement;
4330
+ declare function buildCodeBlockElement(code: string, language?: string): Y.XmlElement;
4331
+ declare function buildBlockquoteElement(text: string): Y.XmlElement;
4332
+ declare function buildHorizontalRuleElement(): Y.XmlElement;
4333
+ /** Parse markdown into block Y.XmlElements (no header/meta). */
4334
+ declare function buildBlocksFromMarkdown(markdown: string): Y.XmlElement[];
4335
+ interface DocumentBlock {
4336
+ type: string;
4337
+ attrs: Record<string, unknown>;
4338
+ text: string;
4339
+ items?: string[];
4340
+ children?: DocumentBlock[];
4341
+ }
4342
+ declare function readBlocksFromFragment(fragment: Y.XmlFragment): DocumentBlock[];
4343
+ //#endregion
4344
+ //#region packages/provider/src/ContentManager.d.ts
4345
+ interface DocumentContent {
4346
+ label: string;
4347
+ type?: string;
4348
+ meta?: PageMeta;
4349
+ title: string;
4350
+ markdown: string;
4351
+ children: Array<{
4352
+ id: string;
4353
+ label: string;
4354
+ type?: string;
4355
+ meta?: PageMeta;
4356
+ }>;
4357
+ }
4358
+ declare class ContentManager {
4359
+ private dm;
4360
+ constructor(dm: DocumentManager);
4361
+ /**
4362
+ * Read document content as markdown.
4363
+ * Returns the title extracted from the TipTap documentHeader, the markdown
4364
+ * body, tree metadata, and immediate children.
4365
+ */
4366
+ read(docId: string): Promise<DocumentContent>;
4367
+ /**
4368
+ * Write markdown content to a document.
4369
+ * Supports optional YAML frontmatter for title and metadata.
4370
+ *
4371
+ * @param mode - "replace" clears existing content first (default),
4372
+ * "append" adds to the end.
4373
+ */
4374
+ write(docId: string, markdown: string, mode?: "replace" | "append"): Promise<void>;
4375
+ private _appendElements;
4376
+ appendHeading(docId: string, text: string, opts?: {
4377
+ level?: 1 | 2 | 3 | 4 | 5 | 6;
4378
+ }): Promise<void>;
4379
+ appendParagraph(docId: string, text: string): Promise<void>;
4380
+ appendBulletList(docId: string, items: string[]): Promise<void>;
4381
+ appendOrderedList(docId: string, items: string[]): Promise<void>;
4382
+ appendTaskList(docId: string, items: Array<{
4383
+ text: string;
4384
+ checked?: boolean;
4385
+ }>): Promise<void>;
4386
+ appendCodeBlock(docId: string, code: string, opts?: {
4387
+ language?: string;
4388
+ }): Promise<void>;
4389
+ appendBlockquote(docId: string, text: string): Promise<void>;
4390
+ appendHorizontalRule(docId: string): Promise<void>;
4391
+ appendMarkdown(docId: string, markdown: string): Promise<void>;
4392
+ getBlocks(docId: string): Promise<DocumentBlock[]>;
4393
+ /**
4394
+ * Get the raw Y.XmlFragment for a document (the 'default' fragment
4395
+ * that TipTap uses for document content).
4396
+ */
4397
+ getFragment(docId: string): Promise<Y.XmlFragment>;
4398
+ /**
4399
+ * Get the raw Y.Doc for a document (synced).
4400
+ */
4401
+ getDoc(docId: string): Promise<Y.Doc>;
4402
+ }
4403
+ //#endregion
4404
+ //#region packages/provider/src/MetaManager.d.ts
4405
+ interface DocumentMetaInfo {
4406
+ id: string;
4407
+ label: string;
4408
+ type?: string;
4409
+ meta: PageMeta;
4410
+ }
4411
+ declare class MetaManager {
4412
+ private dm;
4413
+ constructor(dm: DocumentManager);
4414
+ /** Read metadata for a document. Returns null if not found. */
4415
+ get(docId: string): DocumentMetaInfo | null;
4416
+ /**
4417
+ * Merge fields into a document's metadata.
4418
+ * Existing keys not in the update are preserved.
4419
+ */
4420
+ update(docId: string, meta: Partial<PageMeta>): void;
4421
+ /**
4422
+ * Replace all metadata on a document.
4423
+ * This overwrites the entire meta object.
4424
+ */
4425
+ set(docId: string, meta: PageMeta): void;
4426
+ /**
4427
+ * Clear specific metadata keys (set them to null/undefined).
4428
+ */
4429
+ clear(docId: string, keys: string[]): void;
4430
+ }
4431
+ //#endregion
4432
+ //#region packages/provider/src/DocumentManager.d.ts
4433
+ interface DocumentManagerConfig {
4434
+ /** Server base URL (http or https). */
4435
+ url: string;
4436
+ /** Display name for awareness (cursor labels, presence). */
4437
+ name?: string;
4438
+ /** Cursor / awareness color. */
4439
+ color?: string;
4440
+ /** Invite code for first-time registration. */
4441
+ inviteCode?: string;
4442
+ /** Suppress stderr logging. */
4443
+ quiet?: boolean;
4444
+ /** Disable IndexedDB offline persistence. */
4445
+ disableOfflineStore?: boolean;
4446
+ /** Custom fetch for Node.js environments. */
4447
+ fetch?: typeof globalThis.fetch;
4448
+ /**
4449
+ * Pre-configured AbracadabraClient instance.
4450
+ * When provided, the `url` and `fetch` fields are ignored — the client's
4451
+ * configuration is used instead. This is useful when the consumer has
4452
+ * already authenticated or configured the client externally.
4453
+ */
4454
+ client?: AbracadabraClient;
4455
+ /**
4456
+ * Shared WebSocket connection. Required in Node.js environments — pass an
4457
+ * AbracadabraWS constructed with WebSocketPolyfill set to the `ws` package.
4458
+ * When omitted, each provider creates its own connection from client.wsUrl.
4459
+ * The caller owns this instance and must destroy it after dm.destroy().
4460
+ */
4461
+ websocketProvider?: AbracadabraWS;
4462
+ /**
4463
+ * Known root document ID. When provided, connect() skips server discovery
4464
+ * and connects directly to this document. Useful in tests or CLIs where
4465
+ * the entry-point docId is already known.
4466
+ */
4467
+ rootDocId?: string;
4468
+ }
4469
+ declare class DocumentManager {
4470
+ readonly client: AbracadabraClient;
4471
+ /** Tree CRUD operations. */
4472
+ readonly tree: TreeManager;
4473
+ /** Document content read/write. */
4474
+ readonly content: ContentManager;
4475
+ /** Document metadata read/write. */
4476
+ readonly meta: MetaManager;
4477
+ private _config;
4478
+ private _serverInfo;
4479
+ private _rootDocId;
4480
+ private _spaces;
4481
+ private _rootDoc;
4482
+ private _rootProvider;
4483
+ private childCache;
4484
+ constructor(config: DocumentManagerConfig);
4485
+ get displayName(): string;
4486
+ get displayColor(): string;
4487
+ get serverInfo(): ServerInfo | null;
4488
+ get rootDocId(): string | null;
4489
+ get rootDocument(): Y.Doc | null;
4490
+ get rootProvider(): AbracadabraProvider | null;
4491
+ /**
4492
+ * Spaces visible to the caller — direct children of the server root with
4493
+ * `kind === "space"`. Populated by {@link connect}.
4494
+ */
4495
+ get spaces(): DocumentMeta[];
4496
+ get isConnected(): boolean;
4497
+ /** Get the root doc-tree Y.Map. */
4498
+ getTreeMap(): Y.Map<any> | null;
4499
+ /** Get the root doc-trash Y.Map. */
4500
+ getTrashMap(): Y.Map<any> | null;
4501
+ /** Get the root space-plugins Y.Map. */
4502
+ getPluginsMap(): Y.Map<any> | null;
4503
+ /**
4504
+ * Connect to the server: discover the entry-point document, sync the root
4505
+ * Y.Doc, and set awareness.
4506
+ *
4507
+ * **Authentication must be done before calling connect().**
4508
+ * Call `dm.client.loginWithKey(publicKey, signFn)` or `dm.client.login()`
4509
+ * to authenticate first.
4510
+ *
4511
+ * When `rootDocId` is set in the config, server discovery is skipped and
4512
+ * the manager connects directly to that document.
4513
+ */
4514
+ connect(): Promise<void>;
4515
+ /** Switch active space to a different root document. */
4516
+ switchSpace(docId: string): Promise<void>;
4517
+ /** Create, sync, and set awareness on a root provider for the given docId. */
4518
+ private _connectToRoot;
4519
+ /** Graceful shutdown. */
4520
+ destroy(): Promise<void>;
4521
+ /** Get or create a child provider for a document (synced). */
4522
+ getChildProvider(docId: string): Promise<AbracadabraProvider>;
4523
+ private log;
4524
+ }
4525
+ //#endregion
4526
+ //#region packages/provider/src/DocUtils.d.ts
4527
+ /**
4528
+ * Wait for a provider's `synced` event with a timeout.
4529
+ * Resolves immediately if the provider is already synced.
4530
+ */
4531
+ declare function waitForSync(provider: {
4532
+ isSynced?: boolean;
4533
+ on(event: string, cb: () => void): void;
4534
+ off(event: string, cb: () => void): void;
4535
+ }, timeoutMs?: number): Promise<void>;
4536
+ /**
4537
+ * Wrap a promise with a timeout.
4538
+ */
4539
+ declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message?: string): Promise<T>;
4540
+ /**
4541
+ * Normalize a document ID so the hub/root doc ID is treated as the tree root
4542
+ * (null). This lets callers pass the hub doc_id from list_spaces as
4543
+ * parentId/rootId and get the expected root-level results instead of an empty
4544
+ * set.
4545
+ */
4546
+ declare function normalizeRootId(id: string | null | undefined, rootDocId: string | null): string | null;
4547
+ /**
4548
+ * Safely read a tree map value, converting Y.Map to plain object if needed.
4549
+ */
4550
+ declare function toPlain(val: unknown): unknown;
4551
+ //#endregion
4552
+ export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebRTC, type AbracadabraWebRTCConfiguration, AbracadabraWebSocketConn, AdminConfigField, AdminConfigOriginKind, AuditLogEntry, AuditQueryOpts, AuditVerifyResult, AuthFailureContext, AuthFailureReason, AuthMessageType, AuthorizedScope, AwarenessError, BackgroundSyncManager, type BackgroundSyncManagerOptions, BackgroundSyncPersistence, BroadcastChannelSync, CHANNEL_NAMES, ChannelKeyResolver, type ChatChannel, ChatClient, type ChatClientTransport, type MarkReadInput as ChatMarkReadInput, type ChatMessage, type ChatReadCursor, type ChatReadReceipt, type ChatTypingEvent, CloseEvent, CompleteAbracadabraBaseProviderConfiguration, CompleteAbracadabraWSConfiguration, CompleteHocuspocusProviderConfiguration, CompleteHocuspocusProviderWebsocketConfiguration, ConnectionTimeout, Constructable, ConstructableOutgoingMessage, ContentManager, type CreateNotificationInput, CryptoIdentity, CryptoIdentityKeystore, DEFAULT_FILE_CHUNK_SIZE, DEFAULT_ICE_SERVERS, DataChannelRouter, type DeleteMessageInput, DevicePairingChannel, type DevicePairingConfig, DeviceRegistrationService, type DeviceServerStatus, type DeviceTier, type DocEncryptionInfo, DocKeyManager, DocSearchHit, type DocSyncState, type DocumentBlock, DocumentCache, type DocumentCacheOptions, type DocumentContent, DocumentManager, type DocumentManagerConfig, DocumentMeta, type DocumentMetaInfo, E2EAbracadabraProvider, E2EEChannel, type E2EEIdentity, E2EOfflineStore, type EditMessageInput, EffectivePermissionEntry, EffectivePermissionsResponse, EffectiveRole, EncryptedChatClient, EncryptedYMap, EncryptedYText, EnvSnapshotExtension, EnvSnapshotItem, EnvSnapshotResponse, type FetchInboxInput, type FetchNotificationsInput, FileBlobStore, FileTransferChannel, FileTransferHandle, type FileTransferMeta, type FileTransferStatus, type FoldedMessage, Forbidden, GEO_TYPE_META_SCHEMAS, type GetChatHistoryInput, HealthStatus, HocusPocusWebSocket, HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration, HocuspocusWebSocket, type IdentityDeviceEntry, type IdentityDocConfiguration, IdentityDocProvider, type IdentityProfile, type IdentityServerEntry, type IdentitySpaceEntry, type InboxEntry, type MarkReadInput$1 as InboxMarkReadInput, InviteRow, KEY_EXCHANGE_CHANNEL, Kind, ManualSignaling, type ManualSignalingBlob, type MessageRecord, MessageTooBig, MessageType, MetaFieldType, MetaManager, type NotificationReadUpdate, type NotificationRecord, NotificationsClient, OfflineStore, OutgoingMessageArguments, OutgoingMessageInterface, PAGE_TYPES, PageMeta, PageTypeInfo, PageTypeMetaField, type PairingRequest, type PairingResult, PeerConnection, type PeerInfo, type PeerState, PendingSubdoc, PermissionEntry, PublicKeyInfo, RPC_PREFIX, ReadyzStatus, ResetConnection, type RpcCallHandle, type RpcCallOptions, RpcClient, RpcError, type RpcErrorCode, type RpcErrorPayload, type RpcFrame, type RpcHandler, type RpcHandlerContext, type RpcKind, type RpcTarget, type RpcTransport, SERVER_ROOT_ID, SearchIndex, SearchResult, type SendChatMessageInput, type SendMessageInput, type SendMessageResult, ServerInfo, type SignalingIncoming, type SignalingOutgoing, SignalingSocket, SnapshotCreateResult, SnapshotData, SnapshotFileEntry, SnapshotForkResult, SnapshotMeta, SnapshotRestoreResult, StatesArray, SubdocMessage, SubdocRegisteredEvent, TYPE_ALIASES, TreeEntry, TreeManager, TreeNode, TreeSearchResult, Unauthorized, UploadInfo, UploadMeta, UploadQueueEntry, UploadQueueStatus, UserMetaField, UserProfile, WebSocketStatus, WsReadyStates, YjsDataChannel, attachUpdatedAtObserver, awarenessStatesToArray, wordlist as bip39Wordlist, buildBlockquoteElement, buildBlocksFromMarkdown, buildBulletListElement, buildCodeBlockElement, buildHeadingElement, buildHorizontalRuleElement, buildOrderedListElement, buildParagraphElement, buildTaskListElement, decryptChatContent, decryptField, deriveIdentityDocId, deriveSeedWrappingKey, encryptChatContent, encryptField, filenameToLabel, foldRecords, generateMnemonic, isEncryptedContent, makeEncryptedYMap, makeEncryptedYText, mnemonicToEd25519Seed, mnemonicToKeyPair, normalizeRootId, onAuthenticatedParameters, onAuthenticationFailedParameters, onAwarenessChangeParameters, onAwarenessUpdateParameters, onCloseParameters, onCompactedParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onServerErrorParameters, onStatelessParameters, onStatusParameters, onSubdocLoadedParameters, onSubdocRegisteredParameters, onSyncedParameters, onUnsyncedChangesParameters, parseFrontmatter, populateYDocFromMarkdown, readAuthMessage, readBlocksFromFragment, recordFromYAny, resolvePageType, toPlain, unwrapSeed, validateMnemonic, waitForSync, withTimeout, wrapSeed, writeAuthenticated, writeAuthentication, writePermissionDenied, writeTokenSyncRequest, yjsToMarkdown };