@hocuspocus/provider 3.0.0-rc.0 → 3.0.4-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.
Files changed (39) hide show
  1. package/dist/hocuspocus-provider.cjs +773 -11306
  2. package/dist/hocuspocus-provider.cjs.map +1 -1
  3. package/dist/hocuspocus-provider.esm.js +753 -11303
  4. package/dist/hocuspocus-provider.esm.js.map +1 -1
  5. package/dist/packages/common/src/auth.d.ts +1 -1
  6. package/dist/packages/extension-redis/src/Redis.d.ts +8 -2
  7. package/dist/packages/extension-throttle/src/index.d.ts +1 -0
  8. package/dist/packages/extension-webhook/src/index.d.ts +1 -0
  9. package/dist/packages/provider/src/HocuspocusProvider.d.ts +11 -33
  10. package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +0 -4
  11. package/dist/packages/provider/src/MessageReceiver.d.ts +0 -2
  12. package/dist/packages/provider/src/index.d.ts +0 -2
  13. package/dist/packages/provider/src/types.d.ts +42 -2
  14. package/dist/packages/server/src/ClientConnection.d.ts +15 -5
  15. package/dist/packages/server/src/Connection.d.ts +3 -17
  16. package/dist/packages/server/src/DirectConnection.d.ts +1 -1
  17. package/dist/packages/server/src/Document.d.ts +1 -5
  18. package/dist/packages/server/src/Hocuspocus.d.ts +3 -11
  19. package/dist/packages/server/src/MessageReceiver.d.ts +1 -3
  20. package/dist/packages/server/src/OutgoingMessage.d.ts +1 -0
  21. package/dist/packages/server/src/Server.d.ts +3 -2
  22. package/dist/packages/server/src/index.d.ts +0 -1
  23. package/dist/packages/server/src/types.d.ts +20 -11
  24. package/dist/packages/server/src/util/getParameters.d.ts +2 -0
  25. package/dist/tests/utils/newHocuspocusProvider.d.ts +2 -2
  26. package/dist/tests/utils/newHocuspocusProviderWebsocket.d.ts +1 -1
  27. package/package.json +2 -2
  28. package/src/HocuspocusProvider.ts +76 -198
  29. package/src/HocuspocusProviderWebsocket.ts +18 -68
  30. package/src/MessageReceiver.ts +18 -17
  31. package/src/index.ts +0 -2
  32. package/src/types.ts +48 -2
  33. package/dist/packages/provider/src/TiptapCollabProvider.d.ts +0 -64
  34. package/dist/packages/provider/src/TiptapCollabProviderWebsocket.d.ts +0 -20
  35. package/dist/packages/server/src/Debugger.d.ts +0 -14
  36. package/dist/tests/server/getMessageLogs.d.ts +0 -1
  37. package/dist/tests/server/requiresAuthentication.d.ts +0 -1
  38. package/src/TiptapCollabProvider.ts +0 -321
  39. package/src/TiptapCollabProviderWebsocket.ts +0 -39
@@ -2,6 +2,7 @@ import { readAuthMessage } from '@hocuspocus/common'
2
2
  import { readVarInt, readVarString } from 'lib0/decoding'
3
3
  import * as awarenessProtocol from 'y-protocols/awareness'
4
4
  import { messageYjsSyncStep2, readSyncMessage } from 'y-protocols/sync'
5
+ import type { CloseEvent } from 'ws'
5
6
  import type { HocuspocusProvider } from './HocuspocusProvider.js'
6
7
  import type { IncomingMessage } from './IncomingMessage.js'
7
8
  import { OutgoingMessage } from './OutgoingMessage.js'
