@abraca/dabra 1.8.2 → 2.0.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.
- package/dist/abracadabra-provider.cjs +12722 -9050
- package/dist/abracadabra-provider.cjs.map +1 -1
- package/dist/abracadabra-provider.esm.js +12683 -9061
- package/dist/abracadabra-provider.esm.js.map +1 -1
- package/dist/index.d.ts +1485 -118
- package/package.json +1 -1
- package/src/AbracadabraBaseProvider.ts +51 -2
- package/src/AbracadabraClient.ts +516 -66
- package/src/AbracadabraProvider.ts +22 -7
- package/src/AbracadabraWS.ts +1 -1
- package/src/ChatClient.ts +193 -113
- package/src/ContentManager.ts +228 -0
- package/src/CryptoIdentityKeystore.ts +3 -3
- package/src/DocConverters.ts +1862 -0
- package/src/DocKeyManager.ts +60 -12
- package/src/DocTypes.ts +628 -0
- package/src/DocUtils.ts +89 -0
- package/src/DocumentManager.ts +319 -0
- package/src/E2EAbracadabraProvider.ts +189 -0
- package/src/EncryptedChatClient.ts +173 -0
- package/src/EncryptedY.ts +2 -2
- package/src/FileBlobStore.ts +10 -0
- package/src/IdentityDoc.ts +25 -0
- package/src/MetaManager.ts +100 -0
- package/src/MnemonicKeyDerivation.ts +4 -4
- package/src/NotificationsClient.ts +120 -98
- package/src/OutgoingMessages/SubdocMessage.ts +2 -2
- package/src/RpcClient.ts +659 -0
- package/src/TreeManager.ts +473 -0
- package/src/TreeTimestamps.ts +28 -25
- package/src/index.ts +71 -1
- package/src/messageRecord.ts +121 -0
- package/src/types.ts +174 -16
- package/src/webrtc/AbracadabraWebRTC.ts +2 -2
- package/src/webrtc/DataChannelRouter.ts +2 -2
- package/src/webrtc/E2EEChannel.ts +3 -3
- package/src/webrtc/FileTransferChannel.ts +9 -2
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
|
-
/**
|
|
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
|
-
/**
|
|
417
|
-
|
|
418
|
-
|
|
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,
|
|
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
|
-
|
|
620
|
+
kind?: string | null;
|
|
475
621
|
}): Promise<void>;
|
|
476
622
|
/**
|
|
477
|
-
* List
|
|
478
|
-
*
|
|
479
|
-
|
|
480
|
-
listSpaces(): Promise<SpaceMeta[]>;
|
|
481
|
-
/**
|
|
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.
|
|
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.
|
|
489
626
|
*/
|
|
490
|
-
|
|
627
|
+
listSpaces(): Promise<DocumentMeta[]>;
|
|
491
628
|
/**
|
|
492
|
-
* Create a new
|
|
493
|
-
*
|
|
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?:
|
|
639
|
+
visibility?: "public" | "private";
|
|
499
640
|
id?: string;
|
|
500
|
-
}): Promise<
|
|
641
|
+
}): Promise<DocumentMeta>;
|
|
501
642
|
/**
|
|
502
|
-
* Update
|
|
503
|
-
*
|
|
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
|
-
|
|
680
|
+
findOrCreateDmDoc(otherUserPk: string): Promise<string>;
|
|
506
681
|
/**
|
|
507
|
-
*
|
|
508
|
-
*
|
|
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
|
-
|
|
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,61 @@ 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>;
|
|
531
751
|
/** List snapshot metadata for a document. */
|
|
532
752
|
listSnapshots(docId: string, opts?: {
|
|
533
753
|
limit?: number;
|
|
534
754
|
offset?: number;
|
|
535
755
|
}): Promise<SnapshotMeta[]>;
|
|
536
|
-
/** Fetch a single snapshot including its base64-encoded data blob.
|
|
537
|
-
|
|
756
|
+
/** Fetch a single snapshot including its base64-encoded data blob.
|
|
757
|
+
* Pass `{ include: "files" }` to also receive the joined upload list
|
|
758
|
+
* (each `fileBlock` / `coverUploadId` resolved against `uploads`). */
|
|
759
|
+
getSnapshot(docId: string, version: number, opts?: {
|
|
760
|
+
include?: "files" | string;
|
|
761
|
+
}): Promise<SnapshotData>;
|
|
538
762
|
/** Create a manual snapshot of the current document state. */
|
|
539
763
|
createSnapshot(docId: string, opts?: {
|
|
540
764
|
label?: string;
|
|
@@ -548,7 +772,18 @@ declare class AbracadabraClient {
|
|
|
548
772
|
/** Health check — no auth required. */
|
|
549
773
|
health(): Promise<HealthStatus>;
|
|
550
774
|
/**
|
|
551
|
-
*
|
|
775
|
+
* Readiness probe — pings the database. Returns 200 with
|
|
776
|
+
* `status: "ready"` only when the server can serve traffic, 503 with
|
|
777
|
+
* `status: "unready"` otherwise (load balancers / Kubernetes probes
|
|
778
|
+
* use the status code; the body is informational).
|
|
779
|
+
*
|
|
780
|
+
* The 503 case is special-cased here: instead of throwing, the method
|
|
781
|
+
* returns the unready body so callers can react to the state without
|
|
782
|
+
* try/catch boilerplate.
|
|
783
|
+
*/
|
|
784
|
+
readyz(): Promise<ReadyzStatus>;
|
|
785
|
+
/**
|
|
786
|
+
* Fetch server metadata including `root_doc_id` and the `[access]` policy.
|
|
552
787
|
* No auth required.
|
|
553
788
|
*/
|
|
554
789
|
serverInfo(): Promise<ServerInfo>;
|
|
@@ -782,6 +1017,14 @@ interface AbracadabraProviderConfiguration extends Omit<AbracadabraBaseProviderC
|
|
|
782
1017
|
* sharing one local store. Used for the identity doc.
|
|
783
1018
|
*/
|
|
784
1019
|
serverAgnostic?: boolean;
|
|
1020
|
+
/**
|
|
1021
|
+
* Maximum number of simultaneously cached child providers before LRU
|
|
1022
|
+
* eviction reclaims the least-recently-used unpinned ones. Default 20.
|
|
1023
|
+
* Apps that legitimately need more docs alive (e.g. background-sync of
|
|
1024
|
+
* a working set) should raise this; pin individual children with
|
|
1025
|
+
* `pinChild()` to make them eviction-immune regardless of cap.
|
|
1026
|
+
*/
|
|
1027
|
+
maxChildren?: number;
|
|
785
1028
|
}
|
|
786
1029
|
/**
|
|
787
1030
|
* AbracadabraProvider extends AbracadabraBaseProvider with:
|
|
@@ -815,8 +1058,9 @@ declare class AbracadabraProvider extends AbracadabraBaseProvider {
|
|
|
815
1058
|
private childAccessTimes;
|
|
816
1059
|
/** Pinned children that must not be evicted (e.g. actively viewed docs) */
|
|
817
1060
|
private pinnedChildren;
|
|
818
|
-
/**
|
|
819
|
-
private static readonly
|
|
1061
|
+
/** Default cap on simultaneously cached child providers; configurable per-instance via `maxChildren`. */
|
|
1062
|
+
private static readonly DEFAULT_MAX_CHILDREN;
|
|
1063
|
+
private readonly maxChildren;
|
|
820
1064
|
private abracadabraConfig;
|
|
821
1065
|
private readonly boundHandleYSubdocsChange;
|
|
822
1066
|
/**
|
|
@@ -937,7 +1181,7 @@ declare class AbracadabraProvider extends AbracadabraBaseProvider {
|
|
|
937
1181
|
destroy(): void;
|
|
938
1182
|
}
|
|
939
1183
|
//#endregion
|
|
940
|
-
//#region
|
|
1184
|
+
//#region node_modules/lib0/encoding.d.ts
|
|
941
1185
|
/**
|
|
942
1186
|
* A BinaryEncoder handles the encoding to an Uint8Array.
|
|
943
1187
|
*/
|
|
@@ -981,7 +1225,7 @@ declare const Forbidden: CloseEvent;
|
|
|
981
1225
|
*/
|
|
982
1226
|
declare const ConnectionTimeout: CloseEvent;
|
|
983
1227
|
//#endregion
|
|
984
|
-
//#region
|
|
1228
|
+
//#region node_modules/lib0/decoding.d.ts
|
|
985
1229
|
/**
|
|
986
1230
|
* A Decoder handles the decoding of an Uint8Array.
|
|
987
1231
|
* @template {ArrayBufferLike} [Buf=ArrayBufferLike]
|
|
@@ -1160,6 +1404,12 @@ type onAwarenessChangeParameters = {
|
|
|
1160
1404
|
type onStatelessParameters = {
|
|
1161
1405
|
payload: string;
|
|
1162
1406
|
};
|
|
1407
|
+
/** Fired by E2EAbracadabraProvider when the server acknowledges an E2E
|
|
1408
|
+
* client-side compaction (via the `snapshot:compacted` stateless broadcast). */
|
|
1409
|
+
type onCompactedParameters = {
|
|
1410
|
+
docId: string; /** User id that performed the compaction; undefined if payload was malformed. */
|
|
1411
|
+
by: string | undefined;
|
|
1412
|
+
};
|
|
1163
1413
|
type onServerErrorParameters = {
|
|
1164
1414
|
source: string;
|
|
1165
1415
|
code: string;
|
|
@@ -1202,18 +1452,57 @@ interface UserProfile {
|
|
|
1202
1452
|
role: string;
|
|
1203
1453
|
/** Account-level Ed25519 public key (base64url). Canonical user identity. */
|
|
1204
1454
|
publicKey: string | null;
|
|
1455
|
+
/**
|
|
1456
|
+
* Whether the user has a password set. `false` for key-based soft
|
|
1457
|
+
* identities until they opt in via {@link AbracadabraClient.setPassword}.
|
|
1458
|
+
* Drives the UI's "Set password" vs "Change password" branching.
|
|
1459
|
+
*/
|
|
1460
|
+
hasPassword?: boolean;
|
|
1205
1461
|
}
|
|
1206
1462
|
interface DocumentMeta {
|
|
1207
1463
|
id: string;
|
|
1208
1464
|
parent_id: string | null;
|
|
1465
|
+
/**
|
|
1466
|
+
* Renderer hint — `"kanban"`, `"checklist"`, `"outline"`, `"graph"`,
|
|
1467
|
+
* `"sheet"`, `"mindmap"`, `"doc"`, etc. Drives the dashboard's choice of
|
|
1468
|
+
* Vue component for this doc. Orthogonal to {@link kind}.
|
|
1469
|
+
*/
|
|
1209
1470
|
doc_type?: string | null;
|
|
1210
1471
|
label?: string | null;
|
|
1211
1472
|
description?: string | null;
|
|
1212
1473
|
public_access?: string | null;
|
|
1213
1474
|
owner_id?: string | null;
|
|
1214
|
-
|
|
1475
|
+
/**
|
|
1476
|
+
* Structural role hint — `"server"` for the reserved server-root doc,
|
|
1477
|
+
* `"space"` for top-level workspace containers, `null`/absent otherwise.
|
|
1478
|
+
* Distinct from {@link doc_type}: a Space (`kind: "space"`) can contain
|
|
1479
|
+
* many Kanban boards (each `doc_type: "kanban"`).
|
|
1480
|
+
*/
|
|
1481
|
+
kind?: string | null;
|
|
1215
1482
|
updated_at?: number | null;
|
|
1216
1483
|
}
|
|
1484
|
+
/**
|
|
1485
|
+
* Well-known structural roles for the {@link DocumentMeta.kind} field. These
|
|
1486
|
+
* are conventions only — the server treats `kind` as an opaque string. Use
|
|
1487
|
+
* these constants instead of string literals to avoid typos.
|
|
1488
|
+
*/
|
|
1489
|
+
declare const Kind: {
|
|
1490
|
+
/** 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". */
|
|
1491
|
+
readonly Space: "space"; /** A regular content page rendered by the editor. */
|
|
1492
|
+
readonly Page: "page"; /** A group chat container under a Space. */
|
|
1493
|
+
readonly Channel: "channel"; /** A direct-message container at the server root with two-member permissions. */
|
|
1494
|
+
readonly Dm: "dm"; /** A child of channel/dm holding the messages Y.Array. */
|
|
1495
|
+
readonly ChannelPeriod: "channel-period"; /** A per-user inbox doc holding inbox entries; child of server root. */
|
|
1496
|
+
readonly Inbox: "inbox";
|
|
1497
|
+
};
|
|
1498
|
+
type Kind = typeof Kind[keyof typeof Kind];
|
|
1499
|
+
/**
|
|
1500
|
+
* Hardcoded UUID of the reserved server root document. Every doc in the tree
|
|
1501
|
+
* chains up to this row, so a permission grant on this doc cascades into
|
|
1502
|
+
* every descendant. Mirrors the constant in the Rust crate
|
|
1503
|
+
* (`crate::types::SERVER_ROOT_ID_STR`).
|
|
1504
|
+
*/
|
|
1505
|
+
declare const SERVER_ROOT_ID = "00000000-0000-0000-0000-000000000000";
|
|
1217
1506
|
interface UploadMeta {
|
|
1218
1507
|
id: string;
|
|
1219
1508
|
doc_id: string;
|
|
@@ -1259,9 +1548,28 @@ interface SnapshotMeta {
|
|
|
1259
1548
|
label?: string | null;
|
|
1260
1549
|
created_by?: string | null;
|
|
1261
1550
|
created_at: number;
|
|
1551
|
+
/** Number of uploads referenced by this snapshot's CRDT state.
|
|
1552
|
+
* Always 0 on servers older than the `snapshot_files` migration, or for
|
|
1553
|
+
* snapshots created before that migration ran (until the operator runs
|
|
1554
|
+
* `POST /admin/snapshots/backfill-refs`). */
|
|
1555
|
+
file_count?: number;
|
|
1556
|
+
/** Signed byte delta vs. the previous-version snapshot for this doc.
|
|
1557
|
+
* `null` for the first snapshot of a doc (or when the previous version
|
|
1558
|
+
* has been pruned). Lets the UI render `+12 KB` / `−3 KB`. */
|
|
1559
|
+
delta_bytes?: number | null;
|
|
1560
|
+
}
|
|
1561
|
+
interface SnapshotFileEntry {
|
|
1562
|
+
id: string;
|
|
1563
|
+
doc_id: string;
|
|
1564
|
+
filename: string;
|
|
1565
|
+
mime_type?: string | null;
|
|
1566
|
+
size?: number | null;
|
|
1262
1567
|
}
|
|
1263
1568
|
interface SnapshotData extends SnapshotMeta {
|
|
1264
1569
|
data: string;
|
|
1570
|
+
/** Populated only when fetched with `?include=files`. Each entry is an
|
|
1571
|
+
* upload referenced by this snapshot's CRDT state. */
|
|
1572
|
+
files?: SnapshotFileEntry[];
|
|
1265
1573
|
}
|
|
1266
1574
|
interface SnapshotCreateResult {
|
|
1267
1575
|
version: number;
|
|
@@ -1291,10 +1599,21 @@ interface ServerInfo {
|
|
|
1291
1599
|
version?: string;
|
|
1292
1600
|
/** Hocuspocus wire protocol version (currently 2). */
|
|
1293
1601
|
protocol_version?: number;
|
|
1294
|
-
/**
|
|
1295
|
-
|
|
1296
|
-
|
|
1297
|
-
|
|
1602
|
+
/**
|
|
1603
|
+
* The reserved server root document id. Every doc in the tree chains up
|
|
1604
|
+
* to this row; granting Admin here cascades to every doc. Hardcoded by
|
|
1605
|
+
* the server — clients can also use {@link SERVER_ROOT_ID} directly.
|
|
1606
|
+
*/
|
|
1607
|
+
root_doc_id?: string;
|
|
1608
|
+
/**
|
|
1609
|
+
* Server-wide access policy. Drives client-side decisions like "show the
|
|
1610
|
+
* sign-up CTA?" (anonymous mode) or "warn before publishing?" (anonymous
|
|
1611
|
+
* grants).
|
|
1612
|
+
*/
|
|
1613
|
+
access?: {
|
|
1614
|
+
/** `"none"` rejects unauthenticated requests; `"observer"` allows public read. */anonymous?: "none" | "observer"; /** Server-wide floor for authed users with no explicit grant. */
|
|
1615
|
+
authenticated?: "none" | "observer" | "viewer" | "editor";
|
|
1616
|
+
};
|
|
1298
1617
|
/** Enabled auth methods (e.g. ["crypto", "jwt"]). */
|
|
1299
1618
|
auth_methods?: string[];
|
|
1300
1619
|
/** Whether open registration is enabled. */
|
|
@@ -1306,23 +1625,85 @@ interface ServerInfo {
|
|
|
1306
1625
|
default_mode?: string;
|
|
1307
1626
|
minimum_mode?: string;
|
|
1308
1627
|
};
|
|
1628
|
+
/**
|
|
1629
|
+
* Ed25519 public key (base64url, no padding) the server uses to sign every
|
|
1630
|
+
* accepted `messages:*` record (`server_sig`). Clients can verify message
|
|
1631
|
+
* placement / ordering by checking each record's `server_sig` against this
|
|
1632
|
+
* key over the canonical `{ msg_id, period_id, ts, client_sig }` payload.
|
|
1633
|
+
*/
|
|
1634
|
+
messages_signer_pubkey?: string;
|
|
1309
1635
|
}
|
|
1310
1636
|
interface SearchResult {
|
|
1311
1637
|
docId: string;
|
|
1312
1638
|
/** Number of matching trigrams — higher is better. */
|
|
1313
1639
|
score: number;
|
|
1314
1640
|
}
|
|
1315
|
-
|
|
1316
|
-
|
|
1641
|
+
/**
|
|
1642
|
+
* A single hit returned by the server's full-text search endpoint
|
|
1643
|
+
* (`GET /docs/search`). Distinct from {@link SearchResult}, which is the
|
|
1644
|
+
* client-side trigram index in `SearchIndex.ts`.
|
|
1645
|
+
*
|
|
1646
|
+
* `snippet` is server-rendered HTML with `<mark>` wrappers around the
|
|
1647
|
+
* matched tokens — safe to inject after standard sanitization. `rank` is
|
|
1648
|
+
* a backend-specific score (SQLite bm25 vs Postgres ts_rank); the only
|
|
1649
|
+
* guarantee is that hits arrive in best-first order.
|
|
1650
|
+
*/
|
|
1651
|
+
interface DocSearchHit {
|
|
1317
1652
|
doc_id: string;
|
|
1318
|
-
|
|
1319
|
-
|
|
1320
|
-
|
|
1321
|
-
|
|
1322
|
-
|
|
1323
|
-
|
|
1324
|
-
|
|
1325
|
-
|
|
1653
|
+
parent_id: string | null;
|
|
1654
|
+
label: string | null;
|
|
1655
|
+
kind: string | null;
|
|
1656
|
+
/** HTML-safe snippet with `<mark>` markers around the matched tokens. */
|
|
1657
|
+
snippet: string;
|
|
1658
|
+
rank: number;
|
|
1659
|
+
}
|
|
1660
|
+
/**
|
|
1661
|
+
* A single row from `GET /admin/audit`. Mirrors the server's audit log
|
|
1662
|
+
* row format (see `audit::AuditLogRow`). `metadata` is the parsed JSON
|
|
1663
|
+
* object the server stored, or `null` if the row had no metadata. Each
|
|
1664
|
+
* row carries an internal `prev_hash` / `row_hash` chain that admins
|
|
1665
|
+
* verify with {@link AuditVerifyResult}.
|
|
1666
|
+
*/
|
|
1667
|
+
interface AuditLogEntry {
|
|
1668
|
+
id: string;
|
|
1669
|
+
ts: number;
|
|
1670
|
+
event_type: string;
|
|
1671
|
+
actor_user_id: string | null;
|
|
1672
|
+
actor_ip: string | null;
|
|
1673
|
+
request_id: string | null;
|
|
1674
|
+
target_type: string | null;
|
|
1675
|
+
target_id: string | null;
|
|
1676
|
+
metadata: Record<string, unknown> | null;
|
|
1677
|
+
outcome: string;
|
|
1678
|
+
}
|
|
1679
|
+
/** Filters for `GET /admin/audit`. All optional and AND-combined. */
|
|
1680
|
+
interface AuditQueryOpts {
|
|
1681
|
+
event_type?: string;
|
|
1682
|
+
actor_user_id?: string;
|
|
1683
|
+
target_type?: string;
|
|
1684
|
+
target_id?: string;
|
|
1685
|
+
since_ts?: number;
|
|
1686
|
+
until_ts?: number;
|
|
1687
|
+
limit?: number;
|
|
1688
|
+
offset?: number;
|
|
1689
|
+
}
|
|
1690
|
+
/** Response of `GET /admin/audit/verify`. `status: "broken"` carries `break`. */
|
|
1691
|
+
interface AuditVerifyResult {
|
|
1692
|
+
status: "ok" | "broken";
|
|
1693
|
+
message?: string;
|
|
1694
|
+
break?: {
|
|
1695
|
+
rows_checked: number;
|
|
1696
|
+
row_id: string;
|
|
1697
|
+
reason: string;
|
|
1698
|
+
};
|
|
1699
|
+
}
|
|
1700
|
+
/** Response of `GET /readyz`. HTTP 200 when ready, 503 when not. */
|
|
1701
|
+
interface ReadyzStatus {
|
|
1702
|
+
status: "ready" | "unready";
|
|
1703
|
+
version: string;
|
|
1704
|
+
checks: {
|
|
1705
|
+
database: "ok" | "error";
|
|
1706
|
+
};
|
|
1326
1707
|
}
|
|
1327
1708
|
interface InviteRow {
|
|
1328
1709
|
code: string;
|
|
@@ -1561,6 +1942,193 @@ declare const HocuspocusProviderWebsocket: typeof AbracadabraWS;
|
|
|
1561
1942
|
/** @deprecated Use AbracadabraWS */
|
|
1562
1943
|
type HocuspocusProviderWebsocket = AbracadabraWS;
|
|
1563
1944
|
//#endregion
|
|
1945
|
+
//#region packages/provider/src/RpcClient.d.ts
|
|
1946
|
+
/**
|
|
1947
|
+
* RPC v1 — request/response over `MSG_STATELESS`.
|
|
1948
|
+
*
|
|
1949
|
+
* Mirrors `docs/rpc-v1.md` in the abracadabra-rs server. Frames travel as
|
|
1950
|
+
* `MSG_STATELESS` payloads with the literal prefix `rpc:v1:` followed by a
|
|
1951
|
+
* JSON envelope. The provider's existing `sendStateless` / `stateless` event
|
|
1952
|
+
* stream is the only transport surface this layer touches; everything else
|
|
1953
|
+
* (state machine, deadlines, handler registry, dedupe of self-replies) lives
|
|
1954
|
+
* here.
|
|
1955
|
+
*/
|
|
1956
|
+
declare const RPC_PREFIX = "rpc:v1:";
|
|
1957
|
+
type RpcKind = "req" | "ack" | "nack" | "progress" | "result" | "cancel" | "hb" | "register" | "unregister";
|
|
1958
|
+
interface RpcFrame {
|
|
1959
|
+
kind: RpcKind;
|
|
1960
|
+
id: string;
|
|
1961
|
+
ts?: number;
|
|
1962
|
+
from?: string;
|
|
1963
|
+
to?: string;
|
|
1964
|
+
method?: string;
|
|
1965
|
+
args?: unknown;
|
|
1966
|
+
deadline_ms?: number;
|
|
1967
|
+
data?: unknown;
|
|
1968
|
+
error?: RpcErrorPayload;
|
|
1969
|
+
by?: "server" | "runner";
|
|
1970
|
+
runner_id?: string;
|
|
1971
|
+
seq?: number;
|
|
1972
|
+
methods?: string[];
|
|
1973
|
+
}
|
|
1974
|
+
interface RpcErrorPayload {
|
|
1975
|
+
code: string;
|
|
1976
|
+
message: string;
|
|
1977
|
+
details?: unknown;
|
|
1978
|
+
}
|
|
1979
|
+
type RpcErrorCode = "NO_HANDLER" | "HANDLER_GONE" | "TIMEOUT" | "CANCELLED" | "RATE_LIMITED" | "UNAUTHORIZED" | "SCHEMA" | "INTERNAL" | "APP" | string;
|
|
1980
|
+
/** Thrown by `rpc.call(...)` on terminal nack / error / timeout. */
|
|
1981
|
+
declare class RpcError extends Error {
|
|
1982
|
+
code: RpcErrorCode;
|
|
1983
|
+
details?: unknown;
|
|
1984
|
+
constructor(code: RpcErrorCode, message: string, details?: unknown);
|
|
1985
|
+
}
|
|
1986
|
+
/**
|
|
1987
|
+
* Minimal provider surface RpcClient needs. The base provider already
|
|
1988
|
+
* satisfies it; the indirection is here so handlers can be tested against
|
|
1989
|
+
* a stub without booting a Y.Doc.
|
|
1990
|
+
*/
|
|
1991
|
+
interface RpcTransport {
|
|
1992
|
+
sendStateless(payload: string): void;
|
|
1993
|
+
on(event: string, fn: Function): unknown;
|
|
1994
|
+
off(event: string, fn?: Function): unknown;
|
|
1995
|
+
}
|
|
1996
|
+
type RpcTarget = {
|
|
1997
|
+
kind: "role";
|
|
1998
|
+
role: "service";
|
|
1999
|
+
} | {
|
|
2000
|
+
kind: "user";
|
|
2001
|
+
userId: string;
|
|
2002
|
+
} | {
|
|
2003
|
+
kind: "runner";
|
|
2004
|
+
sessionId: string;
|
|
2005
|
+
};
|
|
2006
|
+
interface RpcCallOptions {
|
|
2007
|
+
/** Defaults to `{ kind: "role", role: "service" }`. */
|
|
2008
|
+
target?: RpcTarget;
|
|
2009
|
+
/** Wall-clock deadline in ms. Server clamps to its own ceiling. */
|
|
2010
|
+
deadline?: number;
|
|
2011
|
+
/** Abort the call (sends `rpc:cancel` to the runner). */
|
|
2012
|
+
signal?: AbortSignal;
|
|
2013
|
+
/** Fired when a runner claims the call (after the server ack). */
|
|
2014
|
+
onClaim?: (runnerId: string) => void;
|
|
2015
|
+
/** Fired for every `rpc:progress` frame the runner emits. */
|
|
2016
|
+
onProgress?: (data: unknown, seq: number) => void;
|
|
2017
|
+
}
|
|
2018
|
+
interface RpcCallHandle<T = unknown> extends Promise<T> {
|
|
2019
|
+
/** RPC id (UUID v7) — useful for log correlation. */
|
|
2020
|
+
readonly id: string;
|
|
2021
|
+
/** Runner session id, populated once a runner has claimed the call. */
|
|
2022
|
+
readonly claimedBy: string | undefined;
|
|
2023
|
+
/** Cancel the call. Equivalent to `signal.abort()` if a signal was passed. */
|
|
2024
|
+
cancel(reason?: string): void;
|
|
2025
|
+
}
|
|
2026
|
+
/**
|
|
2027
|
+
* Handler signature for a runner-side RPC handler.
|
|
2028
|
+
*
|
|
2029
|
+
* Returning a value emits `rpc:result(ok)`. Throwing emits
|
|
2030
|
+
* `rpc:result(err)` — `RpcError` instances pass through their `code` and
|
|
2031
|
+
* `details`; any other thrown value becomes `INTERNAL`.
|
|
2032
|
+
*
|
|
2033
|
+
* Returning an async generator turns each `yield` into a `rpc:progress`
|
|
2034
|
+
* frame (with monotonic `seq`); the generator's return value is the final
|
|
2035
|
+
* `result.data`.
|
|
2036
|
+
*/
|
|
2037
|
+
type RpcHandler = (args: unknown, ctx: RpcHandlerContext) => unknown | Promise<unknown> | AsyncGenerator<unknown, unknown, void>;
|
|
2038
|
+
interface RpcHandlerContext {
|
|
2039
|
+
id: string;
|
|
2040
|
+
method: string;
|
|
2041
|
+
/** Server-stamped caller user id. Trusted. */
|
|
2042
|
+
from: string;
|
|
2043
|
+
/** Aborted when the caller cancels or the deadline is reached. */
|
|
2044
|
+
signal: AbortSignal;
|
|
2045
|
+
}
|
|
2046
|
+
/**
|
|
2047
|
+
* Per-provider RPC layer. Construct one and attach by passing the provider
|
|
2048
|
+
* (or any `RpcTransport`). Disposes on `destroy()`.
|
|
2049
|
+
*
|
|
2050
|
+
* Caller side: `rpc.call('ai.summarize@1', { docId }, { onProgress })`.
|
|
2051
|
+
*
|
|
2052
|
+
* Runner side: `rpc.handle('ai.summarize@1', async (args, ctx) => …)`.
|
|
2053
|
+
*/
|
|
2054
|
+
declare class RpcClient extends EventEmitter {
|
|
2055
|
+
private readonly transport;
|
|
2056
|
+
private readonly pending;
|
|
2057
|
+
private readonly handlers;
|
|
2058
|
+
/** Tracks live runner-side invocations so we can route `rpc:cancel`. */
|
|
2059
|
+
private readonly runningHandlers;
|
|
2060
|
+
/** Pending register frames awaiting server ack — resolved by id. */
|
|
2061
|
+
private readonly pendingRegistrations;
|
|
2062
|
+
/** Grace timer armed on `disconnect`; cancelled on `connect`. Fires
|
|
2063
|
+
* `HANDLER_GONE` on every pending RPC if the WS is still down after
|
|
2064
|
+
* the grace window. v1 used to wait `deadline + 5s` which could be
|
|
2065
|
+
* 35s on default deadlines — way too long for a definitively-dead
|
|
2066
|
+
* connection. */
|
|
2067
|
+
private disconnectGrace;
|
|
2068
|
+
private static readonly DISCONNECT_GRACE_MS;
|
|
2069
|
+
private readonly onStatelessBound;
|
|
2070
|
+
/**
|
|
2071
|
+
* Replays all live `register` frames whenever the underlying provider
|
|
2072
|
+
* (re)syncs — covers WebSocket reconnects where the server allocated a
|
|
2073
|
+
* new session id and the old capability entries were freed.
|
|
2074
|
+
*/
|
|
2075
|
+
private readonly onSyncedBound;
|
|
2076
|
+
private readonly onDisconnectBound;
|
|
2077
|
+
private readonly onConnectBound;
|
|
2078
|
+
private destroyed;
|
|
2079
|
+
constructor(transport: RpcTransport);
|
|
2080
|
+
private armDisconnectGrace;
|
|
2081
|
+
private cancelDisconnectGrace;
|
|
2082
|
+
/**
|
|
2083
|
+
* Called when the WS has been down for the full grace window. Every
|
|
2084
|
+
* in-flight call is dead from the server's perspective (its `close_session`
|
|
2085
|
+
* already fired `HANDLER_GONE` to a now-disconnected caller; on reconnect
|
|
2086
|
+
* the server-side session is fresh, so any cached cancel/result frames
|
|
2087
|
+
* the server tried to deliver were lost). Fail pending immediately.
|
|
2088
|
+
*/
|
|
2089
|
+
private failPendingOnDisconnect;
|
|
2090
|
+
/**
|
|
2091
|
+
* Re-emit a `register` frame for every locally-known handler. Called on
|
|
2092
|
+
* every `synced` event from the provider, since a reconnected WS gets a
|
|
2093
|
+
* fresh server-side session with empty capability state.
|
|
2094
|
+
*/
|
|
2095
|
+
private replayRegistrations;
|
|
2096
|
+
destroy(): void;
|
|
2097
|
+
/**
|
|
2098
|
+
* Send an RPC and return a handle that resolves with the runner's result.
|
|
2099
|
+
* Throws `RpcError` on nack / handler error / timeout / cancellation.
|
|
2100
|
+
*/
|
|
2101
|
+
call<T = unknown>(method: string, args?: unknown, options?: RpcCallOptions): RpcCallHandle<T>;
|
|
2102
|
+
private abortInFlight;
|
|
2103
|
+
/**
|
|
2104
|
+
* Register a handler for `method` and advertise it to the server so
|
|
2105
|
+
* incoming `to: role:service` calls resolve here. Returns an unsubscribe
|
|
2106
|
+
* function. Calling `register` twice for the same method replaces the
|
|
2107
|
+
* handler and re-advertises.
|
|
2108
|
+
*
|
|
2109
|
+
* The advertise is fire-and-forget; if you need to wait until the server
|
|
2110
|
+
* has acknowledged registration (typical in tests with a separate caller
|
|
2111
|
+
* connection), `await rpc.ready()` after registering all handlers.
|
|
2112
|
+
*/
|
|
2113
|
+
handle(method: string, handler: RpcHandler): () => void;
|
|
2114
|
+
/**
|
|
2115
|
+
* Resolve once every outstanding `register` frame has been acknowledged
|
|
2116
|
+
* by the server. Useful when a separate connection is about to issue
|
|
2117
|
+
* `rpc.call(...)` and you need the capability registry to be live first.
|
|
2118
|
+
* Resolves immediately if there's nothing pending.
|
|
2119
|
+
*/
|
|
2120
|
+
ready(): Promise<void>;
|
|
2121
|
+
private send;
|
|
2122
|
+
private receive;
|
|
2123
|
+
private onAck;
|
|
2124
|
+
private onProgress;
|
|
2125
|
+
private onResult;
|
|
2126
|
+
private onNack;
|
|
2127
|
+
private settle;
|
|
2128
|
+
private onReq;
|
|
2129
|
+
private onCancel;
|
|
2130
|
+
}
|
|
2131
|
+
//#endregion
|
|
1564
2132
|
//#region packages/provider/src/AbracadabraBaseProvider.d.ts
|
|
1565
2133
|
type AbracadabraBaseProviderConfiguration = Required<Pick<CompleteAbracadabraBaseProviderConfiguration, "name">> & Partial<CompleteAbracadabraBaseProviderConfiguration> & ((Required<Pick<CompleteAbracadabraWSConfiguration, "url">> & Partial<Pick<CompleteAbracadabraWSConfiguration, "preserveTrailingSlash">>) | Required<Pick<CompleteAbracadabraBaseProviderConfiguration, "websocketProvider">>);
|
|
1566
2134
|
/** @deprecated Use AbracadabraBaseProviderConfiguration */
|
|
@@ -1631,6 +2199,13 @@ declare class AbracadabraBaseProvider extends EventEmitter {
|
|
|
1631
2199
|
intervals: {
|
|
1632
2200
|
forceSync: ReturnType<typeof setInterval> | null;
|
|
1633
2201
|
};
|
|
2202
|
+
/**
|
|
2203
|
+
* Lazily-constructed RPC v1 client. See `RpcClient`/`docs/rpc-v1.md`.
|
|
2204
|
+
* Bound to this provider's stateless transport, so calls and handlers
|
|
2205
|
+
* ride the doc this provider is subscribed to.
|
|
2206
|
+
*/
|
|
2207
|
+
private _rpc;
|
|
2208
|
+
get rpc(): RpcClient;
|
|
1634
2209
|
constructor(configuration: AbracadabraBaseProviderConfiguration);
|
|
1635
2210
|
boundDocumentUpdateHandler: (update: Uint8Array, origin: any) => void;
|
|
1636
2211
|
boundAwarenessUpdateHandler: ({
|
|
@@ -1726,7 +2301,7 @@ declare const awarenessStatesToArray: (states: Map<number, Record<string, any>>)
|
|
|
1726
2301
|
declare class SubdocMessage extends OutgoingMessage {
|
|
1727
2302
|
type: MessageType;
|
|
1728
2303
|
description: string;
|
|
1729
|
-
get(args: Partial<
|
|
2304
|
+
get(args: Partial<AbracadabraOutgoingMessageArguments>): Encoder;
|
|
1730
2305
|
}
|
|
1731
2306
|
//#endregion
|
|
1732
2307
|
//#region packages/provider/src/SearchIndex.d.ts
|
|
@@ -1805,6 +2380,13 @@ declare class FileBlobStore extends EventEmitter {
|
|
|
1805
2380
|
* the object URL reference is stale.
|
|
1806
2381
|
*/
|
|
1807
2382
|
invalidateUrl(docId: string, uploadId: string): void;
|
|
2383
|
+
/**
|
|
2384
|
+
* Clear the 404 negative-cache entry for (docId, uploadId) so the next
|
|
2385
|
+
* getBlobUrl() re-fetches from the server instead of short-circuiting.
|
|
2386
|
+
* Use on explicit user retry or after reconnect, when the file may have
|
|
2387
|
+
* become available since the last 404.
|
|
2388
|
+
*/
|
|
2389
|
+
clearNotFound(docId: string, uploadId: string): void;
|
|
1808
2390
|
/** Revoke the object URL and remove the blob from cache. */
|
|
1809
2391
|
evictBlob(docId: string, uploadId: string): Promise<void>;
|
|
1810
2392
|
/**
|
|
@@ -1831,6 +2413,31 @@ interface E2EAbracadabraProviderConfiguration extends AbracadabraProviderConfigu
|
|
|
1831
2413
|
docKeyManager: DocKeyManager;
|
|
1832
2414
|
keystore: CryptoIdentityKeystore;
|
|
1833
2415
|
client: AbracadabraClient;
|
|
2416
|
+
/**
|
|
2417
|
+
* Enable client-side compaction: after `compactionThreshold` E2E updates,
|
|
2418
|
+
* the provider merges the whole doc, re-encrypts it, and asks the server to
|
|
2419
|
+
* atomically replace its update log via the `snapshot:compact` stateless
|
|
2420
|
+
* protocol. Requires the user to have a role that `can_manage` the doc
|
|
2421
|
+
* (Owner or above); otherwise the server silently rejects.
|
|
2422
|
+
*
|
|
2423
|
+
* Default: true.
|
|
2424
|
+
*/
|
|
2425
|
+
compactionEnabled?: boolean;
|
|
2426
|
+
/**
|
|
2427
|
+
* Number of E2E updates applied in this session before compaction fires.
|
|
2428
|
+
* Default: 50. Ignored when `compactionEnabled === false`.
|
|
2429
|
+
*/
|
|
2430
|
+
compactionThreshold?: number;
|
|
2431
|
+
/**
|
|
2432
|
+
* Quiescence delay: once the threshold is crossed, wait this many ms with
|
|
2433
|
+
* no further updates before firing compaction. Debounces active editing
|
|
2434
|
+
* and reduces the chance of racing an in-flight remote update that hasn't
|
|
2435
|
+
* reached us yet (the server does not currently validate state-vector
|
|
2436
|
+
* coverage, so a compaction fired mid-flight could drop an update).
|
|
2437
|
+
*
|
|
2438
|
+
* Default: 2000 ms.
|
|
2439
|
+
*/
|
|
2440
|
+
compactionQuiescenceMs?: number;
|
|
1834
2441
|
}
|
|
1835
2442
|
declare class E2EAbracadabraProvider extends AbracadabraProvider {
|
|
1836
2443
|
private readonly docKeyManager;
|
|
@@ -1841,6 +2448,16 @@ declare class E2EAbracadabraProvider extends AbracadabraProvider {
|
|
|
1841
2448
|
/** E2E-encrypted offline store; created after the doc key is available. */
|
|
1842
2449
|
private e2eStore;
|
|
1843
2450
|
private readonly e2eServerOrigin;
|
|
2451
|
+
private readonly compactionEnabled;
|
|
2452
|
+
private readonly compactionThreshold;
|
|
2453
|
+
private readonly compactionQuiescenceMs;
|
|
2454
|
+
private updatesSinceCompaction;
|
|
2455
|
+
private compactionInFlight;
|
|
2456
|
+
/** Cleared on `snapshot:compacted` or on 30s timeout. */
|
|
2457
|
+
private compactionInFlightTimeout;
|
|
2458
|
+
/** Quiescence debounce: reset on every update, fires the actual compaction. */
|
|
2459
|
+
private compactionDebounceTimer;
|
|
2460
|
+
private destroyed;
|
|
1844
2461
|
constructor(configuration: E2EAbracadabraProviderConfiguration);
|
|
1845
2462
|
/** Fetch the doc key from the server (requires WebAuthn if not cached). */
|
|
1846
2463
|
private ensureDocKey;
|
|
@@ -1851,6 +2468,17 @@ declare class E2EAbracadabraProvider extends AbracadabraProvider {
|
|
|
1851
2468
|
/** Encrypt local updates before sending over WebSocket. */
|
|
1852
2469
|
documentUpdateHandler(update: Uint8Array, origin: unknown): void;
|
|
1853
2470
|
private _encryptAndSend;
|
|
2471
|
+
/**
|
|
2472
|
+
* Force an immediate compaction attempt, bypassing the threshold and
|
|
2473
|
+
* quiescence debounce. Resolves once the `snapshot:compact` frame has been
|
|
2474
|
+
* sent (or rejected locally for missing prerequisites — destroyed, no
|
|
2475
|
+
* doc key, or already in-flight). The server acknowledges via a
|
|
2476
|
+
* `snapshot:compacted` broadcast, which emits the `"compacted"` event.
|
|
2477
|
+
*/
|
|
2478
|
+
compactNow(): Promise<void>;
|
|
2479
|
+
private _noteUpdateApplied;
|
|
2480
|
+
private _performCompaction;
|
|
2481
|
+
private _handleCompactedBroadcast;
|
|
1854
2482
|
destroy(): void;
|
|
1855
2483
|
}
|
|
1856
2484
|
//#endregion
|
|
@@ -1927,18 +2555,15 @@ declare function makeEncryptedYText(ydoc: Y.Doc, fieldName: string, docKey: Cryp
|
|
|
1927
2555
|
* Attach an observer that writes `updatedAt` to the root doc-tree entry for
|
|
1928
2556
|
* `childDocId` whenever the child doc receives a non-offline update.
|
|
1929
2557
|
*
|
|
1930
|
-
* Writes are throttled: the first qualifying update records the timestamp;
|
|
1931
|
-
* a trailing-edge timer flushes it to the tree map after `throttleMs`.
|
|
1932
|
-
*
|
|
1933
2558
|
* @param treeMap The root doc's "doc-tree" Y.Map.
|
|
1934
2559
|
* @param childDocId The child document's UUID (key in treeMap).
|
|
1935
2560
|
* @param childDoc The child Y.Doc to observe.
|
|
1936
2561
|
* @param offlineStore The child provider's OfflineStore (used to detect
|
|
1937
2562
|
* offline-replay origins and skip them). Pass null when
|
|
1938
2563
|
* the offline store is disabled.
|
|
1939
|
-
* @param options Optional config. `throttleMs` controls the
|
|
1940
|
-
*
|
|
1941
|
-
* @returns Cleanup function — call on provider destroy.
|
|
2564
|
+
* @param options Optional config. `throttleMs` controls the throttle
|
|
2565
|
+
* window (default 5000).
|
|
2566
|
+
* @returns Cleanup function — call on provider destroy. Flushes
|
|
1942
2567
|
* any pending write before detaching.
|
|
1943
2568
|
*/
|
|
1944
2569
|
declare function attachUpdatedAtObserver(treeMap: Y.Map<any>, childDocId: string, childDoc: Y.Doc, offlineStore: OfflineStore | null, options?: {
|
|
@@ -2316,6 +2941,10 @@ declare class FileTransferHandle extends EventEmitter {
|
|
|
2316
2941
|
_setProgress(p: number): void;
|
|
2317
2942
|
/** @internal */
|
|
2318
2943
|
_setStatus(s: FileTransferStatus): void;
|
|
2944
|
+
/** @internal — public alias for the protected emit so the parent
|
|
2945
|
+
* `FileTransferChannel` (a different class instance) can dispatch events
|
|
2946
|
+
* on this handle. Protected access is by-class, not by-hierarchy. */
|
|
2947
|
+
_emit(event: string, ...args: unknown[]): void;
|
|
2319
2948
|
}
|
|
2320
2949
|
/**
|
|
2321
2950
|
* Chunked binary file transfer over a dedicated WebRTC data channel.
|
|
@@ -2929,7 +3558,6 @@ declare class DeviceRegistrationService {
|
|
|
2929
3558
|
//#region packages/provider/src/ChatClient.d.ts
|
|
2930
3559
|
/**
|
|
2931
3560
|
* Minimal provider surface ChatClient needs. Matches `AbracadabraBaseProvider`.
|
|
2932
|
-
* Kept as an interface so consumers can pass any compatible transport.
|
|
2933
3561
|
*/
|
|
2934
3562
|
interface ChatClientTransport {
|
|
2935
3563
|
sendStateless(payload: string): void;
|
|
@@ -2937,98 +3565,305 @@ interface ChatClientTransport {
|
|
|
2937
3565
|
off(event: string, fn?: Function): unknown;
|
|
2938
3566
|
}
|
|
2939
3567
|
/**
|
|
2940
|
-
*
|
|
3568
|
+
* Send a chat message into a channel doc.
|
|
3569
|
+
*
|
|
3570
|
+
* `channel_doc_id` is the UUID of the channel/dm doc — `documents.id` for
|
|
3571
|
+
* a row with `kind = "channel"` or `kind = "dm"`. Group channels under a
|
|
3572
|
+
* Space pass the channel doc's id; DMs pass the DM doc's id (callers
|
|
3573
|
+
* resolve "the DM doc between user A and user B" via their own path —
|
|
3574
|
+
* typically `client.listChildren(serverRootId)` filtered by `kind === "dm"`
|
|
3575
|
+
* with both pubkeys in `permissions`).
|
|
3576
|
+
*/
|
|
3577
|
+
interface SendMessageInput {
|
|
3578
|
+
channel_doc_id: string;
|
|
3579
|
+
content: string;
|
|
3580
|
+
/** Cleartext recipient pubkeys for server-side mention fan-out. */
|
|
3581
|
+
mentions?: string[];
|
|
3582
|
+
/** Message id this is a reply to. */
|
|
3583
|
+
reply_to?: string;
|
|
3584
|
+
/**
|
|
3585
|
+
* Optional Ed25519 signature over the canonical envelope, base64url. When
|
|
3586
|
+
* server config `[messages].require_client_sig = true`, sends without a
|
|
3587
|
+
* sig are rejected. Default-config servers accept unsigned sends — the
|
|
3588
|
+
* threat model relies on JWT-bound session auth + the server's own
|
|
3589
|
+
* `server_sig` over `(msg_id, period_id, ts, sig)`.
|
|
3590
|
+
*/
|
|
3591
|
+
sig?: string;
|
|
3592
|
+
/** Client-side timestamp (ms) for skew-tolerance check. Optional. */
|
|
3593
|
+
ts_hint?: number;
|
|
3594
|
+
}
|
|
3595
|
+
interface SendMessageResult {
|
|
3596
|
+
message_id: string;
|
|
3597
|
+
period_id: string;
|
|
3598
|
+
ts: number;
|
|
3599
|
+
server_sig: string;
|
|
3600
|
+
}
|
|
3601
|
+
interface EditMessageInput {
|
|
3602
|
+
channel_doc_id: string;
|
|
3603
|
+
message_id: string;
|
|
3604
|
+
content: string;
|
|
3605
|
+
sig?: string;
|
|
3606
|
+
}
|
|
3607
|
+
interface DeleteMessageInput {
|
|
3608
|
+
channel_doc_id: string;
|
|
3609
|
+
message_id: string;
|
|
3610
|
+
}
|
|
3611
|
+
interface MarkReadInput {
|
|
3612
|
+
channel_doc_id: string;
|
|
3613
|
+
period_id: string;
|
|
3614
|
+
message_id: string;
|
|
3615
|
+
/** Unix milliseconds. Defaults to server time. */
|
|
3616
|
+
ts?: number;
|
|
3617
|
+
}
|
|
3618
|
+
/**
|
|
3619
|
+
* Thin façade over the `messages:*` stateless protocol.
|
|
2941
3620
|
*
|
|
2942
|
-
*
|
|
2943
|
-
*
|
|
3621
|
+
* The unified messages model stores chat history as Y.Array entries on
|
|
3622
|
+
* `kind = "channel-period"` child docs of channel/dm docs (and notifications
|
|
3623
|
+
* as entries on a per-user `kind = "inbox"` doc). Reading history, listing
|
|
3624
|
+
* channels, observing real-time messages, and tracking read cursors are all
|
|
3625
|
+
* Y.Doc-shaped operations that the SDK consumer performs via
|
|
3626
|
+
* `AbracadabraClient` + `AbracadabraProvider` directly — not through this
|
|
3627
|
+
* façade. ChatClient handles only the *write-and-validate* path (sends,
|
|
3628
|
+
* edits, deletes, typing, mark-read), where the server is the sole authority
|
|
3629
|
+
* over the channel-period Y.Array.
|
|
2944
3630
|
*
|
|
2945
3631
|
* Events emitted:
|
|
2946
|
-
* - `
|
|
2947
|
-
*
|
|
2948
|
-
*
|
|
3632
|
+
* - `typing` → ChatTypingEvent (typing broadcast on the channel doc)
|
|
3633
|
+
*
|
|
3634
|
+
* For incoming-message observation, the consumer opens an
|
|
3635
|
+
* `AbracadabraProvider` on the active period doc and observes its
|
|
3636
|
+
* `messages` Y.Array directly. The dashboard's `useChat` composable does
|
|
3637
|
+
* this; the integration tests do this; external consumers should mirror
|
|
3638
|
+
* the pattern.
|
|
2949
3639
|
*/
|
|
2950
3640
|
declare class ChatClient extends EventEmitter {
|
|
2951
3641
|
private readonly provider;
|
|
2952
3642
|
private readonly responseTimeoutMs;
|
|
2953
3643
|
private readonly pending;
|
|
2954
3644
|
private readonly boundOnStateless;
|
|
3645
|
+
private readonly boundOnServerError;
|
|
2955
3646
|
constructor(provider: ChatClientTransport, options?: {
|
|
2956
3647
|
responseTimeoutMs?: number;
|
|
2957
3648
|
});
|
|
2958
|
-
/** Stop listening for chat messages. Does not disconnect the underlying provider. */
|
|
2959
3649
|
destroy(): void;
|
|
2960
|
-
/** Send a chat message
|
|
2961
|
-
|
|
2962
|
-
/**
|
|
2963
|
-
|
|
2964
|
-
|
|
2965
|
-
|
|
2966
|
-
|
|
2967
|
-
|
|
2968
|
-
|
|
2969
|
-
|
|
2970
|
-
|
|
2971
|
-
channels: ChatChannel[];
|
|
2972
|
-
}>;
|
|
2973
|
-
/** Mark a channel read up to `timestamp` (unix ms). */
|
|
2974
|
-
markRead(channel: string, timestamp: number): void;
|
|
2975
|
-
/** Fetch per-user read cursors for a channel. */
|
|
2976
|
-
getReadCursors(channel: string): Promise<{
|
|
2977
|
-
channel: string;
|
|
2978
|
-
cursors: ChatReadCursor[];
|
|
2979
|
-
}>;
|
|
2980
|
-
onMessage(fn: (m: ChatMessage) => void): this;
|
|
3650
|
+
/** Send a chat message. Resolves with the server-assigned id, ts, and signatures. */
|
|
3651
|
+
send(input: SendMessageInput): Promise<SendMessageResult>;
|
|
3652
|
+
/** Edit a previously-sent message. Append-only — server records an `edit` entry. */
|
|
3653
|
+
edit(input: EditMessageInput): Promise<void>;
|
|
3654
|
+
/** Delete a message. Append-only — server records a `tombstone` entry. */
|
|
3655
|
+
delete(input: DeleteMessageInput): Promise<void>;
|
|
3656
|
+
/** Broadcast a typing indicator on a channel. Fire-and-forget. */
|
|
3657
|
+
typing(channel_doc_id: string): void;
|
|
3658
|
+
/** Mark a (period, message) position as read for the calling user. Fire-and-forget. */
|
|
3659
|
+
markRead(input: MarkReadInput): void;
|
|
3660
|
+
/** Observe typing broadcasts. */
|
|
2981
3661
|
onTyping(fn: (e: ChatTypingEvent) => void): this;
|
|
2982
|
-
onReadReceipt(fn: (e: ChatReadReceipt) => void): this;
|
|
2983
3662
|
private enqueue;
|
|
2984
3663
|
private removePending;
|
|
2985
3664
|
private resolveNext;
|
|
3665
|
+
private rejectNext;
|
|
2986
3666
|
private handleStateless;
|
|
3667
|
+
private handleServerError;
|
|
2987
3668
|
}
|
|
2988
3669
|
//#endregion
|
|
3670
|
+
//#region packages/provider/src/EncryptedChatClient.d.ts
|
|
3671
|
+
/**
|
|
3672
|
+
* Returns true if `content` is wrapped by this module (i.e. an `e2e:1:`
|
|
3673
|
+
* envelope). Cleartext content always returns false.
|
|
3674
|
+
*/
|
|
3675
|
+
declare function isEncryptedContent(content: string): boolean;
|
|
3676
|
+
/**
|
|
3677
|
+
* Decrypt an `e2e:1:` envelope back to cleartext using the channel's
|
|
3678
|
+
* DocKey. Returns null if the envelope is malformed (don't surface
|
|
3679
|
+
* partial decryption — show the user a placeholder instead).
|
|
3680
|
+
*/
|
|
3681
|
+
declare function decryptChatContent(content: string, docKey: CryptoKey): Promise<string | null>;
|
|
3682
|
+
/**
|
|
3683
|
+
* Encrypt cleartext into an `e2e:1:` envelope ready to send as the
|
|
3684
|
+
* stateless `messages:send` `content` field.
|
|
3685
|
+
*/
|
|
3686
|
+
declare function encryptChatContent(content: string, docKey: CryptoKey): Promise<string>;
|
|
3687
|
+
/**
|
|
3688
|
+
* Per-channel encryption-mode + DocKey resolver. Caches the encryption
|
|
3689
|
+
* mode lookup for `cacheTtlMs`; the DocKey itself is cached inside
|
|
3690
|
+
* `DocKeyManager`. Returns `null` for non-E2E channels.
|
|
3691
|
+
*/
|
|
3692
|
+
declare class ChannelKeyResolver {
|
|
3693
|
+
private readonly client;
|
|
3694
|
+
private readonly docKeys;
|
|
3695
|
+
private readonly keystore;
|
|
3696
|
+
private readonly options;
|
|
3697
|
+
private modeCache;
|
|
3698
|
+
private static readonly DEFAULT_TTL_MS;
|
|
3699
|
+
constructor(client: AbracadabraClient, docKeys: DocKeyManager, keystore: CryptoIdentityKeystore, options?: {
|
|
3700
|
+
cacheTtlMs?: number;
|
|
3701
|
+
});
|
|
3702
|
+
modeFor(channelDocId: string): Promise<"none" | "cse" | "e2e">;
|
|
3703
|
+
/**
|
|
3704
|
+
* Returns the DocKey for an E2E channel, or null for cleartext channels
|
|
3705
|
+
* (no envelope to fetch). Throws if the channel is E2E but no envelope
|
|
3706
|
+
* exists for the current user — the caller should let the send fail
|
|
3707
|
+
* loudly rather than fall back to cleartext, which would silently
|
|
3708
|
+
* downgrade the threat model.
|
|
3709
|
+
*/
|
|
3710
|
+
docKeyFor(channelDocId: string): Promise<CryptoKey | null>;
|
|
3711
|
+
/** Drop the cached encryption mode for `channelDocId` (or all). */
|
|
3712
|
+
clearCache(channelDocId?: string): void;
|
|
3713
|
+
}
|
|
3714
|
+
/**
|
|
3715
|
+
* Drop-in wrapper around an existing ChatClient that intercepts the
|
|
3716
|
+
* write side (`send` / `edit`) and encrypts content for E2E channels.
|
|
3717
|
+
* Reading is handled separately — the consumer pumps the period's Y.Array
|
|
3718
|
+
* directly and calls `decryptChatContent` per record.
|
|
3719
|
+
*
|
|
3720
|
+
* Channels in `none` or `cse` mode are passed through untouched.
|
|
3721
|
+
*/
|
|
3722
|
+
declare class EncryptedChatClient {
|
|
3723
|
+
private readonly inner;
|
|
3724
|
+
private readonly resolver;
|
|
3725
|
+
constructor(inner: ChatClient, resolver: ChannelKeyResolver);
|
|
3726
|
+
send(input: SendMessageInput): Promise<SendMessageResult>;
|
|
3727
|
+
edit(input: EditMessageInput): Promise<void>;
|
|
3728
|
+
delete(...args: Parameters<ChatClient["delete"]>): Promise<void>;
|
|
3729
|
+
markRead(...args: Parameters<ChatClient["markRead"]>): void;
|
|
3730
|
+
typing(...args: Parameters<ChatClient["typing"]>): void;
|
|
3731
|
+
destroy(): void;
|
|
3732
|
+
}
|
|
3733
|
+
//#endregion
|
|
3734
|
+
//#region packages/provider/src/messageRecord.d.ts
|
|
3735
|
+
/**
|
|
3736
|
+
* Decode + fold message records from a period doc's `messages` Y.Array
|
|
3737
|
+
* into the flat `ChatMessage[]` shape the dashboard renders.
|
|
3738
|
+
*
|
|
3739
|
+
* The server appends three kinds of records to the array (see
|
|
3740
|
+
* `abracadabra-rs/crates/abracadabra/src/messages.rs`):
|
|
3741
|
+
*
|
|
3742
|
+
* - `record_kind: "message"` — a real message (default kind).
|
|
3743
|
+
* - `record_kind: "edit"` — an updated version of `target_id`.
|
|
3744
|
+
* - `record_kind: "tombstone"` — `target_id` is deleted.
|
|
3745
|
+
*
|
|
3746
|
+
* Folding rules:
|
|
3747
|
+
* - For each `target_id`, apply edits in `ts` order; the *last* edit's
|
|
3748
|
+
* content wins. The original message's id, sender_id, and ts stay.
|
|
3749
|
+
* `editedAt` is the latest edit's ts.
|
|
3750
|
+
* - Any target_id with a tombstone is dropped from the output entirely.
|
|
3751
|
+
* - Records without record_kind default to "message" (back-compat).
|
|
3752
|
+
*
|
|
3753
|
+
* Cross-period folding: edits and tombstones can in principle target a
|
|
3754
|
+
* message in a *prior* period (e.g. user edits a message that lived on
|
|
3755
|
+
* the previous period after rollover). Callers that paginate across
|
|
3756
|
+
* periods should fold the joined list, not each period independently.
|
|
3757
|
+
*/
|
|
3758
|
+
interface MessageRecord {
|
|
3759
|
+
record_kind?: 'message' | 'edit' | 'tombstone';
|
|
3760
|
+
id: string;
|
|
3761
|
+
target_id?: string;
|
|
3762
|
+
sender_id: string;
|
|
3763
|
+
channel_doc_id: string;
|
|
3764
|
+
period_id: string;
|
|
3765
|
+
ts: number;
|
|
3766
|
+
content: string;
|
|
3767
|
+
mentions?: string[];
|
|
3768
|
+
reply_to?: string | null;
|
|
3769
|
+
sig?: string;
|
|
3770
|
+
server_sig?: string;
|
|
3771
|
+
}
|
|
3772
|
+
interface FoldedMessage {
|
|
3773
|
+
id: string;
|
|
3774
|
+
channel: string;
|
|
3775
|
+
senderId: string;
|
|
3776
|
+
senderName?: string;
|
|
3777
|
+
content: string;
|
|
3778
|
+
createdAt: number;
|
|
3779
|
+
/** Set if the message has been edited at least once. */
|
|
3780
|
+
editedAt?: number;
|
|
3781
|
+
/** Reply target message id, if any. */
|
|
3782
|
+
replyTo?: string;
|
|
3783
|
+
}
|
|
3784
|
+
/**
|
|
3785
|
+
* Fold an ordered list of records (oldest-first) into the visible
|
|
3786
|
+
* messages a UI should render. Records may come from one period or
|
|
3787
|
+
* across multiple periods concatenated in time order.
|
|
3788
|
+
*/
|
|
3789
|
+
declare function foldRecords(records: MessageRecord[]): FoldedMessage[];
|
|
3790
|
+
/**
|
|
3791
|
+
* Decode whatever the Y.Array stored for an entry into a MessageRecord.
|
|
3792
|
+
* Note: the server stamps `ts` server-side via `Any::BigInt(now_ts_ms())`,
|
|
3793
|
+
* so on the wire it round-trips as a JS BigInt — `typeof` is `'bigint'`,
|
|
3794
|
+
* not `'number'`. Accept both and coerce.
|
|
3795
|
+
*/
|
|
3796
|
+
declare function recordFromYAny(any: unknown): MessageRecord | null;
|
|
3797
|
+
//#endregion
|
|
2989
3798
|
//#region packages/provider/src/NotificationsClient.d.ts
|
|
3799
|
+
/** Per-user inbox doc entry. Mirrors `InboxEntry` on the server. */
|
|
3800
|
+
interface InboxEntry {
|
|
3801
|
+
id: string;
|
|
3802
|
+
/** "mention" | "reply" | "dm" | "system". */
|
|
3803
|
+
kind: string;
|
|
3804
|
+
channel_doc_id: string;
|
|
3805
|
+
message_id?: string | null;
|
|
3806
|
+
sender_id?: string | null;
|
|
3807
|
+
sender_name?: string | null;
|
|
3808
|
+
/** Empty for E2E channels (server can't read body). Filled otherwise. */
|
|
3809
|
+
preview?: string | null;
|
|
3810
|
+
ts: number;
|
|
3811
|
+
/** Synthesized client-side from the inbox doc's `read` Y.Map. */
|
|
3812
|
+
read: boolean;
|
|
3813
|
+
}
|
|
3814
|
+
interface FetchInboxInput {
|
|
3815
|
+
before?: number;
|
|
3816
|
+
limit?: number;
|
|
3817
|
+
unread_only?: boolean;
|
|
3818
|
+
}
|
|
3819
|
+
interface MarkReadInput$1 {
|
|
3820
|
+
id?: string;
|
|
3821
|
+
ids?: string[];
|
|
3822
|
+
source_id?: string;
|
|
3823
|
+
all?: boolean;
|
|
3824
|
+
}
|
|
2990
3825
|
/**
|
|
2991
|
-
*
|
|
3826
|
+
* Thin façade over the `messages:inbox_*` stateless protocol.
|
|
3827
|
+
*
|
|
3828
|
+
* Per-user notifications live as Y.Array entries on the user's inbox doc
|
|
3829
|
+
* (`kind = "inbox"`, owned by the user, child of the server root, server-only
|
|
3830
|
+
* writer). Real-time observation of new entries is a Y.Array observer the
|
|
3831
|
+
* consumer attaches via `AbracadabraProvider` on the inbox doc.
|
|
2992
3832
|
*
|
|
2993
|
-
*
|
|
2994
|
-
* - `
|
|
2995
|
-
* - `
|
|
3833
|
+
* This client handles only the request/response layer:
|
|
3834
|
+
* - `fetch()` issues `messages:inbox_fetch`, returns the entry list.
|
|
3835
|
+
* - `markRead()` issues `messages:inbox_mark_read` (id / ids / source_id /
|
|
3836
|
+
* all variants).
|
|
3837
|
+
*
|
|
3838
|
+
* For incoming notification observation, open an AbracadabraProvider on the
|
|
3839
|
+
* inbox doc and observe its `entries` Y.Array directly. The dashboard's
|
|
3840
|
+
* `useNotifications` composable does this.
|
|
2996
3841
|
*/
|
|
2997
3842
|
declare class NotificationsClient extends EventEmitter {
|
|
2998
3843
|
private readonly provider;
|
|
2999
3844
|
private readonly responseTimeoutMs;
|
|
3000
3845
|
private readonly pending;
|
|
3001
3846
|
private readonly boundOnStateless;
|
|
3847
|
+
private readonly boundOnServerError;
|
|
3002
3848
|
constructor(provider: ChatClientTransport, options?: {
|
|
3003
3849
|
responseTimeoutMs?: number;
|
|
3004
3850
|
});
|
|
3005
3851
|
destroy(): void;
|
|
3852
|
+
/** Fetch a slice of the calling user's inbox. Resolves with the entries. */
|
|
3853
|
+
fetch(input?: FetchInboxInput): Promise<{
|
|
3854
|
+
entries: InboxEntry[];
|
|
3855
|
+
}>;
|
|
3006
3856
|
/**
|
|
3007
|
-
*
|
|
3008
|
-
*
|
|
3009
|
-
* by the underlying provider if the caller lacks permission.
|
|
3857
|
+
* Mark inbox entries read. One of `id`, `ids`, `source_id`, or `all`.
|
|
3858
|
+
* Returns when the server has acked.
|
|
3010
3859
|
*/
|
|
3011
|
-
|
|
3012
|
-
/** Fetch notification history for the current user. */
|
|
3013
|
-
fetch(input?: FetchNotificationsInput): Promise<{
|
|
3014
|
-
notifications: NotificationRecord[];
|
|
3015
|
-
}>;
|
|
3016
|
-
/** Mark a single notification, or a batch, as read. */
|
|
3017
|
-
markRead(target: {
|
|
3018
|
-
id: string;
|
|
3019
|
-
} | {
|
|
3020
|
-
ids: string[];
|
|
3021
|
-
}): void;
|
|
3022
|
-
/** Mark every notification for the current user as read. */
|
|
3023
|
-
markAllRead(): void;
|
|
3024
|
-
/** Mark all notifications generated by the given source (e.g. a chat channel) as read. */
|
|
3025
|
-
markReadBySource(sourceId: string): void;
|
|
3026
|
-
onNew(fn: (n: NotificationRecord) => void): this;
|
|
3027
|
-
onReadUpdate(fn: (u: NotificationReadUpdate) => void): this;
|
|
3860
|
+
markRead(input: MarkReadInput$1): Promise<void>;
|
|
3028
3861
|
private enqueue;
|
|
3029
3862
|
private removePending;
|
|
3030
3863
|
private resolveNext;
|
|
3864
|
+
private rejectNext;
|
|
3031
3865
|
private handleStateless;
|
|
3866
|
+
private handleServerError;
|
|
3032
3867
|
}
|
|
3033
3868
|
//#endregion
|
|
3034
3869
|
//#region node_modules/@scure/bip39/esm/wordlists/english.d.ts
|
|
@@ -3098,4 +3933,536 @@ declare function wrapSeed(seed: Uint8Array, wrappingKeyBytes: Uint8Array): Promi
|
|
|
3098
3933
|
*/
|
|
3099
3934
|
declare function unwrapSeed(ciphertext: ArrayBuffer, iv: Uint8Array, wrappingKeyBytes: Uint8Array): Promise<Uint8Array>;
|
|
3100
3935
|
//#endregion
|
|
3101
|
-
|
|
3936
|
+
//#region packages/provider/src/DocTypes.d.ts
|
|
3937
|
+
/**
|
|
3938
|
+
* Canonical type definitions for Abracadabra document tree entries, page
|
|
3939
|
+
* metadata, and the static page-type catalog.
|
|
3940
|
+
*
|
|
3941
|
+
* These types were previously scattered across `mcp/converters/types.ts` and
|
|
3942
|
+
* `mcp/converters/page-types.ts`. By living in the provider package they
|
|
3943
|
+
* become first-class SDK types that any consumer (`@abraca/dabra`) can import
|
|
3944
|
+
* directly, removing the need for fragile relative-path re-exports.
|
|
3945
|
+
*/
|
|
3946
|
+
type MetaFieldType = 'datetimerange' | 'daterange' | 'timerange' | 'datetime' | 'date' | 'time' | 'slider' | 'number' | 'toggle' | 'select' | 'multiselect' | 'colorPreset' | 'colorPicker' | 'location' | 'icon' | 'textarea' | 'url' | 'rating' | 'tags' | 'members';
|
|
3947
|
+
interface UserMetaField {
|
|
3948
|
+
id: string;
|
|
3949
|
+
type: string;
|
|
3950
|
+
label?: string;
|
|
3951
|
+
key?: string;
|
|
3952
|
+
latKey?: string;
|
|
3953
|
+
lngKey?: string;
|
|
3954
|
+
startKey?: string;
|
|
3955
|
+
endKey?: string;
|
|
3956
|
+
allDayKey?: string;
|
|
3957
|
+
presets?: string[];
|
|
3958
|
+
options?: string[];
|
|
3959
|
+
min?: number;
|
|
3960
|
+
max?: number;
|
|
3961
|
+
step?: number;
|
|
3962
|
+
unit?: string;
|
|
3963
|
+
default?: boolean;
|
|
3964
|
+
}
|
|
3965
|
+
interface PageMeta extends Record<string, unknown> {
|
|
3966
|
+
color?: string;
|
|
3967
|
+
icon?: string;
|
|
3968
|
+
subtitle?: string;
|
|
3969
|
+
note?: string;
|
|
3970
|
+
datetimeStart?: string;
|
|
3971
|
+
datetimeEnd?: string;
|
|
3972
|
+
allDay?: boolean;
|
|
3973
|
+
dateStart?: string;
|
|
3974
|
+
dateEnd?: string;
|
|
3975
|
+
timeStart?: string;
|
|
3976
|
+
timeEnd?: string;
|
|
3977
|
+
dateTaken?: string;
|
|
3978
|
+
checked?: boolean;
|
|
3979
|
+
priority?: number;
|
|
3980
|
+
status?: string;
|
|
3981
|
+
taskProgress?: number;
|
|
3982
|
+
rating?: number;
|
|
3983
|
+
tags?: string[];
|
|
3984
|
+
members?: {
|
|
3985
|
+
id: string;
|
|
3986
|
+
label: string;
|
|
3987
|
+
}[];
|
|
3988
|
+
url?: string;
|
|
3989
|
+
email?: string;
|
|
3990
|
+
phone?: string;
|
|
3991
|
+
number?: number;
|
|
3992
|
+
unit?: string;
|
|
3993
|
+
coverUploadId?: string;
|
|
3994
|
+
coverDocId?: string;
|
|
3995
|
+
coverMimeType?: string;
|
|
3996
|
+
geoType?: 'marker' | 'line' | 'measure';
|
|
3997
|
+
geoLat?: number;
|
|
3998
|
+
geoLng?: number;
|
|
3999
|
+
geoDescription?: string;
|
|
4000
|
+
deskX?: number;
|
|
4001
|
+
deskY?: number;
|
|
4002
|
+
deskZ?: number;
|
|
4003
|
+
deskMode?: string;
|
|
4004
|
+
mmX?: number;
|
|
4005
|
+
mmY?: number;
|
|
4006
|
+
graphX?: number;
|
|
4007
|
+
graphY?: number;
|
|
4008
|
+
graphPinned?: boolean;
|
|
4009
|
+
spShape?: string;
|
|
4010
|
+
spOpacity?: number;
|
|
4011
|
+
spX?: number;
|
|
4012
|
+
spY?: number;
|
|
4013
|
+
spZ?: number;
|
|
4014
|
+
spRX?: number;
|
|
4015
|
+
spRY?: number;
|
|
4016
|
+
spRZ?: number;
|
|
4017
|
+
spSX?: number;
|
|
4018
|
+
spSY?: number;
|
|
4019
|
+
spSZ?: number;
|
|
4020
|
+
spModelUploadId?: string;
|
|
4021
|
+
spModelDocId?: string;
|
|
4022
|
+
slidesTransition?: string;
|
|
4023
|
+
slidesTheme?: string;
|
|
4024
|
+
mediaDuration?: number;
|
|
4025
|
+
mediaWidth?: number;
|
|
4026
|
+
mediaHeight?: number;
|
|
4027
|
+
mediaCamera?: string;
|
|
4028
|
+
mediaLens?: string;
|
|
4029
|
+
mediaIso?: number;
|
|
4030
|
+
mediaFocalLength?: number;
|
|
4031
|
+
mediaAperture?: number;
|
|
4032
|
+
mediaShutterSpeed?: string;
|
|
4033
|
+
mediaArtist?: string;
|
|
4034
|
+
mediaAlbum?: string;
|
|
4035
|
+
mediaGenre?: string;
|
|
4036
|
+
mediaYear?: number;
|
|
4037
|
+
bold?: boolean;
|
|
4038
|
+
italic?: boolean;
|
|
4039
|
+
textColor?: string;
|
|
4040
|
+
bgColor?: string;
|
|
4041
|
+
align?: string;
|
|
4042
|
+
formula?: string;
|
|
4043
|
+
fileType?: string;
|
|
4044
|
+
entry?: boolean;
|
|
4045
|
+
kanbanColumnWidth?: string;
|
|
4046
|
+
galleryColumns?: number;
|
|
4047
|
+
galleryAspect?: string;
|
|
4048
|
+
galleryCardStyle?: string;
|
|
4049
|
+
galleryShowLabels?: boolean;
|
|
4050
|
+
gallerySortBy?: string;
|
|
4051
|
+
calendarView?: string;
|
|
4052
|
+
calendarWeekStart?: string;
|
|
4053
|
+
calendarShowWeekNumbers?: boolean;
|
|
4054
|
+
tableMode?: string;
|
|
4055
|
+
tableSortKey?: string;
|
|
4056
|
+
tableSortDir?: string;
|
|
4057
|
+
tableColumns?: any[];
|
|
4058
|
+
tableColumnWidths?: Record<string, number>;
|
|
4059
|
+
tableColumnOrder?: string[];
|
|
4060
|
+
timelineZoom?: string;
|
|
4061
|
+
timelinePixelsPerDay?: number;
|
|
4062
|
+
timelineCenterDate?: string;
|
|
4063
|
+
checklistFilter?: string;
|
|
4064
|
+
checklistSort?: string;
|
|
4065
|
+
mapShowLabels?: boolean;
|
|
4066
|
+
spatialGridVisible?: boolean;
|
|
4067
|
+
graphSpacing?: string;
|
|
4068
|
+
graphShowLabels?: boolean;
|
|
4069
|
+
graphEdgeThickness?: string;
|
|
4070
|
+
mmSpacing?: string;
|
|
4071
|
+
showRefEdges?: boolean;
|
|
4072
|
+
chartType?: string;
|
|
4073
|
+
chartMetric?: string;
|
|
4074
|
+
chartColorScheme?: string;
|
|
4075
|
+
chartLimit?: number;
|
|
4076
|
+
chartShowLegend?: boolean;
|
|
4077
|
+
chartShowValues?: boolean;
|
|
4078
|
+
mediaRepeat?: string;
|
|
4079
|
+
mediaShuffle?: boolean;
|
|
4080
|
+
sheetsDefaultColWidth?: number;
|
|
4081
|
+
sheetsDefaultRowHeight?: number;
|
|
4082
|
+
sheetsShowGridlines?: boolean;
|
|
4083
|
+
sheetsColumnWidths?: Record<string, number>;
|
|
4084
|
+
sheetsRowHeights?: Record<string, number>;
|
|
4085
|
+
sheetsFreezeRows?: number;
|
|
4086
|
+
sheetsFreezeCols?: number;
|
|
4087
|
+
_metaFields?: UserMetaField[];
|
|
4088
|
+
_metaInitialized?: boolean;
|
|
4089
|
+
}
|
|
4090
|
+
interface TreeEntry {
|
|
4091
|
+
id: string;
|
|
4092
|
+
label: string;
|
|
4093
|
+
parentId: string | null;
|
|
4094
|
+
order: number;
|
|
4095
|
+
type?: string;
|
|
4096
|
+
meta?: PageMeta;
|
|
4097
|
+
createdAt?: number;
|
|
4098
|
+
updatedAt?: number;
|
|
4099
|
+
}
|
|
4100
|
+
interface TreeNode {
|
|
4101
|
+
id: string;
|
|
4102
|
+
label: string;
|
|
4103
|
+
type?: string;
|
|
4104
|
+
meta?: PageMeta;
|
|
4105
|
+
order: number;
|
|
4106
|
+
children: TreeNode[];
|
|
4107
|
+
}
|
|
4108
|
+
interface TreeSearchResult {
|
|
4109
|
+
id: string;
|
|
4110
|
+
label: string;
|
|
4111
|
+
type?: string;
|
|
4112
|
+
meta?: PageMeta;
|
|
4113
|
+
/** Ancestor labels from root → parent. */
|
|
4114
|
+
path: string[];
|
|
4115
|
+
}
|
|
4116
|
+
interface PageTypeMetaField {
|
|
4117
|
+
type: MetaFieldType;
|
|
4118
|
+
label?: string;
|
|
4119
|
+
/** single-value fields */
|
|
4120
|
+
key?: string;
|
|
4121
|
+
/** location */
|
|
4122
|
+
latKey?: string;
|
|
4123
|
+
lngKey?: string;
|
|
4124
|
+
/** ranges */
|
|
4125
|
+
startKey?: string;
|
|
4126
|
+
endKey?: string;
|
|
4127
|
+
allDayKey?: string;
|
|
4128
|
+
/** color preset */
|
|
4129
|
+
presets?: string[];
|
|
4130
|
+
/** icon / select / tags */
|
|
4131
|
+
options?: string[];
|
|
4132
|
+
/** slider / number */
|
|
4133
|
+
min?: number;
|
|
4134
|
+
max?: number;
|
|
4135
|
+
step?: number;
|
|
4136
|
+
unit?: string;
|
|
4137
|
+
/** toggle default */
|
|
4138
|
+
default?: boolean;
|
|
4139
|
+
}
|
|
4140
|
+
interface PageTypeInfo {
|
|
4141
|
+
key: string;
|
|
4142
|
+
label: string;
|
|
4143
|
+
icon: string;
|
|
4144
|
+
description?: string;
|
|
4145
|
+
/** true = core type (always available); false = requires plugin */
|
|
4146
|
+
core: boolean;
|
|
4147
|
+
plugin?: string;
|
|
4148
|
+
supportsChildren: boolean;
|
|
4149
|
+
childLabel?: string;
|
|
4150
|
+
grandchildLabel?: string;
|
|
4151
|
+
/** -1 = unlimited depth */
|
|
4152
|
+
defaultDepth?: number;
|
|
4153
|
+
/** Fields that apply to this doc's descendants (children, grandchildren, ...) */
|
|
4154
|
+
metaSchema?: PageTypeMetaField[];
|
|
4155
|
+
/** Fields written to this doc's own meta on first render (renderer config) */
|
|
4156
|
+
defaultMetaFields?: PageTypeMetaField[];
|
|
4157
|
+
}
|
|
4158
|
+
declare const GEO_TYPE_META_SCHEMAS: Record<string, PageTypeMetaField[]>;
|
|
4159
|
+
declare const PAGE_TYPES: Record<string, PageTypeInfo>;
|
|
4160
|
+
declare const TYPE_ALIASES: Record<string, string>;
|
|
4161
|
+
declare function resolvePageType(key: string | undefined): PageTypeInfo | undefined;
|
|
4162
|
+
//#endregion
|
|
4163
|
+
//#region packages/provider/src/TreeManager.d.ts
|
|
4164
|
+
declare class TreeManager {
|
|
4165
|
+
private dm;
|
|
4166
|
+
constructor(dm: DocumentManager);
|
|
4167
|
+
/** Read all tree entries as plain objects. */
|
|
4168
|
+
readEntries(): TreeEntry[];
|
|
4169
|
+
/** Get immediate children of a parent (sorted by order). */
|
|
4170
|
+
childrenOf(parentId: string | null): TreeEntry[];
|
|
4171
|
+
/** Get all descendants recursively. */
|
|
4172
|
+
descendantsOf(parentId: string | null): TreeEntry[];
|
|
4173
|
+
/** Build nested tree JSON. */
|
|
4174
|
+
buildTree(rootId?: string | null, maxDepth?: number): TreeNode[];
|
|
4175
|
+
private _buildTree;
|
|
4176
|
+
/** Find a single entry by ID. */
|
|
4177
|
+
get(docId: string): TreeEntry | null;
|
|
4178
|
+
/** Search by label (case-insensitive substring match). */
|
|
4179
|
+
find(query: string, rootId?: string | null): TreeSearchResult[];
|
|
4180
|
+
/** Create a new document in the tree. Returns the new entry. */
|
|
4181
|
+
create(opts: {
|
|
4182
|
+
parentId?: string | null;
|
|
4183
|
+
label: string;
|
|
4184
|
+
type?: string;
|
|
4185
|
+
meta?: Partial<PageMeta>;
|
|
4186
|
+
}): TreeEntry;
|
|
4187
|
+
/**
|
|
4188
|
+
* Create a document and auto-apply renderer defaults from the page type's
|
|
4189
|
+
* `defaultMetaFields` (toggle fields with `default` values).
|
|
4190
|
+
*/
|
|
4191
|
+
createWithTypeDefaults(opts: {
|
|
4192
|
+
parentId?: string | null;
|
|
4193
|
+
label: string;
|
|
4194
|
+
type: string;
|
|
4195
|
+
extraMeta?: Partial<PageMeta>;
|
|
4196
|
+
}): TreeEntry;
|
|
4197
|
+
/** Rename a document. */
|
|
4198
|
+
rename(docId: string, label: string): void;
|
|
4199
|
+
/** Move a document to a new parent. */
|
|
4200
|
+
move(docId: string, newParentId?: string | null, order?: number): void;
|
|
4201
|
+
/** Change the page type of a document. */
|
|
4202
|
+
changeType(docId: string, type: string): void;
|
|
4203
|
+
/**
|
|
4204
|
+
* Soft-delete a document and descendants (move to trash).
|
|
4205
|
+
* @returns count of deleted documents
|
|
4206
|
+
*/
|
|
4207
|
+
delete(docId: string): number;
|
|
4208
|
+
/** Duplicate a document (shallow clone). Returns the new entry. */
|
|
4209
|
+
duplicate(docId: string): TreeEntry;
|
|
4210
|
+
/** Restore a document from trash back into the tree. */
|
|
4211
|
+
restore(docId: string): void;
|
|
4212
|
+
/** List trashed documents. */
|
|
4213
|
+
listTrash(): TreeEntry[];
|
|
4214
|
+
/** Get enabled plugin names from space-plugins map. */
|
|
4215
|
+
getEnabledPlugins(): string[];
|
|
4216
|
+
private _descendantIds;
|
|
4217
|
+
}
|
|
4218
|
+
//#endregion
|
|
4219
|
+
//#region packages/provider/src/DocConverters.d.ts
|
|
4220
|
+
/**
|
|
4221
|
+
* Converts a Y.XmlFragment (TipTap document) to markdown.
|
|
4222
|
+
* Extracts the title from the documentHeader element.
|
|
4223
|
+
*
|
|
4224
|
+
* @returns `{ title, markdown }` where title is the H1/header text
|
|
4225
|
+
*/
|
|
4226
|
+
declare function yjsToMarkdown(fragment: Y.XmlFragment): {
|
|
4227
|
+
title: string;
|
|
4228
|
+
markdown: string;
|
|
4229
|
+
};
|
|
4230
|
+
declare function filenameToLabel(raw: string): string;
|
|
4231
|
+
interface FrontmatterResult {
|
|
4232
|
+
title?: string;
|
|
4233
|
+
meta: Partial<PageMeta>;
|
|
4234
|
+
body: string;
|
|
4235
|
+
}
|
|
4236
|
+
declare function parseFrontmatter(markdown: string): FrontmatterResult;
|
|
4237
|
+
declare function populateYDocFromMarkdown(fragment: Y.XmlFragment, markdown: string, fallbackTitle?: string): void;
|
|
4238
|
+
declare function buildHeadingElement(text: string, level?: 1 | 2 | 3 | 4 | 5 | 6): Y.XmlElement;
|
|
4239
|
+
declare function buildParagraphElement(text: string): Y.XmlElement;
|
|
4240
|
+
declare function buildBulletListElement(items: string[]): Y.XmlElement;
|
|
4241
|
+
declare function buildOrderedListElement(items: string[]): Y.XmlElement;
|
|
4242
|
+
declare function buildTaskListElement(items: Array<{
|
|
4243
|
+
text: string;
|
|
4244
|
+
checked?: boolean;
|
|
4245
|
+
}>): Y.XmlElement;
|
|
4246
|
+
declare function buildCodeBlockElement(code: string, language?: string): Y.XmlElement;
|
|
4247
|
+
declare function buildBlockquoteElement(text: string): Y.XmlElement;
|
|
4248
|
+
declare function buildHorizontalRuleElement(): Y.XmlElement;
|
|
4249
|
+
/** Parse markdown into block Y.XmlElements (no header/meta). */
|
|
4250
|
+
declare function buildBlocksFromMarkdown(markdown: string): Y.XmlElement[];
|
|
4251
|
+
interface DocumentBlock {
|
|
4252
|
+
type: string;
|
|
4253
|
+
attrs: Record<string, unknown>;
|
|
4254
|
+
text: string;
|
|
4255
|
+
items?: string[];
|
|
4256
|
+
children?: DocumentBlock[];
|
|
4257
|
+
}
|
|
4258
|
+
declare function readBlocksFromFragment(fragment: Y.XmlFragment): DocumentBlock[];
|
|
4259
|
+
//#endregion
|
|
4260
|
+
//#region packages/provider/src/ContentManager.d.ts
|
|
4261
|
+
interface DocumentContent {
|
|
4262
|
+
label: string;
|
|
4263
|
+
type?: string;
|
|
4264
|
+
meta?: PageMeta;
|
|
4265
|
+
title: string;
|
|
4266
|
+
markdown: string;
|
|
4267
|
+
children: Array<{
|
|
4268
|
+
id: string;
|
|
4269
|
+
label: string;
|
|
4270
|
+
type?: string;
|
|
4271
|
+
meta?: PageMeta;
|
|
4272
|
+
}>;
|
|
4273
|
+
}
|
|
4274
|
+
declare class ContentManager {
|
|
4275
|
+
private dm;
|
|
4276
|
+
constructor(dm: DocumentManager);
|
|
4277
|
+
/**
|
|
4278
|
+
* Read document content as markdown.
|
|
4279
|
+
* Returns the title extracted from the TipTap documentHeader, the markdown
|
|
4280
|
+
* body, tree metadata, and immediate children.
|
|
4281
|
+
*/
|
|
4282
|
+
read(docId: string): Promise<DocumentContent>;
|
|
4283
|
+
/**
|
|
4284
|
+
* Write markdown content to a document.
|
|
4285
|
+
* Supports optional YAML frontmatter for title and metadata.
|
|
4286
|
+
*
|
|
4287
|
+
* @param mode - "replace" clears existing content first (default),
|
|
4288
|
+
* "append" adds to the end.
|
|
4289
|
+
*/
|
|
4290
|
+
write(docId: string, markdown: string, mode?: "replace" | "append"): Promise<void>;
|
|
4291
|
+
private _appendElements;
|
|
4292
|
+
appendHeading(docId: string, text: string, opts?: {
|
|
4293
|
+
level?: 1 | 2 | 3 | 4 | 5 | 6;
|
|
4294
|
+
}): Promise<void>;
|
|
4295
|
+
appendParagraph(docId: string, text: string): Promise<void>;
|
|
4296
|
+
appendBulletList(docId: string, items: string[]): Promise<void>;
|
|
4297
|
+
appendOrderedList(docId: string, items: string[]): Promise<void>;
|
|
4298
|
+
appendTaskList(docId: string, items: Array<{
|
|
4299
|
+
text: string;
|
|
4300
|
+
checked?: boolean;
|
|
4301
|
+
}>): Promise<void>;
|
|
4302
|
+
appendCodeBlock(docId: string, code: string, opts?: {
|
|
4303
|
+
language?: string;
|
|
4304
|
+
}): Promise<void>;
|
|
4305
|
+
appendBlockquote(docId: string, text: string): Promise<void>;
|
|
4306
|
+
appendHorizontalRule(docId: string): Promise<void>;
|
|
4307
|
+
appendMarkdown(docId: string, markdown: string): Promise<void>;
|
|
4308
|
+
getBlocks(docId: string): Promise<DocumentBlock[]>;
|
|
4309
|
+
/**
|
|
4310
|
+
* Get the raw Y.XmlFragment for a document (the 'default' fragment
|
|
4311
|
+
* that TipTap uses for document content).
|
|
4312
|
+
*/
|
|
4313
|
+
getFragment(docId: string): Promise<Y.XmlFragment>;
|
|
4314
|
+
/**
|
|
4315
|
+
* Get the raw Y.Doc for a document (synced).
|
|
4316
|
+
*/
|
|
4317
|
+
getDoc(docId: string): Promise<Y.Doc>;
|
|
4318
|
+
}
|
|
4319
|
+
//#endregion
|
|
4320
|
+
//#region packages/provider/src/MetaManager.d.ts
|
|
4321
|
+
interface DocumentMetaInfo {
|
|
4322
|
+
id: string;
|
|
4323
|
+
label: string;
|
|
4324
|
+
type?: string;
|
|
4325
|
+
meta: PageMeta;
|
|
4326
|
+
}
|
|
4327
|
+
declare class MetaManager {
|
|
4328
|
+
private dm;
|
|
4329
|
+
constructor(dm: DocumentManager);
|
|
4330
|
+
/** Read metadata for a document. Returns null if not found. */
|
|
4331
|
+
get(docId: string): DocumentMetaInfo | null;
|
|
4332
|
+
/**
|
|
4333
|
+
* Merge fields into a document's metadata.
|
|
4334
|
+
* Existing keys not in the update are preserved.
|
|
4335
|
+
*/
|
|
4336
|
+
update(docId: string, meta: Partial<PageMeta>): void;
|
|
4337
|
+
/**
|
|
4338
|
+
* Replace all metadata on a document.
|
|
4339
|
+
* This overwrites the entire meta object.
|
|
4340
|
+
*/
|
|
4341
|
+
set(docId: string, meta: PageMeta): void;
|
|
4342
|
+
/**
|
|
4343
|
+
* Clear specific metadata keys (set them to null/undefined).
|
|
4344
|
+
*/
|
|
4345
|
+
clear(docId: string, keys: string[]): void;
|
|
4346
|
+
}
|
|
4347
|
+
//#endregion
|
|
4348
|
+
//#region packages/provider/src/DocumentManager.d.ts
|
|
4349
|
+
interface DocumentManagerConfig {
|
|
4350
|
+
/** Server base URL (http or https). */
|
|
4351
|
+
url: string;
|
|
4352
|
+
/** Display name for awareness (cursor labels, presence). */
|
|
4353
|
+
name?: string;
|
|
4354
|
+
/** Cursor / awareness color. */
|
|
4355
|
+
color?: string;
|
|
4356
|
+
/** Invite code for first-time registration. */
|
|
4357
|
+
inviteCode?: string;
|
|
4358
|
+
/** Suppress stderr logging. */
|
|
4359
|
+
quiet?: boolean;
|
|
4360
|
+
/** Disable IndexedDB offline persistence. */
|
|
4361
|
+
disableOfflineStore?: boolean;
|
|
4362
|
+
/** Custom fetch for Node.js environments. */
|
|
4363
|
+
fetch?: typeof globalThis.fetch;
|
|
4364
|
+
/**
|
|
4365
|
+
* Pre-configured AbracadabraClient instance.
|
|
4366
|
+
* When provided, the `url` and `fetch` fields are ignored — the client's
|
|
4367
|
+
* configuration is used instead. This is useful when the consumer has
|
|
4368
|
+
* already authenticated or configured the client externally.
|
|
4369
|
+
*/
|
|
4370
|
+
client?: AbracadabraClient;
|
|
4371
|
+
/**
|
|
4372
|
+
* Shared WebSocket connection. Required in Node.js environments — pass an
|
|
4373
|
+
* AbracadabraWS constructed with WebSocketPolyfill set to the `ws` package.
|
|
4374
|
+
* When omitted, each provider creates its own connection from client.wsUrl.
|
|
4375
|
+
* The caller owns this instance and must destroy it after dm.destroy().
|
|
4376
|
+
*/
|
|
4377
|
+
websocketProvider?: AbracadabraWS;
|
|
4378
|
+
/**
|
|
4379
|
+
* Known root document ID. When provided, connect() skips server discovery
|
|
4380
|
+
* and connects directly to this document. Useful in tests or CLIs where
|
|
4381
|
+
* the entry-point docId is already known.
|
|
4382
|
+
*/
|
|
4383
|
+
rootDocId?: string;
|
|
4384
|
+
}
|
|
4385
|
+
declare class DocumentManager {
|
|
4386
|
+
readonly client: AbracadabraClient;
|
|
4387
|
+
/** Tree CRUD operations. */
|
|
4388
|
+
readonly tree: TreeManager;
|
|
4389
|
+
/** Document content read/write. */
|
|
4390
|
+
readonly content: ContentManager;
|
|
4391
|
+
/** Document metadata read/write. */
|
|
4392
|
+
readonly meta: MetaManager;
|
|
4393
|
+
private _config;
|
|
4394
|
+
private _serverInfo;
|
|
4395
|
+
private _rootDocId;
|
|
4396
|
+
private _spaces;
|
|
4397
|
+
private _rootDoc;
|
|
4398
|
+
private _rootProvider;
|
|
4399
|
+
private childCache;
|
|
4400
|
+
constructor(config: DocumentManagerConfig);
|
|
4401
|
+
get displayName(): string;
|
|
4402
|
+
get displayColor(): string;
|
|
4403
|
+
get serverInfo(): ServerInfo | null;
|
|
4404
|
+
get rootDocId(): string | null;
|
|
4405
|
+
get rootDocument(): Y.Doc | null;
|
|
4406
|
+
get rootProvider(): AbracadabraProvider | null;
|
|
4407
|
+
/**
|
|
4408
|
+
* Spaces visible to the caller — direct children of the server root with
|
|
4409
|
+
* `kind === "space"`. Populated by {@link connect}.
|
|
4410
|
+
*/
|
|
4411
|
+
get spaces(): DocumentMeta[];
|
|
4412
|
+
get isConnected(): boolean;
|
|
4413
|
+
/** Get the root doc-tree Y.Map. */
|
|
4414
|
+
getTreeMap(): Y.Map<any> | null;
|
|
4415
|
+
/** Get the root doc-trash Y.Map. */
|
|
4416
|
+
getTrashMap(): Y.Map<any> | null;
|
|
4417
|
+
/** Get the root space-plugins Y.Map. */
|
|
4418
|
+
getPluginsMap(): Y.Map<any> | null;
|
|
4419
|
+
/**
|
|
4420
|
+
* Connect to the server: discover the entry-point document, sync the root
|
|
4421
|
+
* Y.Doc, and set awareness.
|
|
4422
|
+
*
|
|
4423
|
+
* **Authentication must be done before calling connect().**
|
|
4424
|
+
* Call `dm.client.loginWithKey(publicKey, signFn)` or `dm.client.login()`
|
|
4425
|
+
* to authenticate first.
|
|
4426
|
+
*
|
|
4427
|
+
* When `rootDocId` is set in the config, server discovery is skipped and
|
|
4428
|
+
* the manager connects directly to that document.
|
|
4429
|
+
*/
|
|
4430
|
+
connect(): Promise<void>;
|
|
4431
|
+
/** Switch active space to a different root document. */
|
|
4432
|
+
switchSpace(docId: string): Promise<void>;
|
|
4433
|
+
/** Create, sync, and set awareness on a root provider for the given docId. */
|
|
4434
|
+
private _connectToRoot;
|
|
4435
|
+
/** Graceful shutdown. */
|
|
4436
|
+
destroy(): Promise<void>;
|
|
4437
|
+
/** Get or create a child provider for a document (synced). */
|
|
4438
|
+
getChildProvider(docId: string): Promise<AbracadabraProvider>;
|
|
4439
|
+
private log;
|
|
4440
|
+
}
|
|
4441
|
+
//#endregion
|
|
4442
|
+
//#region packages/provider/src/DocUtils.d.ts
|
|
4443
|
+
/**
|
|
4444
|
+
* Wait for a provider's `synced` event with a timeout.
|
|
4445
|
+
* Resolves immediately if the provider is already synced.
|
|
4446
|
+
*/
|
|
4447
|
+
declare function waitForSync(provider: {
|
|
4448
|
+
isSynced?: boolean;
|
|
4449
|
+
on(event: string, cb: () => void): void;
|
|
4450
|
+
off(event: string, cb: () => void): void;
|
|
4451
|
+
}, timeoutMs?: number): Promise<void>;
|
|
4452
|
+
/**
|
|
4453
|
+
* Wrap a promise with a timeout.
|
|
4454
|
+
*/
|
|
4455
|
+
declare function withTimeout<T>(promise: Promise<T>, timeoutMs: number, message?: string): Promise<T>;
|
|
4456
|
+
/**
|
|
4457
|
+
* Normalize a document ID so the hub/root doc ID is treated as the tree root
|
|
4458
|
+
* (null). This lets callers pass the hub doc_id from list_spaces as
|
|
4459
|
+
* parentId/rootId and get the expected root-level results instead of an empty
|
|
4460
|
+
* set.
|
|
4461
|
+
*/
|
|
4462
|
+
declare function normalizeRootId(id: string | null | undefined, rootDocId: string | null): string | null;
|
|
4463
|
+
/**
|
|
4464
|
+
* Safely read a tree map value, converting Y.Map to plain object if needed.
|
|
4465
|
+
*/
|
|
4466
|
+
declare function toPlain(val: unknown): unknown;
|
|
4467
|
+
//#endregion
|
|
4468
|
+
export { AbracadabraBaseProvider, AbracadabraBaseProviderConfiguration, AbracadabraClient, AbracadabraClientConfig, AbracadabraOutgoingMessageArguments, AbracadabraProvider, AbracadabraProviderConfiguration, AbracadabraWS, AbracadabraWSConfiguration, AbracadabraWebRTC, type AbracadabraWebRTCConfiguration, AbracadabraWebSocketConn, 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, 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 };
|