leafrelay 0.1.7 → 0.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/README.md +3 -1
- package/README.zh-CN.md +3 -1
- package/dist/chunk-J46L4Q2T.js +5157 -0
- package/dist/chunk-J46L4Q2T.js.map +1 -0
- package/dist/{chunk-MNOPLM7M.js → chunk-PRWBFOB2.js} +187 -132
- package/dist/chunk-PRWBFOB2.js.map +1 -0
- package/dist/cli.js +21 -36
- package/dist/cli.js.map +1 -1
- package/dist/daemon.js +959 -0
- package/dist/daemon.js.map +1 -0
- package/dist/index.d.ts +11 -722
- package/dist/index.js +3 -69
- package/package.json +6 -3
- package/dist/chunk-MNOPLM7M.js.map +0 -1
- package/dist/cli.d.ts +0 -1
package/dist/index.js
CHANGED
|
@@ -1,73 +1,7 @@
|
|
|
1
1
|
import {
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
ExtendedBaseAPI,
|
|
5
|
-
FileSyncStateStore,
|
|
6
|
-
FolderKeys,
|
|
7
|
-
NodeReplicaFileSystem,
|
|
8
|
-
OverleafRealtimeSocket,
|
|
9
|
-
RemoteProject,
|
|
10
|
-
SYNC_STATE_SCHEMA_VERSION,
|
|
11
|
-
SocketIOAPI,
|
|
12
|
-
SyncEngine,
|
|
13
|
-
configPath,
|
|
14
|
-
createIgnoreMatcher,
|
|
15
|
-
createSyncState,
|
|
16
|
-
encodeTextBase,
|
|
17
|
-
error,
|
|
18
|
-
getServerSession,
|
|
19
|
-
log,
|
|
20
|
-
mergeText,
|
|
21
|
-
normalizeServerUrl,
|
|
22
|
-
overleafSocketProtocol,
|
|
23
|
-
parseSyncState,
|
|
24
|
-
readConfig,
|
|
25
|
-
readProjectSettings,
|
|
26
|
-
readTextBase,
|
|
27
|
-
removeSyncCheckpoint,
|
|
28
|
-
saveServerSession,
|
|
29
|
-
serverKey,
|
|
30
|
-
setLogSink,
|
|
31
|
-
sha256,
|
|
32
|
-
startServe,
|
|
33
|
-
updateSyncCheckpoint,
|
|
34
|
-
warn,
|
|
35
|
-
writeConfig
|
|
36
|
-
} from "./chunk-MNOPLM7M.js";
|
|
2
|
+
startServe
|
|
3
|
+
} from "./chunk-J46L4Q2T.js";
|
|
37
4
|
export {
|
|
38
|
-
|
|
39
|
-
DEFAULT_IGNORE_PATTERNS,
|
|
40
|
-
ExtendedBaseAPI,
|
|
41
|
-
FileSyncStateStore,
|
|
42
|
-
FolderKeys,
|
|
43
|
-
NodeReplicaFileSystem,
|
|
44
|
-
OverleafRealtimeSocket,
|
|
45
|
-
RemoteProject,
|
|
46
|
-
SYNC_STATE_SCHEMA_VERSION,
|
|
47
|
-
SocketIOAPI,
|
|
48
|
-
SyncEngine,
|
|
49
|
-
configPath,
|
|
50
|
-
createIgnoreMatcher,
|
|
51
|
-
createSyncState,
|
|
52
|
-
encodeTextBase,
|
|
53
|
-
error,
|
|
54
|
-
getServerSession,
|
|
55
|
-
log,
|
|
56
|
-
mergeText,
|
|
57
|
-
normalizeServerUrl,
|
|
58
|
-
overleafSocketProtocol,
|
|
59
|
-
parseSyncState,
|
|
60
|
-
readConfig,
|
|
61
|
-
readProjectSettings,
|
|
62
|
-
readTextBase,
|
|
63
|
-
removeSyncCheckpoint,
|
|
64
|
-
saveServerSession,
|
|
65
|
-
serverKey,
|
|
66
|
-
setLogSink,
|
|
67
|
-
sha256,
|
|
68
|
-
startServe,
|
|
69
|
-
updateSyncCheckpoint,
|
|
70
|
-
warn,
|
|
71
|
-
writeConfig
|
|
5
|
+
startServe
|
|
72
6
|
};
|
|
73
7
|
//# sourceMappingURL=index.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leafrelay",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.2.0",
|
|
4
4
|
"description": "Reliable two-way synchronization between Overleaf and a local directory.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"overleaf",
|
|
@@ -55,10 +55,13 @@
|
|
|
55
55
|
"mime": "4.1.0",
|
|
56
56
|
"minimatch": "^10.2.6",
|
|
57
57
|
"node-diff3": "^3.2.1",
|
|
58
|
-
"uuid": "^14.0.1"
|
|
58
|
+
"uuid": "^14.0.1",
|
|
59
|
+
"vscode-jsonrpc": "9.0.1"
|
|
59
60
|
},
|
|
60
61
|
"devDependencies": {
|
|
61
|
-
"@leafrelay/core": "0.
|
|
62
|
+
"@leafrelay/core": "0.2.0",
|
|
63
|
+
"@leafrelay/protocol": "0.1.7",
|
|
64
|
+
"@leafrelay/daemon": "0.1.7"
|
|
62
65
|
},
|
|
63
66
|
"scripts": {
|
|
64
67
|
"build": "tsup",
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../core/src/api/base.ts","../../core/src/api/overleafRealtimeSocket.ts","../../core/src/core/logger.ts","../../core/src/api/extendedBase.ts","../../core/src/api/socketio.ts","../../core/src/core/projectTypes.ts","../../core/src/node/config.ts","../../core/src/node/localFileSystem.ts","../../core/src/node/projectSettings.ts","../../core/src/node/serve.ts","../../core/src/sync/ignore.ts","../../core/src/sync/remoteProject.ts","../../core/src/sync/syncEngine.ts","../../core/src/sync/checkpoint.ts","../../core/src/sync/threeWayMerge.ts","../../core/src/node/syncStateStore.ts"],"sourcesContent":["/* eslint-disable @typescript-eslint/naming-convention */\nimport { Blob } from 'node:buffer';\nimport mime from 'mime';\nimport {OverleafRealtimeSocket} from './overleafRealtimeSocket';\nimport { v4 as uuidv4 } from 'uuid';\nimport { FileEntity, FileType, FolderEntity, OutputFileEntity } from '../core/projectTypes';\nimport { log } from '../core/logger';\nimport type { MemberEntity, ProjectSettingsSchema } from '../core/projectTypes';\n\nexport type { MemberEntity, ProjectSettingsSchema } from '../core/projectTypes';\n\n// Overleaf rate limits are applied to the authenticated user, not to a single\n// BaseAPI instance. Keep every HTTP request in one process-wide queue so\n// several projects cannot collectively trigger a burst of 429 responses.\nlet globalRequestChain: Promise<void> = Promise.resolve();\nlet globalNextRequestAt = 0;\nlet globalRateLimitedUntil = 0;\nconst GLOBAL_MIN_REQUEST_INTERVAL_MS = 300;\n\nfunction retryAfterHeaderMs(response: any): number {\n const retryAfter = response.headers?.get?.('retry-after');\n if (retryAfter!==undefined && retryAfter!==null) {\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n return Math.max(1000, seconds*1000);\n }\n const retryAt = Date.parse(retryAfter);\n if (Number.isFinite(retryAt)) { return Math.max(1000, retryAt-Date.now()); }\n }\n return 5000;\n}\n\nasync function queuedFetch(url: string, init: any): Promise<any> {\n const previous = globalRequestChain;\n let release!: () => void;\n globalRequestChain = new Promise<void>(resolve => { release = resolve; });\n await previous;\n try {\n const delayMs = Math.max(\n 0,\n globalNextRequestAt-Date.now(),\n globalRateLimitedUntil-Date.now(),\n );\n if (delayMs>0) { await new Promise(resolve => setTimeout(resolve, delayMs)); }\n globalNextRequestAt = Date.now() + GLOBAL_MIN_REQUEST_INTERVAL_MS;\n const response = await fetch(url, init);\n if (response.status===429) {\n globalRateLimitedUntil = Math.max(globalRateLimitedUntil, Date.now() + retryAfterHeaderMs(response));\n log(`Global HTTP request queue entered rate-limit cooldown until ${new Date(globalRateLimitedUntil).toISOString()}.`);\n }\n return response;\n } finally {\n release();\n }\n}\n\n/** Extract set-cookie headers from an undici/Response object. */\nfunction getSetCookie(res: any): string[] {\n if (typeof res.headers?.getSetCookie === 'function') {\n return res.headers.getSetCookie();\n }\n const raw = res.headers?.raw?.()?.['set-cookie'];\n if (raw) {\n return raw;\n }\n return [];\n}\n\nexport interface Identity {\n csrfToken: string;\n cookies: string;\n}\n\nexport interface NewProjectResponseSchema {\n project_id: string,\n owner_ref: string,\n owner: MemberEntity\n}\n\nexport interface CompileResponseSchema {\n status: 'success' | 'failure' | 'error';\n compileGroup: string;\n clsiServerId?: string;\n pdfDownloadDomain?: string;\n outputFiles: Array<OutputFileEntity>;\n stats: {\n \"latexmk-errors\":number, \"pdf-size\":number,\n \"latex-runs\":number, \"latex-runs-with-errors\":number,\n \"latex-runs-0\":number, \"latex-runs-with-error-0s\":number,\n };\n timings: {\n \"sync\":number, \"compile\":number, \"output\":number, \"compileE2E\":number,\n };\n enableHybridPdfDownload: boolean;\n}\n\nexport interface SyncPdfResponseSchema {\n file: string,\n line: number,\n column: number\n}\n\nexport interface SyncCodeResponseSchema {\n pdf: Array<{\n page: number,\n h: number,\n v: number,\n width: number,\n height: number,\n }>\n}\n\nexport interface SnippetItemSchema {\n meta: string,\n score: number,\n caption: string,\n snippet: string,\n}\n\nexport interface MisspellingItemSchema {\n index: number,\n suggestions: string[]\n}\n\nexport interface MetadataResponseScheme {\n projectId: string,\n projectMeta: {\n [id:string]: {\n labels: string[],\n packages: {[K:string]: SnippetItemSchema[]}\n }\n }\n}\n\nexport interface ProjectPersist {\n id: string;\n userId: string;\n name: string;\n lastUpdated?: string;\n lastUpdatedBy?: MemberEntity;\n source?: 'owner' | 'collaborator' | 'readOnly';\n accessLevel: 'owner' | 'collaborator' | 'readOnly';\n archived?: boolean;\n trashed?: boolean;\n scm?: any; //injected by SCMCollectionProvider\n}\n\nexport interface ProjectTagsResponseSchema {\n __v: number,\n _id: string,\n name: string,\n user_id: string,\n project_ids: string[],\n}\n\nexport interface ProjectLabelResponseSchema {\n id: string,\n comment: string,\n version: string,\n user_id: string,\n created_at: number,\n user_display_name?: string,\n}\n\nexport interface ProjectUpdateMeta {\n users: {id:string, first_name:string, last_name?:string, email:string}[],\n start_ts: number,\n end_ts: number,\n}\n\nexport interface ProjectHistoryResponseSchema {\n fromV: number,\n toV: number,\n meta: ProjectUpdateMeta,\n labels: ProjectLabelResponseSchema[],\n pathnames: string[],\n project_ops:{\n add?: {pathname:string},\n remove?: {pathname:string},\n atV: number,\n }[],\n}\n\nexport interface ProjectUpdateResponseSchema {\n updates: ProjectHistoryResponseSchema[],\n nextBeforeTimestamp: number,\n}\n\nexport interface ProjectFileDiffResponseSchema {\n diff: {\n u?: string, d?: string, i?: string,\n meta?: ProjectUpdateMeta,\n }[]\n}\n\nexport interface ProjectFileTreeDiffResponseSchema {\n diff: {\n pathname: string,\n newPathname?: string,\n operation?: 'edited' | 'added' | 'removed' | 'renamed',\n deletedAtV?: number,\n }[]\n}\n\nexport interface ProjectMessageResponseSchema {\n id: string,\n content: string,\n timestamp: number,\n user_id: string,\n user: {id:string, first_name:string, last_name?:string, email:string},\n clientId: string,\n}\n\nexport interface ResponseSchema {\n type: 'success' | 'error';\n statusCode?: number;\n raw?: ArrayBuffer;\n message?: string;\n userInfo?: {userId:string, userEmail:string};\n identity?: Identity;\n projects?: ProjectPersist[];\n entity?: FileEntity;\n entities?: {path:string, type:string}[];\n compile?: CompileResponseSchema;\n content?: Uint8Array;\n syncPdf?: SyncPdfResponseSchema;\n syncCode?: SyncCodeResponseSchema;\n meta?: MetadataResponseScheme;\n misspellings?: MisspellingItemSchema[];\n tags?: ProjectTagsResponseSchema[];\n labels?: ProjectLabelResponseSchema[];\n updates?: ProjectUpdateResponseSchema;\n diff?: ProjectFileDiffResponseSchema;\n treeDiff?: ProjectFileTreeDiffResponseSchema;\n messages?: ProjectMessageResponseSchema[];\n settings?: ProjectSettingsSchema;\n}\n\nexport class BaseAPI {\n private url: string;\n private identity?: Identity;\n private historyRequestChain: Promise<void> = Promise.resolve();\n private lastHistoryRequestAt = 0;\n\n private isHistoryRoute(route: string): boolean {\n return route.includes('/updates?') || route.includes('/filetree/diff?') || route.includes('/diff?');\n }\n\n private async waitForHistoryRequest() {\n const previous = this.historyRequestChain;\n let release!: () => void;\n this.historyRequestChain = new Promise<void>(resolve => { release = resolve; });\n await previous;\n try {\n const minimumIntervalMs = 3000;\n const delayMs = Math.max(0, minimumIntervalMs - (Date.now() - this.lastHistoryRequestAt));\n if (delayMs>0) {\n await new Promise(resolve => setTimeout(resolve, delayMs));\n }\n this.lastHistoryRequestAt = Date.now();\n } finally {\n release();\n }\n }\n\n private retryAfterMs(response: any, attempt: number): number {\n const retryAfter = response.headers?.get?.('retry-after');\n if (retryAfter!==undefined && retryAfter!==null) {\n const seconds = Number(retryAfter);\n if (Number.isFinite(seconds)) {\n return Math.max(1000, seconds*1000);\n }\n const retryAt = Date.parse(retryAfter);\n if (Number.isFinite(retryAt)) {\n return Math.max(1000, retryAt-Date.now());\n }\n }\n return 5000 * Math.pow(2, attempt);\n }\n\n constructor(url:string) {\n this.url = url;\n }\n\n private async getCsrfToken(): Promise<Identity> {\n const res = await queuedFetch(this.url+'login', {\n method: 'GET', redirect: 'manual',\n });\n const body = await res.text();\n const match = body.match(/<input.*name=\"_csrf\".*value=\"([^\"]*)\">/);\n if (!match) {\n throw new Error('Failed to get CSRF token.');\n } else {\n const csrfToken = match[1];\n const cookies = getSetCookie(res)[0]?.split(';')[0] ?? '';\n return { csrfToken, cookies };\n }\n }\n\n private async getUserId(cookies:string) {\n const res = await queuedFetch(this.url+'project', {\n method: 'GET', redirect:'manual',\n headers: {\n 'Connection': 'keep-alive',\n 'Cookie': cookies,\n }\n });\n\n const body = await res.text();\n const userIDMatch = body.match(/<meta\\s+name=\"ol-user_id\"\\s+content=\"([^\"]*)\">/);\n const userEmailMatch = body.match(/<meta\\s+name=\"ol-usersEmail\"\\s+content=\"([^\"]*)\">/);\n const csrfTokenMatch = body.match(/<meta\\s+name=\"ol-csrfToken\"\\s+content=\"([^\"]*)\">/);\n if (userIDMatch!==null && csrfTokenMatch!==null) {\n const userId = userIDMatch[1];\n const csrfToken = csrfTokenMatch[1];\n const userEmail = userEmailMatch ? userEmailMatch[1] : '';\n return {userId, userEmail, csrfToken};\n } else {\n return undefined;\n }\n }\n\n // Reference: \"github:overleaf/overleaf/services/web/frontend/js/ide/connection/ConnectionManager.js#L137\"\n _initSocketV0(identity:Identity, query?:string) {\n const url = new URL(this.url).origin + (query ?? '');\n return new OverleafRealtimeSocket(url, {\n origin:new URL(this.url).origin,\n cookie:identity.cookies,\n reconnect: true,\n reconnectionDelay:1000,\n reconnectionLimit:16000,\n maxReconnectionAttempts:10,\n });\n }\n\n async passportLogin(email:string, password:string): Promise<ResponseSchema> {\n const identity = await this.getCsrfToken();\n const res = await queuedFetch(this.url+'login', {\n method: 'POST', redirect: 'manual',\n headers: {\n 'Accept': '*/*',\n 'Accept-Encoding': 'gzip, deflate, br',\n 'Connection': 'keep-alive',\n 'Content-Type': 'application/json',\n 'Cookie': identity.cookies,\n 'X-Csrf-Token': identity.csrfToken,\n },\n body: JSON.stringify({ _csrf: identity.csrfToken, email: email, password: password })\n });\n\n if (res.status===302) {\n const redirect = ((await res.text()).match(/Found. Redirecting to (.*)/) as any)[1];\n if (redirect==='/project') {\n const cookies = getSetCookie(res)[0] ?? '';\n return (await this.cookiesLogin(cookies));\n } else {\n return {\n type: 'error',\n message: `Redirecting to /${redirect}`\n };\n }\n }\n else if (res.status===200) {\n return {\n type: 'error',\n message: (await res.json() as any).message.message\n };\n } else if (res.status===401) {\n return {\n type: 'error',\n message: (await res.json() as any).message.text\n };\n } else {\n return {\n type: 'error',\n message: `${res.status}: `+await res.text()\n };\n }\n }\n\n async cookiesLogin(cookies: string): Promise<ResponseSchema> {\n const res = await this.getUserId(cookies);\n if (res) {\n const { userId, userEmail, csrfToken } = res;\n const identity: Identity = await this.updateCookies({ cookies, csrfToken });\n return {\n type: 'success',\n userInfo: {userId, userEmail},\n identity: identity\n };\n } else {\n return {\n type: 'error',\n message: 'Failed to get User ID.'\n };\n }\n }\n\n async updateCookies(identity: Identity) {\n const res = await queuedFetch(this.url + 'socket.io/socket.io.js', {\n method: 'GET',\n redirect: 'manual',\n headers: {\n 'Connection': 'keep-alive',\n 'Cookie': identity.cookies,\n }\n });\n const cookies = getSetCookie(res)[0]?.split(';')[0];\n if (cookies) {\n identity.cookies = `${identity.cookies}; ${cookies}`;\n }\n return identity;\n };\n\n setIdentity(identity: Identity) {\n this.identity = identity;\n return this;\n }\n\n /**\n * Check if an HTTP error is transient (worth retrying).\n * Retries on: 5xx server errors, network errors (fetch failures), and 429 rate limiting.\n */\n private isTransientError(statusCode: number | undefined, errorMessage?: string): boolean {\n if (statusCode === undefined) {\n // Network-level error (DNS, connection refused, reset, timeout)\n return true;\n }\n // Server errors and rate limiting\n if (statusCode >= 500 || statusCode === 429) {\n return true;\n }\n // Common transient network error messages\n if (errorMessage && (\n errorMessage.includes('ECONNRESET') ||\n errorMessage.includes('ETIMEDOUT') ||\n errorMessage.includes('ECONNREFUSED') ||\n errorMessage.includes('ENOTFOUND') ||\n errorMessage.includes('socket hang up')\n )) {\n return true;\n }\n return false;\n }\n\n protected async request(type:'GET'|'POST'|'PUT'|'DELETE', route:string, body?:FormData|object, callback?: (res?:string)=>object|undefined, extraHeaders?:object ): Promise<ResponseSchema> {\n if (this.identity===undefined) { return Promise.reject(); }\n\n const MAX_HTTP_RETRIES = 2;\n let lastError: {statusCode?: number, message?: string} = {};\n\n for (let attempt = 0; attempt <= MAX_HTTP_RETRIES; attempt++) {\n try {\n if (this.isHistoryRoute(route)) {\n await this.waitForHistoryRequest();\n }\n let res = undefined;\n switch(type) {\n case 'GET':\n res = await queuedFetch(this.url+route, {\n method: 'GET', redirect: 'manual',\n headers: {\n 'Connection': 'keep-alive',\n 'Cookie': this.identity!.cookies,\n ...extraHeaders\n }\n });\n break;\n case 'POST':\n const content_type = body instanceof FormData ? undefined : {'Content-Type': 'application/json'};\n const raw_body = body instanceof FormData ? body : JSON.stringify({\n _csrf: this.identity!.csrfToken,\n ...body\n });\n res = await queuedFetch(this.url+route, {\n method: 'POST', redirect: 'manual',\n headers: {\n 'Connection': 'keep-alive',\n 'Cookie': this.identity!.cookies,\n ...content_type,\n ...extraHeaders\n },\n body: raw_body\n });\n break;\n case 'PUT':\n break;\n case 'DELETE':\n res = await queuedFetch(this.url+route, {\n method: 'DELETE', redirect: 'manual',\n headers: {\n 'Connection': 'keep-alive',\n 'Cookie': this.identity!.cookies,\n 'X-Csrf-Token': this.identity!.csrfToken,\n ...extraHeaders\n }\n });\n break;\n };\n\n if (res && (res.status===200 || res.status===204)) {\n const _res = res.status===200 ? await res.text() : undefined;\n const response = callback && callback(_res);\n return {\n type: 'success',\n ...response\n } as ResponseSchema;\n } else if (res && this.isTransientError(res.status) && attempt < MAX_HTTP_RETRIES) {\n // Transient error: retry with backoff\n const delayMs = res.status===429 ? this.retryAfterMs(res, attempt) : Math.min(1000 * Math.pow(2, attempt), 4000);\n log(`HTTP ${res.status} on ${route}, retrying in ${delayMs}ms (attempt ${attempt + 1}/${MAX_HTTP_RETRIES})`);\n lastError = {statusCode: res.status, message: await res.text().catch(() => '')};\n await new Promise(r => setTimeout(r, delayMs));\n continue;\n } else {\n const resOrFallback = res || { status:'undefined', text: async () => '' };\n let errorBody = '';\n try { errorBody = await resOrFallback.text(); } catch { errorBody = ''; }\n return {\n type: 'error',\n statusCode: typeof resOrFallback.status==='number' ? resOrFallback.status : undefined,\n message: `${resOrFallback.status}: ${errorBody}`\n };\n }\n } catch (err: any) {\n const errMsg = err?.message || String(err);\n if (this.isTransientError(undefined, errMsg) && attempt < MAX_HTTP_RETRIES) {\n const delayMs = Math.min(1000 * Math.pow(2, attempt), 4000);\n log(`HTTP fetch error on ${route}: ${errMsg}, retrying in ${delayMs}ms (attempt ${attempt + 1}/${MAX_HTTP_RETRIES})`);\n await new Promise(r => setTimeout(r, delayMs));\n continue;\n }\n return {\n type: 'error',\n statusCode: undefined,\n message: errMsg\n };\n }\n }\n\n // All retries exhausted\n return {\n type: 'error',\n statusCode: lastError.statusCode,\n message: lastError.message || `Request failed after ${MAX_HTTP_RETRIES + 1} attempts`\n };\n }\n\n protected async download(route:string) {\n if (this.identity===undefined) { return Promise.reject(); }\n\n let content: Buffer[] = [];\n while(true) {\n const res = await queuedFetch(this.url+route, {\n method: 'GET', redirect: 'manual',\n headers: {\n 'Connection': 'keep-alive',\n 'Cookie': this.identity.cookies,\n }\n });\n if (res.status===200) {\n content.push(Buffer.from(await res.arrayBuffer()));\n break;\n }\n else if (res.status===206) {\n content.push(Buffer.from(await res.arrayBuffer()));\n } else {\n break;\n }\n };\n\n return Buffer.concat(content);\n }\n\n async logout(identity:Identity): Promise<ResponseSchema> {\n this.setIdentity(identity);\n return this.request('POST', 'logout');\n }\n\n async userProjectsJson(identity:Identity): Promise<ResponseSchema> {\n this.setIdentity(identity);\n return this.request('GET', 'user/projects', undefined, (res) => {\n const projects = (JSON.parse(res!) as any).projects as any[];\n projects.forEach(project => {\n project.id = project._id;\n delete project._id;\n });\n return {projects};\n });\n }\n\n async getProjectsJson(identity:Identity): Promise<ResponseSchema> {\n this.setIdentity(identity);\n return this.request('POST', 'api/project', {}, (res) => {\n const projects = (JSON.parse(res!) as any).projects;\n return {projects};\n });\n }\n\n async projectEntitiesJson(identity:Identity, projectId:string): Promise<ResponseSchema> {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/entities`, undefined, (res) => {\n const entities = JSON.parse(res!).entities;\n return {entities};\n });\n }\n\n async newProject(identity:Identity, projectName:string, template:'none'|'example') {\n this.setIdentity(identity);\n return this.request('POST', 'project/new', {projectName, template}, (res) => {\n const message = (JSON.parse(res!) as NewProjectResponseSchema).project_id;\n return {message};\n });\n }\n\n async cloneProject(identity:Identity, projectId:string, projectName:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/clone`, {projectName}, (res) => {\n const message = (JSON.parse(res!) as NewProjectResponseSchema).project_id;\n return {message};\n });\n }\n\n async renameProject(identity:Identity, projectId:string, newProjectName:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/rename`, {newProjectName});\n }\n\n async deleteProject(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `project/${projectId}`);\n }\n\n async archiveProject(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/archive`,\n undefined, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async unarchiveProject(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `project/${projectId}/archive`);\n }\n\n async trashProject(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/trash`,\n undefined, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async untrashProject(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `project/${projectId}/trash`);\n }\n\n async getFile(identity:Identity, projectId:string, fileId:string) {\n this.setIdentity(identity);\n const content = await this.download(`project/${projectId}/file/${fileId}`);\n return {\n type: 'success',\n content: new Uint8Array( content )\n };\n }\n\n async addDoc(identity:Identity, projectId:string, parentFolderId:string, filename:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/doc`, {parent_folder_id:parentFolderId, name:filename}, (res) => {\n const {_id} = JSON.parse(res!) as any;\n const entity = {_type:'doc', _id, name:filename} as FileEntity;\n return {entity};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async uploadFile(identity:Identity, projectId:string, parentFolderId:string, filename:string, fileContent:Uint8Array) {\n const formData = new FormData();\n const mimeType = mime.getType(filename);\n formData.append('targetFolderId', parentFolderId);\n formData.append('name', filename);\n formData.append('type', mimeType? mimeType : 'text/plain');\n formData.append('qqfile', new Blob([Buffer.from(fileContent)], {\n type: mimeType ? mimeType : 'application/octet-stream',\n }), filename);\n\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/upload?folder_id=${parentFolderId}`, formData, (res) => {\n const {success, entity_id, entity_type} = JSON.parse(res!) as any;\n const entity = {_type:entity_type, _id:entity_id, name:filename} as FileEntity;\n return {entity};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async uploadProject(identity:Identity, filename:string, fileContent:Uint8Array) {\n const uuid = uuidv4();\n const formData = new FormData();\n formData.append('qqfile', new Blob([Buffer.from(fileContent)], {\n type: 'application/zip',\n }), filename);\n\n this.setIdentity(identity);\n return this.request('POST', `project/new/upload?_csrf=${identity.csrfToken}&qquuid=${uuid}&qqfilename=${filename}&qqtotalfilesize=${fileContent.length}`, formData, (res) => {\n const message = (JSON.parse(res!) as NewProjectResponseSchema).project_id;\n return {message};\n });\n }\n\n async addFolder(identity:Identity, projectId:string, folderName:string, parentFolderId:string) {\n const body = { name: folderName, parent_folder_id: parentFolderId };\n\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/folder`, body, (res) => {\n const entity = JSON.parse(res!) as FolderEntity;\n return {entity};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async deleteEntity(identity:Identity, projectId:string, fileType:FileType, fileId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `project/${projectId}/${fileType}/${fileId}`);\n }\n\n async deleteAuxFiles(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `project/${projectId}/output`);\n }\n\n async renameEntity(identity:Identity, projectId:string, entityType:string, entityId:string, name:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/${entityType}/${entityId}/rename`,\n {name}, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async moveEntity(identity:Identity, projectId:string, entityType:string, entityId:string, newParentFolderId:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/${entityType}/${entityId}/move`,\n {folder_id:newParentFolderId}, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async compile(identity:Identity, projectId:string, rootResourcePath:string|null,\n draft:boolean=false, stopOnFirstError:boolean=false\n ) {\n const body = {\n check: 'silent',\n draft,\n incrementalCompilesEnabled: true,\n rootResourcePath, // file path e.g. \"main.tex\"\n stopOnFirstError\n };\n\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/compile?auto_compile=true`, body, (res) => {\n const compile = JSON.parse(res!) as CompileResponseSchema;\n return {compile};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async stopCompile(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/compile/stop`, undefined, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async indexAll(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/references/indexAll`, {shouldBroadcast: false}, undefined);\n }\n\n async getMetadata(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/metadata`, undefined, (res) => {\n const meta = JSON.parse(res!) as MetadataResponseScheme;\n return {meta};\n });\n }\n\n async proxyRequestToSpellingApi(identity:Identity, language:string, userId:string, words: string[]) {\n const body = {\n language,\n skipLearnedWords: true,\n token: userId,\n words\n };\n\n this.setIdentity(identity);\n return this.request('POST', 'spelling/check', body, (res) => {\n const misspellings = JSON.parse(res!).misspellings as MisspellingItemSchema[];\n return {misspellings};\n });\n }\n\n async spellingControllerLearn(identity:Identity, userId:string, word: string) {\n const body = {\n token: userId,\n word\n };\n\n this.setIdentity(identity);\n return this.request('POST', 'spelling/learn', body);\n }\n\n async spellingControllerUnlearn(identity:Identity, word: string) {\n this.setIdentity(identity);\n return this.request('POST', 'spelling/unlearn', {word}, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async getProjectSettings(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}`, undefined, (res) => {\n const body = res || '';\n // parse \"ol-learnedWords\"\n const learnedWordsMatch = /<meta\\s+name=\"ol-learnedWords\"\\s+data-type=\"json\"\\s+content=\"(\\[.*?\\])\">/.exec(body);\n const learnedWords = (learnedWordsMatch!==null) ? JSON.parse(learnedWordsMatch[1].replace(/"/g, '\"')) : [];\n // parse \"ol-languages\"\n const languagesMatch = /<meta\\s+name=\"ol-languages\"\\s+data-type=\"json\"\\s+content=\"(\\[.*?\\])\">/.exec(body);\n const languages = (languagesMatch!==null) ? JSON.parse(languagesMatch[1].replace(/"/g, '\"')) as {code:string,name:string}[] : [];\n languages.length && languages.unshift({name:'Off', code:''});\n // fill in compilers\n const compilers = [\n {code: 'pdflatex', name: 'pdfLaTex'},\n {code: 'latex', name: 'LaTex'},\n {code: 'xelatex', name: 'XeLaTex'},\n {code: 'lualatex', name: 'LuaLaTex'},\n ];\n // return parsed results\n const settings = {learnedWords, languages, compilers} as ProjectSettingsSchema;\n return {settings};\n });\n }\n\n async updateProjectSettings(identity:Identity, projectId:string, setting:any) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/settings`, setting);\n }\n\n async getFileFromClsi(identity:Identity, url:string, compileGroup:string, clsiServerId?:string, pdfDownloadDomain?:string) {\n // If we have a CDN download domain, construct the full URL with required query params.\n // The CDN is cross-origin, so we must NOT send web frontend cookies.\n if (pdfDownloadDomain && clsiServerId) {\n const cdnUrl = `${pdfDownloadDomain.replace(/\\/+$/, '')}/${url.replace(/^\\/+/g, '')}` +\n `?compileGroup=${encodeURIComponent(compileGroup)}` +\n `&clsiserverid=${encodeURIComponent(clsiServerId)}` +\n `&enable_pdf_caching=true`;\n const content = await this._downloadAbsolute(cdnUrl, false);\n return { type: 'success', content: new Uint8Array(content) };\n }\n\n // Fallback: download from web frontend (legacy path)\n url = url.replace(/^\\/+/g, '');\n this.setIdentity(identity);\n const content = await this.download(url);\n return {\n type: 'success',\n content: new Uint8Array( content )\n };\n }\n\n /** Download from an absolute URL, optionally including web frontend cookies. */\n private async _downloadAbsolute(absoluteUrl: string, includeCookies: boolean): Promise<Buffer> {\n const headers: Record<string, string> = {\n 'Connection': 'keep-alive',\n };\n if (includeCookies && this.identity) {\n headers['Cookie'] = this.identity.cookies;\n }\n let content: Buffer[] = [];\n while (true) {\n const res = await queuedFetch(absoluteUrl, {\n method: 'GET', redirect: 'manual',\n headers\n });\n if (res.status === 200) {\n content.push(Buffer.from(await res.arrayBuffer()));\n break;\n } else if (res.status === 206) {\n content.push(Buffer.from(await res.arrayBuffer()));\n } else {\n break;\n }\n }\n return Buffer.concat(content);\n }\n\n async proxySyncPdf(identity:Identity, projectId:string, page:number, h:number, v:number, buildId:string) {\n this.setIdentity(identity);\n const request = `project/${projectId}/sync/pdf?page=${page}&h=${h.toFixed(2)}&v=${v.toFixed(2)}&editorId=${uuidv4()}&buildId=${buildId}`;\n return this.request('GET', `project/${projectId}/sync/pdf?page=${page}&h=${h.toFixed(2)}&v=${v.toFixed(2)}&editorId=${uuidv4()}&buildId=${buildId}`,\n undefined, (res) => {\n const syncPdf = (JSON.parse(res!) as any).code[0] as SyncPdfResponseSchema;\n return {syncPdf};\n });\n }\n\n async proxySyncCode(identity:Identity, projectId:string, file:string, line:number, column:number, buildId:string) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/sync/code?file=${file}&line=${line}&column=${column}&editorId=${uuidv4()}&buildId=${buildId}`,\n undefined, (res) => {\n const syncCode = (JSON.parse(res!) as any).pdf as SyncCodeResponseSchema;\n return {syncCode};\n });\n }\n\n async getAllTags(identity:Identity) {\n this.setIdentity(identity);\n return this.request('GET', 'tag', undefined, (res) => {\n const tags = JSON.parse(res!) as ProjectTagsResponseSchema[];\n return {tags};\n });\n }\n\n async createTag(identity:Identity, name:string) {\n this.setIdentity(identity);\n return this.request('POST', 'tag', {name}, (res) => {\n const tags = JSON.parse(res!) as ProjectTagsResponseSchema[];\n return {tags};\n });\n }\n\n async renameTag(identity:Identity, tagId:string, name:string) {\n this.setIdentity(identity);\n return this.request('POST', `tag/${tagId}/rename`, {name});\n }\n\n async deleteTag(identity:Identity, tagId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `tag/${tagId}`);\n }\n\n async addProjectToTag(identity:Identity, tagId:string, projectId:string) {\n this.setIdentity(identity);\n return this.request('POST', `tag/${tagId}/project/${projectId}`);\n }\n\n async removeProjectFromTag(identity:Identity, tagId:string, projectId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `tag/${tagId}/project/${projectId}`);\n }\n\n async proxyToHistoryApiAndGetUpdates(identity:Identity, projectId:string, before?:number) {\n const beforeQuery = before? `&before=${before}` : '';\n\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/updates?min_count=10${beforeQuery}`, undefined, (res) => {\n const updates = JSON.parse(res!) as ProjectUpdateResponseSchema;\n return {updates};\n });\n }\n\n async proxyToHistoryApiAndGetFileDiff(identity:Identity, projectId:string, pathname:string, from:number, to:number) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/diff?pathname=${pathname}&from=${from}&to=${to}`, undefined, (res) => {\n const diff = JSON.parse(res!) as ProjectFileDiffResponseSchema;\n return {diff};\n });\n }\n\n async proxyToHistoryApiAndGetFileTreeDiff(identity:Identity, projectId:string, from:number, to:number) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/filetree/diff?from=${from}&to=${to}`, undefined, (res) => {\n const treeDiff = JSON.parse(res!) as ProjectFileTreeDiffResponseSchema;\n return {treeDiff};\n });\n }\n\n async downloadZipOfVersion(identity:Identity, projectId:string, version:number) {\n this.setIdentity(identity);\n const content = await this.download(`project/${projectId}/version/${version}/zip`);\n return {\n type: 'success',\n content: new Uint8Array(content)\n };\n }\n\n async getLabels(identity:Identity, projectId:string) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/labels`, undefined, (res) => {\n const labels = JSON.parse(res!) as ProjectLabelResponseSchema[];\n return {labels};\n });\n }\n\n async createLabel(identity:Identity, projectId:string, comment:string, version:number) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/labels`, {comment, version}, (res) => {\n const labels = [JSON.parse(res!)] as ProjectLabelResponseSchema[];\n return {labels};\n });\n }\n\n async deleteLabel(identity:Identity, projectId:string, labelId:string) {\n this.setIdentity(identity);\n return this.request('DELETE', `project/${projectId}/labels/${labelId}`);\n }\n\n async getMessages(identity:Identity, projectId:string, limit:number=50) {\n this.setIdentity(identity);\n return this.request('GET', `project/${projectId}/messages?limit=${limit}`, undefined, (res) => {\n const messages = JSON.parse(res!) as ProjectMessageResponseSchema[];\n return {messages};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async sendMessage(identity:Identity, projectId:string, client_id:string, content:string) {\n this.setIdentity(identity);\n return this.request('POST', `project/${projectId}/messages`, {client_id, content}, undefined, {'X-Csrf-Token': identity.csrfToken});\n }\n}\n","import {EventEmitter} from 'node:events';\n\nconst PACKET_TYPES = [\n 'disconnect',\n 'connect',\n 'heartbeat',\n 'message',\n 'json',\n 'event',\n 'ack',\n 'error',\n 'noop',\n] as const;\n\ntype PacketType = typeof PACKET_TYPES[number];\n\ninterface SocketPacket {\n type?: PacketType;\n id?: string;\n ack?: true | 'data';\n endpoint?: string;\n name?: string;\n args?: unknown[];\n data?: unknown;\n ackId?: string;\n reason?: string;\n advice?: string;\n}\n\nexport interface OverleafRealtimeSocketOptions {\n origin: string;\n cookie: string;\n reconnect?: boolean;\n reconnectionDelay?: number;\n reconnectionLimit?: number;\n maxReconnectionAttempts?: number;\n}\n\nfunction encodePacket(packet: SocketPacket): string {\n const type = PACKET_TYPES.indexOf(packet.type ?? 'noop');\n const id = packet.id ?? '';\n let data: string | undefined;\n\n switch (packet.type) {\n case 'event':\n data = JSON.stringify({name:packet.name, args:packet.args ?? []});\n break;\n case 'ack':\n data = `${packet.ackId ?? ''}${packet.args?.length ? `+${JSON.stringify(packet.args)}` : ''}`;\n break;\n case 'message':\n data = String(packet.data ?? '');\n break;\n case 'json':\n data = JSON.stringify(packet.data);\n break;\n default:\n break;\n }\n\n const fields = [String(type), `${id}${packet.ack==='data' ? '+' : ''}`, packet.endpoint ?? ''];\n if (data!==undefined) { fields.push(data); }\n return fields.join(':');\n}\n\nfunction decodePacket(value: string): SocketPacket {\n const match = value.match(/([^:]+):([0-9]+)?(\\+)?:([^:]+)?:?([\\s\\S]*)?/);\n if (!match) { return {}; }\n\n const packet:SocketPacket = {\n type:PACKET_TYPES[Number(match[1])],\n endpoint:match[4] || '',\n };\n if (match[2]) {\n packet.id = match[2];\n packet.ack = match[3] ? 'data' : true;\n }\n\n const data = match[5] || '';\n switch (packet.type) {\n case 'event': {\n const event = JSON.parse(data) as {name:string; args?:unknown[]};\n packet.name = event.name;\n packet.args = event.args ?? [];\n break;\n }\n case 'ack': {\n const ack = data.match(/^([0-9]+)(\\+)?([\\s\\S]*)/);\n if (ack) {\n packet.ackId = ack[1];\n packet.args = ack[3] ? JSON.parse(ack[3]) as unknown[] : [];\n }\n break;\n }\n case 'error': {\n const [reason, advice] = data.split('+');\n packet.reason = ['transport not supported', 'client not handshaken', 'unauthorized'][Number(reason)] ?? '';\n packet.advice = ['reconnect'][Number(advice)] ?? '';\n break;\n }\n case 'json':\n packet.data = JSON.parse(data);\n break;\n case 'message':\n packet.data = data;\n break;\n default:\n break;\n }\n return packet;\n}\n\nfunction decodePayload(value: string): SocketPacket[] {\n if (!value.startsWith('\\ufffd')) { return [decodePacket(value)]; }\n const packets:SocketPacket[] = [];\n let offset = 1;\n while (offset<value.length) {\n const separator = value.indexOf('\\ufffd', offset);\n if (separator===-1) { break; }\n const length = Number(value.slice(offset, separator));\n const start = separator+1;\n packets.push(decodePacket(value.slice(start, start+length)));\n offset = start+length+1;\n }\n return packets;\n}\n\nfunction mergeCookies(current: string, additions: string[]): string {\n const cookies = new Map<string, string>();\n for (const value of [current, ...additions.map(cookie => cookie.split(';', 1)[0])]) {\n for (const part of value.split(';')) {\n const separator = part.indexOf('=');\n if (separator===-1) { continue; }\n cookies.set(part.slice(0, separator).trim(), part.slice(separator+1).trim());\n }\n }\n return [...cookies].map(([name, value]) => `${name}=${value}`).join('; ');\n}\n\nexport class OverleafRealtimeSocket {\n private readonly events = new EventEmitter();\n private readonly endpoint: URL;\n private readonly origin: string;\n private cookie: string;\n private socket?: WebSocket;\n private connected = false;\n private explicitlyDisconnected = false;\n private reconnectEnabled: boolean;\n private reconnectAttempts = 0;\n private reconnectTimer?: NodeJS.Timeout;\n private inactivityTimer?: NodeJS.Timeout;\n private closeTimeoutMs = 60_000;\n private acknowledgementId = 0;\n private readonly acknowledgements = new Map<string, (...args:unknown[]) => void>();\n private readonly sendBuffer: string[] = [];\n\n readonly io = {\n reconnect:(enabled:boolean) => {\n this.reconnectEnabled = enabled;\n if (!enabled && this.reconnectTimer) {\n clearTimeout(this.reconnectTimer);\n this.reconnectTimer = undefined;\n }\n },\n };\n\n constructor(url: string, private readonly options: OverleafRealtimeSocketOptions) {\n this.endpoint = new URL(url);\n this.origin = options.origin;\n this.cookie = options.cookie;\n this.reconnectEnabled = options.reconnect ?? true;\n void this.connect();\n }\n\n on(event: string, handler: (...args:any[]) => void): this {\n this.events.on(event, handler);\n return this;\n }\n\n once(event: string, handler: (...args:any[]) => void): this {\n this.events.once(event, handler);\n return this;\n }\n\n removeListener(event: string, handler: (...args:any[]) => void): this {\n this.events.removeListener(event, handler);\n return this;\n }\n\n removeAllListeners(event?: string): this {\n this.events.removeAllListeners(event);\n return this;\n }\n\n emit(event: string, ...args:any[]): this {\n const callback = typeof args.at(-1)==='function' ? args.pop() as (...values:unknown[]) => void : undefined;\n const id = callback ? String(++this.acknowledgementId) : undefined;\n if (id && callback) { this.acknowledgements.set(id, callback); }\n this.send(encodePacket({\n type:'event',\n id,\n ack:callback ? 'data' : undefined,\n name:event,\n args,\n }));\n return this;\n }\n\n disconnect(): this {\n this.explicitlyDisconnected = true;\n this.reconnectEnabled = false;\n if (this.reconnectTimer) { clearTimeout(this.reconnectTimer); }\n if (this.connected) { this.send(encodePacket({type:'disconnect'})); }\n this.closeSocket('booted');\n return this;\n }\n\n private async connect(): Promise<void> {\n try {\n const handshakeUrl = new URL('/socket.io/1/', this.endpoint.origin);\n for (const [name, value] of this.endpoint.searchParams) {\n handshakeUrl.searchParams.set(name, value);\n }\n handshakeUrl.searchParams.set('t', String(Date.now()));\n const response = await fetch(handshakeUrl, {\n headers:{origin:this.origin, cookie:this.cookie},\n redirect:'manual',\n });\n if (!response.ok) {\n throw new Error(`Socket.IO handshake failed: HTTP ${response.status} ${await response.text()}`);\n }\n const setCookies = response.headers.getSetCookie?.() ?? [];\n this.cookie = mergeCookies(this.cookie, setCookies);\n const [sessionId, heartbeatTimeout, closeTimeout, transports] = (await response.text()).split(':');\n if (!sessionId || !transports?.split(',').includes('websocket')) {\n throw new Error('Overleaf did not offer a Socket.IO WebSocket transport.');\n }\n this.closeTimeoutMs = Math.max(Number(heartbeatTimeout), Number(closeTimeout), 10)*1000;\n\n const websocketUrl = new URL(`/socket.io/1/websocket/${sessionId}`, this.endpoint.origin);\n websocketUrl.protocol = websocketUrl.protocol==='https:' ? 'wss:' : 'ws:';\n websocketUrl.search = this.endpoint.search;\n this.socket = new WebSocket(websocketUrl, {\n headers:{origin:this.origin, cookie:this.cookie},\n });\n this.socket.addEventListener('open', () => this.events.emit('connecting', 'websocket'));\n this.socket.addEventListener('message', event => void this.receive(event.data));\n this.socket.addEventListener('error', error => this.events.emit('error', error));\n this.socket.addEventListener('close', () => this.handleClose());\n } catch (error) {\n this.events.emit('connect_failed', error);\n this.events.emit('error', error);\n this.scheduleReconnect();\n }\n }\n\n private async receive(data: unknown) {\n this.resetInactivityTimer();\n const value = typeof data==='string'\n ? data\n : data instanceof Blob\n ? await data.text()\n : Buffer.from(data as ArrayBuffer).toString('utf8');\n for (const packet of decodePayload(value)) { this.handlePacket(packet); }\n }\n\n private handlePacket(packet: SocketPacket) {\n switch (packet.type) {\n case 'connect': {\n const wasReconnecting = this.reconnectAttempts>0;\n this.connected = true;\n this.events.emit('connect');\n this.flush();\n if (wasReconnecting) {\n this.events.emit('reconnect', 'websocket', this.reconnectAttempts);\n this.reconnectAttempts = 0;\n }\n break;\n }\n case 'heartbeat':\n this.send(encodePacket({type:'heartbeat'}));\n break;\n case 'event': {\n const args = [...(packet.args ?? [])];\n if (packet.ack==='data' && packet.id) {\n args.push((...acknowledgement:unknown[]) => {\n this.send(encodePacket({type:'ack', ackId:packet.id, args:acknowledgement}));\n });\n }\n this.events.emit(packet.name ?? '', ...args);\n break;\n }\n case 'ack': {\n const callback = packet.ackId && this.acknowledgements.get(packet.ackId);\n if (callback && packet.ackId) {\n this.acknowledgements.delete(packet.ackId);\n callback(...(packet.args ?? []));\n }\n break;\n }\n case 'disconnect':\n this.closeSocket('booted');\n break;\n case 'error':\n this.events.emit('error', packet.reason || 'Socket.IO protocol error');\n if (packet.advice==='reconnect') { this.closeSocket('server error'); }\n break;\n case 'message':\n case 'json':\n this.events.emit('message', packet.data);\n break;\n default:\n break;\n }\n }\n\n private send(packet: string) {\n if (!this.connected || this.socket?.readyState!==WebSocket.OPEN) {\n this.sendBuffer.push(packet);\n return;\n }\n this.socket.send(packet);\n }\n\n private flush() {\n while (this.sendBuffer.length>0 && this.socket?.readyState===WebSocket.OPEN) {\n this.socket.send(this.sendBuffer.shift()!);\n }\n }\n\n private resetInactivityTimer() {\n if (this.inactivityTimer) { clearTimeout(this.inactivityTimer); }\n this.inactivityTimer = setTimeout(() => this.closeSocket('timeout'), this.closeTimeoutMs);\n }\n\n private handleClose() {\n const wasConnected = this.connected;\n this.connected = false;\n if (this.inactivityTimer) { clearTimeout(this.inactivityTimer); }\n if (wasConnected) { this.events.emit('disconnect', 'transport close'); }\n this.scheduleReconnect();\n }\n\n private closeSocket(reason: string) {\n const wasConnected = this.connected;\n this.connected = false;\n if (this.inactivityTimer) { clearTimeout(this.inactivityTimer); }\n const socket = this.socket;\n this.socket = undefined;\n socket?.close();\n if (wasConnected) { this.events.emit('disconnect', reason); }\n if (!this.explicitlyDisconnected) { this.scheduleReconnect(); }\n }\n\n private scheduleReconnect() {\n if (!this.reconnectEnabled || this.explicitlyDisconnected || this.reconnectTimer) { return; }\n const maxAttempts = this.options.maxReconnectionAttempts ?? 10;\n if (this.reconnectAttempts>=maxAttempts) {\n this.events.emit('reconnect_failed');\n return;\n }\n this.reconnectAttempts += 1;\n const initial = this.options.reconnectionDelay ?? 1000;\n const limit = this.options.reconnectionLimit ?? 16_000;\n const delay = Math.min(initial*2**(this.reconnectAttempts-1), limit);\n this.events.emit('reconnecting', delay, this.reconnectAttempts);\n this.reconnectTimer = setTimeout(() => {\n this.reconnectTimer = undefined;\n void this.connect();\n }, delay);\n }\n}\n\nexport const overleafSocketProtocol = {encodePacket, decodePacket, decodePayload};\n","export type LogLevel = 'info' | 'warn' | 'error';\n\nexport type LogSink = (level: LogLevel, args: readonly unknown[]) => void;\n\nlet sink: LogSink | undefined;\n\nexport function setLogSink(nextSink: LogSink | undefined) {\n sink = nextSink;\n}\n\nfunction write(level: LogLevel, args: readonly unknown[]) {\n if (sink!==undefined) {\n sink(level, args);\n return;\n }\n const method = level==='error' ? console.error : level==='warn' ? console.warn : console.log;\n method(...args);\n}\n\nexport function log(...args: unknown[]) {\n write('info', args);\n}\n\nexport function warn(...args: unknown[]) {\n write('warn', args);\n}\n\nexport function error(...args: unknown[]) {\n write('error', args);\n}\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { BaseAPI, Identity } from \"./base\";\nexport type { ProjectLinkedFileProvider, UrlLinkedFileProvider } from '../core/projectTypes';\n\nexport class ExtendedBaseAPI extends BaseAPI {\n async refreshLinkedFile(identity:Identity, project_id:string, file_id:string) {\n this.setIdentity(identity);\n return await this.request('POST', `project/${project_id}/linked_file/${file_id}/refresh`, {shouldReindexReferences: false}, (res) => {\n const message = JSON.parse(res!).new_file_id;\n return {message};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n\n async createLinkedFile(identity:Identity, project_id:string, parent_folder_id:string, name:string, provider:string, data:any) {\n this.setIdentity(identity);\n return await this.request('POST', `project/${project_id}/linked_file`, {name, parent_folder_id, provider, data}, (res) => {\n const message = JSON.parse(res!).new_file_id;\n return {message};\n }, {'X-Csrf-Token': identity.csrfToken});\n }\n}\n","/* eslint-disable @typescript-eslint/naming-convention */\nimport { Identity, BaseAPI, ProjectMessageResponseSchema } from './base';\nimport { FileEntity, DocumentEntity, FileRefEntity, FileType, FolderEntity, ProjectEntity } from '../core/projectTypes';\nimport { error as logError, log } from '../core/logger';\nimport { promisify } from 'node:util';\n\nconst SOCKET_OPERATION_TIMEOUT_MS = 15000;\n\nfunction decodePackedUtf8(text: string): string {\n return Buffer.from(text, 'latin1').toString('utf-8');\n}\n\nexport interface UpdateUserSchema {\n id: string,\n user_id: string,\n name: string,\n email: string,\n doc_id: string,\n row: number,\n column: number,\n last_updated_at?: number, //unix timestamp\n}\n\nexport interface OnlineUserSchema {\n client_age: number,\n client_id: string,\n connected: boolean,\n cursorData?: {\n column: number,\n doc_id: string,\n row: number,\n },\n email: string,\n first_name: string,\n last_name?: string,\n last_updated_at: string, //unix timestamp\n user_id: string,\n}\n\nexport interface UpdateSchema {\n doc: string, //doc id\n op?: {\n p: number, //position\n i?: string, //insert\n d?: string, //delete\n u?: boolean, //isUndo\n }[],\n v: number, //doc version number\n lastV?: number, //last version number\n hash?: string, //(not needed if lastV is provided)\n meta?: {\n source: string, //socketio client id\n ts: number, //unix timestamp\n user_id: string,\n }\n}\n\nexport interface EventsHandler {\n onFileCreated?: (parentFolderId:string, type:FileType, entity:FileEntity) => void,\n onFileRenamed?: (entityId:string, newName:string) => void,\n onFileRemoved?: (entityId:string) => void,\n onFileMoved?: (entityId:string, newParentFolderId:string) => void,\n onFileChanged?: (update:UpdateSchema) => void,\n //\n onDisconnected?: () => void,\n onConnectionAccepted?: (publicId:string) => void,\n onClientUpdated?: (user:UpdateUserSchema) => void,\n onClientDisconnected?: (id:string) => void,\n //\n onReceivedMessage?: (message:ProjectMessageResponseSchema) => void,\n //\n onSpellCheckLanguageUpdated?: (language:string) => void,\n onCompilerUpdated?: (compiler:string) => void,\n onRootDocUpdated?: (rootDocId:string) => void,\n}\n\ntype ConnectionScheme = 'Alt' | 'realtime';\ntype AlternativeSocketFactory = (\n url:string,\n api:BaseAPI,\n identity:Identity,\n projectId:string,\n record:Promise<ProjectEntity>,\n) => any;\n\nexport class SocketIOAPI {\n private static alternativeSocketFactory?: AlternativeSocketFactory;\n private scheme: ConnectionScheme;\n private record?: Promise<ProjectEntity>;\n private _handlers: Array<EventsHandler> = [];\n private connectedPublicId?: string;\n\n private socket?: any;\n private emit: any;\n /** Track the scheme used when the socket was last initialized */\n private _socketInitScheme?: ConnectionScheme;\n\n constructor(private url:string,\n private readonly api:BaseAPI,\n private readonly identity:Identity,\n private readonly projectId:string)\n {\n this.scheme = 'realtime';\n this.init();\n }\n\n static setAlternativeSocketFactory(factory: AlternativeSocketFactory) {\n SocketIOAPI.alternativeSocketFactory = factory;\n }\n\n init() {\n // CRITICAL: Properly disconnect old socket before creating a new one.\n // Without this, the old TCP connection is abandoned but still alive. When the\n // server later sends data on it (out-of-order/late packets), the OS TCP stack\n // responds with RST, which can cause the server to drop ALL connections from\n // this client — explaining the \"connection lost\" loop reported in issue #309.\n if (this.socket) {\n try {\n // Remove all listeners to prevent stale event handlers from firing\n if (typeof this.socket.removeAllListeners === 'function') {\n this.socket.removeAllListeners();\n }\n // Gracefully close the connection (sends FIN, not RST)\n if (typeof this.socket.disconnect === 'function') {\n this.socket.disconnect();\n }\n } catch {\n // Best-effort cleanup; socket may already be in a bad state\n }\n }\n\n // connect\n switch(this.scheme) {\n case 'Alt':\n if (!SocketIOAPI.alternativeSocketFactory) {\n throw new Error('The alternative Overleaf connection is not available in this runtime.');\n }\n this.socket = SocketIOAPI.alternativeSocketFactory(\n this.url, this.api, this.identity, this.projectId, this.record!,\n );\n break;\n case 'realtime':\n this.record = undefined;\n const query = `?projectId=${this.projectId}&t=${Date.now()}`;\n this.socket = this.api._initSocketV0(this.identity, query);\n break;\n }\n // create emit\n (this.socket.emit)[promisify.custom] = (event:string, ...args:any[]) => {\n const timeoutPromise = new Promise((_, reject) => {\n setTimeout(() => {\n reject('timeout');\n }, SOCKET_OPERATION_TIMEOUT_MS);\n });\n const waitPromise = new Promise((resolve, reject) => {\n this.socket.emit(event, ...args, (err:any, ...data:any[]) => {\n if (err) {\n reject(err);\n } else {\n resolve(data);\n }\n });\n });\n return Promise.race([waitPromise, timeoutPromise]);\n };\n this.emit = promisify(this.socket.emit).bind(this.socket);\n // resume handlers\n this.initInternalHandlers();\n // Re-register existing event handlers on the new socket\n this.resumeEventHandlers(this._handlers);\n // Track which scheme this socket was created with\n this._socketInitScheme = this.scheme;\n }\n\n /** Returns true if the socket needs re-initialization (scheme changed, or socket was never init'd) */\n get needsReinit(): boolean {\n return this._socketInitScheme !== this.scheme || !this.socket;\n }\n\n get connectionScheme(): ConnectionScheme {\n return this.scheme;\n }\n\n private initInternalHandlers() {\n this.socket.on('connect', () => {\n log('SocketIOAPI: connected', {scheme: this.scheme, projectId: this.projectId});\n });\n this.socket.on('connect_failed', (connectionError:any) => {\n log('SocketIOAPI: connect_failed', {scheme: this.scheme, projectId: this.projectId, error: connectionError});\n });\n this.socket.on('disconnect', (reason:any) => {\n log('SocketIOAPI: disconnect event', {scheme: this.scheme, projectId: this.projectId, reason});\n });\n this.socket.on('reconnecting', (delay:any, attempt:any) => {\n log('SocketIOAPI: reconnecting', {scheme: this.scheme, projectId: this.projectId, delay, attempt});\n });\n this.socket.on('reconnect', (transport:any, attempts:any) => {\n log('SocketIOAPI: reconnected', {scheme: this.scheme, projectId: this.projectId, transport, attempts});\n });\n this.socket.on('reconnect_failed', (error:any) => {\n log('SocketIOAPI: reconnect_failed', {scheme: this.scheme, projectId: this.projectId, error});\n });\n this.socket.on('forceDisconnect', (message:string, delay=10) => {\n log('SocketIOAPI: forceDisconnect', {message, delay, projectId: this.projectId});\n });\n this.socket.on('connectionRejected', (err:any) => {\n log('SocketIOAPI: connectionRejected', {scheme: this.scheme, projectId: this.projectId, error: err});\n // Disable auto-reconnect on this socket: the server explicitly rejected\n // our connection parameters. Reconnecting would just get rejected again,\n // creating unnecessary TCP connection churn (and RST packets).\n if (this.socket.io && typeof this.socket.io.reconnect === 'function') {\n this.socket.io.reconnect(false);\n }\n });\n this.socket.on('error', (err:any) => {\n // Log error instead of throwing to avoid crashing the extension\n const message = err?.message || String(err);\n logError(`Overleaf connection error: ${message}`);\n });\n\n if (this.scheme==='realtime') {\n this.record = new Promise((resolve, reject) => {\n this.socket.on('joinProjectResponse', (res:any) => {\n const publicId = res.publicId as string;\n const project = res.project as ProjectEntity;\n this.connectedPublicId = publicId;\n for (const handler of this._handlers) {\n handler.onConnectionAccepted?.(publicId);\n }\n resolve(project);\n });\n this.socket.on('connectionRejected', (err:any) => {\n reject(err?.message || err);\n });\n });\n }\n }\n\n disconnect() {\n this.socket.disconnect();\n }\n\n get handlers() {\n return this._handlers;\n }\n\n get isUsingAlternativeConnectionScheme() {\n return this.scheme==='Alt';\n }\n\n toggleAlternativeConnectionScheme(url: string, updatedRecord?: ProjectEntity) {\n this.scheme = this.scheme==='Alt' ? 'realtime' : 'Alt';\n if (updatedRecord) {\n this.url = url;\n this.record = Promise.resolve(updatedRecord);\n }\n }\n\n resumeEventHandlers(handlers: Array<EventsHandler>) {\n this._handlers = [];\n handlers.forEach((handler) => {\n this.updateEventHandlers(handler);\n });\n }\n\n updateEventHandlers(handlers: EventsHandler) {\n this._handlers.push(handlers);\n Object.values(handlers).forEach((handler) => {\n switch (handler) {\n case handlers.onFileCreated:\n this.socket.on('reciveNewDoc', (parentFolderId:string, doc:DocumentEntity) => {\n handler(parentFolderId, 'doc', doc);\n });\n this.socket.on('reciveNewFile', (parentFolderId:string, file:FileRefEntity) => {\n handler(parentFolderId, 'file', file);\n });\n this.socket.on('reciveNewFolder', (parentFolderId:string, folder:FolderEntity) => {\n handler(parentFolderId, 'folder', folder);\n });\n break;\n case handlers.onFileRenamed:\n this.socket.on('reciveEntityRename', (entityId:string, newName:string) => {\n handler(entityId, newName);\n });\n break;\n case handlers.onFileRemoved:\n this.socket.on('removeEntity', (entityId:string) => {\n handler(entityId);\n });\n break;\n case handlers.onFileMoved:\n this.socket.on('reciveEntityMove', (entityId:string, folderId:string) => {\n handler(entityId, folderId);\n });\n break;\n case handlers.onFileChanged:\n this.socket.on('otUpdateApplied', (update: UpdateSchema) => {\n handler(update);\n });\n break;\n case handlers.onDisconnected:\n this.socket.on('disconnect', () => {\n handler();\n });\n break;\n case handlers.onConnectionAccepted:\n this.socket.on('connectionAccepted', (_:any, publicId:any) => {\n handler(publicId);\n });\n if (this.connectedPublicId!==undefined) {\n queueMicrotask(() => handler(this.connectedPublicId!));\n }\n break;\n case handlers.onClientUpdated:\n this.socket.on('clientTracking.clientUpdated', (user:UpdateUserSchema) => {\n handler(user);\n });\n break;\n case handlers.onClientDisconnected:\n this.socket.on('clientTracking.clientDisconnected', (id:string) => {\n handler(id);\n });\n break;\n case handlers.onReceivedMessage:\n this.socket.on('new-chat-message', (message:ProjectMessageResponseSchema) => {\n handler(message);\n });\n break;\n case handlers.onSpellCheckLanguageUpdated:\n this.socket.on('spellCheckLanguageUpdated', (language:string) => {\n handler(language);\n });\n break;\n case handlers.onCompilerUpdated:\n this.socket.on('compilerUpdated', (compiler:string) => {\n handler(compiler);\n });\n break;\n case handlers.onRootDocUpdated:\n this.socket.on('rootDocUpdated', (rootDocId:string) => {\n handler(rootDocId);\n });\n break;\n default:\n break;\n }\n });\n }\n\n get unSyncFileChanges(): number {\n return this.scheme==='Alt' ? this.socket.unSyncedChanges : 0;\n }\n\n async syncFileChanges() {\n if (this.scheme==='Alt') {\n return await this.socket.uploadToVFS();\n }\n }\n\n /**\n * Reference: services/web/frontend/js/ide/connection/ConnectionManager.js#L427\n * @param {string} projectId - The project id.\n * @returns {Promise}\n */\n async joinProject(project_id:string): Promise<ProjectEntity> {\n const timeoutPromise: Promise<ProjectEntity> = new Promise((_, reject) => {\n setTimeout(() => {\n reject('timeout');\n }, SOCKET_OPERATION_TIMEOUT_MS);\n });\n\n switch(this.scheme) {\n case 'Alt':\n return Promise.race([\n this.emit('joinProject', {project_id}).then((returns:[ProjectEntity]) => returns[0]),\n timeoutPromise,\n ]);\n case 'realtime':\n return Promise.race([this.record!, timeoutPromise]);\n }\n }\n\n /**\n * Reference: services/web/frontend/js/ide/editor/Document.js#L500\n * @param {string} docId - The document id.\n * @returns {Promise}\n */\n async joinDoc(docId:string) {\n return this.emit('joinDoc', docId, { encodeRanges: true })\n .then((returns: [Array<string>, number, Array<any>, any]) => {\n const [docLinesAscii, version, updates, ranges] = returns;\n const docLines = docLinesAscii.map((line) => decodePackedUtf8(line));\n return {docLines, version, updates, ranges};\n });\n }\n\n /**\n * Reference: services/web/frontend/js/ide/editor/Document.js#L591\n * @param {string} docId - The document id.\n * @returns {Promise}\n */\n async leaveDoc(docId:string) {\n return this.emit('leaveDoc', docId)\n .then(() => {\n return;\n });\n }\n\n /**\n * Reference: services/web/frontend/js/ide/editor/ShareJsDocs.js#L78\n * @param {string} docId - The document id.\n * @param {any} update - The changes.\n * @returns {Promise}\n */\n async applyOtUpdate(docId:string, update:UpdateSchema) {\n try {\n await this.emit('applyOtUpdate', docId, update);\n } catch (error) {\n let detail: string;\n if (error instanceof Error) {\n detail = error.message;\n } else if (typeof error==='string') {\n detail = error;\n } else {\n try { detail = JSON.stringify(error); } catch { detail = String(error); }\n }\n throw new Error(`Overleaf document update rejected: ${detail}`);\n }\n }\n\n /**\n * Reference: services/web/frontend/js/ide/online-users/OnlineUserManager.js#L42\n * @returns {Promise}\n */\n async getConnectedUsers(): Promise<OnlineUserSchema[]> {\n return this.emit('clientTracking.getConnectedUsers')\n .then((returns:[OnlineUserSchema[]]) => {\n const [connectedUsers] = returns;\n return connectedUsers;\n });\n }\n\n /**\n * Reference: services/web/frontend/js/ide/online-users/OnlineUserManager.js#L150\n * @param {string} docId - The document id.\n * @returns {Promise}\n */\n async updatePosition(doc_id:string, row:number, column:number) {\n return this.emit('clientTracking.updatePosition', {row, column, doc_id})\n .then(() => {\n return;\n });\n }\n}\n","/* eslint-disable @typescript-eslint/naming-convention */\n\nexport type FileType = 'doc' | 'file' | 'folder' | 'outputs';\nexport type FolderKey = 'docs' | 'fileRefs' | 'folders' | 'outputs';\n\nexport const FolderKeys: Readonly<Record<string, FolderKey>> = {\n folder: 'folders',\n doc: 'docs',\n file: 'fileRefs',\n outputs: 'outputs',\n};\n\nexport interface ProjectLinkedFileProvider {\n provider: 'project_file';\n source_project_id: string;\n source_entity_path: string;\n}\n\nexport interface UrlLinkedFileProvider {\n provider: 'url';\n url: string;\n}\n\nexport interface FileEntity {\n _id: string;\n name: string;\n _type?: FileType;\n readonly?: boolean;\n}\n\nexport interface DocumentEntity extends FileEntity {\n version?: number;\n mtime?: number;\n lastVersion?: number;\n localCache?: string;\n remoteCache?: string;\n}\n\nexport interface FileRefEntity extends FileEntity {\n linkedFileData: ProjectLinkedFileProvider | UrlLinkedFileProvider | null;\n created: string;\n}\n\nexport interface OutputFileEntity extends FileEntity {\n path: string;\n url: string;\n type: string;\n build: string;\n}\n\nexport interface FolderEntity extends FileEntity {\n docs: DocumentEntity[];\n fileRefs: FileRefEntity[];\n folders: FolderEntity[];\n outputs?: OutputFileEntity[];\n}\n\nexport interface MemberEntity {\n _id: string;\n first_name: string;\n last_name?: string;\n email: string;\n privileges?: string;\n signUpDate?: string;\n}\n\nexport interface ProjectSettingsSchema {\n learnedWords: string[];\n languages: Array<{code:string; name:string}>;\n compilers: Array<{code:string; name:string}>;\n}\n\nexport interface ProjectEntity {\n _id: string;\n name: string;\n rootDoc_id: string;\n rootFolder: FolderEntity[];\n publicAccessLevel: string;\n compiler: string;\n spellCheckLanguage: string;\n deletedDocs: Array<{\n _id: string;\n name: string;\n deletedAt: string;\n }>;\n members: MemberEntity[];\n invites: MemberEntity[];\n owner: MemberEntity;\n features: Record<string, unknown>;\n settings: ProjectSettingsSchema;\n}\n","import {mkdir, readFile, writeFile, chmod} from 'node:fs/promises';\nimport {homedir} from 'node:os';\nimport {dirname, join, resolve} from 'node:path';\nimport type {Identity} from '../api/base';\n\nexport interface ServerSession {\n url: string;\n userId: string;\n userEmail: string;\n identity: Identity;\n updatedAt: string;\n}\n\nexport interface LeafRelayConfig {\n version: 1;\n servers: Record<string, ServerSession>;\n}\n\nexport function configPath(environment: NodeJS.ProcessEnv = process.env): string {\n return environment.LEAFRELAY_CONFIG\n ? resolve(environment.LEAFRELAY_CONFIG)\n : join(homedir(), '.leafrelay', 'config.json');\n}\n\nexport function normalizeServerUrl(value: string): string {\n const url = new URL(value.includes('://') ? value : `https://${value}`);\n url.pathname = '/';\n url.search = '';\n url.hash = '';\n return url.href;\n}\n\nexport function serverKey(value: string): string {\n return new URL(normalizeServerUrl(value)).host;\n}\n\nexport async function readConfig(path = configPath()): Promise<LeafRelayConfig> {\n try {\n const parsed = JSON.parse(await readFile(path, 'utf8')) as Partial<LeafRelayConfig>;\n if (parsed.version!==1 || typeof parsed.servers!=='object' || parsed.servers===null) {\n throw new Error(`Unsupported LeafRelay configuration in ${path}`);\n }\n return parsed as LeafRelayConfig;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code==='ENOENT') {\n return {version:1, servers:{}};\n }\n throw error;\n }\n}\n\nexport async function writeConfig(config: LeafRelayConfig, path = configPath()): Promise<void> {\n await mkdir(dirname(path), {recursive:true, mode:0o700});\n await writeFile(path, `${JSON.stringify(config, null, 2)}\\n`, {encoding:'utf8', mode:0o600});\n await chmod(path, 0o600);\n}\n\nexport async function saveServerSession(session: ServerSession, path = configPath()): Promise<void> {\n const config = await readConfig(path);\n config.servers[serverKey(session.url)] = session;\n await writeConfig(config, path);\n}\n\nexport async function getServerSession(\n server: string,\n environment: NodeJS.ProcessEnv = process.env,\n path = configPath(environment),\n): Promise<ServerSession | undefined> {\n const key = serverKey(server);\n const config = await readConfig(path);\n const stored = config.servers[key];\n const cookie = environment.LEAFRELAY_COOKIE;\n if (!cookie) { return stored; }\n return {\n url: stored?.url ?? normalizeServerUrl(server),\n userId: stored?.userId ?? '',\n userEmail: stored?.userEmail ?? '',\n identity: {cookies:cookie, csrfToken:stored?.identity.csrfToken ?? ''},\n updatedAt: stored?.updatedAt ?? new Date(0).toISOString(),\n };\n}\n","import {lstat, mkdir, readFile, readdir, rm, writeFile} from 'node:fs/promises';\nimport {dirname, relative, resolve, sep} from 'node:path';\nimport {watch, type FSWatcher} from 'chokidar';\nimport type {ReplicaFileSystem} from '../sync/syncEngine';\n\nfunction projectPath(root:string, path:string):string {\n const target = resolve(root, path.replace(/^\\/+/, ''));\n const relativePath = relative(root, target);\n if (relativePath.startsWith('..') || relativePath=== '..') {\n throw new Error(`Path escapes the local project: ${path}`);\n }\n return target;\n}\n\nfunction syncPath(root:string, path:string):string {\n return `/${relative(root, path).split(sep).join('/')}`;\n}\n\nexport class NodeReplicaFileSystem implements ReplicaFileSystem {\n private watcher?:FSWatcher;\n\n constructor(\n private readonly root:string,\n private readonly ignore:(path:string)=>boolean,\n ) {}\n\n async listFiles():Promise<string[]> {\n const files:string[] = [];\n const visit = async (directory:string) => {\n for (const entry of await readdir(directory, {withFileTypes:true})) {\n const absolute = resolve(directory, entry.name);\n const path = syncPath(this.root, absolute);\n if (this.ignore(path) || entry.name.startsWith('.') || entry.isSymbolicLink()) { continue; }\n if (entry.isDirectory()) { await visit(absolute); }\n else if (entry.isFile()) { files.push(path); }\n }\n };\n await visit(this.root);\n return files.sort();\n }\n\n async read(path:string):Promise<Uint8Array|undefined> {\n const target = projectPath(this.root, path);\n try {\n const stat = await lstat(target);\n if (!stat.isFile() || stat.isSymbolicLink()) { return undefined; }\n return new Uint8Array(await readFile(target));\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code==='ENOENT') { return undefined; }\n throw error;\n }\n }\n\n async write(path:string, content:Uint8Array):Promise<void> {\n const target = projectPath(this.root, path);\n await mkdir(dirname(target), {recursive:true});\n await writeFile(target, content);\n }\n\n async remove(path:string):Promise<void> {\n await rm(projectPath(this.root, path), {force:true, recursive:true});\n }\n\n async watch(onChange:(path:string)=>void):Promise<() => Promise<void>> {\n this.watcher = watch(this.root, {\n ignoreInitial:true,\n followSymlinks:false,\n ignored:path => {\n const relativePath = relative(this.root, path);\n if (!relativePath) { return false; }\n const normalized = `/${relativePath.split(sep).join('/')}`;\n return this.ignore(normalized) || normalized.split('/').some(part => part.startsWith('.'));\n },\n awaitWriteFinish:{stabilityThreshold:200, pollInterval:50},\n });\n const handler = (path:string) => onChange(syncPath(this.root, path));\n this.watcher.on('add', handler).on('change', handler).on('unlink', handler);\n await new Promise<void>((resolveReady, reject) => {\n this.watcher!.once('ready', resolveReady).once('error', reject);\n });\n return async () => { await this.watcher?.close(); };\n }\n}\n","import {readFile} from 'node:fs/promises';\nimport {resolve} from 'node:path';\n\nexport interface LocalProjectSettings {\n uri: string;\n serverName: string;\n serverUrl: string;\n projectId: string;\n projectName: string;\n userId?: string;\n localReplica: {\n settings: Record<string, unknown>;\n };\n}\n\nfunction parseProjectUri(value: string) {\n const uri = new URL(value);\n const decodedQuery = decodeURIComponent(uri.search.slice(1));\n const query = new URLSearchParams(decodedQuery);\n const projectId = query.get('project');\n if (!projectId) {\n throw new Error('The project URI in .overleaf/settings.json does not contain a project ID.');\n }\n return {\n serverName:uri.host,\n projectId,\n projectName:decodeURIComponent(uri.pathname.split('/').filter(Boolean)[0] ?? ''),\n userId:query.get('user') ?? undefined,\n };\n}\n\nexport async function readProjectSettings(directory: string): Promise<LocalProjectSettings> {\n const settingsPath = resolve(directory, '.overleaf', 'settings.json');\n const raw = JSON.parse(await readFile(settingsPath, 'utf8')) as Record<string, unknown>;\n if (typeof raw.uri!=='string') {\n throw new Error(`${settingsPath} does not contain a valid project URI.`);\n }\n const parsed = parseProjectUri(raw.uri);\n const serverName = typeof raw.serverName==='string' ? raw.serverName : parsed.serverName;\n const localReplica = raw.localReplica as {settings?:Record<string, unknown>} | undefined;\n return {\n uri:raw.uri,\n serverName,\n serverUrl:typeof raw.serverUrl==='string' ? raw.serverUrl : `https://${serverName}/`,\n projectId:parsed.projectId,\n projectName:typeof raw.projectName==='string' ? raw.projectName : parsed.projectName,\n userId:parsed.userId,\n localReplica:{settings:localReplica?.settings ?? {}},\n };\n}\n","import {resolve} from 'node:path';\nimport {log} from '../core/logger';\nimport {createIgnoreMatcher} from '../sync/ignore';\nimport {RemoteProject} from '../sync/remoteProject';\nimport {SyncEngine} from '../sync/syncEngine';\nimport {getServerSession} from './config';\nimport {NodeReplicaFileSystem} from './localFileSystem';\nimport {readProjectSettings} from './projectSettings';\nimport {FileSyncStateStore} from './syncStateStore';\n\nexport interface RunningServe {\n stop():Promise<void>;\n}\n\nexport async function startServe(directory=process.cwd()):Promise<RunningServe> {\n const root = resolve(directory);\n const settings = await readProjectSettings(root);\n const session = await getServerSession(settings.serverName);\n if (!session) {\n throw new Error(`No login is stored for ${settings.serverName}. Run: leafrelay login ${settings.serverName}`);\n }\n const cookie = process.env.LEAFRELAY_COOKIE || session.identity.cookies;\n const remote = new RemoteProject(session.url || settings.serverUrl, settings.projectId, cookie);\n await remote.connect();\n\n const configuredPatterns = settings.localReplica.settings['ignore-patterns'];\n const ignore = createIgnoreMatcher(configuredPatterns);\n const local = new NodeReplicaFileSystem(root, ignore);\n const engine = new SyncEngine({\n projectUri:settings.uri,\n local,\n remote,\n stateStore:new FileSyncStateStore(root, settings.uri),\n ignore,\n log,\n onConflict:(path, reason) => {\n log(`Conflict paused for ${path}: ${reason}`);\n },\n });\n try {\n await engine.start();\n } catch (error) {\n remote.disconnect();\n throw error;\n }\n log(`LeafRelay is serving ${root} (${settings.projectName}).`);\n return {\n stop:async () => {\n await engine.stop();\n remote.disconnect();\n },\n };\n}\n","import {minimatch} from 'minimatch';\n\nexport const DEFAULT_IGNORE_PATTERNS = [\n '**/.*',\n '**/.*/**',\n '**/*.aux',\n '**/__latexindent*',\n '**/*.bbl',\n '**/*.bcf',\n '**/*.blg',\n '**/*.fdb_latexmk',\n '**/*.fls',\n '**/*.lof',\n '**/*.log',\n '**/*.lot',\n '**/*.out',\n '**/*.run.xml',\n '**/*.synctex(busy)',\n '**/*.synctex.gz',\n '**/*.toc',\n '**/*.xdv',\n '**/main.pdf',\n '**/output.pdf',\n];\n\nexport function createIgnoreMatcher(patterns:unknown): (path:string)=>boolean {\n const configured = Array.isArray(patterns)\n ? patterns.filter((pattern):pattern is string => typeof pattern==='string')\n : [];\n const allPatterns = [...DEFAULT_IGNORE_PATTERNS, ...configured];\n return path => {\n const normalized = path.replace(/^\\/+/, '');\n return normalized.split('/').some(part => part.startsWith('.')) ||\n allPatterns.some(pattern => minimatch(normalized, pattern, {dot:true}));\n };\n}\n","import {createHash} from 'node:crypto';\nimport {posix} from 'node:path';\nimport DiffMatchPatch from 'diff-match-patch';\nimport {BaseAPI, type Identity, type ProjectFileTreeDiffResponseSchema} from '../api/base';\nimport {SocketIOAPI, type UpdateSchema} from '../api/socketio';\nimport type {\n DocumentEntity,\n FileEntity,\n FileRefEntity,\n FileType,\n FolderEntity,\n ProjectEntity,\n} from '../core/projectTypes';\n\nexport interface RemoteEntry {\n path: string;\n type: FileType;\n entity: FileEntity;\n parent?: FolderEntity;\n}\n\nexport type RemoteChange = {path:string; previousPath?:string};\n\nfunction normalizePath(path: string): string {\n const normalized = `/${posix.normalize(path).replace(/^\\/+/, '')}`;\n if (normalized.includes('/../') || normalized.endsWith('/..')) {\n throw new Error(`Invalid project path: ${path}`);\n }\n return normalized;\n}\n\nfunction textContent(content: Uint8Array): string | undefined {\n if (content.includes(0)) { return undefined; }\n try {\n return new TextDecoder('utf-8', {fatal:true}).decode(content);\n } catch {\n return undefined;\n }\n}\n\nexport class RemoteProject {\n private readonly api: BaseAPI;\n private identity!: Identity;\n private socket!: SocketIOAPI;\n private project!: ProjectEntity;\n private readonly entries = new Map<string, RemoteEntry>();\n private readonly idToPath = new Map<string, string>();\n private changeHandler?: (change:RemoteChange) => void;\n\n constructor(\n private readonly url:string,\n private readonly projectId:string,\n private readonly cookies:string,\n ) {\n this.api = new BaseAPI(url);\n }\n\n async connect(): Promise<void> {\n const login = await this.api.cookiesLogin(this.cookies);\n if (login.type!=='success' || !login.identity) {\n throw new Error(login.message || `Authentication to ${this.url} failed.`);\n }\n this.identity = login.identity;\n this.socket = new SocketIOAPI(this.url, this.api, this.identity, this.projectId);\n this.project = await this.socket.joinProject(this.projectId);\n this.reindex();\n this.registerEvents();\n }\n\n disconnect() {\n this.socket?.disconnect();\n }\n\n onChange(handler: (change:RemoteChange) => void) {\n this.changeHandler = handler;\n }\n\n listEntries(): RemoteEntry[] {\n return [...this.entries.values()];\n }\n\n entry(path: string): RemoteEntry | undefined {\n return this.entries.get(normalizePath(path));\n }\n\n async read(path: string): Promise<Uint8Array> {\n const entry = this.requireEntry(path);\n if (entry.type==='doc') {\n const result = await this.socket.joinDoc(entry.entity._id);\n return new TextEncoder().encode(result.docLines.join('\\n'));\n }\n if (entry.type==='file') {\n const result = await this.api.getFile(this.identity, this.projectId, entry.entity._id);\n if (result.type==='success' && result.content) { return result.content; }\n throw new Error(`Could not download ${path}.`);\n }\n throw new Error(`${path} is not a file.`);\n }\n\n async mkdir(path: string): Promise<void> {\n const normalized = normalizePath(path);\n if (this.entries.has(normalized)) { return; }\n const {parent, name} = await this.ensureParent(normalized);\n const result = await this.api.addFolder(this.identity, this.projectId, name, parent._id);\n if (result.type!=='success' || !result.entity) {\n throw new Error(result.message || `Could not create ${normalized}.`);\n }\n const folder = result.entity as FolderEntity;\n folder._type = 'folder';\n folder.docs ??= [];\n folder.fileRefs ??= [];\n folder.folders ??= [];\n parent.folders.push(folder);\n this.reindex();\n }\n\n async write(path: string, content: Uint8Array): Promise<void> {\n const normalized = normalizePath(path);\n const existing = this.entries.get(normalized);\n if (existing?.type==='folder') {\n throw new Error(`${normalized} is a directory.`);\n }\n if (existing?.type==='doc') {\n await this.writeDocument(existing.entity as DocumentEntity, content);\n return;\n }\n if (existing) {\n await this.remove(normalized);\n }\n const {parent, name} = await this.ensureParent(normalized);\n const text = textContent(content);\n if (text!==undefined) {\n const created = await this.api.addDoc(this.identity, this.projectId, parent._id, name);\n if (created.type!=='success' || !created.entity) {\n throw new Error(created.message || `Could not create ${normalized}.`);\n }\n const entity = created.entity as DocumentEntity;\n entity._type = 'doc';\n parent.docs.push(entity);\n this.reindex();\n if (content.length!==0) { await this.writeDocument(entity, content); }\n return;\n }\n const uploaded = await this.api.uploadFile(this.identity, this.projectId, parent._id, name, content);\n if (uploaded.type!=='success' || !uploaded.entity) {\n throw new Error(uploaded.message || `Could not upload ${normalized}.`);\n }\n const entity = uploaded.entity as FileRefEntity;\n entity._type = 'file';\n parent.fileRefs.push(entity);\n this.reindex();\n }\n\n async remove(path: string): Promise<void> {\n const normalized = normalizePath(path);\n const entry = this.requireEntry(normalized);\n if (!entry.parent) { throw new Error('The project root cannot be removed.'); }\n const result = await this.api.deleteEntity(this.identity, this.projectId, entry.type, entry.entity._id);\n if (result.type!=='success') {\n throw new Error(result.message || `Could not remove ${normalized}.`);\n }\n this.removeFromParent(entry);\n this.reindex();\n }\n\n async getCurrentVersion(): Promise<number> {\n const response = await this.api.proxyToHistoryApiAndGetUpdates(this.identity, this.projectId);\n const version = response.updates?.updates.at(0)?.toV ?? 0;\n if (response.type!=='success' || !Number.isInteger(version)) {\n throw new Error(response.message || 'Could not determine the current Overleaf project version.');\n }\n return version;\n }\n\n async getFileTreeDiff(from:number, to:number): Promise<ProjectFileTreeDiffResponseSchema | undefined> {\n if (from>=to) { return {diff:[]}; }\n const response = await this.api.proxyToHistoryApiAndGetFileTreeDiff(\n this.identity, this.projectId, from, to,\n );\n if (response.type==='success') { return response.treeDiff; }\n if (response.statusCode===404) { return undefined; }\n throw new Error(response.message || 'Could not load the Overleaf file-tree history.');\n }\n\n private async writeDocument(entity: DocumentEntity, content: Uint8Array): Promise<void> {\n const text = textContent(content);\n if (text===undefined) {\n const path = this.idToPath.get(entity._id)!;\n await this.remove(path);\n await this.write(path, content);\n return;\n }\n const remote = await this.socket.joinDoc(entity._id);\n const previous = remote.docLines.join('\\n');\n if (previous===text) { return; }\n let position = 0;\n const operations:NonNullable<UpdateSchema['op']> = [];\n for (const part of new DiffMatchPatch().diff_main(previous, text)) {\n const start = position;\n if (part[0]!==-1) { position += part[1].length; }\n if (part[0]===1) { operations.push({p:start, i:part[1]}); }\n if (part[0]===-1) { operations.push({p:start, d:part[1]}); }\n }\n const update: UpdateSchema = {\n doc:entity._id,\n v:remote.version,\n hash:createHash('sha1').update(`blob ${text.length}\\x00${text}`).digest('hex'),\n op:operations,\n };\n await this.socket.applyOtUpdate(entity._id, update);\n }\n\n private async ensureParent(path: string): Promise<{parent:FolderEntity; name:string}> {\n const name = posix.basename(path);\n const parentPath = posix.dirname(path);\n if (parentPath!=='/' && !this.entries.has(parentPath)) {\n await this.mkdir(parentPath);\n }\n const parentEntry = parentPath==='/' ? this.entries.get('/') : this.entries.get(parentPath);\n if (!parentEntry || parentEntry.type!=='folder') {\n throw new Error(`Parent directory ${parentPath} does not exist.`);\n }\n return {parent:parentEntry.entity as FolderEntity, name};\n }\n\n private requireEntry(path: string): RemoteEntry {\n const normalized = normalizePath(path);\n const entry = this.entries.get(normalized);\n if (!entry) { throw new Error(`Remote path not found: ${normalized}`); }\n return entry;\n }\n\n private reindex() {\n this.entries.clear();\n this.idToPath.clear();\n const root = this.project.rootFolder[0];\n root._type = 'folder';\n this.indexFolder(root, '/');\n }\n\n private indexFolder(folder: FolderEntity, path: string, parent?:FolderEntity) {\n this.entries.set(path, {path, type:'folder', entity:folder, parent});\n this.idToPath.set(folder._id, path);\n for (const child of folder.folders ?? []) {\n child._type = 'folder';\n this.indexFolder(child, normalizePath(posix.join(path, child.name)), folder);\n }\n for (const child of folder.docs ?? []) {\n child._type = 'doc';\n const childPath = normalizePath(posix.join(path, child.name));\n this.entries.set(childPath, {path:childPath, type:'doc', entity:child, parent:folder});\n this.idToPath.set(child._id, childPath);\n }\n for (const child of folder.fileRefs ?? []) {\n child._type = 'file';\n const childPath = normalizePath(posix.join(path, child.name));\n this.entries.set(childPath, {path:childPath, type:'file', entity:child, parent:folder});\n this.idToPath.set(child._id, childPath);\n }\n }\n\n private folderById(id:string): FolderEntity | undefined {\n const path = this.idToPath.get(id);\n const entry = path ? this.entries.get(path) : undefined;\n return entry?.type==='folder' ? entry.entity as FolderEntity : undefined;\n }\n\n private removeFromParent(entry: RemoteEntry) {\n if (!entry.parent) { return; }\n const collection = entry.type==='folder'\n ? entry.parent.folders\n : entry.type==='doc' ? entry.parent.docs : entry.parent.fileRefs;\n const index = collection.findIndex(item => item._id===entry.entity._id);\n if (index!==-1) { collection.splice(index, 1); }\n }\n\n private emitChange(path:string, previousPath?:string) {\n this.changeHandler?.({path:normalizePath(path), previousPath});\n }\n\n private registerEvents() {\n this.socket.updateEventHandlers({\n onFileCreated:(parentId, type, entity) => {\n const parent = this.folderById(parentId);\n if (!parent || type==='outputs') { return; }\n if (this.idToPath.has(entity._id)) { return; }\n entity._type = type;\n if (type==='folder') {\n const folder = entity as FolderEntity;\n folder.docs ??= [];\n folder.fileRefs ??= [];\n folder.folders ??= [];\n parent.folders.push(folder);\n } else if (type==='doc') {\n parent.docs.push(entity as DocumentEntity);\n } else {\n parent.fileRefs.push(entity as FileRefEntity);\n }\n const parentPath = this.idToPath.get(parentId) ?? '/';\n this.reindex();\n this.emitChange(posix.join(parentPath, entity.name));\n },\n onFileRenamed:(entityId, newName) => {\n const previousPath = this.idToPath.get(entityId);\n if (!previousPath) { return; }\n this.entries.get(previousPath)!.entity.name = newName;\n this.reindex();\n this.emitChange(this.idToPath.get(entityId)!, previousPath);\n },\n onFileRemoved:(entityId) => {\n const previousPath = this.idToPath.get(entityId);\n if (!previousPath) { return; }\n const entry = this.entries.get(previousPath)!;\n this.removeFromParent(entry);\n this.reindex();\n this.emitChange(previousPath);\n },\n onFileMoved:(entityId, parentId) => {\n const previousPath = this.idToPath.get(entityId);\n const nextParent = this.folderById(parentId);\n if (!previousPath || !nextParent) { return; }\n const entry = this.entries.get(previousPath)!;\n this.removeFromParent(entry);\n if (entry.type==='folder') { nextParent.folders.push(entry.entity as FolderEntity); }\n else if (entry.type==='doc') { nextParent.docs.push(entry.entity as DocumentEntity); }\n else { nextParent.fileRefs.push(entry.entity as FileRefEntity); }\n this.reindex();\n this.emitChange(this.idToPath.get(entityId)!, previousPath);\n },\n onFileChanged:update => {\n const path = this.idToPath.get(update.doc);\n if (path) { this.emitChange(path); }\n },\n });\n }\n}\n","import {posix} from 'node:path';\nimport type {ProjectFileTreeDiffResponseSchema} from '../api/base';\nimport type {RemoteEntry} from './remoteProject';\nimport {\n createSyncState,\n type LocalReplicaSyncState,\n readTextBase,\n removeSyncCheckpoint,\n sha256,\n updateSyncCheckpoint,\n} from './checkpoint';\nimport {mergeText} from './threeWayMerge';\n\nexport interface ReplicaFileSystem {\n listFiles(): Promise<string[]>;\n read(path:string): Promise<Uint8Array | undefined>;\n write(path:string, content:Uint8Array): Promise<void>;\n remove(path:string): Promise<void>;\n watch(onChange:(path:string) => void): Promise<() => Promise<void>>;\n}\n\nexport interface RemoteReplica {\n listEntries(): RemoteEntry[];\n entry(path:string): RemoteEntry | undefined;\n read(path:string): Promise<Uint8Array>;\n write(path:string, content:Uint8Array): Promise<void>;\n remove(path:string): Promise<void>;\n getCurrentVersion(): Promise<number>;\n getFileTreeDiff(from:number, to:number): Promise<ProjectFileTreeDiffResponseSchema | undefined>;\n onChange(handler:(change:{path:string; previousPath?:string}) => void): void;\n}\n\nexport interface SyncStateStore {\n load(): Promise<LocalReplicaSyncState | undefined>;\n save(state:LocalReplicaSyncState): Promise<void>;\n}\n\nexport interface SyncEngineOptions {\n projectUri:string;\n local:ReplicaFileSystem;\n remote:RemoteReplica;\n stateStore:SyncStateStore;\n ignore(path:string):boolean;\n log(message:string):void;\n onConflict(path:string, reason:string):void;\n}\n\ntype ChangeSource = 'local' | 'remote';\n\nfunction normalizePath(path:string):string {\n return `/${posix.normalize(path).replace(/^\\/+/, '')}`;\n}\n\nfunction isRemoteFile(entry:RemoteEntry|undefined):boolean {\n return entry?.type==='doc' || entry?.type==='file';\n}\n\nexport class SyncEngine {\n private state?: LocalReplicaSyncState;\n private queue:Promise<void> = Promise.resolve();\n private conflicts = new Set<string>();\n private stopLocalWatch?: () => Promise<void>;\n private eventTimers = new Map<string, NodeJS.Timeout>();\n\n constructor(private readonly options:SyncEngineOptions) {}\n\n async start():Promise<void> {\n this.state = await this.options.stateStore.load();\n const currentVersion = await this.options.remote.getCurrentVersion();\n const localFiles = await this.options.local.listFiles();\n const remoteFiles = this.remoteFilePaths();\n\n if (!this.state) {\n this.state = createSyncState(this.options.projectUri, currentVersion);\n if (localFiles.length!==0 && remoteFiles.length!==0) {\n throw new Error('Synchronization paused: both the local and Overleaf projects contain files, but no common checkpoint exists.');\n }\n const source:ChangeSource = localFiles.length===0 ? 'remote' : 'local';\n for (const path of source==='remote' ? remoteFiles : localFiles) {\n await this.reconcilePath(path, source);\n }\n this.state.remoteVersion = currentVersion;\n await this.options.stateStore.save(this.state);\n } else {\n await this.startupReconcile(currentVersion, localFiles, remoteFiles);\n }\n\n this.stopLocalWatch = await this.options.local.watch(path => this.schedule(path, 'local'));\n this.options.remote.onChange(change => {\n if (change.previousPath) { this.schedule(change.previousPath, 'remote'); }\n this.schedule(change.path, 'remote');\n });\n this.options.log(`Synchronization active at Overleaf version ${this.state.remoteVersion}.`);\n }\n\n async stop():Promise<void> {\n for (const timer of this.eventTimers.values()) { clearTimeout(timer); }\n this.eventTimers.clear();\n await this.stopLocalWatch?.();\n await this.queue;\n }\n\n private async startupReconcile(currentVersion:number, localFiles:string[], remoteFiles:string[]) {\n const state = this.state!;\n if (state.remoteVersion>currentVersion) {\n throw new Error('Synchronization paused: the local checkpoint is newer than the Overleaf project history.');\n }\n const localHashes = new Map<string,string>();\n for (const path of localFiles) {\n const content = await this.options.local.read(path);\n if (content) { localHashes.set(path, sha256(content)); }\n }\n const localChanged = new Set<string>();\n for (const path of new Set([...Object.keys(state.files), ...localFiles])) {\n if (state.files[path]!==localHashes.get(path)) { localChanged.add(path); }\n }\n\n let remoteDiff:ProjectFileTreeDiffResponseSchema|undefined = {diff:[]};\n if (state.remoteVersion<currentVersion) {\n remoteDiff = await this.options.remote.getFileTreeDiff(state.remoteVersion, currentVersion);\n if (!remoteDiff) {\n throw new Error('Synchronization paused: Overleaf history is unavailable, so remote changes cannot be distinguished safely.');\n }\n }\n const candidates = new Set<string>(localChanged);\n const knownFiles = new Set([...Object.keys(state.files), ...localFiles, ...remoteFiles]);\n for (const change of remoteDiff.diff) {\n const paths = [change.pathname, change.newPathname].filter((path):path is string => Boolean(path));\n for (const changedPath of paths.map(normalizePath)) {\n let matched = false;\n for (const filePath of knownFiles) {\n if (filePath===changedPath || filePath.startsWith(`${changedPath}/`)) {\n candidates.add(filePath);\n matched = true;\n }\n }\n if (!matched) { candidates.add(changedPath); }\n }\n }\n\n let failed = false;\n for (const path of [...candidates].sort()) {\n try {\n await this.reconcilePath(path, localChanged.has(path) ? 'local' : 'remote');\n } catch (error) {\n failed = true;\n this.options.log(`Failed to synchronize ${path}: ${error instanceof Error ? error.message : String(error)}`);\n }\n }\n if (failed || this.conflicts.size!==0) {\n throw new Error(`Synchronization paused for ${failed ? 'failed' : 'conflicting'} paths; successful paths were checkpointed.`);\n }\n state.remoteVersion = currentVersion;\n await this.options.stateStore.save(state);\n }\n\n private schedule(path:string, source:ChangeSource) {\n const normalized = normalizePath(path);\n if (this.shouldIgnore(normalized) || this.conflicts.has(normalized)) { return; }\n const previous = this.eventTimers.get(normalized);\n if (previous) { clearTimeout(previous); }\n this.eventTimers.set(normalized, setTimeout(() => {\n this.eventTimers.delete(normalized);\n this.queue = this.queue.then(() => this.reconcilePath(normalized, source)).catch(error => {\n this.options.log(`Failed to synchronize ${normalized}: ${error instanceof Error ? error.message : String(error)}`);\n });\n }, 250));\n }\n\n private async reconcilePath(path:string, source:ChangeSource):Promise<void> {\n const normalized = normalizePath(path);\n if (this.shouldIgnore(normalized) || this.conflicts.has(normalized)) { return; }\n const remoteEntry = this.options.remote.entry(normalized);\n if (remoteEntry?.type==='folder') { return; }\n const localContent = await this.options.local.read(normalized);\n const remoteContent = isRemoteFile(remoteEntry) ? await this.options.remote.read(normalized) : undefined;\n const baseHash = this.state!.files[normalized];\n const localHash = localContent && sha256(localContent);\n const remoteHash = remoteContent && sha256(remoteContent);\n\n if (localHash===remoteHash) {\n if (localContent) { updateSyncCheckpoint(this.state!, normalized, localContent); }\n else { removeSyncCheckpoint(this.state!, normalized); }\n await this.options.stateStore.save(this.state!);\n return;\n }\n\n const localChanged = localHash!==baseHash;\n const remoteChanged = remoteHash!==baseHash;\n if (localChanged && remoteChanged) {\n const base = readTextBase(this.state, normalized);\n if (base && localContent && remoteContent) {\n const merged = mergeText(base, localContent, remoteContent);\n if (merged.status==='merged' && merged.content) {\n await this.options.local.write(normalized, merged.content);\n await this.options.remote.write(normalized, merged.content);\n updateSyncCheckpoint(this.state!, normalized, merged.content);\n await this.options.stateStore.save(this.state!);\n this.options.log(`Merged non-overlapping local and Overleaf changes in ${normalized}.`);\n return;\n }\n }\n this.conflicts.add(normalized);\n const reason = 'Both local and Overleaf content changed since the last synchronized checkpoint.';\n this.options.onConflict(normalized, reason);\n return;\n }\n\n if (localChanged || (!remoteChanged && source==='local')) {\n if (!localContent) {\n if (remoteEntry) { await this.options.remote.remove(normalized); }\n removeSyncCheckpoint(this.state!, normalized);\n } else {\n await this.options.remote.write(normalized, localContent);\n const synchronized = await this.options.remote.read(normalized);\n if (sha256(synchronized)!==sha256(localContent)) {\n await this.options.local.write(normalized, synchronized);\n }\n updateSyncCheckpoint(this.state!, normalized, synchronized);\n }\n await this.options.stateStore.save(this.state!);\n return;\n }\n\n if (!remoteContent) {\n if (localContent) { await this.options.local.remove(normalized); }\n removeSyncCheckpoint(this.state!, normalized);\n } else {\n await this.options.local.write(normalized, remoteContent);\n updateSyncCheckpoint(this.state!, normalized, remoteContent);\n }\n await this.options.stateStore.save(this.state!);\n }\n\n private remoteFilePaths():string[] {\n return this.options.remote.listEntries()\n .filter(entry => isRemoteFile(entry) && !this.shouldIgnore(entry.path))\n .map(entry => entry.path);\n }\n\n private shouldIgnore(path:string):boolean {\n return this.options.ignore(path) || path.split('/').some(part => part.startsWith('.'));\n }\n}\n","import {createHash} from 'node:crypto';\nimport {encodeTextBase} from './threeWayMerge';\n\nexport const SYNC_STATE_SCHEMA_VERSION = 2;\n\nexport interface LocalReplicaSyncState {\n schemaVersion: number;\n projectUri: string;\n remoteVersion: number;\n files: {[path:string]: string};\n textBases: {[path:string]: string};\n}\n\nexport function sha256(content: Uint8Array): string {\n return createHash('sha256').update(content).digest('hex');\n}\n\nexport function parseSyncState(serialized: string, projectUri: string): LocalReplicaSyncState | undefined {\n try {\n const state = JSON.parse(serialized) as LocalReplicaSyncState;\n if ((state.schemaVersion!==1 && state.schemaVersion!==SYNC_STATE_SCHEMA_VERSION) ||\n state.projectUri!==projectUri ||\n !Number.isInteger(state.remoteVersion) ||\n typeof state.files!=='object' || state.files===null) {\n return undefined;\n }\n return {\n ...state,\n schemaVersion:SYNC_STATE_SCHEMA_VERSION,\n textBases:typeof state.textBases==='object' && state.textBases!==null ? state.textBases : {},\n };\n } catch {\n return undefined;\n }\n}\n\nexport function createSyncState(projectUri: string, remoteVersion: number): LocalReplicaSyncState {\n return {\n schemaVersion:SYNC_STATE_SCHEMA_VERSION,\n projectUri,\n remoteVersion,\n files:{},\n textBases:{},\n };\n}\n\nexport function updateSyncCheckpoint(state: LocalReplicaSyncState, path: string, content: Uint8Array) {\n state.files[path] = sha256(content);\n const textBase = encodeTextBase(content);\n if (textBase===undefined) {\n delete state.textBases[path];\n } else {\n state.textBases[path] = textBase;\n }\n}\n\nexport function removeSyncCheckpoint(state: LocalReplicaSyncState, path: string) {\n for (const checkpointPath of Object.keys(state.files)) {\n if (checkpointPath===path || checkpointPath.startsWith(`${path}/`)) {\n delete state.files[checkpointPath];\n delete state.textBases[checkpointPath];\n }\n }\n}\n\nexport function readTextBase(state: LocalReplicaSyncState | undefined, path: string): Uint8Array | undefined {\n const textBase = state?.textBases[path];\n return textBase===undefined ? undefined : new TextEncoder().encode(textBase);\n}\n","import {diff3Merge} from 'node-diff3';\n\nconst textDecoder = new TextDecoder('utf-8', {fatal:true});\nconst textEncoder = new TextEncoder();\n\nexport interface TextMergeResult {\n status: 'merged'|'conflict'|'binary';\n content?: Uint8Array;\n}\n\nfunction decodeText(content: Uint8Array): string | undefined {\n if (content.includes(0)) { return undefined; }\n try {\n return textDecoder.decode(content);\n } catch {\n return undefined;\n }\n}\n\nfunction splitLines(content: string): string[] {\n return content.match(/[^\\n]*\\n|[^\\n]+$/g) ?? [];\n}\n\nexport function encodeTextBase(content: Uint8Array): string | undefined {\n return decodeText(content);\n}\n\nexport function mergeText(\n baseContent: Uint8Array,\n localContent: Uint8Array,\n remoteContent: Uint8Array,\n): TextMergeResult {\n const base = decodeText(baseContent);\n const local = decodeText(localContent);\n const remote = decodeText(remoteContent);\n if (base===undefined || local===undefined || remote===undefined) {\n return {status:'binary'};\n }\n\n const regions = diff3Merge(\n splitLines(local),\n splitLines(base),\n splitLines(remote),\n {excludeFalseConflicts:true},\n );\n if (regions.some(region => region.conflict!==undefined)) {\n return {status:'conflict'};\n }\n return {\n status:'merged',\n content:textEncoder.encode(regions.flatMap(region => region.ok ?? []).join('')),\n };\n}\n","import {mkdir, readFile, writeFile} from 'node:fs/promises';\nimport {dirname, resolve} from 'node:path';\nimport {parseSyncState, type LocalReplicaSyncState} from '../sync/checkpoint';\nimport type {SyncStateStore} from '../sync/syncEngine';\n\nexport class FileSyncStateStore implements SyncStateStore {\n private readonly path:string;\n private serialized?:string;\n\n constructor(directory:string, private readonly projectUri:string) {\n this.path = resolve(directory, '.overleaf', 'sync-state.json');\n }\n\n async load():Promise<LocalReplicaSyncState|undefined> {\n try {\n const content = await readFile(this.path, 'utf8');\n const state = parseSyncState(content, this.projectUri);\n if (state) { this.serialized = `${JSON.stringify(state, null, 2)}\\n`; }\n return state;\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code==='ENOENT') { return undefined; }\n throw error;\n }\n }\n\n async save(state:LocalReplicaSyncState):Promise<void> {\n const serialized = `${JSON.stringify(state, null, 2)}\\n`;\n if (serialized===this.serialized) { return; }\n await mkdir(dirname(this.path), {recursive:true});\n await writeFile(this.path, serialized, 'utf8');\n this.serialized = serialized;\n }\n}\n"],"mappings":"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","names":["Blob","mkdir","readFile","writeFile","dirname","resolve","posix","createHash","error","content","entity","normalizePath"]}
|
package/dist/cli.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
#!/usr/bin/env node
|