mirror of
https://github.com/zadam/trilium.git
synced 2025-10-20 07:08:55 +02:00
refactor: add typesafety to TaskContext
This commit is contained in:
parent
777d5ab3b7
commit
9c8b0611ea
@ -111,7 +111,7 @@ ws.subscribeToMessages(async (message) => {
|
||||
return;
|
||||
}
|
||||
|
||||
const isProtecting = message.data.protect;
|
||||
const isProtecting = message.data?.protect;
|
||||
const title = isProtecting ? t("protected_session.protecting-title") : t("protected_session.unprotecting-title");
|
||||
|
||||
if (message.type === "taskError") {
|
||||
|
@ -137,13 +137,13 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
|
||||
*
|
||||
* @returns true if note has been deleted, false otherwise
|
||||
*/
|
||||
deleteBranch(deleteId?: string, taskContext?: TaskContext): boolean {
|
||||
deleteBranch(deleteId?: string, taskContext?: TaskContext<"deleteNotes">): boolean {
|
||||
if (!deleteId) {
|
||||
deleteId = utils.randomString(10);
|
||||
}
|
||||
|
||||
if (!taskContext) {
|
||||
taskContext = new TaskContext("no-progress-reporting");
|
||||
taskContext = new TaskContext("no-progress-reporting", "deleteNotes", null);
|
||||
}
|
||||
|
||||
taskContext.increaseProgressCount();
|
||||
|
@ -1512,7 +1512,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
||||
*
|
||||
* @param deleteId - optional delete identified
|
||||
*/
|
||||
deleteNote(deleteId: string | null = null, taskContext: TaskContext | null = null) {
|
||||
deleteNote(deleteId: string | null = null, taskContext: TaskContext<"deleteNotes"> | null = null) {
|
||||
if (this.isDeleted) {
|
||||
return;
|
||||
}
|
||||
@ -1522,7 +1522,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
|
||||
}
|
||||
|
||||
if (!taskContext) {
|
||||
taskContext = new TaskContext("no-progress-reporting");
|
||||
taskContext = new TaskContext("no-progress-reporting", "deleteNotes", null);
|
||||
}
|
||||
|
||||
// needs to be run before branches and attributes are deleted and thus attached relations disappear
|
||||
|
@ -108,7 +108,7 @@ function register(router: Router) {
|
||||
return res.sendStatus(204);
|
||||
}
|
||||
|
||||
note.deleteNote(null, new TaskContext("no-progress-reporting"));
|
||||
note.deleteNote(null, new TaskContext("no-progress-reporting", "deleteNotes", null));
|
||||
|
||||
res.sendStatus(204);
|
||||
});
|
||||
@ -153,7 +153,7 @@ function register(router: Router) {
|
||||
throw new eu.EtapiError(400, "UNRECOGNIZED_EXPORT_FORMAT", `Unrecognized export format '${format}', supported values are 'html' (default) or 'markdown'.`);
|
||||
}
|
||||
|
||||
const taskContext = new TaskContext("no-progress-reporting");
|
||||
const taskContext = new TaskContext("no-progress-reporting", "export", null);
|
||||
|
||||
// technically a branch is being exported (includes prefix), but it's such a minor difference yet usability pain
|
||||
// (e.g. branchIds are not seen in UI), that we export "note export" instead.
|
||||
@ -164,7 +164,7 @@ function register(router: Router) {
|
||||
|
||||
eu.route(router, "post", "/etapi/notes/:noteId/import", (req, res, next) => {
|
||||
const note = eu.getAndCheckNote(req.params.noteId);
|
||||
const taskContext = new TaskContext("no-progress-reporting");
|
||||
const taskContext = new TaskContext("no-progress-reporting", "importNotes", null);
|
||||
|
||||
zipImportService.importZip(taskContext, req.body, note).then((importedNote) => {
|
||||
res.status(201).json({
|
||||
|
@ -236,7 +236,7 @@ function deleteBranch(req: Request) {
|
||||
const eraseNotes = req.query.eraseNotes === "true";
|
||||
const branch = becca.getBranchOrThrow(req.params.branchId);
|
||||
|
||||
const taskContext = TaskContext.getInstance(req.query.taskId as string, "deleteNotes");
|
||||
const taskContext = TaskContext.getInstance(req.query.taskId as string, "deleteNotes", null);
|
||||
|
||||
const deleteId = utils.randomString(10);
|
||||
let noteDeleted;
|
||||
@ -251,7 +251,7 @@ function deleteBranch(req: Request) {
|
||||
}
|
||||
|
||||
if (last) {
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
|
||||
return {
|
||||
|
@ -23,7 +23,7 @@ function exportBranch(req: Request, res: Response) {
|
||||
return;
|
||||
}
|
||||
|
||||
const taskContext = new TaskContext(taskId, "export");
|
||||
const taskContext = new TaskContext(taskId, "export", null);
|
||||
|
||||
try {
|
||||
if (type === "subtree" && (format === "html" || format === "markdown")) {
|
||||
|
@ -116,7 +116,7 @@ function importAttachmentsToNote(req: Request) {
|
||||
}
|
||||
|
||||
const parentNote = becca.getNoteOrThrow(parentNoteId);
|
||||
const taskContext = TaskContext.getInstance(taskId, "importAttachment", options);
|
||||
const taskContext = TaskContext.getInstance(taskId, "importNotes", options);
|
||||
|
||||
// unlike in note import, we let the events run, because a huge number of attachments is not likely
|
||||
|
||||
|
@ -184,7 +184,7 @@ function deleteNote(req: Request) {
|
||||
if (typeof taskId !== "string") {
|
||||
throw new ValidationError("Missing or incorrect type for task ID.");
|
||||
}
|
||||
const taskContext = TaskContext.getInstance(taskId, "deleteNotes");
|
||||
const taskContext = TaskContext.getInstance(taskId, "deleteNotes", null);
|
||||
|
||||
note.deleteNote(deleteId, taskContext);
|
||||
|
||||
@ -193,16 +193,16 @@ function deleteNote(req: Request) {
|
||||
}
|
||||
|
||||
if (last) {
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
}
|
||||
|
||||
function undeleteNote(req: Request) {
|
||||
const taskContext = TaskContext.getInstance(utils.randomString(10), "undeleteNotes");
|
||||
const taskContext = TaskContext.getInstance(utils.randomString(10), "undeleteNotes", null);
|
||||
|
||||
noteService.undeleteNote(req.params.noteId, taskContext);
|
||||
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
|
||||
function sortChildNotes(req: Request) {
|
||||
@ -226,7 +226,7 @@ function protectNote(req: Request) {
|
||||
|
||||
noteService.protectNoteRecursively(note, protect, includingSubTree, taskContext);
|
||||
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
|
||||
function setNoteTypeMime(req: Request) {
|
||||
|
@ -6,7 +6,7 @@ import type TaskContext from "../task_context.js";
|
||||
import type BBranch from "../../becca/entities/bbranch.js";
|
||||
import type { Response } from "express";
|
||||
|
||||
function exportToOpml(taskContext: TaskContext, branch: BBranch, version: string, res: Response) {
|
||||
function exportToOpml(taskContext: TaskContext<"export">, branch: BBranch, version: string, res: Response) {
|
||||
if (!["1.0", "2.0"].includes(version)) {
|
||||
throw new Error(`Unrecognized OPML version ${version}`);
|
||||
}
|
||||
@ -77,7 +77,7 @@ function exportToOpml(taskContext: TaskContext, branch: BBranch, version: string
|
||||
</opml>`);
|
||||
res.end();
|
||||
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
|
||||
function prepareText(text: string) {
|
||||
|
@ -10,7 +10,7 @@ import type BBranch from "../../becca/entities/bbranch.js";
|
||||
import type { Response } from "express";
|
||||
import type BNote from "../../becca/entities/bnote.js";
|
||||
|
||||
function exportSingleNote(taskContext: TaskContext, branch: BBranch, format: "html" | "markdown", res: Response) {
|
||||
function exportSingleNote(taskContext: TaskContext<"export">, branch: BBranch, format: "html" | "markdown", res: Response) {
|
||||
const note = branch.getNote();
|
||||
|
||||
if (note.type === "image" || note.type === "file") {
|
||||
@ -30,7 +30,7 @@ function exportSingleNote(taskContext: TaskContext, branch: BBranch, format: "ht
|
||||
res.send(payload);
|
||||
|
||||
taskContext.increaseProgressCount();
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
}
|
||||
|
||||
export function mapByNoteType(note: BNote, content: string | Buffer<ArrayBufferLike>, format: "html" | "markdown") {
|
||||
|
@ -40,7 +40,7 @@ export interface AdvancedExportOptions {
|
||||
customRewriteLinks?: (originalRewriteLinks: RewriteLinksFn, getNoteTargetUrl: (targetNoteId: string, sourceMeta: NoteMeta) => string | null) => RewriteLinksFn;
|
||||
}
|
||||
|
||||
async function exportToZip(taskContext: TaskContext, branch: BBranch, format: "html" | "markdown", res: Response | fs.WriteStream, setHeaders = true, zipExportOptions?: AdvancedExportOptions) {
|
||||
async function exportToZip(taskContext: TaskContext<"export">, branch: BBranch, format: "html" | "markdown", res: Response | fs.WriteStream, setHeaders = true, zipExportOptions?: AdvancedExportOptions) {
|
||||
if (!["html", "markdown"].includes(format)) {
|
||||
throw new ValidationError(`Only 'html' and 'markdown' allowed as export format, '${format}' given`);
|
||||
}
|
||||
@ -611,7 +611,7 @@ ${markdownContent}`;
|
||||
|
||||
archive.pipe(res);
|
||||
await archive.finalize();
|
||||
taskContext.taskSucceeded();
|
||||
taskContext.taskSucceeded(null);
|
||||
} catch (e: unknown) {
|
||||
const message = `Export failed with error: ${e instanceof Error ? e.message : String(e)}`;
|
||||
log.error(message);
|
||||
@ -627,7 +627,7 @@ ${markdownContent}`;
|
||||
|
||||
async function exportToZipFile(noteId: string, format: "markdown" | "html", zipFilePath: string, zipExportOptions?: AdvancedExportOptions) {
|
||||
const fileOutputStream = fs.createWriteStream(zipFilePath);
|
||||
const taskContext = new TaskContext("no-progress-reporting");
|
||||
const taskContext = new TaskContext("no-progress-reporting", "export", null);
|
||||
|
||||
const note = becca.getNote(noteId);
|
||||
|
||||
|
@ -55,7 +55,7 @@ interface Note {
|
||||
let note: Partial<Note> = {};
|
||||
let resource: Resource;
|
||||
|
||||
function importEnex(taskContext: TaskContext, file: File, parentNote: BNote): Promise<BNote> {
|
||||
function importEnex(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote): Promise<BNote> {
|
||||
const saxStream = sax.createStream(true);
|
||||
|
||||
const rootNoteTitle = file.originalname.toLowerCase().endsWith(".enex") ? file.originalname.substr(0, file.originalname.length - 5) : file.originalname;
|
||||
|
@ -91,14 +91,14 @@ function getMime(fileName: string) {
|
||||
return mimeFromExt || mimeTypes.lookup(fileNameLc);
|
||||
}
|
||||
|
||||
function getType(options: TaskData, mime: string): NoteType {
|
||||
function getType(options: TaskData<"importNotes">, mime: string): NoteType {
|
||||
const mimeLc = mime?.toLowerCase();
|
||||
|
||||
switch (true) {
|
||||
case options.textImportedAsText && ["text/html", "text/markdown", "text/x-markdown", "text/mdx"].includes(mimeLc):
|
||||
case options?.textImportedAsText && ["text/html", "text/markdown", "text/x-markdown", "text/mdx"].includes(mimeLc):
|
||||
return "text";
|
||||
|
||||
case options.codeImportedAsCode && CODE_MIME_TYPES.has(mimeLc):
|
||||
case options?.codeImportedAsCode && CODE_MIME_TYPES.has(mimeLc):
|
||||
return "code";
|
||||
|
||||
case mime.startsWith("image/"):
|
||||
|
@ -28,7 +28,7 @@ interface OpmlOutline {
|
||||
outline: OpmlOutline[];
|
||||
}
|
||||
|
||||
async function importOpml(taskContext: TaskContext, fileBuffer: string | Buffer, parentNote: BNote) {
|
||||
async function importOpml(taskContext: TaskContext<"importNotes">, fileBuffer: string | Buffer, parentNote: BNote) {
|
||||
const xml = await new Promise<OpmlXml>(function (resolve, reject) {
|
||||
parseString(fileBuffer, function (err: any, result: OpmlXml) {
|
||||
if (err) {
|
||||
|
@ -14,7 +14,7 @@ import htmlSanitizer from "../html_sanitizer.js";
|
||||
import type { File } from "./common.js";
|
||||
import type { NoteType } from "@triliumnext/commons";
|
||||
|
||||
function importSingleFile(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importSingleFile(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
const mime = mimeService.getMime(file.originalname) || file.mimetype;
|
||||
|
||||
if (taskContext?.data?.textImportedAsText) {
|
||||
@ -42,7 +42,7 @@ function importSingleFile(taskContext: TaskContext, file: File, parentNote: BNot
|
||||
return importFile(taskContext, file, parentNote);
|
||||
}
|
||||
|
||||
function importImage(file: File, parentNote: BNote, taskContext: TaskContext) {
|
||||
function importImage(file: File, parentNote: BNote, taskContext: TaskContext<"importNotes">) {
|
||||
if (typeof file.buffer === "string") {
|
||||
throw new Error("Invalid file content for image.");
|
||||
}
|
||||
@ -53,7 +53,7 @@ function importImage(file: File, parentNote: BNote, taskContext: TaskContext) {
|
||||
return note;
|
||||
}
|
||||
|
||||
function importFile(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importFile(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
const originalName = file.originalname;
|
||||
|
||||
const { note } = noteService.createNewNote({
|
||||
@ -72,7 +72,7 @@ function importFile(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
return note;
|
||||
}
|
||||
|
||||
function importCodeNote(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importCodeNote(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
const title = getNoteTitle(file.originalname, !!taskContext.data?.replaceUnderscoresWithSpaces);
|
||||
const content = processStringOrBuffer(file.buffer);
|
||||
const detectedMime = mimeService.getMime(file.originalname) || file.mimetype;
|
||||
@ -97,7 +97,7 @@ function importCodeNote(taskContext: TaskContext, file: File, parentNote: BNote)
|
||||
return note;
|
||||
}
|
||||
|
||||
function importCustomType(taskContext: TaskContext, file: File, parentNote: BNote, type: NoteType, mime: string) {
|
||||
function importCustomType(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote, type: NoteType, mime: string) {
|
||||
const title = getNoteTitle(file.originalname, !!taskContext.data?.replaceUnderscoresWithSpaces);
|
||||
const content = processStringOrBuffer(file.buffer);
|
||||
|
||||
@ -115,7 +115,7 @@ function importCustomType(taskContext: TaskContext, file: File, parentNote: BNot
|
||||
return note;
|
||||
}
|
||||
|
||||
function importPlainText(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importPlainText(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
const title = getNoteTitle(file.originalname, !!taskContext.data?.replaceUnderscoresWithSpaces);
|
||||
const plainTextContent = processStringOrBuffer(file.buffer);
|
||||
const htmlContent = convertTextToHtml(plainTextContent);
|
||||
@ -150,7 +150,7 @@ function convertTextToHtml(text: string) {
|
||||
return text;
|
||||
}
|
||||
|
||||
function importMarkdown(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importMarkdown(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
const title = getNoteTitle(file.originalname, !!taskContext.data?.replaceUnderscoresWithSpaces);
|
||||
|
||||
const markdownContent = processStringOrBuffer(file.buffer);
|
||||
@ -174,7 +174,7 @@ function importMarkdown(taskContext: TaskContext, file: File, parentNote: BNote)
|
||||
return note;
|
||||
}
|
||||
|
||||
function importHtml(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importHtml(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
let content = processStringOrBuffer(file.buffer);
|
||||
|
||||
// Try to get title from HTML first, fall back to filename
|
||||
@ -202,7 +202,7 @@ function importHtml(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
return note;
|
||||
}
|
||||
|
||||
function importAttachment(taskContext: TaskContext, file: File, parentNote: BNote) {
|
||||
function importAttachment(taskContext: TaskContext<"importNotes">, file: File, parentNote: BNote) {
|
||||
const mime = mimeService.getMime(file.originalname) || file.mimetype;
|
||||
|
||||
if (mime.startsWith("image/") && typeof file.buffer !== "string") {
|
||||
|
@ -30,7 +30,7 @@ interface ImportZipOpts {
|
||||
preserveIds?: boolean;
|
||||
}
|
||||
|
||||
async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRootNote: BNote, opts?: ImportZipOpts): Promise<BNote> {
|
||||
async function importZip(taskContext: TaskContext<"importNotes">, fileBuffer: Buffer, importRootNote: BNote, opts?: ImportZipOpts): Promise<BNote> {
|
||||
/** maps from original noteId (in ZIP file) to newly generated noteId */
|
||||
const noteIdMap: Record<string, string> = {};
|
||||
/** type maps from original attachmentId (in ZIP file) to newly generated attachmentId */
|
||||
@ -174,7 +174,7 @@ async function importZip(taskContext: TaskContext, fileBuffer: Buffer, importRoo
|
||||
return noteId;
|
||||
}
|
||||
|
||||
function detectFileTypeAndMime(taskContext: TaskContext, filePath: string) {
|
||||
function detectFileTypeAndMime(taskContext: TaskContext<"importNotes">, filePath: string) {
|
||||
const mime = mimeService.getMime(filePath) || "application/octet-stream";
|
||||
const type = mimeService.getType(taskContext.data || {}, mime);
|
||||
|
||||
|
@ -296,7 +296,7 @@ function createNewNoteWithTarget(target: "into" | "after" | "before", targetBran
|
||||
}
|
||||
}
|
||||
|
||||
function protectNoteRecursively(note: BNote, protect: boolean, includingSubTree: boolean, taskContext: TaskContext) {
|
||||
function protectNoteRecursively(note: BNote, protect: boolean, includingSubTree: boolean, taskContext: TaskContext<"protectNotes">) {
|
||||
protectNote(note, protect);
|
||||
|
||||
taskContext.increaseProgressCount();
|
||||
@ -765,7 +765,7 @@ function updateNoteData(noteId: string, content: string, attachments: Attachment
|
||||
}
|
||||
}
|
||||
|
||||
function undeleteNote(noteId: string, taskContext: TaskContext) {
|
||||
function undeleteNote(noteId: string, taskContext: TaskContext<"undeleteNotes">) {
|
||||
const noteRow = sql.getRow<NoteRow>("SELECT * FROM notes WHERE noteId = ?", [noteId]);
|
||||
|
||||
if (!noteRow.isDeleted || !noteRow.deleteId) {
|
||||
@ -785,7 +785,7 @@ function undeleteNote(noteId: string, taskContext: TaskContext) {
|
||||
}
|
||||
}
|
||||
|
||||
function undeleteBranch(branchId: string, deleteId: string, taskContext: TaskContext) {
|
||||
function undeleteBranch(branchId: string, deleteId: string, taskContext: TaskContext<"undeleteNotes">) {
|
||||
const branchRow = sql.getRow<BranchRow>("SELECT * FROM branches WHERE branchId = ?", [branchId]);
|
||||
|
||||
if (!branchRow.isDeleted) {
|
||||
|
@ -122,7 +122,7 @@ async function createInitialDatabase(skipDemoDb?: boolean) {
|
||||
|
||||
log.info("Importing demo content ...");
|
||||
|
||||
const dummyTaskContext = new TaskContext("no-progress-reporting", "import", false);
|
||||
const dummyTaskContext = new TaskContext("no-progress-reporting", "importNotes", null);
|
||||
|
||||
if (demoFile) {
|
||||
await zipImportService.importZip(dummyTaskContext, demoFile, rootNote);
|
||||
|
@ -1,20 +1,20 @@
|
||||
"use strict";
|
||||
|
||||
import type { TaskType } from "@triliumnext/commons";
|
||||
import type { TaskData, TaskResult, TaskType, WebSocketMessage } from "@triliumnext/commons";
|
||||
import ws from "./ws.js";
|
||||
|
||||
// taskId => TaskContext
|
||||
const taskContexts: Record<string, TaskContext<TaskType>> = {};
|
||||
const taskContexts: Record<string, TaskContext<any>> = {};
|
||||
|
||||
class TaskContext<TaskTypeT extends TaskType> {
|
||||
class TaskContext<T extends TaskType> {
|
||||
private taskId: string;
|
||||
private taskType: TaskType;
|
||||
private progressCount: number;
|
||||
private lastSentCountTs: number;
|
||||
data: TaskData | null;
|
||||
data: TaskData<T>;
|
||||
noteDeletionHandlerTriggered: boolean;
|
||||
|
||||
constructor(taskId: string, taskType: TaskTypeT, data: {} | null = {}) {
|
||||
constructor(taskId: string, taskType: T, data: TaskData<T>) {
|
||||
this.taskId = taskId;
|
||||
this.taskType = taskType;
|
||||
this.data = data;
|
||||
@ -31,7 +31,7 @@ class TaskContext<TaskTypeT extends TaskType> {
|
||||
this.increaseProgressCount();
|
||||
}
|
||||
|
||||
static getInstance<TaskTypeT extends TaskType>(taskId: string, taskType: TaskTypeT, data: {} | null = null): TaskContext<TaskTypeT> {
|
||||
static getInstance<T extends TaskType>(taskId: string, taskType: T, data: TaskData<T>): TaskContext<T> {
|
||||
if (!taskContexts[taskId]) {
|
||||
taskContexts[taskId] = new TaskContext(taskId, taskType, data);
|
||||
}
|
||||
@ -51,7 +51,7 @@ class TaskContext<TaskTypeT extends TaskType> {
|
||||
taskType: this.taskType,
|
||||
data: this.data,
|
||||
progressCount: this.progressCount
|
||||
});
|
||||
} as WebSocketMessage);
|
||||
}
|
||||
}
|
||||
|
||||
@ -62,17 +62,17 @@ class TaskContext<TaskTypeT extends TaskType> {
|
||||
taskType: this.taskType,
|
||||
data: this.data,
|
||||
message
|
||||
});
|
||||
} as WebSocketMessage);
|
||||
}
|
||||
|
||||
taskSucceeded(result?: string | Record<string, string | undefined>) {
|
||||
taskSucceeded(result: TaskResult<T>) {
|
||||
ws.sendMessageToAllClients({
|
||||
type: "taskSucceeded",
|
||||
taskId: this.taskId,
|
||||
taskType: this.taskType,
|
||||
data: this.data,
|
||||
result
|
||||
});
|
||||
} as WebSocketMessage);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -13,7 +13,7 @@ import type { IncomingMessage, Server as HttpServer } from "http";
|
||||
import { WebSocketMessage, type EntityChange } from "@triliumnext/commons";
|
||||
|
||||
let webSocketServer!: WebSocketServer;
|
||||
let lastSyncedPush: number | null = null;
|
||||
let lastSyncedPush: number;
|
||||
|
||||
type SessionParser = (req: IncomingMessage, params: {}, cb: () => void) => void;
|
||||
function init(httpServer: HttpServer, sessionParser: SessionParser) {
|
||||
|
@ -26,37 +26,64 @@ export interface EntityChangeRecord {
|
||||
entity?: EntityRow;
|
||||
}
|
||||
|
||||
type TaskStatus<TypeT, DataT, ResultT> = {
|
||||
type TaskDataDefinitions = {
|
||||
empty: null,
|
||||
deleteNotes: null,
|
||||
undeleteNotes: null,
|
||||
export: null,
|
||||
protectNotes: {
|
||||
protect: boolean;
|
||||
}
|
||||
importNotes: {
|
||||
textImportedAsText?: boolean;
|
||||
codeImportedAsCode?: boolean;
|
||||
replaceUnderscoresWithSpaces?: boolean;
|
||||
shrinkImages?: boolean;
|
||||
safeImport?: boolean;
|
||||
} | null,
|
||||
importAttachments: null
|
||||
}
|
||||
|
||||
type TaskResultDefinitions = {
|
||||
empty: null,
|
||||
deleteNotes: null,
|
||||
undeleteNotes: null,
|
||||
export: null,
|
||||
protectNotes: null,
|
||||
importNotes: {
|
||||
parentNoteId?: string;
|
||||
importedNoteId?: string
|
||||
};
|
||||
importAttachments: {
|
||||
parentNoteId?: string;
|
||||
importedNoteId?: string
|
||||
};
|
||||
}
|
||||
|
||||
export type TaskType = keyof TaskDataDefinitions | keyof TaskResultDefinitions;
|
||||
export type TaskData<T extends TaskType> = TaskDataDefinitions[T];
|
||||
export type TaskResult<T extends TaskType> = TaskResultDefinitions[T];
|
||||
|
||||
type TaskDefinition<T extends TaskType> = {
|
||||
type: "taskProgressCount",
|
||||
taskId: string;
|
||||
taskType: TypeT;
|
||||
data: DataT,
|
||||
taskType: T;
|
||||
data: TaskData<T>,
|
||||
progressCount: number
|
||||
} | {
|
||||
type: "taskError",
|
||||
taskId: string;
|
||||
taskType: TypeT;
|
||||
data: DataT;
|
||||
taskType: T;
|
||||
data: TaskData<T>,
|
||||
message: string;
|
||||
} | {
|
||||
type: "taskSucceeded",
|
||||
taskId: string;
|
||||
taskType: TypeT;
|
||||
data: DataT;
|
||||
result: ResultT;
|
||||
taskType: T;
|
||||
data: TaskData<T>,
|
||||
result: TaskResult<T>;
|
||||
}
|
||||
|
||||
type TaskDefinitions =
|
||||
TaskStatus<"protectNotes", { protect: boolean; }, null>
|
||||
| TaskStatus<"importNotes", null, { importedNoteId: string }>
|
||||
| TaskStatus<"importAttachments", null, { parentNoteId?: string; importedNoteId: string }>
|
||||
| TaskStatus<"deleteNotes", null, null>
|
||||
| TaskStatus<"undeleteNotes", null, null>
|
||||
| TaskStatus<"export", null, null>
|
||||
;
|
||||
|
||||
export type TaskType = TaskDefinitions["taskType"];
|
||||
|
||||
export interface OpenedFileUpdateStatus {
|
||||
entityType: string;
|
||||
entityId: string;
|
||||
@ -64,7 +91,16 @@ export interface OpenedFileUpdateStatus {
|
||||
filePath: string;
|
||||
}
|
||||
|
||||
export type WebSocketMessage = TaskDefinitions | {
|
||||
type AllTaskDefinitions =
|
||||
| TaskDefinition<"empty">
|
||||
| TaskDefinition<"deleteNotes">
|
||||
| TaskDefinition<"undeleteNotes">
|
||||
| TaskDefinition<"export">
|
||||
| TaskDefinition<"protectNotes">
|
||||
| TaskDefinition<"importNotes">
|
||||
| TaskDefinition<"importAttachments">;
|
||||
|
||||
export type WebSocketMessage = AllTaskDefinitions | {
|
||||
type: "ping"
|
||||
} | {
|
||||
type: "frontend-update",
|
||||
|
Loading…
x
Reference in New Issue
Block a user