فهرست منبع

refactor(yjs): extract YJS_WEBSOCKET_BASE_PATH constant to @growi/core

Replace hardcoded '/yjs/' path strings across server, client, and vite
config with a shared constant defined in @growi/core/dist/consts.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Yuki Takei 2 هفته پیش
والد
کامیت
c94cbb10ad

+ 3 - 1
apps/app/src/server/service/yjs/upgrade-handler.ts

@@ -1,4 +1,5 @@
 import type { IPage, IUserHasId } from '@growi/core';
+import { YJS_WEBSOCKET_BASE_PATH } from '@growi/core/dist/consts';
 import type { RequestHandler } from 'express';
 import expressSession from 'express-session';
 import type { IncomingMessage, ServerResponse } from 'http';
@@ -40,7 +41,8 @@ const runMiddleware = (
  */
 const extractPageId = (url: string | undefined): string | null => {
   if (url == null) return null;
-  const match = url.match(/^\/yjs\/([a-f0-9]{24})/);
+  const pattern = new RegExp(`^${YJS_WEBSOCKET_BASE_PATH}/([a-f0-9]{24})`);
+  const match = url.match(pattern);
   return match?.[1] ?? null;
 };
 

+ 2 - 2
apps/app/src/server/service/yjs/yjs.ts

@@ -1,5 +1,5 @@
 import type http from 'node:http';
-import { YDocStatus } from '@growi/core/dist/consts';
+import { YDocStatus, YJS_WEBSOCKET_BASE_PATH } from '@growi/core/dist/consts';
 import mongoose from 'mongoose';
 import type { Server } from 'socket.io';
 import { WebSocketServer } from 'ws';
@@ -20,7 +20,7 @@ import { createUpgradeHandler } from './upgrade-handler';
 
 const MONGODB_PERSISTENCE_COLLECTION_NAME = 'yjs-writings';
 const MONGODB_PERSISTENCE_FLUSH_SIZE = 100;
-const YJS_PATH_PREFIX = '/yjs/';
+const YJS_PATH_PREFIX = `${YJS_WEBSOCKET_BASE_PATH}/`;
 
 const logger = loggerFactory('growi:service:yjs');
 

+ 5 - 0
packages/core/src/consts/ydoc-status.ts

@@ -13,3 +13,8 @@ export const YDocStatus = {
   ISOLATED: 'isolated',
 } as const;
 export type YDocStatus = (typeof YDocStatus)[keyof typeof YDocStatus];
+
+/**
+ * The base path for Yjs WebSocket connections.
+ */
+export const YJS_WEBSOCKET_BASE_PATH = '/yjs';

+ 2 - 1
packages/editor/src/client/stores/use-collaborative-editor-mode.ts

@@ -1,5 +1,6 @@
 import { useEffect, useState } from 'react';
 import { keymap } from '@codemirror/view';
+import { YJS_WEBSOCKET_BASE_PATH } from '@growi/core/dist/consts';
 import type { IUserHasId } from '@growi/core/dist/interfaces';
 import { yCollab, yUndoManagerKeymap } from 'y-codemirror.next';
 import { WebsocketProvider } from 'y-websocket';
@@ -54,7 +55,7 @@ export const useCollaborativeEditorMode = (
       }
 
       const wsProtocol = window.location.protocol === 'https:' ? 'wss:' : 'ws:';
-      const serverUrl = `${wsProtocol}//${window.location.host}/yjs`;
+      const serverUrl = `${wsProtocol}//${window.location.host}${YJS_WEBSOCKET_BASE_PATH}`;
 
       _provider = new WebsocketProvider(serverUrl, pageId, primaryDoc, {
         connect: true,

+ 5 - 2
packages/editor/vite.config.ts

@@ -1,4 +1,5 @@
 import path from 'node:path';
+import { YJS_WEBSOCKET_BASE_PATH } from '@growi/core/dist/consts';
 import react from '@vitejs/plugin-react';
 import glob from 'glob';
 import { nodeExternals } from 'rollup-plugin-node-externals';
@@ -6,6 +7,8 @@ import type { Plugin } from 'vite';
 import { defineConfig } from 'vite';
 import dts from 'vite-plugin-dts';
 
+const YJS_PATH_PREFIX = `${YJS_WEBSOCKET_BASE_PATH}/`;
+
 const excludeFiles = [
   '**/components/playground/*',
   '**/main.tsx',
@@ -27,9 +30,9 @@ const devWebSocketPlugin = (): Plugin => ({
 
     server.httpServer.on('upgrade', (request, socket, head) => {
       const url = request.url ?? '';
-      if (!url.startsWith('/yjs/')) return;
+      if (!url.startsWith(YJS_PATH_PREFIX)) return;
 
-      const pageId = url.slice('/yjs/'.length).split('?')[0];
+      const pageId = url.slice(YJS_PATH_PREFIX.length).split('?')[0];
 
       wss.handleUpgrade(request, socket, head, (ws) => {
         wss.emit('connection', ws, request);