@fileverse-dev/ddoc 4.2.3 → 4.2.4-patch-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.
Files changed (31) hide show
  1. package/dist/{index-DU4ChFqp.mjs → index-CsZ0zljP.mjs} +25769 -25255
  2. package/dist/{index-B59aQPXt.mjs → index-Dehs4zRZ.mjs} +1 -1
  3. package/dist/index.d.ts +2 -0
  4. package/dist/index.es.js +13 -9
  5. package/dist/{markdown-source-pane-bDzJJavW.mjs → markdown-source-pane-CqqDAHCy.mjs} +2 -2
  6. package/dist/package/components/editor-bubble-menu/types.d.ts +0 -1
  7. package/dist/package/components/inline-comment/comment-drawer-desktop.d.ts +1 -2
  8. package/dist/package/components/inline-comment/comment-drawer-mobile.d.ts +1 -2
  9. package/dist/package/components/inline-comment/comment-drawer.d.ts +1 -1
  10. package/dist/package/components/inline-comment/comment-input-field.d.ts +1 -2
  11. package/dist/package/components/inline-comment/comment-reply-input.d.ts +1 -2
  12. package/dist/package/components/inline-comment/comment-section.d.ts +1 -1
  13. package/dist/package/components/inline-comment/floating-comment/comment-floating-container.d.ts +1 -1
  14. package/dist/package/components/inline-comment/floating-comment/suggestion-thread-floating-card.d.ts +1 -1
  15. package/dist/package/components/inline-comment/floating-comment/thread-floating-card.d.ts +1 -1
  16. package/dist/package/components/inline-comment/floating-comment/types.d.ts +0 -2
  17. package/dist/package/components/inline-comment/types.d.ts +0 -2
  18. package/dist/package/hooks/use-tab-editor.d.ts +3 -3
  19. package/dist/package/hooks/use-yjs-setup.d.ts +7 -1
  20. package/dist/package/sync-local/SyncManager.d.ts +40 -7
  21. package/dist/package/sync-local/crypto/room-key.d.ts +2 -0
  22. package/dist/package/sync-local/floor.d.ts +6 -0
  23. package/dist/package/sync-local/presence.d.ts +11 -0
  24. package/dist/package/sync-local/session-tools.d.ts +31 -0
  25. package/dist/package/sync-local/socketClient.d.ts +78 -8
  26. package/dist/package/sync-local/types/index.d.ts +111 -12
  27. package/dist/package/sync-local/useSyncManager.d.ts +4 -0
  28. package/dist/package/types.d.ts +2 -1
  29. package/dist/package/use-ddoc-editor.d.ts +5 -0
  30. package/dist/{split-view-toolbar-fzF0a8Qb.mjs → split-view-toolbar-CXCPVdyq.mjs} +2 -2
  31. package/package.json +2 -3
