@fileverse-dev/ddoc 4.2.4-patch-yjs-1 → 4.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{index-B3eaAAg-.mjs → index-BHEcRC2F.mjs} +1 -1
- package/dist/{index-BJz7x8xS.mjs → index-DPuANynY.mjs} +33222 -28014
- package/dist/index.d.ts +0 -2
- package/dist/index.es.js +9 -13
- package/dist/{markdown-source-pane-BgevwwEq.mjs → markdown-source-pane-BDPSou1J.mjs} +2 -2
- package/dist/package/components/editor-bubble-menu/types.d.ts +1 -1
- package/dist/package/components/inline-comment/comment-drawer-desktop.d.ts +2 -1
- package/dist/package/components/inline-comment/comment-drawer-mobile.d.ts +2 -1
- package/dist/package/components/inline-comment/comment-drawer.d.ts +1 -1
- package/dist/package/components/inline-comment/comment-input-field.d.ts +2 -1
- package/dist/package/components/inline-comment/comment-reply-input.d.ts +2 -1
- package/dist/package/components/inline-comment/comment-section.d.ts +1 -1
- package/dist/package/components/inline-comment/floating-comment/comment-floating-container.d.ts +1 -1
- package/dist/package/components/inline-comment/floating-comment/suggestion-thread-floating-card.d.ts +1 -1
- package/dist/package/components/inline-comment/floating-comment/thread-floating-card.d.ts +1 -1
- package/dist/package/components/inline-comment/floating-comment/types.d.ts +2 -0
- package/dist/package/components/inline-comment/types.d.ts +2 -0
- package/dist/package/hooks/use-tab-editor.d.ts +3 -3
- package/dist/package/hooks/use-yjs-setup.d.ts +1 -7
- package/dist/package/sync-local/SyncManager.d.ts +7 -40
- package/dist/package/sync-local/socketClient.d.ts +8 -78
- package/dist/package/sync-local/types/index.d.ts +12 -111
- package/dist/package/sync-local/useSyncManager.d.ts +0 -4
- package/dist/package/types.d.ts +1 -2
- package/dist/package/use-ddoc-editor.d.ts +0 -5
- package/dist/{split-view-toolbar-UOnFAMzh.mjs → split-view-toolbar-BXnE-1Ad.mjs} +2 -2
- package/package.json +5 -5
- package/dist/package/sync-local/crypto/room-key.d.ts +0 -2
- package/dist/package/sync-local/floor.d.ts +0 -6
- package/dist/package/sync-local/presence.d.ts +0 -11
- package/dist/package/sync-local/session-tools.d.ts +0 -31
|
@@ -7,64 +7,6 @@ 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;
|
|
68
10
|
ownerEdSecret?: string;
|
|
69
11
|
contractAddress?: string;
|
|
70
12
|
ownerAddress?: string;
|
|
@@ -79,14 +21,18 @@ export interface CollabSessionMeta {
|
|
|
79
21
|
username: string;
|
|
80
22
|
isEns?: boolean;
|
|
81
23
|
}
|
|
82
|
-
|
|
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
|
+
}
|
|
83
29
|
export type CollabErrorCode = 'CONNECTION_FAILED' | 'AUTH_FAILED' | 'SYNC_FAILED' | 'TIMEOUT' | 'UNKNOWN';
|
|
84
30
|
export type CollabError = {
|
|
85
31
|
code: CollabErrorCode;
|
|
86
32
|
message: string;
|
|
87
33
|
recoverable: boolean;
|
|
88
34
|
};
|
|
89
|
-
export type CollabStatus = 'idle' | 'connecting' | 'syncing' | 'ready' | 'reconnecting' | '
|
|
35
|
+
export type CollabStatus = 'idle' | 'connecting' | 'syncing' | 'ready' | 'reconnecting' | 'error' | 'terminated';
|
|
90
36
|
export type CollabState = {
|
|
91
37
|
status: 'idle';
|
|
92
38
|
} | {
|
|
@@ -100,10 +46,6 @@ export type CollabState = {
|
|
|
100
46
|
status: 'reconnecting';
|
|
101
47
|
attempt: number;
|
|
102
48
|
maxAttempts: number;
|
|
103
|
-
}
|
|
104
|
-
/** roomKey migration in flight — distinct from `terminated` so consumers don't mistake it for a kick. */
|
|
105
|
-
| {
|
|
106
|
-
status: 'rotating';
|
|
107
49
|
} | {
|
|
108
50
|
status: 'error';
|
|
109
51
|
error: CollabError;
|
|
@@ -132,10 +74,6 @@ export type CollabEvent = {
|
|
|
132
74
|
} | {
|
|
133
75
|
type: 'SESSION_TERMINATED';
|
|
134
76
|
reason?: string;
|
|
135
|
-
}
|
|
136
|
-
/** roomKey cutover in progress; no-op on status — lets the manager gate re-entrancy itself. */
|
|
137
|
-
| {
|
|
138
|
-
type: 'CUTOVER';
|
|
139
77
|
} | {
|
|
140
78
|
type: 'RESET';
|
|
141
79
|
};
|
|
@@ -155,13 +93,6 @@ export interface CollabCallbacks {
|
|
|
155
93
|
data: AckResponse;
|
|
156
94
|
roomKey: string;
|
|
157
95
|
}) => 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>;
|
|
165
96
|
}
|
|
166
97
|
/** Discriminated union — TypeScript enforces config+services only when enabled */
|
|
167
98
|
export type CollaborationProps = {
|
|
@@ -196,10 +127,7 @@ export declare enum ServerErrorCode {
|
|
|
196
127
|
INVALID_ADDRESS = "INVALID_ADDRESS",
|
|
197
128
|
NOT_AUTHENTICATED = "NOT_AUTHENTICATED",
|
|
198
129
|
DB_ERROR = "DB_ERROR",
|
|
199
|
-
INTERNAL_ERROR = "INTERNAL_ERROR"
|
|
200
|
-
JOIN_DISABLED = "JOIN_DISABLED",
|
|
201
|
-
EDIT_REVOKED = "EDIT_REVOKED",
|
|
202
|
-
ROOM_NOT_ESTABLISHED = "ROOM_NOT_ESTABLISHED"
|
|
130
|
+
INTERNAL_ERROR = "INTERNAL_ERROR"
|
|
203
131
|
}
|
|
204
132
|
export interface AckResponse<T = Record<string, any>> {
|
|
205
133
|
status: boolean;
|
|
@@ -217,30 +145,11 @@ export interface SendUpdateResponse extends AckResponse<{
|
|
|
217
145
|
createdAt: number;
|
|
218
146
|
}> {
|
|
219
147
|
}
|
|
220
|
-
export interface
|
|
221
|
-
|
|
148
|
+
export interface CommitResponse extends AckResponse<{
|
|
149
|
+
cid: string;
|
|
150
|
+
createdAt: number;
|
|
222
151
|
documentId: string;
|
|
223
|
-
|
|
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;
|
|
152
|
+
updates: string[];
|
|
244
153
|
}> {
|
|
245
154
|
}
|
|
246
155
|
export interface ISocketInitConfig {
|
|
@@ -248,7 +157,7 @@ export interface ISocketInitConfig {
|
|
|
248
157
|
onDisconnect: () => void;
|
|
249
158
|
onSocketDropped: () => void;
|
|
250
159
|
onError: (err: Error) => void;
|
|
251
|
-
onHandShakeError: (err: Error, statusCode?: number
|
|
160
|
+
onHandShakeError: (err: Error, statusCode?: number) => void;
|
|
252
161
|
onContentUpdate: (data: {
|
|
253
162
|
id: string;
|
|
254
163
|
data: string;
|
|
@@ -262,8 +171,6 @@ export interface ISocketInitConfig {
|
|
|
262
171
|
};
|
|
263
172
|
roomId: string;
|
|
264
173
|
}) => void;
|
|
265
|
-
onPresenceChange?: (collaborators: IDocCollabUsers[]) => void;
|
|
266
|
-
onTitleUpdate?: (encryptedTitle: string | null) => void;
|
|
267
174
|
onSessionTerminated: (data: {
|
|
268
175
|
roomId: string;
|
|
269
176
|
}) => void;
|
|
@@ -289,10 +196,4 @@ export interface IAuthArgs {
|
|
|
289
196
|
contractAddress?: string;
|
|
290
197
|
sessionDid?: string;
|
|
291
198
|
roomInfo?: string;
|
|
292
|
-
ownerIdentityDid?: string;
|
|
293
|
-
identityToken?: string;
|
|
294
|
-
identityContractAddress?: string;
|
|
295
|
-
editUcan?: string;
|
|
296
|
-
actorHandle?: string;
|
|
297
|
-
joinOnly?: boolean;
|
|
298
199
|
}
|
|
@@ -5,10 +5,6 @@ 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;
|
|
12
8
|
isReady: boolean;
|
|
13
9
|
isSyncing: boolean;
|
|
14
10
|
awareness: import('y-protocols/awareness.js').Awareness | null;
|
package/dist/package/types.d.ts
CHANGED
|
@@ -9,11 +9,10 @@ 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:
|
|
12
|
+
clientId: number;
|
|
13
13
|
name: string;
|
|
14
14
|
isEns: string;
|
|
15
15
|
color: string;
|
|
16
|
-
isPlaceholder?: boolean;
|
|
17
16
|
}
|
|
18
17
|
export type InlineCommentData = {
|
|
19
18
|
inlineCommentText: string;
|
|
@@ -28,13 +28,8 @@ 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;
|
|
32
31
|
isReady: boolean;
|
|
33
32
|
isSyncing: boolean;
|
|
34
|
-
updateTitle: (args: {
|
|
35
|
-
encryptedTitle: string;
|
|
36
|
-
documentTitle: string;
|
|
37
|
-
}) => void;
|
|
38
33
|
hasCollabContentInitialised: boolean;
|
|
39
34
|
isIndexeddbSynced: boolean;
|
|
40
35
|
initialiseYjsIndexedDbProvider: () => Promise<void>;
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { j as d } from "./index-
|
|
1
|
+
import { j as d } from "./index-DPuANynY.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-
|
|
4
|
+
import { a3 as A, a4 as P, c as y } from "./index-BHEcRC2F.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.4
|
|
5
|
+
"version": "4.2.4",
|
|
6
6
|
"main": "dist/index.es.js",
|
|
7
7
|
"module": "dist/index.es.js",
|
|
8
8
|
"exports": {
|
|
@@ -121,6 +121,8 @@
|
|
|
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
|
+
"yjs": "^13.6.15",
|
|
124
126
|
"zustand": "^5.0.12"
|
|
125
127
|
},
|
|
126
128
|
"peerDependencies": {
|
|
@@ -133,7 +135,6 @@
|
|
|
133
135
|
"framer-motion": ">=11.2.10",
|
|
134
136
|
"frimousse": ">=0.3.0",
|
|
135
137
|
"mermaid": "11.14.0",
|
|
136
|
-
"yjs": ">=13.6.30 <14",
|
|
137
138
|
"viem": ">=2.35.0"
|
|
138
139
|
},
|
|
139
140
|
"devDependencies": {
|
|
@@ -164,7 +165,6 @@
|
|
|
164
165
|
"tailwindcss": "^3.4.3",
|
|
165
166
|
"typescript": "^5.2.2",
|
|
166
167
|
"vite": "^5.0.0",
|
|
167
|
-
"vitest": "^2.1.0"
|
|
168
|
-
"yjs": "13.6.30"
|
|
168
|
+
"vitest": "^2.1.0"
|
|
169
169
|
}
|
|
170
|
-
}
|
|
170
|
+
}
|
|
@@ -1,11 +0,0 @@
|
|
|
1
|
-
import { IDocCollabUsers } from '../types';
|
|
2
|
-
|
|
3
|
-
export interface AwarenessIdentity {
|
|
4
|
-
name: string;
|
|
5
|
-
color: string;
|
|
6
|
-
isEns: string | boolean;
|
|
7
|
-
}
|
|
8
|
-
export declare const PLACEHOLDER_COLOR = "#9CA3AF";
|
|
9
|
-
export declare function buildIdentityMap(states: Map<number, Record<string, unknown>>): Map<string, AwarenessIdentity>;
|
|
10
|
-
export declare function mergePresence(roomMembers: string[], identityBySocketId: Map<string, AwarenessIdentity>): IDocCollabUsers[];
|
|
11
|
-
export declare function identitySignature(roomMembers: string[], identityBySocketId: Map<string, AwarenessIdentity>): string;
|
|
@@ -1,31 +0,0 @@
|
|
|
1
|
-
import { CollabConnectionConfig } from './types';
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* Headless hydrate: pulls the OLD session's durable log and decrypts it with `roomKey`.
|
|
5
|
-
* The old session still exists server-side — termination only rejects writes, so a
|
|
6
|
-
* joinOnly read succeeds even after cutover. Mirrors the connect-time hydration pull
|
|
7
|
-
* (SyncManager.catchUpFloor / decodeInto), minus the Y.Doc/floor bookkeeping. Throws on
|
|
8
|
-
* connect/auth/pull failure; an individual undecryptable row is skipped, not fatal.
|
|
9
|
-
*/
|
|
10
|
-
export declare function fetchSessionState(args: {
|
|
11
|
-
ddocId: string;
|
|
12
|
-
roomKey: string;
|
|
13
|
-
ownerAuth: CollabConnectionConfig;
|
|
14
|
-
}): Promise<Uint8Array[]>;
|
|
15
|
-
/**
|
|
16
|
-
* Headless seed: pushes `state` into a brand-new session as a single owner snapshot,
|
|
17
|
-
* encrypted under `newRoomKey`. `floorSeq: 0` — the target session is freshly created by
|
|
18
|
-
* the rotate op and holds no rows yet, so there is nothing to catch up before stamping.
|
|
19
|
-
*
|
|
20
|
-
* Caller ordering: must run AFTER the rotate op has already created the target session.
|
|
21
|
-
* This function's own owner `/auth` is create-or-join — calling it first would create the
|
|
22
|
-
* target session itself and, as an owner /auth, sweep (terminate) any other non-terminated
|
|
23
|
-
* session for this document, which is the OLD session that's supposed to keep draining
|
|
24
|
-
* stragglers during the rotation window. Seeding early collapses that drain early.
|
|
25
|
-
*/
|
|
26
|
-
export declare function seedSession(args: {
|
|
27
|
-
ddocId: string;
|
|
28
|
-
newRoomKey: string;
|
|
29
|
-
state: Uint8Array;
|
|
30
|
-
ownerAuth: CollabConnectionConfig;
|
|
31
|
-
}): Promise<void>;
|