[WEB-1116] feat: pages realtime collaboration (#5493)
* [WEB-1116] feat: pages realtime sync (#5057) * init: live server for editor realtime sync * chore: authentication added * chore: updated logic to convert html to binary for old pages * chore: added description json on page update * chore: made all functions generic * chore: save description in json and html formats * refactor: document editor components * chore: uncomment ui package components * fix: without props extensions refactor * fix: merge conflicts resolved from preview * chore: init docker compose * chore: pages custom error codes * chore: add health check endpoint to the live server * chore: update without props extensions type * chore: better error handling * chore: update react-hook-form versions --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com> * fix: docker related fixes * fix: module type fixes * fix: nginx update * fix: adding live server workflow * fix: workflow fixes * fix: docker compose fixes * fix: workflow fixes * fix: path config * fix: docker compose warnings * fix: nginx port forwarding * fix: update docker compose with new env * fix: env var fixes * fix: error handling * fix: docker compose env var * fix: compose fixes * chore: update server start message * chore: handle errors * fix: build errors * chore: update port * chore: update server port * chore: show error on authentication fail * chore: show error on authentication fail * feat: add redis extension * chore: updated restore version logic --------- Co-authored-by: NarayanBavisetti <narayan3119@gmail.com> Co-authored-by: sriram veeraghanta <veeraghanta.sriram@gmail.com> Co-authored-by: Palanikannan M <akashmalinimurugu@gmail.com>
This commit is contained in:
parent
2c950713a7
commit
6c3a8a9647
71 changed files with 4135 additions and 4105 deletions
123
live/src/server.ts
Normal file
123
live/src/server.ts
Normal file
|
|
@ -0,0 +1,123 @@
|
|||
import { Server } from "@hocuspocus/server";
|
||||
import { Redis } from "@hocuspocus/extension-redis";
|
||||
|
||||
import { Database } from "@hocuspocus/extension-database";
|
||||
import { Logger } from "@hocuspocus/extension-logger";
|
||||
import express from "express";
|
||||
import expressWs, { Application } from "express-ws";
|
||||
// page actions
|
||||
import {
|
||||
fetchPageDescriptionBinary,
|
||||
updatePageDescription,
|
||||
} from "./core/lib/page.js";
|
||||
// types
|
||||
import { TDocumentTypes } from "./core/types/common.js";
|
||||
// helpers
|
||||
import { handleAuthentication } from "./core/lib/authentication.js";
|
||||
|
||||
const server = Server.configure({
|
||||
onAuthenticate: async ({
|
||||
requestHeaders,
|
||||
requestParameters,
|
||||
connection,
|
||||
// user id used as token for authentication
|
||||
token,
|
||||
}) => {
|
||||
// request headers
|
||||
const cookie = requestHeaders.cookie?.toString();
|
||||
// params
|
||||
const params = requestParameters;
|
||||
|
||||
if (!cookie) {
|
||||
throw Error("Credentials not provided");
|
||||
}
|
||||
|
||||
try {
|
||||
await handleAuthentication({
|
||||
connection,
|
||||
cookie,
|
||||
params,
|
||||
token,
|
||||
});
|
||||
} catch (error) {
|
||||
throw Error("Authentication unsuccessful!");
|
||||
}
|
||||
},
|
||||
extensions: [
|
||||
new Redis({
|
||||
host: process.env.REDIS_HOST || "localhost",
|
||||
port: Number(process.env.REDIS_PORT || 6379),
|
||||
}),
|
||||
new Logger(),
|
||||
new Database({
|
||||
fetch: async ({
|
||||
documentName: pageId,
|
||||
requestHeaders,
|
||||
requestParameters,
|
||||
}) => {
|
||||
// request headers
|
||||
const cookie = requestHeaders.cookie?.toString();
|
||||
// query params
|
||||
const params = requestParameters;
|
||||
const documentType = params.get("documentType")?.toString() as
|
||||
| TDocumentTypes
|
||||
| undefined;
|
||||
|
||||
return new Promise(async (resolve) => {
|
||||
try {
|
||||
if (documentType === "project_page") {
|
||||
const fetchedData = await fetchPageDescriptionBinary(
|
||||
params,
|
||||
pageId,
|
||||
cookie,
|
||||
);
|
||||
resolve(fetchedData);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in fetching document", error);
|
||||
}
|
||||
});
|
||||
},
|
||||
store: async ({
|
||||
state,
|
||||
documentName: pageId,
|
||||
requestHeaders,
|
||||
requestParameters,
|
||||
}) => {
|
||||
// request headers
|
||||
const cookie = requestHeaders.cookie?.toString();
|
||||
// query params
|
||||
const params = requestParameters;
|
||||
const documentType = params.get("documentType")?.toString() as
|
||||
| TDocumentTypes
|
||||
| undefined;
|
||||
|
||||
return new Promise(async () => {
|
||||
try {
|
||||
if (documentType === "project_page") {
|
||||
await updatePageDescription(params, pageId, state, cookie);
|
||||
}
|
||||
} catch (error) {
|
||||
console.error("Error in updating document", error);
|
||||
}
|
||||
});
|
||||
},
|
||||
}),
|
||||
],
|
||||
});
|
||||
|
||||
const { app }: { app: Application } = expressWs(express());
|
||||
|
||||
app.set("port", process.env.PORT || 3000);
|
||||
|
||||
app.get("/health", (_request, response) => {
|
||||
response.status(200);
|
||||
});
|
||||
|
||||
app.ws("/collaboration", (websocket, request) => {
|
||||
server.handleConnection(websocket, request);
|
||||
});
|
||||
|
||||
app.listen(app.get("port"), () => {
|
||||
console.log("Live server has started at port", app.get("port"));
|
||||
});
|
||||
Loading…
Add table
Add a link
Reference in a new issue