@hocuspocus/extension-redis 2.1.0-alpha.0 → 2.2.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 +201 -153
- package/dist/hocuspocus-redis.cjs.map +1 -1
- package/dist/hocuspocus-redis.esm.js +200 -153
- package/dist/hocuspocus-redis.esm.js.map +1 -1
- package/dist/packages/common/src/CloseEvents.d.ts +29 -29
- package/dist/packages/common/src/auth.d.ts +6 -6
- package/dist/packages/common/src/awarenessStatesToArray.d.ts +3 -3
- package/dist/packages/common/src/index.d.ts +4 -4
- package/dist/packages/common/src/types.d.ts +10 -10
- package/dist/packages/extension-database/src/Database.d.ts +30 -30
- package/dist/packages/extension-database/src/index.d.ts +1 -1
- package/dist/packages/extension-logger/src/Logger.d.ts +67 -67
- package/dist/packages/extension-logger/src/index.d.ts +1 -1
- package/dist/packages/extension-redis/src/Redis.d.ts +116 -95
- package/dist/packages/extension-redis/src/index.d.ts +1 -1
- package/dist/packages/extension-sqlite/src/SQLite.d.ts +26 -26
- package/dist/packages/extension-sqlite/src/index.d.ts +1 -1
- package/dist/packages/extension-throttle/src/index.d.ts +31 -31
- package/dist/packages/extension-webhook/src/index.d.ts +57 -57
- package/dist/packages/provider/src/EventEmitter.d.ts +9 -9
- package/dist/packages/provider/src/HocuspocusProvider.d.ts +110 -110
- package/dist/packages/provider/src/HocuspocusProviderWebsocket.d.ts +115 -115
- package/dist/packages/provider/src/IncomingMessage.d.ts +16 -16
- package/dist/packages/provider/src/MessageReceiver.d.ts +13 -13
- package/dist/packages/provider/src/MessageSender.d.ts +10 -10
- package/dist/packages/provider/src/OutgoingMessage.d.ts +9 -9
- package/dist/packages/provider/src/OutgoingMessages/AuthenticationMessage.d.ts +7 -7
- package/dist/packages/provider/src/OutgoingMessages/AwarenessMessage.d.ts +8 -8
- package/dist/packages/provider/src/OutgoingMessages/CloseMessage.d.ts +8 -8
- package/dist/packages/provider/src/OutgoingMessages/QueryAwarenessMessage.d.ts +8 -8
- package/dist/packages/provider/src/OutgoingMessages/StatelessMessage.d.ts +7 -7
- package/dist/packages/provider/src/OutgoingMessages/SyncStepOneMessage.d.ts +8 -8
- package/dist/packages/provider/src/OutgoingMessages/SyncStepTwoMessage.d.ts +8 -8
- package/dist/packages/provider/src/OutgoingMessages/UpdateMessage.d.ts +7 -7
- package/dist/packages/provider/src/TiptapCollabProvider.d.ts +11 -11
- package/dist/packages/provider/src/TiptapCollabProviderWebsocket.d.ts +11 -11
- package/dist/packages/provider/src/index.d.ts +5 -5
- package/dist/packages/provider/src/types.d.ts +84 -84
- package/dist/packages/server/src/ClientConnection.d.ts +56 -0
- package/dist/packages/server/src/Connection.d.ts +71 -71
- package/dist/packages/server/src/Debugger.d.ts +14 -14
- package/dist/packages/server/src/DirectConnection.d.ts +14 -0
- package/dist/packages/server/src/Document.d.ts +91 -88
- package/dist/packages/server/src/Hocuspocus.d.ts +103 -108
- package/dist/packages/server/src/IncomingMessage.d.ts +21 -21
- package/dist/packages/server/src/MessageReceiver.d.ts +12 -12
- package/dist/packages/server/src/OutgoingMessage.d.ts +20 -20
- package/dist/packages/server/src/index.d.ts +8 -8
- package/dist/packages/server/src/types.d.ts +270 -264
- package/dist/packages/server/src/util/getParameters.d.ts +8 -0
- package/dist/packages/transformer/src/Prosemirror.d.ts +11 -11
- package/dist/packages/transformer/src/Tiptap.d.ts +10 -10
- package/dist/packages/transformer/src/index.d.ts +3 -3
- package/dist/packages/transformer/src/types.d.ts +5 -5
- package/dist/playground/backend/src/default.d.ts +1 -1
- package/dist/playground/backend/src/express.d.ts +1 -1
- package/dist/playground/backend/src/koa.d.ts +1 -1
- package/dist/playground/backend/src/load-document.d.ts +1 -1
- package/dist/playground/backend/src/redis.d.ts +1 -1
- package/dist/playground/backend/src/slow.d.ts +1 -1
- package/dist/playground/backend/src/tiptapcollab.d.ts +1 -1
- package/dist/playground/backend/src/webhook.d.ts +1 -1
- package/dist/playground/frontend/src/main.d.ts +1 -1
- package/dist/playground/frontend/vite.config.d.ts +2 -2
- package/dist/tests/extension-database/fetch.d.ts +1 -1
- package/dist/tests/extension-logger/onListen.d.ts +1 -1
- package/dist/tests/extension-redis/closeConnections.d.ts +1 -1
- package/dist/tests/extension-redis/getConnectionCount.d.ts +1 -1
- package/dist/tests/extension-redis/getDocumentsCount.d.ts +1 -1
- package/dist/tests/extension-redis/onAwarenessChange.d.ts +1 -1
- package/dist/tests/extension-redis/onChange.d.ts +1 -1
- package/dist/tests/extension-redis/onStateless.d.ts +1 -1
- package/dist/tests/extension-redis/onStoreDocument.d.ts +1 -1
- package/dist/tests/extension-throttle/banning.d.ts +1 -1
- package/dist/tests/extension-throttle/configuration.d.ts +1 -1
- package/dist/tests/provider/observe.d.ts +1 -1
- package/dist/tests/provider/observeDeep.d.ts +1 -1
- package/dist/tests/provider/onAuthenticated.d.ts +1 -1
- package/dist/tests/provider/onAuthenticationFailed.d.ts +1 -1
- package/dist/tests/provider/onAwarenessChange.d.ts +1 -1
- package/dist/tests/provider/onAwarenessUpdate.d.ts +1 -1
- package/dist/tests/provider/onClose.d.ts +1 -1
- package/dist/tests/provider/onConnect.d.ts +1 -1
- package/dist/tests/provider/onDisconnect.d.ts +1 -1
- package/dist/tests/provider/onMessage.d.ts +1 -1
- package/dist/tests/provider/onOpen.d.ts +1 -1
- package/dist/tests/provider/onStateless.d.ts +1 -1
- package/dist/tests/provider/onSynced.d.ts +1 -1
- package/dist/tests/providerwebsocket/configuration.d.ts +1 -1
- package/dist/tests/server/address.d.ts +1 -1
- package/dist/tests/server/afterStoreDocument.d.ts +1 -1
- package/dist/tests/server/beforeBroadcastStateless.d.ts +1 -1
- package/dist/tests/server/beforeHandleMessage.d.ts +1 -1
- package/dist/tests/server/closeConnections.d.ts +1 -1
- package/dist/tests/server/getConnectionsCount.d.ts +1 -1
- package/dist/tests/server/getDocumentsCount.d.ts +1 -1
- package/dist/tests/server/getMessageLogs.d.ts +1 -1
- package/dist/tests/server/listen.d.ts +1 -1
- package/dist/tests/server/onAuthenticate.d.ts +1 -1
- package/dist/tests/server/onAwarenessUpdate.d.ts +1 -1
- package/dist/tests/server/onChange.d.ts +1 -1
- package/dist/tests/server/onClose.d.ts +1 -1
- package/dist/tests/server/onConfigure.d.ts +1 -1
- package/dist/tests/server/onConnect.d.ts +1 -1
- package/dist/tests/server/onDestroy.d.ts +1 -1
- package/dist/tests/server/onDisconnect.d.ts +1 -1
- package/dist/tests/server/onListen.d.ts +1 -1
- package/dist/tests/server/onLoadDocument.d.ts +1 -1
- package/dist/tests/server/onRequest.d.ts +1 -1
- package/dist/tests/server/onStateless.d.ts +1 -1
- package/dist/tests/server/onStoreDocument.d.ts +1 -1
- package/dist/tests/server/onUpgrade.d.ts +1 -1
- package/dist/tests/server/openDirectConnection.d.ts +1 -0
- package/dist/tests/server/requiresAuthentication.d.ts +1 -1
- package/dist/tests/server/websocketError.d.ts +1 -1
- package/dist/tests/transformer/TiptapTransformer.d.ts +1 -1
- package/dist/tests/utils/createDirectory.d.ts +1 -1
- package/dist/tests/utils/flushRedis.d.ts +1 -1
- package/dist/tests/utils/index.d.ts +9 -9
- package/dist/tests/utils/newHocuspocus.d.ts +2 -2
- package/dist/tests/utils/newHocuspocusProvider.d.ts +3 -3
- package/dist/tests/utils/newHocuspocusProviderWebsocket.d.ts +3 -3
- package/dist/tests/utils/randomInteger.d.ts +1 -1
- package/dist/tests/utils/redisConnectionSettings.d.ts +4 -4
- package/dist/tests/utils/removeDirectory.d.ts +1 -1
- package/dist/tests/utils/retryableAssertion.d.ts +2 -2
- package/dist/tests/utils/sleep.d.ts +1 -1
- package/package.json +9 -5
- package/src/Redis.ts +74 -13
- package/src/index.ts +1 -1
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
declare const _default: import("vite").UserConfigExport;
|
|
2
|
-
export default _default;
|
|
1
|
+
declare const _default: import("vite").UserConfigExport;
|
|
2
|
+
export default _default;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export {};
|
|
1
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const createDirectory: (dir: string) => void;
|
|
1
|
+
export declare const createDirectory: (dir: string) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const flushRedis: () => Promise<string>;
|
|
1
|
+
export declare const flushRedis: () => Promise<string>;
|
|
@@ -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.js';
|
|
2
|
+
export * from './flushRedis.js';
|
|
3
|
+
export * from './newHocuspocus.js';
|
|
4
|
+
export * from './newHocuspocusProvider.js';
|
|
5
|
+
export * from './newHocuspocusProviderWebsocket.js';
|
|
6
|
+
export * from './randomInteger.js';
|
|
7
|
+
export * from './redisConnectionSettings.js';
|
|
8
|
+
export * from './removeDirectory.js';
|
|
9
|
+
export * from './sleep.js';
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { Hocuspocus, Configuration } from '@hocuspocus/server';
|
|
2
|
-
export declare const newHocuspocus: (options?: Partial<Configuration>) => Promise<Hocuspocus>;
|
|
1
|
+
import { Hocuspocus, Configuration } from '@hocuspocus/server';
|
|
2
|
+
export declare const newHocuspocus: (options?: Partial<Configuration>) => Promise<Hocuspocus>;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
2
|
-
import { Hocuspocus } from '@hocuspocus/server';
|
|
3
|
-
export declare const newHocuspocusProvider: (server: Hocuspocus, options?: Partial<HocuspocusProviderConfiguration>, websocketOptions?: Partial<HocuspocusProviderWebsocketConfiguration>) => HocuspocusProvider;
|
|
1
|
+
import { HocuspocusProvider, HocuspocusProviderConfiguration, HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
2
|
+
import { Hocuspocus } from '@hocuspocus/server';
|
|
3
|
+
export declare const newHocuspocusProvider: (server: Hocuspocus, options?: Partial<HocuspocusProviderConfiguration>, websocketOptions?: Partial<HocuspocusProviderWebsocketConfiguration>) => HocuspocusProvider;
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
2
|
-
import { Hocuspocus } from '@hocuspocus/server';
|
|
3
|
-
export declare const newHocuspocusProviderWebsocket: (server: Hocuspocus, options?: Partial<Omit<HocuspocusProviderWebsocketConfiguration, 'url'>>) => HocuspocusProviderWebsocket;
|
|
1
|
+
import { HocuspocusProviderWebsocket, HocuspocusProviderWebsocketConfiguration } from '@hocuspocus/provider';
|
|
2
|
+
import { Hocuspocus } from '@hocuspocus/server';
|
|
3
|
+
export declare const newHocuspocusProviderWebsocket: (server: Hocuspocus, options?: Partial<Omit<HocuspocusProviderWebsocketConfiguration, 'url'>>) => HocuspocusProviderWebsocket;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const randomInteger: (min: number, max: number) => number;
|
|
1
|
+
export declare const randomInteger: (min: number, max: number) => number;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export declare const redisConnectionSettings: {
|
|
2
|
-
host: string;
|
|
3
|
-
port: number;
|
|
4
|
-
};
|
|
1
|
+
export declare const redisConnectionSettings: {
|
|
2
|
+
host: string;
|
|
3
|
+
port: number;
|
|
4
|
+
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const removeDirectory: (dir: string) => void;
|
|
1
|
+
export declare const removeDirectory: (dir: string) => void;
|
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { ExecutionContext } from 'ava';
|
|
2
|
-
export declare const retryableAssertion: (t: ExecutionContext, recoverableTry: (tt: ExecutionContext) => void) => Promise<void>;
|
|
1
|
+
import { ExecutionContext } from 'ava';
|
|
2
|
+
export declare const retryableAssertion: (t: ExecutionContext, recoverableTry: (tt: ExecutionContext) => void) => Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export declare const sleep: (time: number) => Promise<unknown>;
|
|
1
|
+
export declare const sleep: (time: number) => Promise<unknown>;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@hocuspocus/extension-redis",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "Scale Hocuspocus horizontally with Redis",
|
|
5
5
|
"homepage": "https://hocuspocus.dev",
|
|
6
6
|
"keywords": [
|
|
@@ -19,7 +19,8 @@
|
|
|
19
19
|
},
|
|
20
20
|
"default": {
|
|
21
21
|
"import": "./dist/hocuspocus-redis.esm.js",
|
|
22
|
-
"require": "./dist/hocuspocus-redis.cjs"
|
|
22
|
+
"require": "./dist/hocuspocus-redis.cjs",
|
|
23
|
+
"types": "./dist/packages/extension-redis/src/index.d.ts"
|
|
23
24
|
}
|
|
24
25
|
},
|
|
25
26
|
"files": [
|
|
@@ -27,13 +28,16 @@
|
|
|
27
28
|
"dist"
|
|
28
29
|
],
|
|
29
30
|
"devDependencies": {
|
|
30
|
-
"@types/
|
|
31
|
+
"@types/ioredis": "^4.28.7",
|
|
32
|
+
"@types/lodash.debounce": "^4.0.6",
|
|
33
|
+
"@types/redlock": "^4.0.3"
|
|
31
34
|
},
|
|
32
35
|
"dependencies": {
|
|
33
|
-
"@hocuspocus/server": "^2.
|
|
34
|
-
"ioredis": "^
|
|
36
|
+
"@hocuspocus/server": "^2.2.0",
|
|
37
|
+
"ioredis": "^4.28.2",
|
|
35
38
|
"kleur": "^4.1.4",
|
|
36
39
|
"lodash.debounce": "^4.0.8",
|
|
40
|
+
"redlock": "^4.2.0",
|
|
37
41
|
"uuid": "^9.0.0"
|
|
38
42
|
},
|
|
39
43
|
"peerDependencies": {
|
package/src/Redis.ts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import RedisClient, {
|
|
2
|
-
|
|
3
|
-
} from 'ioredis'
|
|
1
|
+
import RedisClient, { ClusterNode, ClusterOptions, RedisOptions } from 'ioredis'
|
|
2
|
+
import Redlock from 'redlock'
|
|
4
3
|
import { v4 as uuid } from 'uuid'
|
|
5
4
|
import {
|
|
6
5
|
IncomingMessage,
|
|
@@ -8,7 +7,9 @@ import {
|
|
|
8
7
|
Document,
|
|
9
8
|
Extension,
|
|
10
9
|
afterLoadDocumentPayload,
|
|
10
|
+
afterStoreDocumentPayload,
|
|
11
11
|
onDisconnectPayload,
|
|
12
|
+
onStoreDocumentPayload,
|
|
12
13
|
onAwarenessUpdatePayload,
|
|
13
14
|
onChangePayload,
|
|
14
15
|
MessageReceiver,
|
|
@@ -17,7 +18,7 @@ import {
|
|
|
17
18
|
beforeBroadcastStatelessPayload, Hocuspocus,
|
|
18
19
|
} from '@hocuspocus/server'
|
|
19
20
|
|
|
20
|
-
export type RedisInstance = RedisClient |
|
|
21
|
+
export type RedisInstance = RedisClient.Cluster | RedisClient.Redis
|
|
21
22
|
|
|
22
23
|
export interface Configuration {
|
|
23
24
|
/**
|
|
@@ -55,6 +56,10 @@ export interface Configuration {
|
|
|
55
56
|
* Namespace for Redis keys, if none is provided 'hocuspocus' is used
|
|
56
57
|
*/
|
|
57
58
|
prefix: string,
|
|
59
|
+
/**
|
|
60
|
+
* The maximum time for the Redis lock in ms (in case it can’t be released).
|
|
61
|
+
*/
|
|
62
|
+
lockTimeout: number,
|
|
58
63
|
/**
|
|
59
64
|
* A delay before onDisconnect is executed. This allows last minute updates'
|
|
60
65
|
* sync messages to be received by the subscription before it's closed.
|
|
@@ -75,6 +80,7 @@ export class Redis implements Extension {
|
|
|
75
80
|
host: '127.0.0.1',
|
|
76
81
|
prefix: 'hocuspocus',
|
|
77
82
|
identifier: `host-${uuid()}`,
|
|
83
|
+
lockTimeout: 1000,
|
|
78
84
|
disconnectDelay: 1000,
|
|
79
85
|
}
|
|
80
86
|
|
|
@@ -84,6 +90,10 @@ export class Redis implements Extension {
|
|
|
84
90
|
|
|
85
91
|
instance!: Hocuspocus
|
|
86
92
|
|
|
93
|
+
redlock: Redlock
|
|
94
|
+
|
|
95
|
+
locks = new Map<string, Redlock.Lock>()
|
|
96
|
+
|
|
87
97
|
logger: Debugger
|
|
88
98
|
|
|
89
99
|
public constructor(configuration: Partial<Configuration>) {
|
|
@@ -92,6 +102,9 @@ export class Redis implements Extension {
|
|
|
92
102
|
...configuration,
|
|
93
103
|
}
|
|
94
104
|
|
|
105
|
+
// We’ll replace that in the onConfigure hook with the global instance.
|
|
106
|
+
this.logger = new Debugger()
|
|
107
|
+
|
|
95
108
|
// Create Redis instance
|
|
96
109
|
const {
|
|
97
110
|
port,
|
|
@@ -112,13 +125,12 @@ export class Redis implements Extension {
|
|
|
112
125
|
this.pub = new RedisClient.Cluster(nodes, options)
|
|
113
126
|
this.sub = new RedisClient.Cluster(nodes, options)
|
|
114
127
|
} else {
|
|
115
|
-
this.pub = new RedisClient(port, host, options
|
|
116
|
-
this.sub = new RedisClient(port, host, options
|
|
128
|
+
this.pub = new RedisClient(port, host, options)
|
|
129
|
+
this.sub = new RedisClient(port, host, options)
|
|
117
130
|
}
|
|
118
131
|
this.sub.on('pmessageBuffer', this.handleIncomingMessage)
|
|
119
132
|
|
|
120
|
-
|
|
121
|
-
this.logger = new Debugger()
|
|
133
|
+
this.redlock = new Redlock([this.pub])
|
|
122
134
|
}
|
|
123
135
|
|
|
124
136
|
async onConfigure({ instance }: onConfigurePayload) {
|
|
@@ -138,6 +150,10 @@ export class Redis implements Extension {
|
|
|
138
150
|
return `${this.getKey(documentName)}:*`
|
|
139
151
|
}
|
|
140
152
|
|
|
153
|
+
private lockKey(documentName: string) {
|
|
154
|
+
return `${this.getKey(documentName)}:lock`
|
|
155
|
+
}
|
|
156
|
+
|
|
141
157
|
/**
|
|
142
158
|
* Once a document is laoded, subscribe to the channel in Redis.
|
|
143
159
|
*/
|
|
@@ -167,7 +183,7 @@ export class Redis implements Extension {
|
|
|
167
183
|
.createSyncMessage()
|
|
168
184
|
.writeFirstSyncStepFor(document)
|
|
169
185
|
|
|
170
|
-
return this.pub.
|
|
186
|
+
return this.pub.publishBuffer(this.pubKey(documentName), Buffer.from(syncMessage.toUint8Array()))
|
|
171
187
|
}
|
|
172
188
|
|
|
173
189
|
/**
|
|
@@ -177,12 +193,49 @@ export class Redis implements Extension {
|
|
|
177
193
|
const awarenessMessage = new OutgoingMessage(documentName)
|
|
178
194
|
.writeQueryAwareness()
|
|
179
195
|
|
|
180
|
-
return this.pub.
|
|
196
|
+
return this.pub.publishBuffer(
|
|
181
197
|
this.pubKey(documentName),
|
|
182
198
|
Buffer.from(awarenessMessage.toUint8Array()),
|
|
183
199
|
)
|
|
184
200
|
}
|
|
185
201
|
|
|
202
|
+
/**
|
|
203
|
+
* Before the document is stored, make sure to set a lock in Redis.
|
|
204
|
+
* That’s meant to avoid conflicts with other instances trying to store the document.
|
|
205
|
+
*/
|
|
206
|
+
async onStoreDocument({ documentName }: onStoreDocumentPayload) {
|
|
207
|
+
// Attempt to acquire a lock and read lastReceivedTimestamp from Redis,
|
|
208
|
+
// to avoid conflict with other instances storing the same document.
|
|
209
|
+
return new Promise((resolve, reject) => {
|
|
210
|
+
this.redlock.lock(this.lockKey(documentName), this.configuration.lockTimeout, async (error, lock) => {
|
|
211
|
+
if (error || !lock) {
|
|
212
|
+
// Expected behavior: Could not acquire lock, another instance locked it already.
|
|
213
|
+
// No further `onStoreDocument` hooks will be executed.
|
|
214
|
+
reject()
|
|
215
|
+
return
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
this.locks.set(this.lockKey(documentName), lock)
|
|
219
|
+
|
|
220
|
+
resolve(undefined)
|
|
221
|
+
})
|
|
222
|
+
})
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
/**
|
|
226
|
+
* Release the Redis lock, so other instances can store documents.
|
|
227
|
+
*/
|
|
228
|
+
async afterStoreDocument({ documentName }: afterStoreDocumentPayload) {
|
|
229
|
+
this.locks.get(this.lockKey(documentName))?.unlock()
|
|
230
|
+
.catch(() => {
|
|
231
|
+
// Not able to unlock Redis. The lock will expire after ${lockTimeout} ms.
|
|
232
|
+
// console.error(`Not able to unlock Redis. The lock will expire after ${this.configuration.lockTimeout}ms.`)
|
|
233
|
+
})
|
|
234
|
+
.finally(() => {
|
|
235
|
+
this.locks.delete(this.lockKey(documentName))
|
|
236
|
+
})
|
|
237
|
+
}
|
|
238
|
+
|
|
186
239
|
/**
|
|
187
240
|
* Handle awareness update messages received directly by this Hocuspocus instance.
|
|
188
241
|
*/
|
|
@@ -193,7 +246,7 @@ export class Redis implements Extension {
|
|
|
193
246
|
const message = new OutgoingMessage(documentName)
|
|
194
247
|
.createAwarenessUpdateMessage(awareness, changedClients)
|
|
195
248
|
|
|
196
|
-
return this.pub.
|
|
249
|
+
return this.pub.publishBuffer(
|
|
197
250
|
this.pubKey(documentName),
|
|
198
251
|
Buffer.from(message.toUint8Array()),
|
|
199
252
|
)
|
|
@@ -226,7 +279,7 @@ export class Redis implements Extension {
|
|
|
226
279
|
message,
|
|
227
280
|
this.logger,
|
|
228
281
|
).apply(document, undefined, reply => {
|
|
229
|
-
return this.pub.
|
|
282
|
+
return this.pub.publishBuffer(
|
|
230
283
|
this.pubKey(document.name),
|
|
231
284
|
Buffer.from(reply),
|
|
232
285
|
)
|
|
@@ -268,10 +321,18 @@ export class Redis implements Extension {
|
|
|
268
321
|
const message = new OutgoingMessage(data.documentName)
|
|
269
322
|
.writeBroadcastStateless(data.payload)
|
|
270
323
|
|
|
271
|
-
return this.pub.
|
|
324
|
+
return this.pub.publishBuffer(
|
|
272
325
|
this.pubKey(data.documentName),
|
|
273
326
|
Buffer.from(message.toUint8Array()),
|
|
274
327
|
)
|
|
275
328
|
}
|
|
276
329
|
|
|
330
|
+
/**
|
|
331
|
+
* Kill the Redlock connection immediately.
|
|
332
|
+
*/
|
|
333
|
+
async onDestroy() {
|
|
334
|
+
await this.redlock.quit()
|
|
335
|
+
this.pub.disconnect(false)
|
|
336
|
+
this.sub.disconnect(false)
|
|
337
|
+
}
|
|
277
338
|
}
|
package/src/index.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export * from './Redis'
|
|
1
|
+
export * from './Redis.js'
|