mirror of
https://github.com/docmost/docmost.git
synced 2026-06-16 06:57:01 +08:00
move types to own file
This commit is contained in:
@@ -5,7 +5,7 @@ import type {
|
|||||||
RSAMessageClose,
|
RSAMessageClose,
|
||||||
RSAMessagePing,
|
RSAMessagePing,
|
||||||
RSAMessageSend,
|
RSAMessageSend,
|
||||||
} from './redis-sync.extension';
|
} from './redis-sync.types';
|
||||||
|
|
||||||
export class CollabProxySocket extends EventEmitter {
|
export class CollabProxySocket extends EventEmitter {
|
||||||
private replyTo: string;
|
private replyTo: string;
|
||||||
|
|||||||
@@ -1,7 +1,5 @@
|
|||||||
// Source https://github.com/ueberdosis/hocuspocus/pull/1008
|
// Source https://github.com/ueberdosis/hocuspocus/pull/1008
|
||||||
import type EventEmitter from 'node:events';
|
|
||||||
import type { IncomingMessage } from 'node:http';
|
import type { IncomingMessage } from 'node:http';
|
||||||
import type { IncomingHttpHeaders } from 'node:http2';
|
|
||||||
import {
|
import {
|
||||||
type Extension,
|
type Extension,
|
||||||
type Hocuspocus,
|
type Hocuspocus,
|
||||||
@@ -14,129 +12,36 @@ import type RedisClient from 'ioredis';
|
|||||||
import { readVarString } from 'lib0/decoding.js';
|
import { readVarString } from 'lib0/decoding.js';
|
||||||
import type { WebSocket } from 'ws';
|
import type { WebSocket } from 'ws';
|
||||||
import { CollabProxySocket } from './collab-proxy-socket';
|
import { CollabProxySocket } from './collab-proxy-socket';
|
||||||
|
import { Injectable } from '@nestjs/common';
|
||||||
|
import type {
|
||||||
|
BaseWebSocket,
|
||||||
|
Configuration,
|
||||||
|
CustomEvents,
|
||||||
|
Pack,
|
||||||
|
RSAMessage,
|
||||||
|
RSAMessageCloseProxy,
|
||||||
|
RSAMessageCustomEventComplete,
|
||||||
|
RSAMessageCustomEventStart,
|
||||||
|
RSAMessagePong,
|
||||||
|
RSAMessageProxy,
|
||||||
|
RSAMessageUnload,
|
||||||
|
SerializedHTTPRequest,
|
||||||
|
Unpack,
|
||||||
|
} from './redis-sync.types';
|
||||||
|
|
||||||
export type SecondParam<T> = T extends (
|
export type { Pack, SerializedHTTPRequest } from './redis-sync.types';
|
||||||
arg1: unknown,
|
|
||||||
arg2: infer A,
|
|
||||||
...args: unknown[]
|
|
||||||
) => unknown
|
|
||||||
? A
|
|
||||||
: never;
|
|
||||||
export type RSAMessageProxy = {
|
|
||||||
type: 'proxy';
|
|
||||||
replyTo: string;
|
|
||||||
// @ts-ignore
|
|
||||||
message: Uint8Array<ArrayBufferLike>;
|
|
||||||
serializedHTTPRequest: SerializedHTTPRequest;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessageCloseProxy = {
|
|
||||||
type: 'closeProxy';
|
|
||||||
socketId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessageUnload = {
|
|
||||||
type: 'unload';
|
|
||||||
documentName: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessageClose = {
|
|
||||||
type: 'close';
|
|
||||||
code?: number;
|
|
||||||
reason?: string;
|
|
||||||
socketId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessagePing = {
|
|
||||||
type: 'ping';
|
|
||||||
socketId: string;
|
|
||||||
respondTo: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessagePong = {
|
|
||||||
type: 'pong';
|
|
||||||
socketId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessageSend = {
|
|
||||||
type: 'send';
|
|
||||||
// @ts-ignore
|
|
||||||
message: Uint8Array<ArrayBufferLike>;
|
|
||||||
socketId: string;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessageCustomEventStart<TName = string, TPayload = unknown> = {
|
|
||||||
type: 'customEventStart';
|
|
||||||
documentName: string;
|
|
||||||
eventName: TName;
|
|
||||||
payload: TPayload;
|
|
||||||
replyTo: string;
|
|
||||||
replyId: number;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessageCustomEventComplete = {
|
|
||||||
type: 'customEventComplete';
|
|
||||||
replyId: number;
|
|
||||||
payload: unknown;
|
|
||||||
};
|
|
||||||
|
|
||||||
export type RSAMessage =
|
|
||||||
| RSAMessageProxy
|
|
||||||
| RSAMessageCloseProxy
|
|
||||||
| RSAMessageUnload
|
|
||||||
| RSAMessageClose
|
|
||||||
| RSAMessagePing
|
|
||||||
| RSAMessagePong
|
|
||||||
| RSAMessageSend
|
|
||||||
| RSAMessageCustomEventStart
|
|
||||||
| RSAMessageCustomEventComplete;
|
|
||||||
|
|
||||||
export type SerializedHTTPRequest = {
|
|
||||||
method: string;
|
|
||||||
url: string;
|
|
||||||
headers: IncomingHttpHeaders & { 'sec-websocket-key': string };
|
|
||||||
socket: { remoteAddress: string };
|
|
||||||
};
|
|
||||||
// @ts-ignore
|
|
||||||
export type Pack = (msg: RSAMessage) => string | Buffer<ArrayBufferLike>;
|
|
||||||
type Unpack = (
|
|
||||||
// @ts-ignore
|
|
||||||
packedMessage: Uint8Array | Buffer<ArrayBufferLike>,
|
|
||||||
) => RSAMessage;
|
|
||||||
type ServerId = string;
|
type ServerId = string;
|
||||||
type DocumentName = string;
|
type DocumentName = string;
|
||||||
type SocketId = string;
|
type SocketId = string;
|
||||||
type CustomEventName = string;
|
|
||||||
type CustomEvents = Record<
|
|
||||||
CustomEventName,
|
|
||||||
(documentName: string, payload: unknown) => Promise<unknown>
|
|
||||||
>;
|
|
||||||
|
|
||||||
interface Configuration<TCE> {
|
|
||||||
redis: RedisClient;
|
|
||||||
pack: Pack;
|
|
||||||
unpack: Unpack;
|
|
||||||
serverId: ServerId;
|
|
||||||
lockTTL?: number;
|
|
||||||
customEventTTL?: number;
|
|
||||||
proxySocketTTL?: number;
|
|
||||||
prefix?: string;
|
|
||||||
customEvents?: TCE;
|
|
||||||
}
|
|
||||||
|
|
||||||
interface BaseWebSocket extends EventEmitter {
|
|
||||||
readyState: number;
|
|
||||||
close(code?: number, reason?: string): void;
|
|
||||||
ping(): void;
|
|
||||||
send(message: Uint8Array): void;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
export class RedisSyncExtension<TCE extends CustomEvents> implements Extension {
|
export class RedisSyncExtension<TCE extends CustomEvents> implements Extension {
|
||||||
priority = 1000;
|
priority = 1000;
|
||||||
private pub: RedisClient;
|
private readonly pub: RedisClient;
|
||||||
private sub: RedisClient;
|
private sub: RedisClient;
|
||||||
private pack: Pack;
|
private readonly pack: Pack;
|
||||||
private unpack: Unpack;
|
private readonly unpack: Unpack;
|
||||||
private originSockets: Record<SocketId, BaseWebSocket> = {};
|
private originSockets: Record<SocketId, BaseWebSocket> = {};
|
||||||
private locks: Record<DocumentName, NodeJS.Timeout> = {};
|
private locks: Record<DocumentName, NodeJS.Timeout> = {};
|
||||||
private lockPromises: Record<DocumentName, Promise<ServerId | null>> = {};
|
private lockPromises: Record<DocumentName, Promise<ServerId | null>> = {};
|
||||||
@@ -144,15 +49,15 @@ export class RedisSyncExtension<TCE extends CustomEvents> implements Extension {
|
|||||||
SocketId,
|
SocketId,
|
||||||
{ socket: CollabProxySocket; cleanup: NodeJS.Timeout }
|
{ socket: CollabProxySocket; cleanup: NodeJS.Timeout }
|
||||||
> = {};
|
> = {};
|
||||||
private prefix: string;
|
private readonly prefix: string;
|
||||||
private lockPrefix: string;
|
private readonly lockPrefix: string;
|
||||||
private msgChannel: string;
|
private readonly msgChannel: string;
|
||||||
private serverId: ServerId;
|
private readonly serverId: ServerId;
|
||||||
private customEventTTL: number;
|
private readonly customEventTTL: number;
|
||||||
private lockTTL: number;
|
private readonly lockTTL: number;
|
||||||
private proxySocketTTL: number;
|
private readonly proxySocketTTL: number;
|
||||||
private instance!: Hocuspocus;
|
private instance!: Hocuspocus;
|
||||||
private customEvents: TCE;
|
private readonly customEvents: TCE;
|
||||||
private replyIdCounter = 0;
|
private replyIdCounter = 0;
|
||||||
private pendingReplies: Record<
|
private pendingReplies: Record<
|
||||||
number,
|
number,
|
||||||
|
|||||||
@@ -0,0 +1,123 @@
|
|||||||
|
import type EventEmitter from 'node:events';
|
||||||
|
import type { IncomingHttpHeaders } from 'node:http2';
|
||||||
|
import type RedisClient from 'ioredis';
|
||||||
|
|
||||||
|
export type SecondParam<T> = T extends (
|
||||||
|
arg1: unknown,
|
||||||
|
arg2: infer A,
|
||||||
|
...args: unknown[]
|
||||||
|
) => unknown
|
||||||
|
? A
|
||||||
|
: never;
|
||||||
|
|
||||||
|
export type SerializedHTTPRequest = {
|
||||||
|
method: string;
|
||||||
|
url: string;
|
||||||
|
headers: IncomingHttpHeaders & { 'sec-websocket-key': string };
|
||||||
|
socket: { remoteAddress: string };
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageProxy = {
|
||||||
|
type: 'proxy';
|
||||||
|
replyTo: string;
|
||||||
|
// @ts-ignore
|
||||||
|
message: Uint8Array<ArrayBufferLike>;
|
||||||
|
serializedHTTPRequest: SerializedHTTPRequest;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageCloseProxy = {
|
||||||
|
type: 'closeProxy';
|
||||||
|
socketId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageUnload = {
|
||||||
|
type: 'unload';
|
||||||
|
documentName: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageClose = {
|
||||||
|
type: 'close';
|
||||||
|
code?: number;
|
||||||
|
reason?: string;
|
||||||
|
socketId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessagePing = {
|
||||||
|
type: 'ping';
|
||||||
|
socketId: string;
|
||||||
|
respondTo: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessagePong = {
|
||||||
|
type: 'pong';
|
||||||
|
socketId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageSend = {
|
||||||
|
type: 'send';
|
||||||
|
// @ts-ignore
|
||||||
|
message: Uint8Array<ArrayBufferLike>;
|
||||||
|
socketId: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageCustomEventStart<TName = string, TPayload = unknown> = {
|
||||||
|
type: 'customEventStart';
|
||||||
|
documentName: string;
|
||||||
|
eventName: TName;
|
||||||
|
payload: TPayload;
|
||||||
|
replyTo: string;
|
||||||
|
replyId: number;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessageCustomEventComplete = {
|
||||||
|
type: 'customEventComplete';
|
||||||
|
replyId: number;
|
||||||
|
payload: unknown;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type RSAMessage =
|
||||||
|
| RSAMessageProxy
|
||||||
|
| RSAMessageCloseProxy
|
||||||
|
| RSAMessageUnload
|
||||||
|
| RSAMessageClose
|
||||||
|
| RSAMessagePing
|
||||||
|
| RSAMessagePong
|
||||||
|
| RSAMessageSend
|
||||||
|
| RSAMessageCustomEventStart
|
||||||
|
| RSAMessageCustomEventComplete;
|
||||||
|
|
||||||
|
// @ts-ignore
|
||||||
|
export type Pack = (msg: RSAMessage) => string | Buffer<ArrayBufferLike>;
|
||||||
|
|
||||||
|
export type Unpack = (
|
||||||
|
// @ts-ignore
|
||||||
|
packedMessage: Uint8Array | Buffer<ArrayBufferLike>,
|
||||||
|
) => RSAMessage;
|
||||||
|
|
||||||
|
type ServerId = string;
|
||||||
|
type DocumentName = string;
|
||||||
|
type CustomEventName = string;
|
||||||
|
|
||||||
|
export type CustomEvents = Record<
|
||||||
|
CustomEventName,
|
||||||
|
(documentName: string, payload: unknown) => Promise<unknown>
|
||||||
|
>;
|
||||||
|
|
||||||
|
export type Configuration<TCE> = {
|
||||||
|
redis: RedisClient;
|
||||||
|
pack: Pack;
|
||||||
|
unpack: Unpack;
|
||||||
|
serverId: ServerId;
|
||||||
|
lockTTL?: number;
|
||||||
|
customEventTTL?: number;
|
||||||
|
proxySocketTTL?: number;
|
||||||
|
prefix?: string;
|
||||||
|
customEvents?: TCE;
|
||||||
|
};
|
||||||
|
|
||||||
|
export type BaseWebSocket = EventEmitter & {
|
||||||
|
readyState: number;
|
||||||
|
close(code?: number, reason?: string): void;
|
||||||
|
ping(): void;
|
||||||
|
send(message: Uint8Array): void;
|
||||||
|
};
|
||||||
Reference in New Issue
Block a user