server-ts: Port becca_loader

This commit is contained in:
Elian Doran 2024-02-17 20:45:31 +02:00
parent 3d5ef81860
commit d35613f510
No known key found for this signature in database
13 changed files with 61 additions and 56 deletions

View File

@ -1,5 +1,5 @@
module.exports = () => {
const beccaLoader = require('../../src/becca/becca_loader.js');
const beccaLoader = require('../../src/becca/becca_loader');
const becca = require('../../src/becca/becca.js');
const cls = require('../../src/services/cls');
const log = require('../../src/services/log');

View File

@ -8,7 +8,7 @@ const sessionParser = require('./routes/session_parser.js');
const utils = require('./services/utils');
require('./services/handlers.js');
require('./becca/becca_loader.js');
require('./becca/becca_loader');
const app = express();

View File

@ -1,19 +1,20 @@
"use strict";
const sql = require('../services/sql');
const eventService = require('../services/events');
const becca = require('./becca');
const sqlInit = require('../services/sql_init');
const log = require('../services/log');
const BNote = require('./entities/bnote');
const BBranch = require('./entities/bbranch');
const BAttribute = require('./entities/battribute');
const BOption = require('./entities/boption');
const BEtapiToken = require('./entities/betapi_token');
const cls = require('../services/cls');
const entityConstructor = require('../becca/entity_constructor');
import sql = require('../services/sql');
import eventService = require('../services/events');
import becca = require('./becca');
import sqlInit = require('../services/sql_init');
import log = require('../services/log');
import BNote = require('./entities/bnote');
import BBranch = require('./entities/bbranch');
import BAttribute = require('./entities/battribute');
import BOption = require('./entities/boption');
import BEtapiToken = require('./entities/betapi_token');
import cls = require('../services/cls');
import entityConstructor = require('../becca/entity_constructor');
import { AttributeRow, BranchRow, EtapiTokenRow, NoteRow, OptionRow } from './entities/rows';
const beccaLoaded = new Promise((res, rej) => {
const beccaLoaded = new Promise<void>((res, rej) => {
sqlInit.dbReady.then(() => {
cls.init(() => {
load();
@ -38,7 +39,7 @@ function load() {
new BNote().update(row).init();
}
const branchRows = sql.getRawRows(`SELECT branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0`);
const branchRows = sql.getRawRows<{ notePosition: number}>(`SELECT branchId, noteId, parentNoteId, prefix, notePosition, isExpanded, utcDateModified FROM branches WHERE isDeleted = 0`);
// in-memory sort is faster than in the DB
branchRows.sort((a, b) => a.notePosition - b.notePosition);
@ -46,15 +47,15 @@ function load() {
new BBranch().update(row).init();
}
for (const row of sql.getRawRows(`SELECT attributeId, noteId, type, name, value, isInheritable, position, utcDateModified FROM attributes WHERE isDeleted = 0`)) {
for (const row of sql.getRawRows<AttributeRow>(`SELECT attributeId, noteId, type, name, value, isInheritable, position, utcDateModified FROM attributes WHERE isDeleted = 0`)) {
new BAttribute().update(row).init();
}
for (const row of sql.getRows(`SELECT name, value, isSynced, utcDateModified FROM options`)) {
for (const row of sql.getRows<OptionRow>(`SELECT name, value, isSynced, utcDateModified FROM options`)) {
new BOption(row);
}
for (const row of sql.getRows(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
for (const row of sql.getRows<EtapiTokenRow>(`SELECT etapiTokenId, name, tokenHash, utcDateCreated, utcDateModified FROM etapi_tokens WHERE isDeleted = 0`)) {
new BEtapiToken(row);
}
});
@ -68,7 +69,7 @@ function load() {
log.info(`Becca (note cache) load took ${Date.now() - start}ms`);
}
function reload(reason) {
function reload(reason: string) {
load();
require('../services/ws').reloadFrontend(reason || "becca reloaded");
@ -112,7 +113,7 @@ eventService.subscribeBeccaLoader(eventService.ENTITY_CHANGED, ({entityName, en
* @param entityRow - can be a becca entity (change comes from this trilium instance) or just a row (from sync).
* It should be therefore treated as a row.
*/
function postProcessEntityUpdate(entityName, entityRow) {
function postProcessEntityUpdate(entityName: string, entityRow: any) {
if (entityName === 'notes') {
noteUpdated(entityRow);
} else if (entityName === 'branches') {
@ -140,13 +141,13 @@ eventService.subscribeBeccaLoader([eventService.ENTITY_DELETED, eventService.ENT
}
});
function noteDeleted(noteId) {
function noteDeleted(noteId: string) {
delete becca.notes[noteId];
becca.dirtyNoteSetCache();
}
function branchDeleted(branchId) {
function branchDeleted(branchId: string) {
const branch = becca.branches[branchId];
if (!branch) {
@ -173,23 +174,26 @@ function branchDeleted(branchId) {
}
delete becca.childParentToBranch[`${branch.noteId}-${branch.parentNoteId}`];
delete becca.branches[branch.branchId];
}
function noteUpdated(entityRow) {
const note = becca.notes[entityRow.noteId];
if (note) {
// type / mime could have been changed, and they are present in flatTextCache
note.flatTextCache = null;
if (branch.branchId) {
delete becca.branches[branch.branchId];
}
}
function branchUpdated(branchRow) {
function noteUpdated(entityRow: NoteRow) {
const note = becca.notes[entityRow.noteId];
if (note) {
// FIXME, this wouldn't have worked in the original implementation since the variable was named __flatTextCache.
// type / mime could have been changed, and they are present in flatTextCache
note.__flatTextCache = null;
}
}
function branchUpdated(branchRow: BranchRow) {
const childNote = becca.notes[branchRow.noteId];
if (childNote) {
childNote.flatTextCache = null;
childNote.__flatTextCache = null;
childNote.sortParents();
// notes in the subtree can get new inherited attributes
@ -204,7 +208,7 @@ function branchUpdated(branchRow) {
}
}
function attributeDeleted(attributeId) {
function attributeDeleted(attributeId: string) {
const attribute = becca.attributes[attributeId];
if (!attribute) {
@ -239,8 +243,7 @@ function attributeDeleted(attributeId) {
}
}
/** @param {BAttribute} attributeRow */
function attributeUpdated(attributeRow) {
function attributeUpdated(attributeRow: BAttribute) {
const attribute = becca.attributes[attributeRow.attributeId];
const note = becca.notes[attributeRow.noteId];
@ -253,7 +256,7 @@ function attributeUpdated(attributeRow) {
}
}
function noteReorderingUpdated(branchIdList) {
function noteReorderingUpdated(branchIdList: number[]) {
const parentNoteIds = new Set();
for (const branchId in branchIdList) {
@ -267,7 +270,7 @@ function noteReorderingUpdated(branchIdList) {
}
}
function etapiTokenDeleted(etapiTokenId) {
function etapiTokenDeleted(etapiTokenId: string) {
delete becca.etapiTokens[etapiTokenId];
}
@ -275,14 +278,14 @@ eventService.subscribeBeccaLoader(eventService.ENTER_PROTECTED_SESSION, () => {
try {
becca.decryptProtectedNotes();
}
catch (e) {
catch (e: any) {
log.error(`Could not decrypt protected notes: ${e.message} ${e.stack}`);
}
});
eventService.subscribeBeccaLoader(eventService.LEAVE_PROTECTED_SESSION, load);
module.exports = {
export = {
load,
reload,
beccaLoaded

View File

@ -28,7 +28,7 @@ class BAttribute extends AbstractBeccaEntity<BAttribute> {
value!: string;
isInheritable!: boolean;
constructor(row: AttributeRow) {
constructor(row?: AttributeRow) {
super();
if (!row) {
@ -52,7 +52,7 @@ class BAttribute extends AbstractBeccaEntity<BAttribute> {
]);
}
update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]: any[]) {
update([attributeId, noteId, type, name, value, isInheritable, position, utcDateModified]: any) {
this.attributeId = attributeId;
this.noteId = noteId;
this.type = type;

View File

@ -30,7 +30,7 @@ class BBranch extends AbstractBeccaEntity<BBranch> {
isExpanded!: boolean;
utcDateModified?: string;
constructor(row: BranchRow) {
constructor(row?: BranchRow) {
super();
if (!row) {

View File

@ -24,7 +24,7 @@ class BEtapiToken extends AbstractBeccaEntity<BEtapiToken> {
tokenHash!: string;
private _isDeleted?: boolean;
constructor(row: EtapiTokenRow) {
constructor(row?: EtapiTokenRow) {
super();
if (!row) {

View File

@ -70,7 +70,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
children!: BNote[];
targetRelations!: BAttribute[];
private __flatTextCache!: string | null;
__flatTextCache!: string | null;
private __attributeCache!: BAttribute[] | null;
private __inheritableAttributeCache!: BAttribute[] | null;
@ -86,7 +86,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
/** number of note revisions for this note */
private revisionCount!: number | null;
constructor(row: Partial<NoteRow>) {
constructor(row?: Partial<NoteRow>) {
super();
if (!row) {

View File

@ -16,10 +16,12 @@ class BOption extends AbstractBeccaEntity<BOption> {
value!: string;
isSynced!: boolean;
constructor(row: OptionRow) {
constructor(row?: OptionRow) {
super();
this.updateFromRow(row);
if (row) {
this.updateFromRow(row);
}
this.becca.options[this.name] = this;
}

View File

@ -7,7 +7,7 @@ const singleImportService = require('../../services/import/single.js');
const cls = require('../../services/cls');
const path = require('path');
const becca = require('../../becca/becca');
const beccaLoader = require('../../becca/becca_loader.js');
const beccaLoader = require('../../becca/becca_loader');
const log = require('../../services/log');
const TaskContext = require('../../services/task_context');
const ValidationError = require('../../errors/validation_error');

View File

@ -766,7 +766,7 @@ class ConsistencyChecks {
}
if (this.reloadNeeded) {
require('../becca/becca_loader.js').reload("consistency checks need becca reload");
require('../becca/becca_loader').reload("consistency checks need becca reload");
}
return !this.unrecoveredConsistencyErrors;

View File

@ -143,8 +143,8 @@ function getRows<T>(query: string, params: Params = []): T[] {
return wrap(query, s => s.all(params)) as T[];
}
function getRawRows<T extends {} | unknown[]>(query: string, params: Params = []): T[] | null {
return wrap(query, s => s.raw().all(params)) as T[] | null;
function getRawRows<T extends {} | unknown[]>(query: string, params: Params = []): T[] {
return (wrap(query, s => s.raw().all(params)) as T[] | null) || [];
}
function iterateRows(query: string, params: Params = []) {
@ -259,7 +259,7 @@ function transactional<T>(func: (statement: Statement) => T) {
if (entityChangeIds.length > 0) {
log.info("Transaction rollback dirtied the becca, forcing reload.");
require('../becca/becca_loader.js').load();
require('../becca/becca_loader').load();
}
// the maxEntityChangeId has been incremented during failed transaction, need to recalculate

View File

@ -61,7 +61,7 @@ async function createInitialDatabase() {
sql.executeScript(schema);
require('../becca/becca_loader.js').load();
require('../becca/becca_loader').load();
const BNote = require('../becca/entities/bnote');
const BBranch = require('../becca/entities/bbranch');

View File

@ -399,7 +399,7 @@ function getOutstandingPullCount() {
return outstandingPullCount;
}
require('../becca/becca_loader.js').beccaLoaded.then(() => {
require('../becca/becca_loader').beccaLoaded.then(() => {
setInterval(cls.wrap(sync), 60000);
// kickoff initial sync immediately, but should happen after initial consistency checks