mirror of
				https://github.com/zadam/trilium.git
				synced 2025-10-31 02:16:05 +01:00 
			
		
		
		
	client-ts: Port services/app/ws
This commit is contained in:
		| @@ -1,6 +1,6 @@ | ||||
| import dayjs from "dayjs"; | ||||
|  | ||||
| function reloadFrontendApp(reason: string) { | ||||
| function reloadFrontendApp(reason?: string) { | ||||
|     if (reason) { | ||||
|         logInfo(`Frontend app reload: ${reason}`); | ||||
|     } | ||||
| @@ -301,7 +301,7 @@ function dynamicRequire(moduleName: string) { | ||||
|     } | ||||
| } | ||||
|  | ||||
| function timeLimit<T>(promise: Promise<T>, limitMs: number, errorMessage: string) { | ||||
| function timeLimit<T>(promise: Promise<T>, limitMs: number, errorMessage?: string) { | ||||
|     if (!promise || !promise.then) { // it's not actually a promise | ||||
|         return promise; | ||||
|     } | ||||
|   | ||||
| @@ -4,17 +4,19 @@ import server from "./server.js"; | ||||
| import options from "./options.js"; | ||||
| import frocaUpdater from "./froca_updater.js"; | ||||
| import appContext from "../components/app_context.js"; | ||||
| import { EntityChange } from '../../../services/entity_changes_interface.js'; | ||||
| 
 | ||||
| const messageHandlers = []; | ||||
| type MessageHandler = (message: any) => void; | ||||
| const messageHandlers: MessageHandler[] = []; | ||||
| 
 | ||||
| let ws; | ||||
| let ws: WebSocket; | ||||
| let lastAcceptedEntityChangeId = window.glob.maxEntityChangeIdAtLoad; | ||||
| let lastAcceptedEntityChangeSyncId = window.glob.maxEntityChangeSyncIdAtLoad; | ||||
| let lastProcessedEntityChangeId = window.glob.maxEntityChangeIdAtLoad; | ||||
| let lastPingTs; | ||||
| let frontendUpdateDataQueue = []; | ||||
| let lastPingTs: number; | ||||
| let frontendUpdateDataQueue: EntityChange[] = []; | ||||
| 
 | ||||
| function logError(message) { | ||||
| function logError(message: string) { | ||||
|     console.error(utils.now(), message); // needs to be separate from .trace()
 | ||||
| 
 | ||||
|     if (ws && ws.readyState === 1) { | ||||
| @@ -26,7 +28,7 @@ function logError(message) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| function logInfo(message) { | ||||
| function logInfo(message: string) { | ||||
|     console.log(utils.now(), message); | ||||
| 
 | ||||
|     if (ws && ws.readyState === 1) { | ||||
| @@ -40,17 +42,17 @@ function logInfo(message) { | ||||
| window.logError = logError; | ||||
| window.logInfo = logInfo; | ||||
| 
 | ||||
| function subscribeToMessages(messageHandler) { | ||||
| function subscribeToMessages(messageHandler: MessageHandler) { | ||||
|     messageHandlers.push(messageHandler); | ||||
| } | ||||
| 
 | ||||
| // used to serialize frontend update operations
 | ||||
| let consumeQueuePromise = null; | ||||
| let consumeQueuePromise: Promise<void> | null = null; | ||||
| 
 | ||||
| // to make sure each change event is processed only once. Not clear if this is still necessary
 | ||||
| const processedEntityChangeIds = new Set(); | ||||
| 
 | ||||
| function logRows(entityChanges) { | ||||
| function logRows(entityChanges: EntityChange[]) { | ||||
|     const filteredRows = entityChanges.filter(row => | ||||
|         !processedEntityChangeIds.has(row.id) | ||||
|         && (row.entityName !== 'options' || row.entityId !== 'openNoteContexts')); | ||||
| @@ -60,7 +62,7 @@ function logRows(entityChanges) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async function executeFrontendUpdate(entityChanges) { | ||||
| async function executeFrontendUpdate(entityChanges: EntityChange[]) { | ||||
|     lastPingTs = Date.now(); | ||||
| 
 | ||||
|     if (entityChanges.length > 0) { | ||||
| @@ -71,6 +73,10 @@ async function executeFrontendUpdate(entityChanges) { | ||||
|         // we set lastAcceptedEntityChangeId even before frontend update processing and send ping so that backend can start sending more updates
 | ||||
| 
 | ||||
|         for (const entityChange of entityChanges) { | ||||
|             if (!entityChange.id) { | ||||
|                 continue; | ||||
|             } | ||||
| 
 | ||||
|             lastAcceptedEntityChangeId = Math.max(lastAcceptedEntityChangeId, entityChange.id); | ||||
| 
 | ||||
|             if (entityChange.isSynced) { | ||||
| @@ -97,7 +103,7 @@ async function executeFrontendUpdate(entityChanges) { | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| async function handleMessage(event) { | ||||
| async function handleMessage(event: MessageEvent<any>) { | ||||
|     const message = JSON.parse(event.data); | ||||
| 
 | ||||
|     for (const messageHandler of messageHandlers) { | ||||
| @@ -126,24 +132,32 @@ async function handleMessage(event) { | ||||
|         toastService.showMessage(message.message); | ||||
|     } | ||||
|     else if (message.type === 'execute-script') { | ||||
|         const bundleService = (await import("../services/bundle.js")).default; | ||||
|         const froca = (await import("../services/froca.js")).default; | ||||
|         // TODO: Remove after porting the file
 | ||||
|         // @ts-ignore
 | ||||
|         const bundleService = (await import("../services/bundle.js")).default as any; | ||||
|         // TODO: Remove after porting the file
 | ||||
|         // @ts-ignore
 | ||||
|         const froca = (await import("../services/froca.js")).default as any; | ||||
|         const originEntity = message.originEntityId ? await froca.getNote(message.originEntityId) : null; | ||||
| 
 | ||||
|         bundleService.getAndExecuteBundle(message.currentNoteId, originEntity, message.script, message.params); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| let entityChangeIdReachedListeners = []; | ||||
| let entityChangeIdReachedListeners: { | ||||
|     desiredEntityChangeId: number; | ||||
|     resolvePromise: () => void; | ||||
|     start: number; | ||||
| }[] = []; | ||||
| 
 | ||||
| function waitForEntityChangeId(desiredEntityChangeId) { | ||||
| function waitForEntityChangeId(desiredEntityChangeId: number) { | ||||
|     if (desiredEntityChangeId <= lastProcessedEntityChangeId) { | ||||
|         return Promise.resolve(); | ||||
|     } | ||||
| 
 | ||||
|     console.debug(`Waiting for ${desiredEntityChangeId}, last processed is ${lastProcessedEntityChangeId}, last accepted ${lastAcceptedEntityChangeId}`); | ||||
| 
 | ||||
|     return new Promise((res, rej) => { | ||||
|     return new Promise<void>((res, rej) => { | ||||
|         entityChangeIdReachedListeners.push({ | ||||
|             desiredEntityChangeId: desiredEntityChangeId, | ||||
|             resolvePromise: res, | ||||
| @@ -178,7 +192,7 @@ async function consumeFrontendUpdateData() { | ||||
|         try { | ||||
|             await utils.timeLimit(frocaUpdater.processEntityChanges(nonProcessedEntityChanges), 30000); | ||||
|         } | ||||
|         catch (e) { | ||||
|         catch (e: any) { | ||||
|             logError(`Encountered error ${e.message}: ${e.stack}, reloading frontend.`); | ||||
| 
 | ||||
|             if (!glob.isDev && !options.is('debugModeEnabled')) { | ||||
| @@ -196,7 +210,9 @@ async function consumeFrontendUpdateData() { | ||||
|         for (const entityChange of nonProcessedEntityChanges) { | ||||
|             processedEntityChangeIds.add(entityChange.id); | ||||
| 
 | ||||
|             lastProcessedEntityChangeId = Math.max(lastProcessedEntityChangeId, entityChange.id); | ||||
|             if (entityChange.id) { | ||||
|                 lastProcessedEntityChangeId = Math.max(lastProcessedEntityChangeId, entityChange.id); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| 
 | ||||
| @@ -248,3 +264,4 @@ export default { | ||||
|     waitForMaxKnownEntityChangeId, | ||||
|     getMaxKnownEntityChangeSyncId: () => lastAcceptedEntityChangeSyncId | ||||
| }; | ||||
| 
 | ||||
							
								
								
									
										2
									
								
								src/public/app/types.d.ts
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										2
									
								
								src/public/app/types.d.ts
									
									
									
									
										vendored
									
									
								
							| @@ -26,6 +26,8 @@ interface CustomGlobals { | ||||
|     baseApiUrl: string; | ||||
|     isProtectedSessionAvailable: boolean; | ||||
|     isDev: boolean; | ||||
|     maxEntityChangeIdAtLoad: number; | ||||
|     maxEntityChangeSyncIdAtLoad: number; | ||||
| } | ||||
|  | ||||
| type RequireMethod = (moduleName: string) => any; | ||||
|   | ||||
		Reference in New Issue
	
	Block a user