@@ -11,18 +12,10 @@ export class MessageReceiver {
11
12
 
12
13
  message: IncomingMessage
13
14
 
14
- broadcasted = false
15
-
16
15
  constructor(message: IncomingMessage) {
17
16
  this.message = message
18
17
  }
19
18
 
20
- public setBroadcasted(value: boolean) {
21
- this.broadcasted = value
22
-
23
- return this
24
- }
25
-
26
19
  public apply(provider: HocuspocusProvider, emitSynced: boolean) {
27
20
  const { message } = this
28
21
  const type = message.readVarUint()
@@ -53,21 +46,29 @@ export class MessageReceiver {
53
46
  case MessageType.SyncStatus:
54
47
  this.applySyncStatusMessage(provider, readVarInt(message.decoder) === 1)
55
48
  break
49
+
50
+ case MessageType.CLOSE:
51
+ // eslint-disable-next-line no-case-declarations
52
+ const event: CloseEvent = {
53
+ code: 1000,
54
+ reason: readVarString(message.decoder),
55
+ // @ts-ignore
56
+ target: provider.configuration.websocketProvider.webSocket!,
57
+ type: 'close',
58
+ }
59
+ provider.onClose()
60
+ provider.configuration.onClose({ event })
61
+ provider.forwardClose(event)
62
+ break
63
+
56
64
  default:
57
65
  throw new Error(`Can’t apply message of unknown type: ${type}`)
58
66
  }
59
67
 
60
68
  // Reply
61
69
  if (message.length() > emptyMessageLength + 1) { // length of documentName (considered in emptyMessageLength plus length of yjs sync type, set in applySyncMessage)
62
- if (this.broadcasted) {
63
- // TODO: Some weird TypeScript error
64
- // @ts-ignore
65
- provider.broadcast(OutgoingMessage, { encoder: message.encoder })
66
- } else {
67
- // TODO: Some weird TypeScript error
68
- // @ts-ignore
69
- provider.send(OutgoingMessage, { encoder: message.encoder })
70
- }
70
+ // @ts-ignore
71
+ provider.send(OutgoingMessage, { encoder: message.encoder })
71
72
  }
72
73
  }
73
74
 
package/src/index.ts CHANGED
@@ -1,5 +1,3 @@
1
1
  export * from './HocuspocusProvider.js'
2
- export * from './TiptapCollabProvider.js'
3
- export * from './TiptapCollabProviderWebsocket.js'
4
2
  export * from './HocuspocusProviderWebsocket.js'
5
3
  export * from './types.js'
package/src/types.ts CHANGED
@@ -110,15 +110,18 @@ 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>[];
116
+ deletedComments: TCollabComment<CommentData>[];
115
117
  data: Data
116
118
  }
117
119
 
118
120
  export type TCollabComment<Data = any> = {
119
121
  id: string;
120
- createdAt: number;
121
- updatedAt: number;
122
+ createdAt: string;
123
+ updatedAt: string;
124
+ deletedAt?: string;
122
125
  data: Data
123
126
  content: any
124
127
  }
@@ -183,3 +186,46 @@ export type THistoryDocumentRevertedEvent = {
183
186
  event: 'document.reverted';
184
187
  version: number;
185
188
  };
