@hocuspocus/extension-redis 3.0.0-rc.0 → 3.0.6-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-redis.cjs +41 -33137
- package/dist/hocuspocus-redis.cjs.map +1 -1
- package/dist/hocuspocus-redis.esm.js +35 -33131
- package/dist/hocuspocus-redis.esm.js.map +1 -1
- package/dist/packages/common/src/index.d.ts +4 -4
- package/dist/packages/extension-database/src/index.d.ts +1 -1
- package/dist/packages/extension-logger/src/index.d.ts +1 -1
- package/dist/packages/extension-redis/src/Redis.d.ts +6 -2
- package/dist/packages/extension-redis/src/index.d.ts +1 -1
- package/dist/packages/extension-sqlite/src/index.d.ts +1 -1
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +14 -36
- package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +4 -8
- package/dist/packages/provider/src/IncomingMessage.d.ts +2 -2
- package/dist/packages/provider/src/MessageReceiver.d.ts +2 -4
- package/dist/packages/provider/src/MessageSender.d.ts +2 -2
- package/dist/packages/provider/src/OutgoingMessage.d.ts +2 -2
- package/dist/packages/provider/src/OutgoingMessages/AuthenticationMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/AwarenessMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/CloseMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/QueryAwarenessMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/StatelessMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/SyncStepOneMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/SyncStepTwoMessage.d.ts +3 -3
- package/dist/packages/provider/src/OutgoingMessages/UpdateMessage.d.ts +3 -3
- package/dist/packages/provider/src/index.d.ts +3 -5
- package/dist/packages/provider/src/types.d.ts +50 -10
- package/dist/packages/server/src/ClientConnection.d.ts +16 -8
- package/dist/packages/server/src/Connection.d.ts +14 -20
- package/dist/packages/server/src/DirectConnection.d.ts +4 -4
- package/dist/packages/server/src/Document.d.ts +2 -6
- package/dist/packages/server/src/Hocuspocus.d.ts +6 -15
- package/dist/packages/server/src/IncomingMessage.d.ts +4 -3
- package/dist/packages/server/src/MessageReceiver.d.ts +6 -8
- package/dist/packages/server/src/OutgoingMessage.d.ts +2 -1
- package/dist/packages/server/src/Server.d.ts +3 -3
- package/dist/packages/server/src/index.d.ts +9 -10
- package/dist/packages/server/src/types.d.ts +41 -13
- package/dist/packages/transformer/src/Prosemirror.d.ts +1 -1
- package/dist/packages/transformer/src/Tiptap.d.ts +1 -1
- package/dist/packages/transformer/src/index.d.ts +3 -3
- package/dist/playground/frontend/app/SocketContext.d.ts +2 -0
- package/dist/playground/frontend/next.config.d.ts +3 -0
- package/dist/tests/utils/index.d.ts +9 -9
- package/dist/tests/utils/newHocuspocusProvider.d.ts +2 -2
- package/package.json +4 -4
- package/src/Redis.ts +39 -13
- package/src/index.ts +1 -1
- package/dist/packages/provider/src/TiptapCollabProvider.d.ts +0 -64
- package/dist/packages/provider/src/TiptapCollabProviderWebsocket.d.ts +0 -20
- package/dist/packages/server/src/Debugger.d.ts +0 -14
- package/dist/playground/frontend/vite.config.d.ts +0 -2
- package/dist/tests/server/getMessageLogs.d.ts +0 -1
- package/dist/tests/server/requiresAuthentication.d.ts +0 -1
- /package/dist/{playground/frontend/src/main.d.ts → tests/server/beforeSync.d.ts} +0 -0
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import type { IncomingMessage } from 'http';
|
|
2
2
|
import type WebSocket from 'ws';
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import {
|
|
6
|
-
import
|
|
7
|
-
import type { Configuration, ConnectionConfiguration, HookName, HookPayloadByName, onStoreDocumentPayload } from './types.js';
|
|
3
|
+
import { DirectConnection } from './DirectConnection.ts';
|
|
4
|
+
import Document from './Document.ts';
|
|
5
|
+
import type { Server } from './Server.ts';
|
|
6
|
+
import type { Configuration, ConnectionConfiguration, HookName, HookPayloadByName, onStoreDocumentPayload } from './types.ts';
|
|
8
7
|
export declare const defaultConfiguration: {
|
|
9
8
|
name: null;
|
|
10
9
|
timeout: number;
|
|
@@ -22,7 +21,6 @@ export declare class Hocuspocus {
|
|
|
22
21
|
loadingDocuments: Map<string, Promise<Document>>;
|
|
23
22
|
documents: Map<string, Document>;
|
|
24
23
|
server?: Server;
|
|
25
|
-
debugger: Debugger;
|
|
26
24
|
debouncer: {
|
|
27
25
|
debounce: (id: string, func: Function, debounce: number, maxDebounce: number) => any;
|
|
28
26
|
isDebounced: (id: string) => boolean;
|
|
@@ -33,7 +31,6 @@ export declare class Hocuspocus {
|
|
|
33
31
|
* Configure Hocuspocus
|
|
34
32
|
*/
|
|
35
33
|
configure(configuration: Partial<Configuration>): Hocuspocus;
|
|
36
|
-
get requiresAuthentication(): boolean;
|
|
37
34
|
/**
|
|
38
35
|
* Get the total number of active documents
|
|
39
36
|
*/
|
|
@@ -68,19 +65,13 @@ export declare class Hocuspocus {
|
|
|
68
65
|
* Create a new document by the given request
|
|
69
66
|
*/
|
|
70
67
|
createDocument(documentName: string, request: Partial<Pick<IncomingMessage, 'headers' | 'url'>>, socketId: string, connection: ConnectionConfiguration, context?: any): Promise<Document>;
|
|
71
|
-
loadDocument(documentName: string, request: Partial<Pick<IncomingMessage, 'headers' | 'url'>>, socketId: string,
|
|
68
|
+
loadDocument(documentName: string, request: Partial<Pick<IncomingMessage, 'headers' | 'url'>>, socketId: string, connectionConfig: ConnectionConfiguration, context?: any): Promise<Document>;
|
|
72
69
|
storeDocumentHooks(document: Document, hookPayload: onStoreDocumentPayload, immediately?: boolean): any;
|
|
73
70
|
/**
|
|
74
71
|
* Run the given hook on all configured extensions.
|
|
75
72
|
* Runs the given callback after each hook.
|
|
76
73
|
*/
|
|
77
74
|
hooks<T extends HookName>(name: T, payload: HookPayloadByName[T], callback?: Function | null): Promise<any>;
|
|
78
|
-
unloadDocument(document: Document):
|
|
79
|
-
enableDebugging(): void;
|
|
80
|
-
enableMessageLogging(): void;
|
|
81
|
-
disableLogging(): void;
|
|
82
|
-
disableDebugging(): void;
|
|
83
|
-
flushMessageLogs(): this;
|
|
84
|
-
getMessageLogs(): any[];
|
|
75
|
+
unloadDocument(document: Document): Promise<any>;
|
|
85
76
|
openDirectConnection(documentName: string, context?: any): Promise<DirectConnection>;
|
|
86
77
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Decoder } from 'lib0/decoding';
|
|
2
2
|
import type { Encoder } from 'lib0/encoding';
|
|
3
|
-
import type { MessageType } from './types.
|
|
3
|
+
import type { MessageType } from './types.ts';
|
|
4
4
|
export declare class IncomingMessage {
|
|
5
5
|
/**
|
|
6
6
|
* Access to the received message.
|
|
@@ -14,10 +14,11 @@ export declare class IncomingMessage {
|
|
|
14
14
|
private encoderInternal?;
|
|
15
15
|
constructor(input: any);
|
|
16
16
|
get encoder(): Encoder;
|
|
17
|
-
readVarUint8Array(): Uint8Array
|
|
17
|
+
readVarUint8Array(): Uint8Array<ArrayBufferLike>;
|
|
18
|
+
peekVarUint8Array(): Uint8Array<ArrayBufferLike>;
|
|
18
19
|
readVarUint(): number;
|
|
19
20
|
readVarString(): string;
|
|
20
|
-
toUint8Array(): Uint8Array
|
|
21
|
+
toUint8Array(): Uint8Array<ArrayBufferLike>;
|
|
21
22
|
writeVarUint(type: MessageType): void;
|
|
22
23
|
writeVarString(string: string): void;
|
|
23
24
|
get length(): number;
|
|
@@ -1,13 +1,11 @@
|
|
|
1
|
-
import type Connection from './Connection.
|
|
2
|
-
import type
|
|
3
|
-
import type
|
|
4
|
-
import type { IncomingMessage } from './IncomingMessage.js';
|
|
1
|
+
import type Connection from './Connection.ts';
|
|
2
|
+
import type Document from './Document.ts';
|
|
3
|
+
import type { IncomingMessage } from './IncomingMessage.ts';
|
|
5
4
|
export declare class MessageReceiver {
|
|
6
5
|
message: IncomingMessage;
|
|
7
|
-
logger: Debugger;
|
|
8
6
|
defaultTransactionOrigin?: string;
|
|
9
|
-
constructor(message: IncomingMessage,
|
|
10
|
-
apply(document: Document, connection?: Connection, reply?: (message: Uint8Array) => void): void
|
|
11
|
-
readSyncMessage(message: IncomingMessage, document: Document, connection?: Connection, reply?: (message: Uint8Array) => void, requestFirstSync?: boolean): 0 | 1 | 2
|
|
7
|
+
constructor(message: IncomingMessage, defaultTransactionOrigin?: string);
|
|
8
|
+
apply(document: Document, connection?: Connection, reply?: (message: Uint8Array) => void): Promise<void>;
|
|
9
|
+
readSyncMessage(message: IncomingMessage, document: Document, connection?: Connection, reply?: (message: Uint8Array) => void, requestFirstSync?: boolean): Promise<0 | 1 | 2>;
|
|
12
10
|
applyQueryAwarenessMessage(document: Document, reply?: (message: Uint8Array) => void): void;
|
|
13
11
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Encoder } from 'lib0/encoding';
|
|
2
2
|
import type { Awareness } from 'y-protocols/awareness';
|
|
3
|
-
import type Document from './Document.
|
|
3
|
+
import type Document from './Document.ts';
|
|
4
4
|
export declare class OutgoingMessage {
|
|
5
5
|
encoder: Encoder;
|
|
6
6
|
type?: number;
|
|
@@ -17,5 +17,6 @@ export declare class OutgoingMessage {
|
|
|
17
17
|
writeStateless(payload: string): OutgoingMessage;
|
|
18
18
|
writeBroadcastStateless(payload: string): OutgoingMessage;
|
|
19
19
|
writeSyncStatus(updateSaved: boolean): OutgoingMessage;
|
|
20
|
+
writeCloseMessage(reason: string): OutgoingMessage;
|
|
20
21
|
toUint8Array(): Uint8Array;
|
|
21
22
|
}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import type { IncomingMessage, Server as HTTPServer, ServerResponse } from 'http';
|
|
2
|
-
import type { AddressInfo } from 'ws';
|
|
3
2
|
import { WebSocketServer } from 'ws';
|
|
4
|
-
import {
|
|
3
|
+
import type { AddressInfo, ServerOptions } from 'ws';
|
|
4
|
+
import { Hocuspocus } from './Hocuspocus.ts';
|
|
5
5
|
import type { Configuration } from './types';
|
|
6
6
|
export interface ServerConfiguration extends Configuration {
|
|
7
7
|
port?: number;
|
|
@@ -18,7 +18,7 @@ export declare class Server {
|
|
|
18
18
|
webSocketServer: WebSocketServer;
|
|
19
19
|
hocuspocus: Hocuspocus;
|
|
20
20
|
configuration: ServerConfiguration;
|
|
21
|
-
constructor(configuration?: Partial<ServerConfiguration
|
|
21
|
+
constructor(configuration?: Partial<ServerConfiguration>, websocketOptions?: ServerOptions);
|
|
22
22
|
setupWebsocketConnection: () => void;
|
|
23
23
|
setupHttpUpgrade: () => void;
|
|
24
24
|
requestHandler: (request: IncomingMessage, response: ServerResponse) => Promise<void>;
|
|
@@ -1,10 +1,9 @@
|
|
|
1
|
-
export * from './Connection.
|
|
2
|
-
export * from './
|
|
3
|
-
export * from './
|
|
4
|
-
export * from './
|
|
5
|
-
export * from './
|
|
6
|
-
export * from './
|
|
7
|
-
export * from './
|
|
8
|
-
export * from './
|
|
9
|
-
export * from './
|
|
10
|
-
export * from './util/debounce.js';
|
|
1
|
+
export * from './Connection.ts';
|
|
2
|
+
export * from './Document.ts';
|
|
3
|
+
export * from './Hocuspocus.ts';
|
|
4
|
+
export * from './IncomingMessage.ts';
|
|
5
|
+
export * from './MessageReceiver.ts';
|
|
6
|
+
export * from './OutgoingMessage.ts';
|
|
7
|
+
export * from './Server.ts';
|
|
8
|
+
export * from './types.ts';
|
|
9
|
+
export * from './util/debounce.ts';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import type { IncomingHttpHeaders, IncomingMessage, ServerResponse } from 'http';
|
|
2
2
|
import type { URLSearchParams } from 'url';
|
|
3
3
|
import type { Awareness } from 'y-protocols/awareness';
|
|
4
|
-
import type Connection from './Connection.
|
|
5
|
-
import type Document from './Document.
|
|
6
|
-
import type { Hocuspocus } from './Hocuspocus.
|
|
4
|
+
import type Connection from './Connection.ts';
|
|
5
|
+
import type Document from './Document.ts';
|
|
6
|
+
import type { Hocuspocus } from './Hocuspocus.ts';
|
|
7
7
|
export declare enum MessageType {
|
|
8
8
|
Unknown = -1,
|
|
9
9
|
Sync = 0,
|
|
@@ -23,7 +23,6 @@ export interface AwarenessUpdate {
|
|
|
23
23
|
}
|
|
24
24
|
export interface ConnectionConfiguration {
|
|
25
25
|
readOnly: boolean;
|
|
26
|
-
requiresAuthentication: boolean;
|
|
27
26
|
isAuthenticated: boolean;
|
|
28
27
|
}
|
|
29
28
|
export interface Extension {
|
|
@@ -39,6 +38,7 @@ export interface Extension {
|
|
|
39
38
|
onLoadDocument?(data: onLoadDocumentPayload): Promise<any>;
|
|
40
39
|
afterLoadDocument?(data: afterLoadDocumentPayload): Promise<any>;
|
|
41
40
|
beforeHandleMessage?(data: beforeHandleMessagePayload): Promise<any>;
|
|
41
|
+
beforeSync?(data: beforeSyncPayload): Promise<any>;
|
|
42
42
|
beforeBroadcastStateless?(data: beforeBroadcastStatelessPayload): Promise<any>;
|
|
43
43
|
onStateless?(payload: onStatelessPayload): Promise<any>;
|
|
44
44
|
onChange?(data: onChangePayload): Promise<any>;
|
|
@@ -47,10 +47,11 @@ export interface Extension {
|
|
|
47
47
|
onAwarenessUpdate?(data: onAwarenessUpdatePayload): Promise<any>;
|
|
48
48
|
onRequest?(data: onRequestPayload): Promise<any>;
|
|
49
49
|
onDisconnect?(data: onDisconnectPayload): Promise<any>;
|
|
50
|
+
beforeUnloadDocument?(data: beforeUnloadDocumentPayload): Promise<any>;
|
|
50
51
|
afterUnloadDocument?(data: afterUnloadDocumentPayload): Promise<any>;
|
|
51
52
|
onDestroy?(data: onDestroyPayload): Promise<any>;
|
|
52
53
|
}
|
|
53
|
-
export type HookName = 'onConfigure' | 'onListen' | 'onUpgrade' | 'onConnect' | 'connected' | 'onAuthenticate' | 'onCreateDocument' | 'onLoadDocument' | 'afterLoadDocument' | 'beforeHandleMessage' | 'beforeBroadcastStateless' | 'onStateless' | 'onChange' | 'onStoreDocument' | 'afterStoreDocument' | 'onAwarenessUpdate' | 'onRequest' | 'onDisconnect' | 'afterUnloadDocument' | 'onDestroy';
|
|
54
|
+
export type HookName = 'onConfigure' | 'onListen' | 'onUpgrade' | 'onConnect' | 'connected' | 'onAuthenticate' | 'onCreateDocument' | 'onLoadDocument' | 'afterLoadDocument' | 'beforeHandleMessage' | 'beforeBroadcastStateless' | 'beforeSync' | 'onStateless' | 'onChange' | 'onStoreDocument' | 'afterStoreDocument' | 'onAwarenessUpdate' | 'onRequest' | 'onDisconnect' | 'beforeUnloadDocument' | 'afterUnloadDocument' | 'onDestroy';
|
|
54
55
|
export type HookPayloadByName = {
|
|
55
56
|
onConfigure: onConfigurePayload;
|
|
56
57
|
onListen: onListenPayload;
|
|
@@ -63,6 +64,7 @@ export type HookPayloadByName = {
|
|
|
63
64
|
afterLoadDocument: afterLoadDocumentPayload;
|
|
64
65
|
beforeHandleMessage: beforeHandleMessagePayload;
|
|
65
66
|
beforeBroadcastStateless: beforeBroadcastStatelessPayload;
|
|
67
|
+
beforeSync: beforeSyncPayload;
|
|
66
68
|
onStateless: onStatelessPayload;
|
|
67
69
|
onChange: onChangePayload;
|
|
68
70
|
onStoreDocument: onStoreDocumentPayload;
|
|
@@ -71,6 +73,7 @@ export type HookPayloadByName = {
|
|
|
71
73
|
onRequest: onRequestPayload;
|
|
72
74
|
onDisconnect: onDisconnectPayload;
|
|
73
75
|
afterUnloadDocument: afterUnloadDocumentPayload;
|
|
76
|
+
beforeUnloadDocument: beforeUnloadDocumentPayload;
|
|
74
77
|
onDestroy: onDestroyPayload;
|
|
75
78
|
};
|
|
76
79
|
export interface Configuration extends Extension {
|
|
@@ -130,7 +133,7 @@ export interface onAuthenticatePayload {
|
|
|
130
133
|
request: IncomingMessage;
|
|
131
134
|
socketId: string;
|
|
132
135
|
token: string;
|
|
133
|
-
|
|
136
|
+
connectionConfig: ConnectionConfiguration;
|
|
134
137
|
}
|
|
135
138
|
export interface onCreateDocumentPayload {
|
|
136
139
|
context: any;
|
|
@@ -139,7 +142,7 @@ export interface onCreateDocumentPayload {
|
|
|
139
142
|
requestHeaders: IncomingHttpHeaders;
|
|
140
143
|
requestParameters: URLSearchParams;
|
|
141
144
|
socketId: string;
|
|
142
|
-
|
|
145
|
+
connectionConfig: ConnectionConfiguration;
|
|
143
146
|
}
|
|
144
147
|
export interface onConnectPayload {
|
|
145
148
|
context: any;
|
|
@@ -149,7 +152,7 @@ export interface onConnectPayload {
|
|
|
149
152
|
requestHeaders: IncomingHttpHeaders;
|
|
150
153
|
requestParameters: URLSearchParams;
|
|
151
154
|
socketId: string;
|
|
152
|
-
|
|
155
|
+
connectionConfig: ConnectionConfiguration;
|
|
153
156
|
}
|
|
154
157
|
export interface connectedPayload {
|
|
155
158
|
context: any;
|
|
@@ -159,8 +162,8 @@ export interface connectedPayload {
|
|
|
159
162
|
requestHeaders: IncomingHttpHeaders;
|
|
160
163
|
requestParameters: URLSearchParams;
|
|
161
164
|
socketId: string;
|
|
162
|
-
|
|
163
|
-
|
|
165
|
+
connectionConfig: ConnectionConfiguration;
|
|
166
|
+
connection: Connection;
|
|
164
167
|
}
|
|
165
168
|
export interface onLoadDocumentPayload {
|
|
166
169
|
context: any;
|
|
@@ -170,7 +173,7 @@ export interface onLoadDocumentPayload {
|
|
|
170
173
|
requestHeaders: IncomingHttpHeaders;
|
|
171
174
|
requestParameters: URLSearchParams;
|
|
172
175
|
socketId: string;
|
|
173
|
-
|
|
176
|
+
connectionConfig: ConnectionConfiguration;
|
|
174
177
|
}
|
|
175
178
|
export interface afterLoadDocumentPayload {
|
|
176
179
|
context: any;
|
|
@@ -180,7 +183,7 @@ export interface afterLoadDocumentPayload {
|
|
|
180
183
|
requestHeaders: IncomingHttpHeaders;
|
|
181
184
|
requestParameters: URLSearchParams;
|
|
182
185
|
socketId: string;
|
|
183
|
-
|
|
186
|
+
connectionConfig: ConnectionConfiguration;
|
|
184
187
|
}
|
|
185
188
|
export interface onChangePayload {
|
|
186
189
|
clientsCount: number;
|
|
@@ -206,6 +209,27 @@ export interface beforeHandleMessagePayload {
|
|
|
206
209
|
socketId: string;
|
|
207
210
|
connection: Connection;
|
|
208
211
|
}
|
|
212
|
+
export interface beforeSyncPayload {
|
|
213
|
+
clientsCount: number;
|
|
214
|
+
context: any;
|
|
215
|
+
document: Document;
|
|
216
|
+
documentName: string;
|
|
217
|
+
connection: Connection;
|
|
218
|
+
/**
|
|
219
|
+
* The y-protocols/sync message type
|
|
220
|
+
* @example
|
|
221
|
+
* 0: SyncStep1
|
|
222
|
+
* 1: SyncStep2
|
|
223
|
+
* 2: YjsUpdate
|
|
224
|
+
*
|
|
225
|
+
* @see https://github.com/yjs/y-protocols/blob/master/sync.js#L13-L40
|
|
226
|
+
*/
|
|
227
|
+
type: number;
|
|
228
|
+
/**
|
|
229
|
+
* The payload of the y-sync message.
|
|
230
|
+
*/
|
|
231
|
+
payload: Uint8Array;
|
|
232
|
+
}
|
|
209
233
|
export interface beforeBroadcastStatelessPayload {
|
|
210
234
|
document: Document;
|
|
211
235
|
documentName: string;
|
|
@@ -250,7 +274,7 @@ export interface fetchPayload {
|
|
|
250
274
|
requestHeaders: IncomingHttpHeaders;
|
|
251
275
|
requestParameters: URLSearchParams;
|
|
252
276
|
socketId: string;
|
|
253
|
-
|
|
277
|
+
connectionConfig: ConnectionConfiguration;
|
|
254
278
|
}
|
|
255
279
|
export interface storePayload extends onStoreDocumentPayload {
|
|
256
280
|
state: Buffer;
|
|
@@ -293,6 +317,10 @@ export interface afterUnloadDocumentPayload {
|
|
|
293
317
|
instance: Hocuspocus;
|
|
294
318
|
documentName: string;
|
|
295
319
|
}
|
|
320
|
+
export interface beforeUnloadDocumentPayload {
|
|
321
|
+
instance: Hocuspocus;
|
|
322
|
+
documentName: string;
|
|
323
|
+
}
|
|
296
324
|
export interface DirectConnection {
|
|
297
325
|
transact(transaction: (document: Document) => void): Promise<void>;
|
|
298
326
|
disconnect(): void;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Doc } from 'yjs';
|
|
2
2
|
import { Schema } from '@tiptap/pm/model';
|
|
3
|
-
import type { Transformer } from './types.
|
|
3
|
+
import type { Transformer } from './types.ts';
|
|
4
4
|
declare class Prosemirror implements Transformer {
|
|
5
5
|
defaultSchema: Schema;
|
|
6
6
|
schema(schema: Schema): Prosemirror;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Doc } from 'yjs';
|
|
2
2
|
import type { Extensions } from '@tiptap/core';
|
|
3
|
-
import type { Transformer } from './types.
|
|
3
|
+
import type { Transformer } from './types.ts';
|
|
4
4
|
export declare class Tiptap implements Transformer {
|
|
5
5
|
defaultExtensions: Extensions;
|
|
6
6
|
extensions(extensions: Extensions): Tiptap;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export * from './Prosemirror.
|
|
2
|
-
export * from './Tiptap.
|
|
3
|
-
export * from './types.
|
|
1
|
+
export * from './Prosemirror.ts';
|
|
2
|
+
export * from './Tiptap.ts';
|
|
3
|
+
export * from './types.ts';
|
|
@@ -1,9 +1,9 @@
|
|
|
1
|
-
export * from './createDirectory.
|
|
2
|
-
export * from './flushRedis.
|
|
3
|
-
export * from './newHocuspocus.
|
|
4
|
-
export * from './newHocuspocusProvider.
|
|
5
|
-
export * from './newHocuspocusProviderWebsocket.
|
|
6
|
-
export * from './randomInteger.
|
|
7
|
-
export * from './redisConnectionSettings.
|
|
8
|
-
export * from './removeDirectory.
|
|
9
|
-
export * from './sleep.
|
|
1
|
+
export * from './createDirectory.ts';
|
|
2
|
+
export * from './flushRedis.ts';
|
|
3
|
+
export * from './newHocuspocus.ts';
|
|
4
|
+
export * from './newHocuspocusProvider.ts';
|
|
5
|
+
export * from './newHocuspocusProviderWebsocket.ts';
|
|
6
|
+
export * from './randomInteger.ts';
|
|
7
|
+
export * from './redisConnectionSettings.ts';
|
|
8
|
+
export * from './removeDirectory.ts';
|
|
9
|
+
export * from './sleep.ts';
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { HocuspocusProvider, type HocuspocusProviderConfiguration, type HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
1
|
+
import { HocuspocusProvider, type HocuspocusProviderConfiguration, type HocuspocusProviderWebsocket, type HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
2
2
|
import type { 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/extension-redis",
|
|
3
|
-
"version": "3.0.
|
|
3
|
+
"version": "3.0.6-rc.0",
|
|
4
4
|
"description": "Scale Hocuspocus horizontally with Redis",
|
|
5
5
|
"homepage": "https://hocuspocus.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
"types": "dist/packages/extension-redis/src/index.d.ts",
|
|
16
16
|
"exports": {
|
|
17
17
|
"source": {
|
|
18
|
-
"import": "./src"
|
|
18
|
+
"import": "./src/index.ts"
|
|
19
19
|
},
|
|
20
20
|
"default": {
|
|
21
21
|
"import": "./dist/hocuspocus-redis.esm.js",
|
|
@@ -33,12 +33,12 @@
|
|
|
33
33
|
"@types/redlock": "^4.0.3"
|
|
34
34
|
},
|
|
35
35
|
"dependencies": {
|
|
36
|
-
"@hocuspocus/server": "^3.0.
|
|
36
|
+
"@hocuspocus/server": "^3.0.6-rc.0",
|
|
37
37
|
"ioredis": "^4.28.2",
|
|
38
38
|
"kleur": "^4.1.4",
|
|
39
39
|
"lodash.debounce": "^4.0.8",
|
|
40
40
|
"redlock": "^4.2.0",
|
|
41
|
-
"uuid": "^
|
|
41
|
+
"uuid": "^11.0.3"
|
|
42
42
|
},
|
|
43
43
|
"peerDependencies": {
|
|
44
44
|
"y-protocols": "^1.0.6",
|
package/src/Redis.ts
CHANGED
|
@@ -17,7 +17,6 @@ import {
|
|
|
17
17
|
IncomingMessage,
|
|
18
18
|
OutgoingMessage,
|
|
19
19
|
MessageReceiver,
|
|
20
|
-
Debugger,
|
|
21
20
|
} from '@hocuspocus/server'
|
|
22
21
|
|
|
23
22
|
export type RedisInstance = RedisClient.Cluster | RedisClient.Redis
|
|
@@ -98,19 +97,22 @@ export class Redis implements Extension {
|
|
|
98
97
|
|
|
99
98
|
locks = new Map<string, Redlock.Lock>()
|
|
100
99
|
|
|
101
|
-
logger: Debugger
|
|
102
|
-
|
|
103
100
|
messagePrefix: Buffer
|
|
104
101
|
|
|
102
|
+
/**
|
|
103
|
+
* When we have a high frequency of updates to a document we don't need tons of setTimeouts
|
|
104
|
+
* piling up, so we'll track them to keep it to the most recent per document.
|
|
105
|
+
*/
|
|
106
|
+
private pendingDisconnects = new Map<string, NodeJS.Timeout>()
|
|
107
|
+
|
|
108
|
+
private pendingAfterStoreDocumentResolves = new Map<string, { timeout: NodeJS.Timeout; resolve:() => void }>()
|
|
109
|
+
|
|
105
110
|
public constructor(configuration: Partial<Configuration>) {
|
|
106
111
|
this.configuration = {
|
|
107
112
|
...this.configuration,
|
|
108
113
|
...configuration,
|
|
109
114
|
}
|
|
110
115
|
|
|
111
|
-
// We’ll replace that in the onConfigure hook with the global instance.
|
|
112
|
-
this.logger = new Debugger()
|
|
113
|
-
|
|
114
116
|
// Create Redis instance
|
|
115
117
|
const {
|
|
116
118
|
port,
|
|
@@ -145,7 +147,6 @@ export class Redis implements Extension {
|
|
|
145
147
|
}
|
|
146
148
|
|
|
147
149
|
async onConfigure({ instance }: onConfigurePayload) {
|
|
148
|
-
this.logger = instance.debugger
|
|
149
150
|
this.instance = instance
|
|
150
151
|
}
|
|
151
152
|
|
|
@@ -262,9 +263,27 @@ export class Redis implements Extension {
|
|
|
262
263
|
// if the change was initiated by a directConnection, we need to delay this hook to make sure sync can finish first.
|
|
263
264
|
// for provider connections, this usually happens in the onDisconnect hook
|
|
264
265
|
if (socketId === 'server') {
|
|
265
|
-
|
|
266
|
-
|
|
266
|
+
const pending = this.pendingAfterStoreDocumentResolves.get(documentName)
|
|
267
|
+
|
|
268
|
+
if (pending) {
|
|
269
|
+
clearTimeout(pending.timeout)
|
|
270
|
+
pending.resolve()
|
|
271
|
+
this.pendingAfterStoreDocumentResolves.delete(documentName)
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
let resolveFunction: () => void = () => {}
|
|
275
|
+
const delayedPromise = new Promise<void>(resolve => {
|
|
276
|
+
resolveFunction = resolve
|
|
267
277
|
})
|
|
278
|
+
|
|
279
|
+
const timeout = setTimeout(() => {
|
|
280
|
+
this.pendingAfterStoreDocumentResolves.delete(documentName)
|
|
281
|
+
resolveFunction()
|
|
282
|
+
}, this.configuration.disconnectDelay)
|
|
283
|
+
|
|
284
|
+
this.pendingAfterStoreDocumentResolves.set(documentName, { timeout, resolve: resolveFunction })
|
|
285
|
+
|
|
286
|
+
await delayedPromise
|
|
268
287
|
}
|
|
269
288
|
}
|
|
270
289
|
|
|
@@ -303,14 +322,11 @@ export class Redis implements Extension {
|
|
|
303
322
|
const document = this.instance.documents.get(documentName)
|
|
304
323
|
|
|
305
324
|
if (!document) {
|
|
306
|
-
// What does this mean? Why are we subscribed to this document?
|
|
307
|
-
this.logger.log(`Received message for unknown document ${documentName}`)
|
|
308
325
|
return
|
|
309
326
|
}
|
|
310
327
|
|
|
311
328
|
new MessageReceiver(
|
|
312
329
|
message,
|
|
313
|
-
this.logger,
|
|
314
330
|
this.redisTransactionOrigin,
|
|
315
331
|
).apply(document, undefined, reply => {
|
|
316
332
|
return this.pub.publishBuffer(
|
|
@@ -334,9 +350,18 @@ export class Redis implements Extension {
|
|
|
334
350
|
* no one connected anymore.
|
|
335
351
|
*/
|
|
336
352
|
public onDisconnect = async ({ documentName }: onDisconnectPayload) => {
|
|
353
|
+
const pending = this.pendingDisconnects.get(documentName)
|
|
354
|
+
|
|
355
|
+
if (pending) {
|
|
356
|
+
clearTimeout(pending)
|
|
357
|
+
this.pendingDisconnects.delete(documentName)
|
|
358
|
+
}
|
|
359
|
+
|
|
337
360
|
const disconnect = () => {
|
|
338
361
|
const document = this.instance.documents.get(documentName)
|
|
339
362
|
|
|
363
|
+
this.pendingDisconnects.delete(documentName)
|
|
364
|
+
|
|
340
365
|
// Do nothing, when other users are still connected to the document.
|
|
341
366
|
if (!document || document.getConnectionsCount() > 0) {
|
|
342
367
|
return
|
|
@@ -352,7 +377,8 @@ export class Redis implements Extension {
|
|
|
352
377
|
this.instance.unloadDocument(document)
|
|
353
378
|
}
|
|
354
379
|
// Delay the disconnect procedure to allow last minute syncs to happen
|
|
355
|
-
setTimeout(disconnect, this.configuration.disconnectDelay)
|
|
380
|
+
const timeout = setTimeout(disconnect, this.configuration.disconnectDelay)
|
|
381
|
+
this.pendingDisconnects.set(documentName, timeout)
|
|
356
382
|
}
|
|
357
383
|
|
|
358
384
|
async beforeBroadcastStateless(data: beforeBroadcastStatelessPayload) {
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './Redis.
|
|
1
|
+
export * from './Redis.ts'
|
|
@@ -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 +0,0 @@
|
|
|
1
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export {};
|
|
File without changes
|