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