snapshot of https://github.com/ueberdosis/hocuspocus.git @ cf3cfa355b4d3bb61c6b6c80071f71783e32470e (2026-09-15)
Some checks failed
build / lint (22) (push) Failing after 17s
build / test (22) (push) Failing after 8s
build / lint (23) (push) Failing after 2s
build / build (22) (push) Has been skipped
build / build (23) (push) Has been skipped
build / test (23) (push) Failing after 4s
docsearch / docsearch (push) Failing after 1s

This commit is contained in:
upstream-mirror
2026-09-15 17:21:35 +05:00
commit e0c588ca1c
265 changed files with 55259 additions and 0 deletions

1195
packages/common/CHANGELOG.md Normal file

File diff suppressed because it is too large Load Diff

14
packages/common/README.md Normal file
View File

@@ -0,0 +1,14 @@
# @hocuspocus/common
[![Version](https://img.shields.io/npm/v/@hocuspocus/common.svg?label=version)](https://www.npmjs.com/package/@hocuspocus/common)
[![Downloads](https://img.shields.io/npm/dm/@hocuspocus/common.svg)](https://npmcharts.com/compare/tiptap?minimal=true)
[![License](https://img.shields.io/npm/l/@hocuspocus/common.svg)](https://www.npmjs.com/package/@hocuspocus/common)
[![Sponsor](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D%A4&logo=GitHub)](https://github.com/sponsors/ueberdosis)
## Introduction
Shared types and utilities used across [Hocuspocus](https://github.com/ueberdosis/hocuspocus) packages – including message/sync protocol helpers and common enums. This package is an internal building block; most users will depend on `@hocuspocus/server` or `@hocuspocus/provider` instead.
## Official Documentation
Documentation can be found in the [GitHub repository](https://github.com/ueberdosis/hocuspocus).
## License
Hocuspocus is open-sourced software licensed under the [MIT license](https://github.com/ueberdosis/hocuspocus/blob/main/LICENSE.md).

View File

@@ -0,0 +1,38 @@
{
"name": "@hocuspocus/common",
"description": "shared code for multiple Hocuspocus packages",
"version": "4.7.0",
"homepage": "https://hocuspocus.dev",
"keywords": [
"hocuspocus"
],
"license": "MIT",
"type": "module",
"main": "dist/hocuspocus-common.cjs",
"module": "dist/hocuspocus-common.esm.js",
"types": "dist/index.d.ts",
"exports": {
"source": {
"import": "./src/index.ts"
},
"default": {
"import": "./dist/hocuspocus-common.esm.js",
"require": "./dist/hocuspocus-common.cjs",
"types": "./dist/index.d.ts"
}
},
"files": [
"src",
"dist"
],
"gitHead": "cd788b6a315f608ef531524409abdce1e6790726",
"dependencies": {
"lib0": "^0.2.117"
},
"repository": {
"url": "https://github.com/ueberdosis/hocuspocus"
},
"publishConfig": {
"access": "public"
}
}

View File

@@ -0,0 +1,49 @@
export interface CloseEvent {
code: number;
reason: string;
}
/**
* The server is terminating the connection because a data frame was received
* that is too large.
* See: https://developer.mozilla.org/en-US/docs/Web/API/CloseEvent/code
*/
export const MessageTooBig: CloseEvent = {
code: 1009,
reason: "Message Too Big",
};
/**
* The server successfully processed the request, asks that the requester reset
* its document view, and is not returning any content.
*/
export const ResetConnection: CloseEvent = {
code: 4205,
reason: "Reset Connection",
};
/**
* Similar to Forbidden, but specifically for use when authentication is required and has
* failed or has not yet been provided.
*/
export const Unauthorized: CloseEvent = {
code: 4401,
reason: "Unauthorized",
};
/**
* The request contained valid data and was understood by the server, but the server
* is refusing action.
*/
export const Forbidden: CloseEvent = {
code: 4403,
reason: "Forbidden",
};
/**
* The server timed out waiting for the request.
*/
export const ConnectionTimeout: CloseEvent = {
code: 4408,
reason: "Connection Timeout",
};

View File

@@ -0,0 +1,6 @@
export class SkipFurtherHooksError extends Error {
constructor(message?: string) {
super(message ?? "Further hooks skipped");
this.name = "SkipFurtherHooksError";
}
}

View File

@@ -0,0 +1,62 @@
import * as encoding from "lib0/encoding";
import * as decoding from "lib0/decoding";
import type {AuthorizedScope} from "../../provider/src"
export enum AuthMessageType {
Token = 0,
PermissionDenied = 1,
Authenticated = 2,
}
export const writeAuthentication = (
encoder: encoding.Encoder,
auth: string,
) => {
encoding.writeVarUint(encoder, AuthMessageType.Token);
encoding.writeVarString(encoder, auth);
};
export const writePermissionDenied = (
encoder: encoding.Encoder,
reason: string,
) => {
encoding.writeVarUint(encoder, AuthMessageType.PermissionDenied);
encoding.writeVarString(encoder, reason);
};
export const writeAuthenticated = (
encoder: encoding.Encoder,
scope: AuthorizedScope,
) => {
encoding.writeVarUint(encoder, AuthMessageType.Authenticated);
encoding.writeVarString(encoder, scope);
};
export const writeTokenSyncRequest = (
encoder: encoding.Encoder,
) => {
encoding.writeVarUint(encoder, AuthMessageType.Token);
};
export const readAuthMessage = (
decoder: decoding.Decoder,
sendToken: () => void,
permissionDeniedHandler: (reason: string) => void,
authenticatedHandler: (scope: string) => void,
) => {
switch (decoding.readVarUint(decoder)) {
case AuthMessageType.Token: {
sendToken();
break;
}
case AuthMessageType.PermissionDenied: {
permissionDeniedHandler(decoding.readVarString(decoder));
break;
}
case AuthMessageType.Authenticated: {
authenticatedHandler(decoding.readVarString(decoder));
break;
}
default:
}
};

View File

@@ -0,0 +1,10 @@
export const awarenessStatesToArray = (
states: Map<number, Record<string, any>>,
) => {
return Array.from(states.entries()).map(([key, value]) => {
return {
clientId: key,
...value,
};
});
};

View File

@@ -0,0 +1,6 @@
export * from "./auth.ts";
export * from "./CloseEvents.ts";
export * from "./awarenessStatesToArray.ts";
export * from "./routingKey.ts";
export * from "./SkipFurtherHooksError.ts";
export * from "./types.ts";

View File

@@ -0,0 +1,11 @@
const SEPARATOR = '\0';
export function makeRoutingKey(documentName: string, sessionId: string): string {
return documentName + SEPARATOR + sessionId;
}
export function parseRoutingKey(key: string): { documentName: string; sessionId: string | null } {
const idx = key.indexOf(SEPARATOR);
if (idx === -1) return { documentName: key, sessionId: null };
return { documentName: key.substring(0, idx), sessionId: key.substring(idx + 1) };
}

View File

@@ -0,0 +1,10 @@
/**
* State of the WebSocket connection.
* https://developer.mozilla.org/de/docs/Web/API/WebSocket/readyState
*/
export enum WsReadyStates {
Connecting = 0,
Open = 1,
Closing = 2,
Closed = 3,
}