@hocuspocus/provider 2.2.1 → 2.2.3

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.
@@ -72,6 +72,17 @@ export declare class HocuspocusProvider extends EventEmitter {
72
72
  intervals: any;
73
73
  isConnected: boolean;
74
74
  constructor(configuration: HocuspocusProviderConfiguration);
75
+ boundBroadcastChannelSubscriber: (data: ArrayBuffer) => void;
76
+ boundBeforeUnload: () => void;
77
+ boundOnOpen: (event: Event) => Promise<void>;
78
+ boundOnMessage: (event: MessageEvent) => void;
79
+ boundOnClose: (event: CloseEvent) => void;
80
+ boundOnStatus: ({ status }: onStatusParameters) => void;
81
+ forwardConnect: (e: any) => this;
82
+ forwardOpen: (e: any) => this;
83
+ forwardClose: (e: any) => this;
84
+ forwardDisconnect: (e: any) => this;
85
+ forwardDestroy: (e: any) => this;
75
86
  onStatus({ status }: onStatusParameters): void;
76
87
  setConfiguration(configuration?: Partial<HocuspocusProviderConfiguration>): void;
77
88
  get document(): Y.Doc;
@@ -79,7 +90,6 @@ export declare class HocuspocusProvider extends EventEmitter {
79
90
  get hasUnsyncedChanges(): boolean;
80
91
  updateUnsyncedChanges(unsyncedChanges?: number): void;
81
92
  forceSync(): void;
82
- boundBeforeUnload: () => void;
83
93
  beforeUnload(): void;
84
94
  registerEventListeners(): void;
85
95
  sendStateless(payload: string): void;
@@ -101,7 +111,6 @@ export declare class HocuspocusProvider extends EventEmitter {
101
111
  permissionDeniedHandler(reason: string): void;
102
112
  authenticatedHandler(scope: string): void;
103
113
  get broadcastChannel(): string;
104
- boundBroadcastChannelSubscriber: (data: ArrayBuffer) => void;
105
114
  broadcastChannelSubscriber(data: ArrayBuffer): void;
106
115
  subscribeToBroadcastChannel(): void;
107
116
  disconnectBroadcastChannel(): void;
@@ -1,11 +1,28 @@
1
+ import type { AbstractType, YArrayEvent } from 'yjs';
1
2
  import { HocuspocusProvider, HocuspocusProviderConfiguration } from './HocuspocusProvider.js';
2
- export type TiptapCollabProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & AdditionalTiptapCollabProviderConfiguration;
3
+ import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket.js';
4
+ export type TiptapCollabProviderConfiguration = Required<Pick<HocuspocusProviderConfiguration, 'name'>> & Partial<HocuspocusProviderConfiguration> & (Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'websocketProvider'>> | Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>>);
3
5
  export interface AdditionalTiptapCollabProviderConfiguration {
4
6
  /**
5
7
  * A Hocuspocus Cloud App ID, get one here: https://collab.tiptap.dev
6
8
  */
7
- appId: string;
9
+ appId?: string;
10
+ websocketProvider?: TiptapCollabProviderWebsocket;
8
11
  }
12
+ export type AuditHistoryVersion = {
13
+ name?: string;
14
+ version: number;
15
+ date: number;
16
+ };
9
17
  export declare class TiptapCollabProvider extends HocuspocusProvider {
18
+ tiptapCollabConfigurationPrefix: string;
10
19
  constructor(configuration: TiptapCollabProviderConfiguration);
20
+ createVersion(name?: string): void;
21
+ revertToVersion(targetVersion: number): void;
22
+ getVersions(): AuditHistoryVersion[];
23
+ watchVersions(callback: Parameters<AbstractType<YArrayEvent<AuditHistoryVersion>>['observe']>[0]): void;
24
+ unwatchVersions(callback: Parameters<AbstractType<YArrayEvent<AuditHistoryVersion>>['unobserve']>[0]): void;
25
+ isAutoVersioning(): boolean;
26
+ enableAutoVersioning(): number;
27
+ disableAutoVersioning(): number;
11
28
  }
@@ -1,22 +1,23 @@
1
+ import { Encoder } from 'lib0/encoding';
2
+ import type { CloseEvent, Event, MessageEvent } from 'ws';
1
3
  import { Awareness } from 'y-protocols/awareness';
2
4
  import * as Y from 'yjs';
3
- import { Encoder } from 'lib0/encoding';
4
- import type { Event, CloseEvent, MessageEvent } from 'ws';
5
+ import { IncomingMessage } from './IncomingMessage.js';
6
+ import { OutgoingMessage } from './OutgoingMessage.js';
5
7
  import { AuthenticationMessage } from './OutgoingMessages/AuthenticationMessage.js';
6
8
  import { AwarenessMessage } from './OutgoingMessages/AwarenessMessage.js';
7
9
  import { QueryAwarenessMessage } from './OutgoingMessages/QueryAwarenessMessage.js';
8
10
  import { SyncStepOneMessage } from './OutgoingMessages/SyncStepOneMessage.js';
9
11
  import { SyncStepTwoMessage } from './OutgoingMessages/SyncStepTwoMessage.js';
10
12
  import { UpdateMessage } from './OutgoingMessages/UpdateMessage.js';
11
- import { IncomingMessage } from './IncomingMessage.js';
12
- import { OutgoingMessage } from './OutgoingMessage.js';
13
13
  export declare enum MessageType {
14
14
  Sync = 0,
15
15
  Awareness = 1,
16
16
  Auth = 2,
17
17
  QueryAwareness = 3,
18
18
  Stateless = 5,
19
- CLOSE = 7
19
+ CLOSE = 7,
20
+ SyncStatus = 8
20
21
  }
21
22
  export declare enum WebSocketStatus {
22
23
  Connecting = "connecting",
@@ -1,6 +1,6 @@
1
1
  import Document from './Document.js';
2
2
  import type { Hocuspocus } from './Hocuspocus.js';
3
- import type { DirectConnection as DirectConnectionInterface } from './types';
3
+ import type { DirectConnection as DirectConnectionInterface } from './types.js';
4
4
  export declare class DirectConnection implements DirectConnectionInterface {
5
5
  document: Document | null;
6
6
  instance: Hocuspocus;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hocuspocus/provider",
3
- "version": "2.2.1",
3
+ "version": "2.2.3",
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.2.1",
32
+ "@hocuspocus/common": "^2.2.3",
33
33
  "@lifeomic/attempt": "^3.0.2",
34
34
  "lib0": "^0.2.47",
35
35
  "ws": "^7.5.9"
@@ -166,24 +166,24 @@ export class HocuspocusProvider extends EventEmitter {
166
166
  this.on('authenticationFailed', this.configuration.onAuthenticationFailed)
167
167
 
168
168
  this.configuration.websocketProvider.on('connect', this.configuration.onConnect)
169
- this.configuration.websocketProvider.on('connect', (e: Event) => this.emit('connect', e))
169
+ this.configuration.websocketProvider.on('connect', this.forwardConnect)
170
170
 
171
- this.configuration.websocketProvider.on('open', this.onOpen.bind(this))
172
- this.configuration.websocketProvider.on('open', (e: Event) => this.emit('open', e))
171
+ this.configuration.websocketProvider.on('open', this.boundOnOpen)
172
+ this.configuration.websocketProvider.on('open', this.forwardOpen)
173
173
 
174
- this.configuration.websocketProvider.on('message', this.onMessage.bind(this))
174
+ this.configuration.websocketProvider.on('message', this.boundOnMessage)
175
175
 
176
- this.configuration.websocketProvider.on('close', this.onClose.bind(this))
176
+ this.configuration.websocketProvider.on('close', this.boundOnClose)
177
177
  this.configuration.websocketProvider.on('close', this.configuration.onClose)
178
- this.configuration.websocketProvider.on('close', (e: Event) => this.emit('close', e))
178
+ this.configuration.websocketProvider.on('close', this.forwardClose)
179
179
 
180
- this.configuration.websocketProvider.on('status', this.onStatus.bind(this))
180
+ this.configuration.websocketProvider.on('status', this.boundOnStatus)
181
181
 
182
182
  this.configuration.websocketProvider.on('disconnect', this.configuration.onDisconnect)
183
- this.configuration.websocketProvider.on('disconnect', (e: Event) => this.emit('disconnect', e))
183
+ this.configuration.websocketProvider.on('disconnect', this.forwardDisconnect)
184
184
 
185
185
  this.configuration.websocketProvider.on('destroy', this.configuration.onDestroy)
186
- this.configuration.websocketProvider.on('destroy', (e: Event) => this.emit('destroy', e))
186
+ this.configuration.websocketProvider.on('destroy', this.forwardDestroy)
187
187
 
188
188
  this.awareness.on('update', () => {
189
189
  this.emit('awarenessUpdate', { states: awarenessStatesToArray(this.awareness.getStates()) })
@@ -207,6 +207,28 @@ export class HocuspocusProvider extends EventEmitter {
207
207
  this.configuration.websocketProvider.attach(this)
208
208
  }
209
209
 
210
+ boundBroadcastChannelSubscriber = this.broadcastChannelSubscriber.bind(this)
211
+
212
+ boundBeforeUnload = this.beforeUnload.bind(this)
213
+
214
+ boundOnOpen = this.onOpen.bind(this)
215
+
216
+ boundOnMessage = this.onMessage.bind(this)
217
+
218
+ boundOnClose = this.onClose.bind(this)
219
+
220
+ boundOnStatus = this.onStatus.bind(this)
221
+
222
+ forwardConnect = (e: any) => this.emit('connect', e)
223
+
224
+ forwardOpen = (e: any) => this.emit('open', e)
225
+
226
+ forwardClose = (e: any) => this.emit('close', e)
227
+
228
+ forwardDisconnect = (e: any) => this.emit('disconnect', e)
229
+
230
+ forwardDestroy = (e: any) => this.emit('destroy', e)
231
+
210
232
  public onStatus({ status } : onStatusParameters) {
211
233
  this.status = status
212
234
 
@@ -248,8 +270,6 @@ export class HocuspocusProvider extends EventEmitter {
248
270
  this.send(SyncStepOneMessage, { document: this.document, documentName: this.configuration.name })
249
271
  }
250
272
 
251
- boundBeforeUnload = this.beforeUnload.bind(this)
252
-
253
273
  beforeUnload() {
254
274
  removeAwarenessStates(this.awareness, [this.document.clientID], 'window unload')
255
275
  }
@@ -414,6 +434,20 @@ export class HocuspocusProvider extends EventEmitter {
414
434
 
415
435
  this.removeAllListeners()
416
436
 
437
+ this.configuration.websocketProvider.off('connect', this.configuration.onConnect)
438
+ this.configuration.websocketProvider.off('connect', this.forwardConnect)
439
+ this.configuration.websocketProvider.off('open', this.boundOnOpen)
440
+ this.configuration.websocketProvider.off('open', this.forwardOpen)
441
+ this.configuration.websocketProvider.off('message', this.boundOnMessage)
442
+ this.configuration.websocketProvider.off('close', this.boundOnClose)
443
+ this.configuration.websocketProvider.off('close', this.configuration.onClose)
444
+ this.configuration.websocketProvider.off('close', this.forwardClose)
445
+ this.configuration.websocketProvider.off('status', this.boundOnStatus)
446
+ this.configuration.websocketProvider.off('disconnect', this.configuration.onDisconnect)
447
+ this.configuration.websocketProvider.off('disconnect', this.forwardDisconnect)
448
+ this.configuration.websocketProvider.off('destroy', this.configuration.onDestroy)
449
+ this.configuration.websocketProvider.off('destroy', this.forwardDestroy)
450
+
417
451
  this.send(CloseMessage, { documentName: this.configuration.name })
418
452
  this.isConnected = false
419
453
 
@@ -443,8 +477,6 @@ export class HocuspocusProvider extends EventEmitter {
443
477
  return `${this.configuration.name}`
444
478
  }
445
479
 
446
- boundBroadcastChannelSubscriber = this.broadcastChannelSubscriber.bind(this)
447
-
448
480
  broadcastChannelSubscriber(data: ArrayBuffer) {
449
481
  this.mux(() => {
450
482
  const message = new IncomingMessage(data)
@@ -50,6 +50,10 @@ export class MessageReceiver {
50
50
  provider.receiveStateless(readVarString(message.decoder))
51
51
  break
52
52
 
53
+ case MessageType.SyncStatus:
54
+ // nothing for now; forward-compatability
55
+ break
56
+
53
57
  default:
54
58
  throw new Error(`Can’t apply message of unknown type: ${type}`)
55
59
  }
@@ -1,3 +1,4 @@
1
+ import type { AbstractType, YArrayEvent } from 'yjs'
1
2
  import {
2
3
  HocuspocusProvider,
3
4
  HocuspocusProviderConfiguration,
@@ -8,19 +9,30 @@ import { TiptapCollabProviderWebsocket } from './TiptapCollabProviderWebsocket.j
8
9
  export type TiptapCollabProviderConfiguration =
9
10
  Required<Pick<HocuspocusProviderConfiguration, 'name'>> &
10
11
  Partial<HocuspocusProviderConfiguration> &
11
- AdditionalTiptapCollabProviderConfiguration
12
+ (Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'websocketProvider'>> |
13
+ Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>>)
12
14
 
13
15
  export interface AdditionalTiptapCollabProviderConfiguration {
14
16
  /**
15
17
  * A Hocuspocus Cloud App ID, get one here: https://collab.tiptap.dev
16
18
  */
17
- appId: string,
19
+ appId?: string,
20
+
21
+ websocketProvider?: TiptapCollabProviderWebsocket
22
+ }
23
+
24
+ export type AuditHistoryVersion = {
25
+ name?: string;
26
+ version: number;
27
+ date: number;
18
28
  }
19
29
 
20
30
  export class TiptapCollabProvider extends HocuspocusProvider {
31
+ tiptapCollabConfigurationPrefix = '__tiptapcollab__'
32
+
21
33
  constructor(configuration: TiptapCollabProviderConfiguration) {
22
34
  if (!configuration.websocketProvider) {
23
- configuration.websocketProvider = new TiptapCollabProviderWebsocket({ appId: configuration.appId })
35
+ configuration.websocketProvider = new TiptapCollabProviderWebsocket({ appId: (configuration as Required<Pick<AdditionalTiptapCollabProviderConfiguration, 'appId'>>).appId })
24
36
  }
25
37
 
26
38
  if (!configuration.token) {
@@ -29,4 +41,45 @@ export class TiptapCollabProvider extends HocuspocusProvider {
29
41
 
30
42
  super(configuration as HocuspocusProviderConfiguration)
31
43
  }
44
+
45
+ createVersion(name?: string) {
46
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
47
+ return this.sendStateless(JSON.stringify({ action: 'version.create', name }))
48
+ }
49
+
50
+ revertToVersion(targetVersion: number) {
51
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
52
+ return this.sendStateless(JSON.stringify({ action: 'version.revert', version: targetVersion }))
53
+ }
54
+
55
+ getVersions(): AuditHistoryVersion[] {
56
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
57
+ return this.configuration.document.getArray<AuditHistoryVersion>(`${this.tiptapCollabConfigurationPrefix}versions`).toArray()
58
+ }
59
+
60
+ watchVersions(callback: Parameters<AbstractType<YArrayEvent<AuditHistoryVersion>>['observe']>[0]) {
61
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
62
+ return this.configuration.document.getArray<AuditHistoryVersion>('__tiptapcollab__versions').observe(callback)
63
+ }
64
+
65
+ unwatchVersions(callback: Parameters<AbstractType<YArrayEvent<AuditHistoryVersion>>['unobserve']>[0]) {
66
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
67
+ return this.configuration.document.getArray<AuditHistoryVersion>('__tiptapcollab__versions').unobserve(callback)
68
+ }
69
+
70
+ isAutoVersioning(): boolean {
71
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
72
+ return !!this.configuration.document.getMap<number>(`${this.tiptapCollabConfigurationPrefix}config`).get('autoVersioning')
73
+ }
74
+
75
+ enableAutoVersioning() {
76
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
77
+ return this.configuration.document.getMap<number>(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 1)
78
+ }
79
+
80
+ disableAutoVersioning() {
81
+ console.error('This doesnt work yet! If you want to join as a beta tester, send an email to humans@tiptap.dev')
82
+ return this.configuration.document.getMap<number>(`${this.tiptapCollabConfigurationPrefix}config`).set('autoVersioning', 0)
83
+ }
84
+
32
85
  }
package/src/types.ts CHANGED
@@ -1,15 +1,15 @@
1
+ import { Encoder } from 'lib0/encoding'
2
+ import type { CloseEvent, Event, MessageEvent } from 'ws'
1
3
  import { Awareness } from 'y-protocols/awareness'
2
4
  import * as Y from 'yjs'
3
- import { Encoder } from 'lib0/encoding'
4
- import type { Event, CloseEvent, MessageEvent } from 'ws'
5
+ import { IncomingMessage } from './IncomingMessage.js'
6
+ import { OutgoingMessage } from './OutgoingMessage.js'
5
7
  import { AuthenticationMessage } from './OutgoingMessages/AuthenticationMessage.js'
6
8
  import { AwarenessMessage } from './OutgoingMessages/AwarenessMessage.js'
7
9
  import { QueryAwarenessMessage } from './OutgoingMessages/QueryAwarenessMessage.js'
8
10
  import { SyncStepOneMessage } from './OutgoingMessages/SyncStepOneMessage.js'
9
11
  import { SyncStepTwoMessage } from './OutgoingMessages/SyncStepTwoMessage.js'
10
12
  import { UpdateMessage } from './OutgoingMessages/UpdateMessage.js'
11
- import { IncomingMessage } from './IncomingMessage.js'
12
- import { OutgoingMessage } from './OutgoingMessage.js'
13
13
 
14
14
  export enum MessageType {
15
15
  Sync = 0,
@@ -18,6 +18,7 @@ export enum MessageType {
18
18
  QueryAwareness = 3,
19
19
  Stateless = 5,
20
20
  CLOSE = 7,
21
+ SyncStatus = 8,
21
22
  }
22
23
 
23
24
  export enum WebSocketStatus {