@hocuspocus/provider 2.14.0 → 2.15.1-rc.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/hocuspocus-provider.cjs +61 -7
- package/dist/hocuspocus-provider.cjs.map +1 -1
- package/dist/hocuspocus-provider.esm.js +61 -7
- package/dist/hocuspocus-provider.esm.js.map +1 -1
- package/dist/packages/provider/src/TiptapCollabProvider.d.ts +17 -6
- package/dist/packages/provider/src/types.d.ts +28 -0
- package/dist/packages/server/src/Hocuspocus.d.ts +1 -1
- package/dist/tests/utils/newHocuspocusProvider.d.ts +2 -2
- package/package.json +2 -2
- package/src/TiptapCollabProvider.ts +85 -11
- package/src/types.ts +32 -0
|
@@ -2,7 +2,7 @@ import type { AbstractType, YArrayEvent } from 'yjs';
|
|
|
2
2
|
import * as Y from 'yjs';
|
|
3
3
|
import { HocuspocusProvider, HocuspocusProviderConfiguration } from './HocuspocusProvider.js';
|
|
4
4
|
import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket.js';
|
|
5
|
-
import type
|
|
5
|
+
import { type DeleteCommentOptions, type DeleteThreadOptions, type GetThreadsOptions, type TCollabComment, type TCollabThread, type THistoryVersion } from './types.js';
|
|
6
6
|
export type TiptapCollabProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & (Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'websocketProvider'>> | Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>> | Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'baseUrl'>>) & Pick<AdditionalTiptapCollabProviderConfiguration, 'user'> & {
|
|
7
7
|
/**
|
|
8
8
|
* Pass `true` if you want to delete a thread when the first comment is deleted.
|
|
@@ -55,9 +55,10 @@ export declare class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
55
55
|
private getYThreads;
|
|
56
56
|
/**
|
|
57
57
|
* Finds all threads in the document and returns them as JSON objects
|
|
58
|
+
* @options Options to control the output of the threads (e.g. include deleted threads)
|
|
58
59
|
* @returns An array of threads as JSON objects
|
|
59
60
|
*/
|
|
60
|
-
getThreads<Data, CommentData>(): TCollabThread<Data, CommentData>[];
|
|
61
|
+
getThreads<Data, CommentData>(options?: GetThreadsOptions): TCollabThread<Data, CommentData>[];
|
|
61
62
|
/**
|
|
62
63
|
* Find the index of a thread by its id
|
|
63
64
|
* @param id The thread id
|
|
@@ -81,7 +82,7 @@ export declare class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
81
82
|
* @param data The thread data
|
|
82
83
|
* @returns The created thread
|
|
83
84
|
*/
|
|
84
|
-
createThread(data: Omit<TCollabThread, 'id' | 'createdAt' | 'updatedAt' | 'comments' | 'deletedComments'>): TCollabThread;
|
|
85
|
+
createThread(data: Omit<TCollabThread, 'id' | 'createdAt' | 'updatedAt' | 'deletedAt' | 'comments' | 'deletedComments'>): TCollabThread;
|
|
85
86
|
/**
|
|
86
87
|
* Update a specific thread
|
|
87
88
|
* @param id The thread id
|
|
@@ -92,11 +93,21 @@ export declare class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
92
93
|
resolvedAt: TCollabThread['resolvedAt'] | null;
|
|
93
94
|
}>): TCollabThread;
|
|
94
95
|
/**
|
|
95
|
-
*
|
|
96
|
+
* Handle the deletion of a thread. By default, the thread and it's comments are not deleted, but marked as deleted
|
|
97
|
+
* via the `deletedAt` property. Forceful deletion can be enabled by setting the `force` option to `true`.
|
|
98
|
+
*
|
|
99
|
+
* If you only want to delete the comments of a thread, you can set the `deleteComments` option to `true`.
|
|
100
|
+
* @param id The thread id
|
|
101
|
+
* @param options A set of options that control how the thread is deleted
|
|
102
|
+
* @returns The deleted thread or null if the thread is not found
|
|
103
|
+
*/
|
|
104
|
+
deleteThread(id: TCollabThread['id'], options?: DeleteThreadOptions): TCollabThread | null | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Tries to restore a deleted thread
|
|
96
107
|
* @param id The thread id
|
|
97
|
-
* @returns
|
|
108
|
+
* @returns The restored thread or null if the thread is not found
|
|
98
109
|
*/
|
|
99
|
-
|
|
110
|
+
restoreThread(id: TCollabThread['id']): TCollabThread | null;
|
|
100
111
|
/**
|
|
101
112
|
* Returns comments from a thread, either deleted or not
|
|
102
113
|
* @param threadId The thread id
|
|
@@ -88,6 +88,7 @@ export type TCollabThread<Data = any, CommentData = any> = {
|
|
|
88
88
|
id: string;
|
|
89
89
|
createdAt: number;
|
|
90
90
|
updatedAt: number;
|
|
91
|
+
deletedAt: number | null;
|
|
91
92
|
resolvedAt?: string;
|
|
92
93
|
comments: TCollabComment<CommentData>[];
|
|
93
94
|
deletedComments: TCollabComment<CommentData>[];
|
|
@@ -156,3 +157,30 @@ export type DeleteCommentOptions = {
|
|
|
156
157
|
*/
|
|
157
158
|
deleteContent?: boolean;
|
|
158
159
|
};
|
|
160
|
+
export type DeleteThreadOptions = {
|
|
161
|
+
/**
|
|
162
|
+
* If `true`, will remove the comments on the thread,
|
|
163
|
+
* otherwise will only mark the thread as deleted
|
|
164
|
+
* and keep the comments
|
|
165
|
+
* @default false
|
|
166
|
+
*/
|
|
167
|
+
deleteComments?: boolean;
|
|
168
|
+
/**
|
|
169
|
+
* If `true`, will forcefully remove the thread and all comments,
|
|
170
|
+
* otherwise will only mark the thread as deleted
|
|
171
|
+
* and keep the comments
|
|
172
|
+
* @default false
|
|
173
|
+
*/
|
|
174
|
+
force?: boolean;
|
|
175
|
+
};
|
|
176
|
+
/**
|
|
177
|
+
* The type of thread
|
|
178
|
+
*/
|
|
179
|
+
export type ThreadType = 'archived' | 'unarchived';
|
|
180
|
+
export type GetThreadsOptions = {
|
|
181
|
+
/**
|
|
182
|
+
* The types of threads to get
|
|
183
|
+
* @default ['unarchived']
|
|
184
|
+
*/
|
|
185
|
+
types?: Array<ThreadType>;
|
|
186
|
+
};
|
|
@@ -95,7 +95,7 @@ export declare class Hocuspocus {
|
|
|
95
95
|
* Runs the given callback after each hook.
|
|
96
96
|
*/
|
|
97
97
|
hooks<T extends HookName>(name: T, payload: HookPayloadByName[T], callback?: Function | null): Promise<any>;
|
|
98
|
-
unloadDocument(document: Document):
|
|
98
|
+
unloadDocument(document: Document): Promise<any>;
|
|
99
99
|
enableDebugging(): void;
|
|
100
100
|
enableMessageLogging(): void;
|
|
101
101
|
disableLogging(): void;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
1
|
+
import { HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
2
2
|
import { Hocuspocus } from '@hocuspocus/server';
|
|
3
|
-
export declare const newHocuspocusProvider: (server: Hocuspocus, options?: Partial<HocuspocusProviderConfiguration>, websocketOptions?: Partial<HocuspocusProviderWebsocketConfiguration
|
|
3
|
+
export declare const newHocuspocusProvider: (server: Hocuspocus, options?: Partial<HocuspocusProviderConfiguration>, websocketOptions?: Partial<HocuspocusProviderWebsocketConfiguration>, websocketProvider?: HocuspocusProviderWebsocket) => HocuspocusProvider;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hocuspocus/provider",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.1-rc.0",
|
|
4
4
|
"description": "hocuspocus provider",
|
|
5
5
|
"homepage": "https://hocuspocus.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -29,7 +29,7 @@
|
|
|
29
29
|
"dist"
|
|
30
30
|
],
|
|
31
31
|
"dependencies": {
|
|
32
|
-
"@hocuspocus/common": "^2.
|
|
32
|
+
"@hocuspocus/common": "^2.15.1-rc.0",
|
|
33
33
|
"@lifeomic/attempt": "^3.0.2",
|
|
34
34
|
"lib0": "^0.2.87",
|
|
35
35
|
"ws": "^8.17.1"
|
|
@@ -7,9 +7,11 @@ import {
|
|
|
7
7
|
} from './HocuspocusProvider.js'
|
|
8
8
|
|
|
9
9
|
import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket.js'
|
|
10
|
-
import
|
|
11
|
-
DeleteCommentOptions,
|
|
12
|
-
|
|
10
|
+
import {
|
|
11
|
+
type DeleteCommentOptions,
|
|
12
|
+
type DeleteThreadOptions,
|
|
13
|
+
type GetThreadsOptions,
|
|
14
|
+
type TCollabComment, type TCollabThread, type THistoryVersion,
|
|
13
15
|
} from './types.js'
|
|
14
16
|
|
|
15
17
|
const defaultDeleteCommentOptions: DeleteCommentOptions = {
|
|
@@ -17,6 +19,15 @@ const defaultDeleteCommentOptions: DeleteCommentOptions = {
|
|
|
17
19
|
deleteThread: false,
|
|
18
20
|
}
|
|
19
21
|
|
|
22
|
+
const defaultGetThreadsOptions: GetThreadsOptions = {
|
|
23
|
+
types: ['unarchived'],
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
const defaultDeleteThreadOptions: DeleteThreadOptions = {
|
|
27
|
+
deleteComments: false,
|
|
28
|
+
force: false,
|
|
29
|
+
}
|
|
30
|
+
|
|
20
31
|
export type TiptapCollabProviderConfiguration =
|
|
21
32
|
Required<Pick<HocuspocusProviderConfiguration, 'name'>> &
|
|
22
33
|
Partial<HocuspocusProviderConfiguration> &
|
|
@@ -128,10 +139,29 @@ export class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
128
139
|
|
|
129
140
|
/**
|
|
130
141
|
* Finds all threads in the document and returns them as JSON objects
|
|
142
|
+
* @options Options to control the output of the threads (e.g. include deleted threads)
|
|
131
143
|
* @returns An array of threads as JSON objects
|
|
132
144
|
*/
|
|
133
|
-
getThreads<Data, CommentData>(): TCollabThread<Data, CommentData>[] {
|
|
134
|
-
|
|
145
|
+
getThreads<Data, CommentData>(options?: GetThreadsOptions): TCollabThread<Data, CommentData>[] {
|
|
146
|
+
const { types } = { ...defaultGetThreadsOptions, ...options } as GetThreadsOptions
|
|
147
|
+
|
|
148
|
+
const threads = this.getYThreads().toJSON() as TCollabThread<Data, CommentData>[]
|
|
149
|
+
|
|
150
|
+
if (types?.includes('archived') && types?.includes('unarchived')) {
|
|
151
|
+
return threads
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
return threads.filter(currentThead => {
|
|
155
|
+
if (types?.includes('archived') && currentThead.deletedAt) {
|
|
156
|
+
return true
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
if (types?.includes('unarchived') && !currentThead.deletedAt) {
|
|
160
|
+
return true
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return false
|
|
164
|
+
})
|
|
135
165
|
}
|
|
136
166
|
|
|
137
167
|
/**
|
|
@@ -144,7 +174,7 @@ export class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
144
174
|
|
|
145
175
|
let i = 0
|
|
146
176
|
// eslint-disable-next-line no-restricted-syntax
|
|
147
|
-
for (const thread of this.getThreads()) {
|
|
177
|
+
for (const thread of this.getThreads({ types: ['archived', 'unarchived'] })) {
|
|
148
178
|
if (thread.id === id) {
|
|
149
179
|
index = i
|
|
150
180
|
break
|
|
@@ -190,7 +220,7 @@ export class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
190
220
|
* @param data The thread data
|
|
191
221
|
* @returns The created thread
|
|
192
222
|
*/
|
|
193
|
-
createThread(data: Omit<TCollabThread, 'id' | 'createdAt' | 'updatedAt' | 'comments' | 'deletedComments'>) {
|
|
223
|
+
createThread(data: Omit<TCollabThread, 'id' | 'createdAt' | 'updatedAt' | 'deletedAt' | 'comments' | 'deletedComments'>) {
|
|
194
224
|
let createdThread: TCollabThread = {} as TCollabThread
|
|
195
225
|
|
|
196
226
|
this.document.transact(() => {
|
|
@@ -199,6 +229,7 @@ export class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
199
229
|
thread.set('createdAt', (new Date()).toISOString())
|
|
200
230
|
thread.set('comments', new Y.Array())
|
|
201
231
|
thread.set('deletedComments', new Y.Array())
|
|
232
|
+
thread.set('deletedAt', null)
|
|
202
233
|
|
|
203
234
|
this.getYThreads().push([thread])
|
|
204
235
|
createdThread = this.updateThread(String(thread.get('id')), data)
|
|
@@ -242,18 +273,57 @@ export class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
242
273
|
}
|
|
243
274
|
|
|
244
275
|
/**
|
|
245
|
-
*
|
|
276
|
+
* Handle the deletion of a thread. By default, the thread and it's comments are not deleted, but marked as deleted
|
|
277
|
+
* via the `deletedAt` property. Forceful deletion can be enabled by setting the `force` option to `true`.
|
|
278
|
+
*
|
|
279
|
+
* If you only want to delete the comments of a thread, you can set the `deleteComments` option to `true`.
|
|
246
280
|
* @param id The thread id
|
|
247
|
-
* @
|
|
281
|
+
* @param options A set of options that control how the thread is deleted
|
|
282
|
+
* @returns The deleted thread or null if the thread is not found
|
|
248
283
|
*/
|
|
249
|
-
deleteThread(id: TCollabThread['id']) {
|
|
284
|
+
deleteThread(id: TCollabThread['id'], options?: DeleteThreadOptions) {
|
|
285
|
+
const { deleteComments, force } = { ...defaultDeleteThreadOptions, ...options }
|
|
286
|
+
|
|
250
287
|
const index = this.getThreadIndex(id)
|
|
251
288
|
|
|
252
289
|
if (index === null) {
|
|
290
|
+
return null
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (force) {
|
|
294
|
+
this.getYThreads().delete(index, 1)
|
|
253
295
|
return
|
|
254
296
|
}
|
|
255
297
|
|
|
256
|
-
this.getYThreads().
|
|
298
|
+
const thread = this.getYThreads().get(index)
|
|
299
|
+
|
|
300
|
+
thread.set('deletedAt', (new Date()).toISOString())
|
|
301
|
+
|
|
302
|
+
if (deleteComments) {
|
|
303
|
+
thread.set('comments', new Y.Array())
|
|
304
|
+
thread.set('deletedComments', new Y.Array())
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
return thread.toJSON() as TCollabThread
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
/**
|
|
311
|
+
* Tries to restore a deleted thread
|
|
312
|
+
* @param id The thread id
|
|
313
|
+
* @returns The restored thread or null if the thread is not found
|
|
314
|
+
*/
|
|
315
|
+
restoreThread(id: TCollabThread['id']) {
|
|
316
|
+
const index = this.getThreadIndex(id)
|
|
317
|
+
|
|
318
|
+
if (index === null) {
|
|
319
|
+
return null
|
|
320
|
+
}
|
|
321
|
+
|
|
322
|
+
const thread = this.getYThreads().get(index)
|
|
323
|
+
|
|
324
|
+
thread.set('deletedAt', null)
|
|
325
|
+
|
|
326
|
+
return thread.toJSON() as TCollabThread
|
|
257
327
|
}
|
|
258
328
|
|
|
259
329
|
/**
|
|
@@ -406,7 +476,11 @@ export class TiptapCollabProvider extends HocuspocusProvider {
|
|
|
406
476
|
newComment.set('data', comment.get('data'))
|
|
407
477
|
newComment.set('content', deleteContent ? null : comment.get('content'))
|
|
408
478
|
|
|
479
|
+
if (!thread.get('deletedComments')) {
|
|
480
|
+
thread.set('deletedComments', new Y.Array())
|
|
481
|
+
}
|
|
409
482
|
thread.get('deletedComments').push([newComment])
|
|
483
|
+
|
|
410
484
|
thread.get('comments').delete(commentIndex)
|
|
411
485
|
|
|
412
486
|
return thread.toJSON() as TCollabThread
|
package/src/types.ts
CHANGED
|
@@ -110,6 +110,7 @@ export type TCollabThread<Data = any, CommentData = any> = {
|
|
|
110
110
|
id: string;
|
|
111
111
|
createdAt: number;
|
|
112
112
|
updatedAt: number;
|
|
113
|
+
deletedAt: number | null;
|
|
113
114
|
resolvedAt?: string; // (new Date()).toISOString()
|
|
114
115
|
comments: TCollabComment<CommentData>[];
|
|
115
116
|
deletedComments: TCollabComment<CommentData>[];
|
|
@@ -197,3 +198,34 @@ export type DeleteCommentOptions = {
|
|
|
197
198
|
*/
|
|
198
199
|
deleteContent?: boolean
|
|
199
200
|
}
|
|
201
|
+
|
|
202
|
+
export type DeleteThreadOptions = {
|
|
203
|
+
/**
|
|
204
|
+
* If `true`, will remove the comments on the thread,
|
|
205
|
+
* otherwise will only mark the thread as deleted
|
|
206
|
+
* and keep the comments
|
|
207
|
+
* @default false
|
|
208
|
+
*/
|
|
209
|
+
deleteComments?: boolean
|
|
210
|
+
|
|
211
|
+
/**
|
|
212
|
+
* If `true`, will forcefully remove the thread and all comments,
|
|
213
|
+
* otherwise will only mark the thread as deleted
|
|
214
|
+
* and keep the comments
|
|
215
|
+
* @default false
|
|
216
|
+
*/
|
|
217
|
+
force?: boolean,
|
|
218
|
+
}
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* The type of thread
|
|
222
|
+
*/
|
|
223
|
+
export type ThreadType = 'archived' | 'unarchived'
|
|
224
|
+
|
|
225
|
+
export type GetThreadsOptions = {
|
|
226
|
+
/**
|
|
227
|
+
* The types of threads to get
|
|
228
|
+
* @default ['unarchived']
|
|
229
|
+
*/
|
|
230
|
+
types?: Array<ThreadType>
|
|
231
|
+
}
|