189
+
190
+ export type DeleteCommentOptions = {
191
+ /**
192
+ * If `true`, the thread will also be deleted if the deleted comment was the first comment in the thread.
193
+ */
194
+ deleteThread?: boolean
195
+
196
+ /**
197
+ * If `true`, will remove the content of the deleted comment
198
+ */
199
+ deleteContent?: boolean
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
+ }
@@ -1,64 +0,0 @@
1
- import type { AbstractType, YArrayEvent } from 'yjs';
2
- import * as Y from 'yjs';
3
- import type { HocuspocusProviderConfiguration } from './HocuspocusProvider.js';
4
- import { HocuspocusProvider } from './HocuspocusProvider.js';
5
- import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket.js';
6
- import type { TCollabComment, TCollabThread, THistoryVersion } from './types.js';
7
- export type TiptapCollabProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & (Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'websocketProvider'>> | Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>> | Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'baseUrl'>>) & Pick<AdditionalTiptapCollabProviderConfiguration, 'user'>;
8
- export interface AdditionalTiptapCollabProviderConfiguration {
9
- /**
10
- * A Hocuspocus Cloud App ID, get one here: https://cloud.tiptap.dev
11
- */
12
- appId?: string;
13
- /**
14
- * If you are using the on-premise version of TiptapCollab, put your baseUrl here (e.g. https://collab.yourdomain.com)
15
- */
16
- baseUrl?: string;
17
- websocketProvider?: TiptapCollabProviderWebsocket;
18
- user?: string;
19
- }
20
- export declare class TiptapCollabProvider extends HocuspocusProvider {
21
- tiptapCollabConfigurationPrefix: string;
22
- userData?: Y.PermanentUserData;
23
- constructor(configuration: TiptapCollabProviderConfiguration);
24
- /**
25
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
26
- */
27
- createVersion(name?: string): void;
28
- /**
29
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
30
- */
31
- revertToVersion(targetVersion: number): void;
32
- /**
33
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
34
- *
35
- * The server will reply with a stateless message (THistoryVersionPreviewEvent)
36
- */
37
- previewVersion(targetVersion: number): void;
38
- /**
39
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
40
- */
41
- getVersions(): THistoryVersion[];
42
- watchVersions(callback: Parameters<AbstractType<YArrayEvent<THistoryVersion>>['observe']>[0]): void;
43
- unwatchVersions(callback: Parameters<AbstractType<YArrayEvent<THistoryVersion>>['unobserve']>[0]): void;
44
- isAutoVersioning(): boolean;
45
- enableAutoVersioning(): 1;
46
- disableAutoVersioning(): 0;
47
- private getYThreads;
48
- getThreads<Data, CommentData>(): TCollabThread<Data, CommentData>[];
49
- private getThreadIndex;
50
- getThread<Data, CommentData>(id: string): TCollabThread<Data, CommentData> | null;
51
- private getYThread;
52
- createThread(data: Omit<TCollabThread, 'id' | 'createdAt' | 'updatedAt' | 'comments'>): TCollabThread;
53
- updateThread(id: TCollabThread['id'], data: Partial<Pick<TCollabThread, 'data'> & {
54
- resolvedAt: TCollabThread['resolvedAt'] | null;
55
- }>): TCollabThread;
56
- deleteThread(id: TCollabThread['id']): void;
57
- getThreadComments(threadId: TCollabThread['id']): TCollabComment[] | null;
58
- getThreadComment(threadId: TCollabThread['id'], commentId: TCollabComment['id']): TCollabComment | null;
59
- addComment(threadId: TCollabThread['id'], data: Omit<TCollabComment, 'id' | 'updatedAt' | 'createdAt'>): TCollabThread;
60
- updateComment(threadId: TCollabThread['id'], commentId: TCollabComment['id'], data: Partial<Pick<TCollabComment, 'data' | 'content'>>): TCollabThread;
61
- deleteComment(threadId: TCollabThread['id'], commentId: TCollabComment['id']): TCollabThread | null | undefined;
62
- watchThreads(callback: () => void): void;
63
- unwatchThreads(callback: () => void): void;
64
- }
@@ -1,20 +0,0 @@
1
- import type { CompleteHocuspocusProviderWebsocketConfiguration } from './HocuspocusProviderWebsocket.js';
2
- import { HocuspocusProviderWebsocket } from './HocuspocusProviderWebsocket.js';
3
- export type TiptapCollabProviderWebsocketConfiguration = Partial<CompleteHocuspocusProviderWebsocketConfiguration> & AdditionalTiptapCollabProviderWebsocketConfiguration;
4
- export interface AdditionalTiptapCollabProviderWebsocketConfiguration {
5
- /**
6
- * A Hocuspocus Cloud App ID, get one here: https://cloud.tiptap.dev
7
- */
8
- appId?: string;
9
- /**
10
- * If you are using the on-premise version of TiptapCollab, put your baseUrl here (e.g. https://collab.yourdomain.com)
11
- */
12
- baseUrl?: string;
13
- /**
14
- * Only fill this if you are using Tiptap Collab HA.
15
- */
16
- shardKey?: string;
17
- }
18
- export declare class TiptapCollabProviderWebsocket extends HocuspocusProviderWebsocket {
19
- constructor(configuration: TiptapCollabProviderWebsocketConfiguration);
20
- }
@@ -1,14 +0,0 @@
1
- export declare class Debugger {
2
- logs: any[];
3
- listen: boolean;
4
- output: boolean;
5
- enable(): void;
6
- disable(): void;
7
- verbose(): void;
8
- quiet(): void;
9
- log(message: any): this;
10
- flush(): this;
11
- get(): {
12
- logs: any[];
13
- };
14
- }
@@ -1 +0,0 @@
1
- export {};
@@ -1 +0,0 @@
1
- export {};
@@ -1,321 +0,0 @@
1
- import type { AbstractType, YArrayEvent } from 'yjs'
2
- import * as Y from 'yjs'
3
- import { uuidv4 } from 'lib0/random'
4
- import type {
5
- HocuspocusProviderConfiguration} from './HocuspocusProvider.js'
6
- import {
7
- HocuspocusProvider,
8
- } from './HocuspocusProvider.js'
9
-
10
- import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket.js'
11
- import type {
12
- TCollabComment, TCollabThread, THistoryVersion,
13
- } from './types.js'
14
-
15
- export type TiptapCollabProviderConfiguration =
16
- Required<Pick<HocuspocusProviderConfiguration, 'name'>> &
17
- Partial<HocuspocusProviderConfiguration> &
18
- (Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'websocketProvider'>> |
19
- Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>>|
20
- Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'baseUrl'>>) &
21
- Pick<AdditionalTiptapCollabProviderConfiguration, 'user'>
22
-
23
- export interface AdditionalTiptapCollabProviderConfiguration {
24
- /**
25
- * A Hocuspocus Cloud App ID, get one here: https://cloud.tiptap.dev
26
- */
27
- appId?: string,
28
-
29
- /**
30
- * If you are using the on-premise version of TiptapCollab, put your baseUrl here (e.g. https://collab.yourdomain.com)
31
- */
32
- baseUrl?: string
33
-
34
- websocketProvider?: TiptapCollabProviderWebsocket
35
-
36
- user?: string
37
- }
38
-
39
- export class TiptapCollabProvider extends HocuspocusProvider {
40
- tiptapCollabConfigurationPrefix = '__tiptapcollab__'
41
-
42
- userData?: Y.PermanentUserData
43
-
44
- constructor(configuration: TiptapCollabProviderConfiguration) {
45
- if (!configuration.websocketProvider) {
46
- configuration.websocketProvider = new TiptapCollabProviderWebsocket({ appId: (configuration as Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>>).appId, baseUrl: (configuration as Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'baseUrl'>>).baseUrl })
47
- }
48
-
49
- if (!configuration.token) {
50
- configuration.token = 'notoken' // need to send a token anyway (which will be ignored)
51
- }
52
-
53
- super(configuration as HocuspocusProviderConfiguration)
54
-
55
- if (configuration.user) {
56
- this.userData = new Y.PermanentUserData(this.document, this.document.getMap('__tiptapcollab__users'))
57
- this.userData.setUserMapping(this.document, this.document.clientID, configuration.user)
58
- }
59
- }
60
-
61
- /**
62
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
63
- */
64
- createVersion(name?: string) {
65
- return this.sendStateless(JSON.stringify({ action: 'version.create', name }))
66
- }
67
-
68
- /**
69
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
70
- */
71
- revertToVersion(targetVersion: number) {
72
- return this.sendStateless(JSON.stringify({ action: 'document.revert', version: targetVersion }))
73
- }
74
-
75
- /**
76
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
77
- *
78
- * The server will reply with a stateless message (THistoryVersionPreviewEvent)
79
- */
80
- previewVersion(targetVersion: number) {
81
- return this.sendStateless(JSON.stringify({ action: 'version.preview', version: targetVersion }))
82
- }
83
-
84
- /**
85
- * note: this will only work if your server loaded @hocuspocus-pro/extension-history, or if you are on a Tiptap business plan.
86
- */
87
- getVersions(): THistoryVersion[] {
88
- return this.configuration.document.getArray<THistoryVersion>(`${this.tiptapCollabConfigurationPrefix}versions`).toArray()
89
- }
90
-
91
- watchVersions(callback: Parameters<AbstractType<YArrayEvent<THistoryVersion>>['observe']>[0]) {
92
- return this.configuration.document.getArray<THistoryVersion>('__tiptapcollab__versions').observe(callback)
93
- }
94
-
95
- unwatchVersions(callback: Parameters<AbstractType<YArrayEvent<THistoryVersion>>['unobserve']>[0]) {
96
- return this.configuration.document.getArray<THistoryVersion>('__tiptapcollab__versions').unobserve(callback)
97
- }
98
-
99
- isAutoVersioning(): boolean {
100
- return !!this.configuration.document.getMap<number>(`${this.tiptapCollabConfigurationPrefix}config`).get('autoVersioning')
101
- }
102
-
103
- enableAutoVersioning() {
104
- return this.configuration.document.getMap<number>(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 1)
105
- }
106
-
107
- disableAutoVersioning() {
108
- return this.configuration.document.getMap<number>(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 0)
109
- }
110
-
111
- private getYThreads() {
112
- return this.configuration.document.getArray<Y.Map<any>>(`${this.tiptapCollabConfigurationPrefix}threads`)
113
- }
114
-
115
- getThreads<Data, CommentData>(): TCollabThread<Data, CommentData>[] {
116
- return this.getYThreads().toJSON() as TCollabThread<Data, CommentData>[]
117
- }
118
-
119
- private getThreadIndex(id: string): number | null {
120
- let index = null
121
-
122
- let i = 0
123
- // eslint-disable-next-line no-restricted-syntax
124
- for (const thread of this.getThreads()) {
125
- if (thread.id === id) {
126
- index = i
127
- break
128
- }
129
- i += 1
130
- }
131
-
132
- return index
133
- }
134
-
135
- getThread<Data, CommentData>(id: string): TCollabThread<Data, CommentData> | null {
136
- const index = this.getThreadIndex(id)
137
-
138
- if (index === null) {
139
- return null
140
- }
141
-
142
- return this.getYThreads().get(index).toJSON() as TCollabThread<Data, CommentData>
143
- }
144
-
145
- private getYThread(id: string) {
146
- const index = this.getThreadIndex(id)
147
-
148
- if (index === null) {
149
- return null
150
- }
151
-
152
- return this.getYThreads().get(index)
153
- }
154
-
155
- createThread(data: Omit<TCollabThread, 'id' | 'createdAt' | 'updatedAt' | 'comments'>) {
156
- let createdThread: TCollabThread = {} as TCollabThread
157
-
158
- this.document.transact(() => {
159
- const thread = new Y.Map()
160
- thread.set('id', uuidv4())
161
- thread.set('createdAt', (new Date()).toISOString())
162
- thread.set('comments', new Y.Array())
163
-
164
- this.getYThreads().push([thread])
165
- createdThread = this.updateThread(String(thread.get('id')), data)
166
- })
167
-
168
- return createdThread
169
- }
170
-
171
- updateThread(id: TCollabThread['id'], data: Partial<Pick<TCollabThread, 'data'> & {
172
- resolvedAt: TCollabThread['resolvedAt'] | null
173
- }>) {
174
- let updatedThread: TCollabThread = {} as TCollabThread
175
-
176
- this.document.transact(() => {
177
- const thread = this.getYThread(id)
178
-
179
- if (thread === null) {
180
- return null
181
- }
182
-
183
- thread.set('updatedAt', (new Date()).toISOString())
184
-
185
- if (data.data) {
186
- thread.set('data', data.data)
187
- }
188
-
189
- if (data.resolvedAt || data.resolvedAt === null) {
190
- thread.set('resolvedAt', data.resolvedAt)
191
- }
192
-
193
- updatedThread = thread.toJSON() as TCollabThread
194
- })
195
-
196
- return updatedThread
197
- }
198
-
199
- deleteThread(id: TCollabThread['id']) {
200
- const index = this.getThreadIndex(id)
201
-
202
- if (index === null) {
203
- return
204
- }
205
-
206
- this.getYThreads().delete(index, 1)
207
- }
208
-
209
- getThreadComments(threadId: TCollabThread['id']): TCollabComment[] | null {
210
- const index = this.getThreadIndex(threadId)
211
-
212
- if (index === null) {
213
- return null
214
- }
215
-
216
- return this.getThread(threadId)?.comments ?? []
217
- }
218
-
219
- getThreadComment(threadId: TCollabThread['id'], commentId: TCollabComment['id']): TCollabComment | null {
220
- const index = this.getThreadIndex(threadId)
221
-
222
- if (index === null) {
223
- return null
224
- }
225
-
226
- return this.getThread(threadId)?.comments.find(comment => comment.id === commentId) ?? null
227
- }
228
-
229
- addComment(threadId: TCollabThread['id'], data: Omit<TCollabComment, 'id' | 'updatedAt' | 'createdAt'>) {
230
- let updatedThread: TCollabThread = {} as TCollabThread
231
-
232
- this.document.transact(() => {
233
- const thread = this.getYThread(threadId)
234
-
235
- if (thread === null) return null
236
-
237
- const commentMap = new Y.Map()
238
- commentMap.set('id', uuidv4())
239
- commentMap.set('createdAt', (new Date()).toISOString())
240
- thread.get('comments').push([commentMap])
241
-
242
- this.updateComment(threadId, String(commentMap.get('id')), data)
243
-
244
- updatedThread = thread.toJSON() as TCollabThread
245
- })
246
-
247
- return updatedThread
248
- }
249
-
250
- updateComment(threadId: TCollabThread['id'], commentId: TCollabComment['id'], data: Partial<Pick<TCollabComment, 'data' | 'content'>>) {
251
- let updatedThread: TCollabThread = {} as TCollabThread
252
-
253
- this.document.transact(() => {
254
- const thread = this.getYThread(threadId)
255
-
256
- if (thread === null) return null
257
-
258
- let comment = null
259
- // eslint-disable-next-line no-restricted-syntax
260
- for (const c of thread.get('comments')) {
261
- if (c.get('id') === commentId) {
262
- comment = c
263
- break
264
- }
265
- }
266
-
267
- if (comment === null) return null
268
-
269
- comment.set('updatedAt', (new Date()).toISOString())
270
-
271
- if (data.data) {
272
- comment.set('data', data.data)
273
- }
274
-
275
- if (data.content) {
276
- comment.set('content', data.content)
277
- }
278
-
279
- updatedThread = thread.toJSON() as TCollabThread
280
- })
281
-
282
- return updatedThread
283
- }
284
-
285
- deleteComment(threadId: TCollabThread['id'], commentId: TCollabComment['id']) {
286
- const thread = this.getYThread(threadId)
287
-
288
- if (thread === null) return null
289
-
290
- let commentIndex = 0
291
- // eslint-disable-next-line no-restricted-syntax
292
- for (const c of thread.get('comments')) {
293
- if (c.get('id') === commentId) {
294
- break
295
- }
296
- commentIndex += 1
297
- }
298
-
299
- // if the first comment of a thread is deleted we also
300
- // delete the thread itself as the source comment is gone
301
- if (commentIndex === 0) {
302
- this.deleteThread(threadId)
303
- return
304
- }
305
-
306
- if (commentIndex > 0) {
307
- thread.get('comments').delete(commentIndex)
308
- }
309
-
310
- return thread.toJSON() as TCollabThread
311
- }
312
-
313
- watchThreads(callback: () => void) {
314
- this.getYThreads().observeDeep(callback)
315
- }
316
-
317
- unwatchThreads(callback: () => void) {
318
- this.getYThreads().unobserveDeep(callback)
319
- }
320
-
321
- }
@@ -1,39 +0,0 @@
1
- import type {
2
- CompleteHocuspocusProviderWebsocketConfiguration, HocuspocusProviderWebsocketConfiguration} from './HocuspocusProviderWebsocket.js'
3
- import {
4
- HocuspocusProviderWebsocket,
5
- } from './HocuspocusProviderWebsocket.js'
6
-
7
- export type TiptapCollabProviderWebsocketConfiguration =
8
- Partial<CompleteHocuspocusProviderWebsocketConfiguration> &
9
- AdditionalTiptapCollabProviderWebsocketConfiguration
10
-
11
- export interface AdditionalTiptapCollabProviderWebsocketConfiguration {
12
- /**
13
- * A Hocuspocus Cloud App ID, get one here: https://cloud.tiptap.dev
14
- */
15
- appId?: string,
16
-
17
- /**
18
- * If you are using the on-premise version of TiptapCollab, put your baseUrl here (e.g. https://collab.yourdomain.com)
19
- */
20
- baseUrl?: string
21
-
22
- /**
23
- * Only fill this if you are using Tiptap Collab HA.
24
- */
25
- shardKey?: string
26
- }
27
-
28
- export class TiptapCollabProviderWebsocket extends HocuspocusProviderWebsocket {
29
- constructor(configuration: TiptapCollabProviderWebsocketConfiguration) {
30
- let url = configuration.baseUrl ?? `wss://${configuration.appId}.collab.tiptap.cloud`
31
-
32
- if (configuration.shardKey) {
33
- url += url.includes('?') ? '&' : '?'
34
- url += `shard=${configuration.shardKey}`
35
- }
36
-
37
- super({ ...configuration as HocuspocusProviderWebsocketConfiguration, url })
38
- }
39
- }