@@ -7,6 +7,64 @@ export interface CollabConnectionConfig {
7
7
  roomId: string;
8
8
  wsUrl: string;
9
9
  isOwner: boolean;
10
+ /** Host signal: doc is in an active live-collaboration context (shared / peers present). Keeps the socket connected. */
11
+ livePresence?: boolean;
12
+ /** Host signal: connect once on open to initialise durability even without an edit. */
13
+ connectOnOpen?: boolean;
14
+ /** Host signal (owner-only): the owner identity signingKey DID. Recorded by the durable server on the first owner /auth as the R3 owner binding. */
15
+ ownerIdentityDid?: string;
16
+ /** Host signal (owner-only): wrapped roomKey bytes (owner-lock construction), uploaded as the server editLock recovery artifact. Opaque to the package. */
17
+ editLock?: string;
18
+ /** Host signal (owner-only): the document title encrypted with the roomKey, uploaded as the server title recovery artifact. Opaque to the package. */
19
+ encryptedTitle?: string;
20
+ /** Host signal (owner-only): Ed25519 UCAN proving the owner identity, sent on /auth so the server binds the CRYPTOGRAPHICALLY PROVEN owner DID (not a bare asserted string). Opaque to the package. */
21
+ identityToken?: string;
22
+ /** Host signal (owner-only): the identity contract address the server reads to resolve the on-chain signingDid that verifies identityToken. */
23
+ identityContractAddress?: string;
24
+ /** Host signal (non-owner editor): the gate-minted edit-admission UCAN, forwarded on /auth so the
25
+ * server admits this connection as a GP-rail editor. Opaque to the package. */
26
+ editUcan?: string;
27
+ /** Host signal (non-owner editor): re-mints a CURRENT-epoch editUcan. Called at every /auth
28
+ * (incl. reconnect after a force-drop). Tri-state: `ok` (fresh token; overrides the static
29
+ * `editUcan`), `demoted` (no longer an editor → terminal, drop to viewer), or `unavailable`
30
+ * (transient/network → retry on the last-good claim). Opaque to the package. */
31
+ refreshEditClaim?: () => Promise<{
32
+ status: 'ok';
33
+ token: string;
34
+ } | {
35
+ status: 'demoted';
36
+ } | {
37
+ status: 'unavailable';
38
+ }>;
39
+ /** Host signal: resolves the rotated roomKey for the given epoch payload (GP: gate release
40
+ * unwrap of `gp`; workspace: app-key unwrap of `appLock`). Returns the new base64 roomKey —
41
+ * or, for a gate-admitted editor, `{ roomKey, editUcan }`: the same gate release that unwraps
42
+ * the relay also mints the new-epoch editUcan, and the cutover re-auth must present THAT token
43
+ * (a re-mint through the host's fresh-open flow can race the deferred publish and hand back a
44
+ * stale-epoch claim). `null` if this actor can't resolve it (falls back to the decrypt-miss
45
+ * self-heal path). Opaque to the package. */
46
+ onRotationPrepare?: (inner: {
47
+ epoch: number;
48
+ gp: string;
49
+ appLock?: string;
50
+ }) => Promise<string | {
51
+ roomKey: string;
52
+ editUcan?: string;
53
+ } | null>;
54
+ /** Host signal: an anonymous per-connection actor handle (public rail). Record-only; opaque. */
55
+ actorHandle?: string;
56
+ /** Host signal (non-creator workspace member): join-only. The server never creates or
57
+ * binds a session for this connection and caps the role at editor; every handshake
58
+ * rejection resolves to a quiet terminated state ('ROOM_NOT_ESTABLISHED' when the room
59
+ * was never established, 'JOIN_REJECTED' otherwise) instead of an error. */
60
+ joinOnly?: boolean;
61
+ /** Host signal (editor): produces the view-plane mirror ciphertext from the live Yjs state. The app
62
+ * AES-GCM-encrypts `{ file: base64(yjsUpdate), source }` under the fileKey in the publish wire
63
+ * format. Absent ⇒ the mirror is not written. The package never sees the fileKey or the crypto. */
64
+ encryptMirror?: (yjsUpdate: Uint8Array) => Promise<string>;
65
+ /** Host signal: the fileKey's rotation epoch (the gate `currentEpoch` / fileKey version — NOT
66
+ * `editGrantEpoch`; default 0 for non-rotating plain-public docs). */
67
+ fileKeyEpoch?: number;
10
68
  ownerEdSecret?: string;
11
69
  contractAddress?: string;
12
70
  ownerAddress?: string;
@@ -21,18 +79,14 @@ export interface CollabSessionMeta {
21
79
  username: string;
22
80
  isEns?: boolean;
23
81
  }
24
- /** Storage integrations the sync engine depends on */
25
- export interface CollabServices {
26
- commitToStorage?: (file: File) => Promise<string>;
27
- fetchFromStorage?: (cid: string) => Promise<any>;
28
- }
82
+ export type CollabServices = Record<string, never>;
29
83
  export type CollabErrorCode = 'CONNECTION_FAILED' | 'AUTH_FAILED' | 'SYNC_FAILED' | 'TIMEOUT' | 'UNKNOWN';
30
84
  export type CollabError = {
31
85
  code: CollabErrorCode;
32
86
  message: string;
33
87
  recoverable: boolean;
34
88
  };
35
- export type CollabStatus = 'idle' | 'connecting' | 'syncing' | 'ready' | 'reconnecting' | 'error' | 'terminated';
89
+ export type CollabStatus = 'idle' | 'connecting' | 'syncing' | 'ready' | 'reconnecting' | 'rotating' | 'error' | 'terminated';
36
90
  export type CollabState = {
37
91
  status: 'idle';
38
92
  } | {
@@ -46,6 +100,10 @@ export type CollabState = {
46
100
  status: 'reconnecting';
47
101
  attempt: number;
48
102
  maxAttempts: number;
103
+ }
104
+ /** roomKey migration in flight — distinct from `terminated` so consumers don't mistake it for a kick. */
105
+ | {
106
+ status: 'rotating';
49
107
  } | {
50
108
  status: 'error';
51
109
  error: CollabError;
@@ -74,6 +132,10 @@ export type CollabEvent = {
74
132
  } | {
75
133
  type: 'SESSION_TERMINATED';
76
134
  reason?: string;
135
+ }
136
+ /** roomKey cutover in progress; no-op on status — lets the manager gate re-entrancy itself. */
137
+ | {
138
+ type: 'CUTOVER';
77
139
  } | {
78
140
  type: 'RESET';
79
141
  };
@@ -93,6 +155,13 @@ export interface CollabCallbacks {
93
155
  data: AckResponse;
94
156
  roomKey: string;
95
157
  }) => void;
158
+ /** Live rename from the room owner; title is roomKey-encrypted. */
159
+ onTitleUpdate?: (encryptedTitle: string | null) => void;
160
+ /** Decrypt-miss self-heal: resolves the CURRENT-epoch roomKey (same resolution the host
161
+ * uses for `onRotationPrepare`, minus the relay payload — re-read the blob's
162
+ * `wrappedRoomKey` / appLock). Returns the new base64 roomKey, or `null` if this actor
163
+ * can't resolve one (the miss is then a real revocation, not a rotation lag). */
164
+ onRotationSelfHeal?: () => Promise<string | null>;
96
165
  }
97
166
  /** Discriminated union — TypeScript enforces config+services only when enabled */
98
167
  export type CollaborationProps = {
@@ -127,7 +196,10 @@ export declare enum ServerErrorCode {
127
196
  INVALID_ADDRESS = "INVALID_ADDRESS",
128
197
  NOT_AUTHENTICATED = "NOT_AUTHENTICATED",
129
198
  DB_ERROR = "DB_ERROR",
130
- INTERNAL_ERROR = "INTERNAL_ERROR"
199
+ INTERNAL_ERROR = "INTERNAL_ERROR",
200
+ JOIN_DISABLED = "JOIN_DISABLED",
201
+ EDIT_REVOKED = "EDIT_REVOKED",
202
+ ROOM_NOT_ESTABLISHED = "ROOM_NOT_ESTABLISHED"
131
203
  }
132
204
  export interface AckResponse<T = Record<string, any>> {
133
205
  status: boolean;
@@ -145,11 +217,30 @@ export interface SendUpdateResponse extends AckResponse<{
145
217
  createdAt: number;
146
218
  }> {
147
219
  }
148
- export interface CommitResponse extends AckResponse<{
149
- cid: string;
150
- createdAt: number;
220
+ export interface HydrationRow {
221
+ id: string;
151
222
  documentId: string;
152
- updates: string[];
223
+ seq: number;
224
+ data: string;
225
+ updateType: string;
226
+ committed?: boolean;
227
+ commitCid?: string | null;
228
+ createdAt?: number;
229
+ sessionDid?: string;
230
+ publishedMarker?: string | null;
231
+ floorSeq?: number | null;
232
+ }
233
+ export interface HydrationResponse extends AckResponse<{
234
+ history: HydrationRow[];
235
+ total: number;
236
+ snapshot: HydrationRow | null;
237
+ nextSeq: number | null;
238
+ hasMore: boolean;
239
+ }> {
240
+ }
241
+ export interface SnapshotResponse extends AckResponse<{
242
+ id: string;
243
+ seq: number;
153
244
  }> {
154
245
  }
155
246
  export interface ISocketInitConfig {
@@ -157,7 +248,7 @@ export interface ISocketInitConfig {
157
248
  onDisconnect: () => void;
158
249
  onSocketDropped: () => void;
159
250
  onError: (err: Error) => void;
160
- onHandShakeError: (err: Error, statusCode?: number) => void;
251
+ onHandShakeError: (err: Error, statusCode?: number, errorCode?: ServerErrorCode) => void;
161
252
  onContentUpdate: (data: {
162
253
  id: string;
163
254
  data: string;
@@ -171,6 +262,8 @@ export interface ISocketInitConfig {
171
262
  };
172
263
  roomId: string;
173
264
  }) => void;
265
+ onPresenceChange?: (collaborators: IDocCollabUsers[]) => void;
266
+ onTitleUpdate?: (encryptedTitle: string | null) => void;
174
267
  onSessionTerminated: (data: {
175
268
  roomId: string;
176
269
  }) => void;
@@ -196,4 +289,10 @@ export interface IAuthArgs {
196
289
  contractAddress?: string;
197
290
  sessionDid?: string;
198
291
  roomInfo?: string;
292
+ ownerIdentityDid?: string;
293
+ identityToken?: string;
294
+ identityContractAddress?: string;
295
+ editUcan?: string;
296
+ actorHandle?: string;
297
+ joinOnly?: boolean;
199
298
  }
@@ -5,6 +5,10 @@ export declare const useSyncManager: (config: SyncManagerConfig) => {
5
5
  connect: (connectConfig: CollabConnectionConfig) => void;
6
6
  disconnect: () => void;
7
7
  terminateSession: () => void;
8
+ updateTitle: (args: {
9
+ encryptedTitle: string;
10
+ documentTitle: string;
11
+ }) => void;
8
12
  isReady: boolean;
9
13
  isSyncing: boolean;
10
14
  awareness: import('y-protocols/awareness.js').Awareness | null;
@@ -9,10 +9,11 @@ import { CollaborationProps } from './sync-local/types';
9
9
  export type { CollaborationProps, CollabConnectionConfig, CollabSessionMeta, CollabServices, CollabCallbacks, CollabState, CollabError, CollabErrorCode, CollabStatus, } from './sync-local/types';
10
10
  export declare const DdocEditorProps: EditorProps;
11
11
  export interface IDocCollabUsers {
12
- clientId: number;
12
+ clientId: string | number;
13
13
  name: string;
14
14
  isEns: string;
15
15
  color: string;
16
+ isPlaceholder?: boolean;
16
17
  }
17
18
  export type InlineCommentData = {
18
19
  inlineCommentText: string;
@@ -28,8 +28,13 @@ export declare const useDdocEditor: ({ isPreviewMode, viewerMode, initialContent
28
28
  duplicateTab: (tabId: string) => string | undefined;
29
29
  orderTab: (destinationTabId: string, movedTabId: string) => void;
30
30
  onConnect: (connectConfig: import('./types').CollabConnectionConfig) => void;
31
+ onDisconnect: () => void;
31
32
  isReady: boolean;
32
33
  isSyncing: boolean;
34
+ updateTitle: (args: {
35
+ encryptedTitle: string;
36
+ documentTitle: string;
37
+ }) => void;
33
38
  hasCollabContentInitialised: boolean;
34
39
  isIndexeddbSynced: boolean;
35
40
  initialiseYjsIndexedDbProvider: () => Promise<void>;
@@ -1,7 +1,7 @@
1
- import { j as d } from "./index-DU4ChFqp.mjs";
1
+ import { j as d } from "./index-CsZ0zljP.mjs";
2
2
  import { useRef as I, useState as N, useEffect as D } from "react";
3
3
  import { DynamicDropdown as E, Tooltip as R, IconButton as O } from "@fileverse/ui";
4
- import { a3 as A, a4 as P, c as y } from "./index-B59aQPXt.mjs";
4
+ import { a3 as A, a4 as P, c as y } from "./index-Dehs4zRZ.mjs";
5
5
  const p = (e, t, o = t) => {
6
6
  const { state: s } = e, l = s.changeByRange((n) => {
7
7
  const u = s.sliceDoc(n.from, n.to), r = s.sliceDoc(
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@fileverse-dev/ddoc",
3
3
  "private": false,
4
4
  "description": "DDoc",
5
- "version": "4.2.3",
5
+ "version": "4.2.4-patch-0",
6
6
  "main": "dist/index.es.js",
7
7
  "module": "dist/index.es.js",
8
8
  "exports": {
@@ -121,7 +121,6 @@
121
121
  "y-indexeddb": "^9.0.12",
122
122
  "y-prosemirror": "^1.2.5",
123
123
  "y-protocols": "^1.0.6",
124
- "y-webrtc": "^10.3.0",
125
124
  "yjs": "^13.6.15",
126
125
  "zustand": "^5.0.12"
127
126
  },
@@ -167,4 +166,4 @@
167
166
  "vite": "^5.0.0",
168
167
  "vitest": "^2.1.0"
169
168
  }
170
- }
169
+ }