@hocuspocus/provider 2.0.0-alpha.0 → 2.0.0-beta.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.
@@ -2,7 +2,6 @@
2
2
  import { Extension, onChangePayload, onConnectPayload, onLoadDocumentPayload, onDisconnectPayload } from '@hocuspocus/server';
3
3
  import { Doc } from 'yjs';
4
4
  import { Transformer } from '@hocuspocus/transformer';
5
- import { AxiosResponse } from 'axios';
6
5
  export declare enum Events {
7
6
  onChange = "change",
8
7
  onConnect = "connect",
@@ -41,7 +40,7 @@ export declare class Webhook implements Extension {
41
40
  /**
42
41
  * Send a request to the given url containing the given data
43
42
  */
44
- sendRequest(event: Events, payload: any): Promise<AxiosResponse<any, any>>;
43
+ sendRequest(event: Events, payload: any): Promise<import("axios").AxiosResponse<any, any>>;
45
44
  /**
46
45
  * onChange hook
47
46
  */
@@ -4,9 +4,9 @@ import * as mutex from 'lib0/mutex';
4
4
  import type { CloseEvent, Event, MessageEvent } from 'ws';
5
5
  import EventEmitter from './EventEmitter';
6
6
  import { ConstructableOutgoingMessage, onAuthenticationFailedParameters, onCloseParameters, onDisconnectParameters, onMessageParameters, onOpenParameters, onOutgoingMessageParameters, onStatelessParameters, onStatusParameters, onSyncedParameters, WebSocketStatus } from './types';
7
- import { HocuspocusProviderWebsocket } from './HocuspocusProviderWebsocket';
7
+ import { CompleteHocuspocusProviderWebsocketConfiguration, HocuspocusProviderWebsocket } from './HocuspocusProviderWebsocket';
8
8
  import { onAwarenessChangeParameters, onAwarenessUpdateParameters } from '.';
9
- export declare type HocuspocusProviderConfiguration = Required<Pick<CompleteHocuspocusProviderConfiguration, 'name' | 'websocketProvider'>> & Partial<CompleteHocuspocusProviderConfiguration>;
9
+ export declare type HocuspocusProviderConfiguration = Required<Pick<CompleteHocuspocusProviderConfiguration, 'name'>> & Partial<CompleteHocuspocusProviderConfiguration> & (Required<Pick<CompleteHocuspocusProviderWebsocketConfiguration, 'url'>> | Required<Pick<CompleteHocuspocusProviderConfiguration, 'websocketProvider'>>);
10
10
  export interface CompleteHocuspocusProviderConfiguration {
11
11
  /**
12
12
  * The identifier/name of your document
@@ -70,6 +70,7 @@ export declare class HocuspocusProvider extends EventEmitter {
70
70
  isAuthenticated: boolean;
71
71
  mux: mutex.mutex;
72
72
  intervals: any;
73
+ isConnected: boolean;
73
74
  constructor(configuration: HocuspocusProviderConfiguration);
74
75
  onStatus({ status }: onStatusParameters): void;
75
76
  setConfiguration(configuration?: Partial<HocuspocusProviderConfiguration>): void;
@@ -87,6 +88,7 @@ export declare class HocuspocusProvider extends EventEmitter {
87
88
  set synced(state: boolean);
88
89
  receiveStateless(payload: string): void;
89
90
  get isAuthenticationRequired(): boolean;
91
+ connect(): Promise<unknown>;
90
92
  disconnect(): void;
91
93
  onOpen(event: Event): Promise<void>;
92
94
  getToken(): Promise<string | null>;
@@ -0,0 +1,8 @@
1
+ import * as encoding from 'lib0/encoding';
2
+ import { MessageType, OutgoingMessageArguments } from '../types';
3
+ import { OutgoingMessage } from '../OutgoingMessage';
4
+ export declare class CloseMessage extends OutgoingMessage {
5
+ type: MessageType;
6
+ description: string;
7
+ get(args: Partial<OutgoingMessageArguments>): encoding.Encoder;
8
+ }
@@ -15,7 +15,8 @@ export declare enum MessageType {
15
15
  Awareness = 1,
16
16
  Auth = 2,
17
17
  QueryAwareness = 3,
18
- Stateless = 5
18
+ Stateless = 5,
19
+ CLOSE = 7
19
20
  }
20
21
  export declare enum WebSocketStatus {
21
22
  Connecting = "connecting",
@@ -23,10 +23,14 @@ export declare class Connection {
23
23
  * Constructor.
24
24
  */
25
25
  constructor(connection: WebSocket, request: HTTPIncomingMessage, document: Document, timeout: number, socketId: string, context: any, readOnly: boolean | undefined, logger: Debugger);
26
+ boundClose: (event?: CloseEvent | undefined) => void;
27
+ boundHandleMessage: (data: Uint8Array) => void;
28
+ boundHandlePong: () => void;
29
+ handlePong(): void;
26
30
  /**
27
31
  * Set a callback that will be triggered when the connection is closed
28
32
  */
29
- onClose(callback: (document: Document) => void): Connection;
33
+ onClose(callback: (document: Document, event?: CloseEvent) => void): Connection;
30
34
  /**
31
35
  * Set a callback that will be triggered when an stateless message is received
32
36
  */
@@ -13,7 +13,8 @@ export declare enum MessageType {
13
13
  QueryAwareness = 3,
14
14
  SyncReply = 4,
15
15
  Stateless = 5,
16
- BroadcastStateless = 6
16
+ BroadcastStateless = 6,
17
+ CLOSE = 7
17
18
  }
18
19
  export interface AwarenessUpdate {
19
20
  added: Array<any>;
@@ -0,0 +1 @@
1
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hocuspocus/provider",
3
- "version": "2.0.0-alpha.0",
3
+ "version": "2.0.0-beta.0",
4
4
  "description": "hocuspocus provider",
5
5
  "homepage": "https://hocuspocus.dev",
6
6
  "keywords": [
@@ -28,9 +28,10 @@
28
28
  "dist"
29
29
  ],
30
30
  "dependencies": {
31
- "@hocuspocus/common": "^2.0.0-alpha.0",
31
+ "@hocuspocus/common": "^2.0.0-beta.0",
32
32
  "@lifeomic/attempt": "^3.0.2",
33
- "lib0": "^0.2.47"
33
+ "lib0": "^0.2.47",
34
+ "ws": "^7.5.9"
34
35
  },
35
36
  "peerDependencies": {
36
37
  "y-protocols": "^1.0.5",
@@ -26,13 +26,20 @@ import {
26
26
  onSyncedParameters,
27
27
  WebSocketStatus,
28
28
  } from './types'
29
- import { HocuspocusProviderWebsocket } from './HocuspocusProviderWebsocket'
29
+ import {
30
+ CompleteHocuspocusProviderWebsocketConfiguration,
31
+ HocuspocusProviderWebsocket,
32
+ } from './HocuspocusProviderWebsocket'
30
33
  import { StatelessMessage } from './OutgoingMessages/StatelessMessage'
34
+ import { CloseMessage } from './OutgoingMessages/CloseMessage'
31
35
  import { onAwarenessChangeParameters, onAwarenessUpdateParameters } from '.'
32
36
 
33
37
  export type HocuspocusProviderConfiguration =
34
- Required<Pick<CompleteHocuspocusProviderConfiguration, 'name' | 'websocketProvider'>>
35
- & Partial<CompleteHocuspocusProviderConfiguration>
38
+ Required<Pick<CompleteHocuspocusProviderConfiguration, 'name'>>
39
+ & Partial<CompleteHocuspocusProviderConfiguration> & (
40
+ Required<Pick<CompleteHocuspocusProviderWebsocketConfiguration, 'url'>> |
41
+ Required<Pick<CompleteHocuspocusProviderConfiguration, 'websocketProvider'>>
42
+ )
36
43
 
37
44
  export interface CompleteHocuspocusProviderConfiguration {
38
45
  /**
@@ -134,6 +141,8 @@ export class HocuspocusProvider extends EventEmitter {
134
141
  forceSync: null,
135
142
  }
136
143
 
144
+ isConnected = true
145
+
137
146
  constructor(configuration: HocuspocusProviderConfiguration) {
138
147
  super()
139
148
  this.setConfiguration(configuration)
@@ -203,6 +212,10 @@ export class HocuspocusProvider extends EventEmitter {
203
212
  }
204
213
 
205
214
  public setConfiguration(configuration: Partial<HocuspocusProviderConfiguration> = {}): void {
215
+ if (!configuration.websocketProvider && (configuration as CompleteHocuspocusProviderWebsocketConfiguration).url) {
216
+ this.configuration.websocketProvider = new HocuspocusProviderWebsocket({ url: (configuration as CompleteHocuspocusProviderWebsocketConfiguration).url })
217
+ }
218
+
206
219
  this.configuration = { ...this.configuration, ...configuration }
207
220
  }
208
221
 
@@ -281,6 +294,11 @@ export class HocuspocusProvider extends EventEmitter {
281
294
  return !!this.configuration.token && !this.isAuthenticated
282
295
  }
283
296
 
297
+ // not needed, but provides backward compatibility with e.g. lexicla/yjs
298
+ async connect() {
299
+ return this.configuration.websocketProvider.connect()
300
+ }
301
+
284
302
  disconnect() {
285
303
  this.disconnectBroadcastChannel()
286
304
  this.configuration.websocketProvider.detach(this)
@@ -294,7 +312,6 @@ export class HocuspocusProvider extends EventEmitter {
294
312
  token: await this.getToken(),
295
313
  documentName: this.configuration.name,
296
314
  })
297
- return
298
315
  }
299
316
 
300
317
  this.startSync()
@@ -322,6 +339,8 @@ export class HocuspocusProvider extends EventEmitter {
322
339
  }
323
340
 
324
341
  send(message: ConstructableOutgoingMessage, args: any, broadcast = false) {
342
+ if (!this.isConnected) return
343
+
325
344
  if (broadcast) {
326
345
  this.mux(() => { this.broadcast(message, args) })
327
346
  }
@@ -376,6 +395,9 @@ export class HocuspocusProvider extends EventEmitter {
376
395
 
377
396
  this.removeAllListeners()
378
397
 
398
+ this.send(CloseMessage, { documentName: this.configuration.name })
399
+ this.isConnected = false
400
+
379
401
  if (typeof window === 'undefined') {
380
402
  return
381
403
  }
@@ -409,8 +409,10 @@ export class HocuspocusProviderWebsocket extends EventEmitter {
409
409
  }
410
410
 
411
411
  if (event.code === Unauthorized.code) {
412
- if (!this.configuration.quiet) {
412
+ if (event.reason === Unauthorized.reason) {
413
413
  console.warn('[HocuspocusProvider] An authentication token is required, but you didn’t send one. Try adding a `token` to your HocuspocusProvider configuration. Won’t try again.')
414
+ } else {
415
+ console.warn(`[HocuspocusProvider] Connection closed with status Unauthorized: ${event.reason}`)
414
416
  }
415
417
 
416
418
  this.shouldConnect = false
@@ -0,0 +1,16 @@
1
+ import * as encoding from 'lib0/encoding'
2
+ import { MessageType, OutgoingMessageArguments } from '../types'
3
+ import { OutgoingMessage } from '../OutgoingMessage'
4
+
5
+ export class CloseMessage extends OutgoingMessage {
6
+ type = MessageType.CLOSE
7
+
8
+ description = 'Ask the server to close the connection'
9
+
10
+ get(args: Partial<OutgoingMessageArguments>) {
11
+ encoding.writeVarString(this.encoder, args.documentName!)
12
+ encoding.writeVarUint(this.encoder, this.type)
13
+
14
+ return this.encoder
15
+ }
16
+ }
package/src/types.ts CHANGED
@@ -17,6 +17,7 @@ export enum MessageType {
17
17
  Auth = 2,
18
18
  QueryAwareness = 3,
19
19
  Stateless = 5,
20
+ CLOSE = 7,
20
21
  }
21
22
 
22
23
  export enum WebSocketStatus {