chore(server): fix some type errors

This commit is contained in:
Elian Doran 2025-05-28 19:03:53 +03:00
parent 05c4721bd5
commit ba7c93967e
No known key found for this signature in database
19 changed files with 86 additions and 49 deletions

View File

@ -251,7 +251,7 @@ export default class Becca {
getAllNoteSet() { getAllNoteSet() {
// caching this since it takes 10s of milliseconds to fill this initial NoteSet for many notes // caching this since it takes 10s of milliseconds to fill this initial NoteSet for many notes
if (!this.allNoteSetCache) { if (!this.allNoteSetCache) {
const allNotes = []; const allNotes: BNote[] = [];
for (const noteId in this.notes) { for (const noteId in this.notes) {
const note = this.notes[noteId]; const note = this.notes[noteId];

View File

@ -76,7 +76,7 @@ function getNoteTitleArrayForPath(notePathArray: string[]) {
return [getNoteTitle(notePathArray[0])]; return [getNoteTitle(notePathArray[0])];
} }
const titles = []; const titles: string[] = [];
let parentNoteId = "root"; let parentNoteId = "root";
let hoistedNotePassed = false; let hoistedNotePassed = false;

View File

@ -388,7 +388,7 @@ class BNote extends AbstractBeccaEntity<BNote> {
} }
} }
const templateAttributes = []; const templateAttributes: BAttribute[] = [];
for (const ownedAttr of parentAttributes) { for (const ownedAttr of parentAttributes) {
// parentAttributes so we process also inherited templates // parentAttributes so we process also inherited templates

View File

@ -254,7 +254,7 @@ function hasConnectingRelation(sourceNote: BNote, targetNote: BNote) {
} }
async function findSimilarNotes(noteId: string): Promise<SimilarNote[] | undefined> { async function findSimilarNotes(noteId: string): Promise<SimilarNote[] | undefined> {
const results = []; const results: SimilarNote[] = [];
let i = 0; let i = 0;
const baseNote = becca.notes[noteId]; const baseNote = becca.notes[noteId];

View File

@ -12,6 +12,11 @@ interface Backlink {
excerpts?: string[]; excerpts?: string[];
} }
interface TreeLink {
sourceNoteId: string;
targetNoteId: string;
}
function buildDescendantCountMap(noteIdsToCount: string[]) { function buildDescendantCountMap(noteIdsToCount: string[]) {
if (!Array.isArray(noteIdsToCount)) { if (!Array.isArray(noteIdsToCount)) {
throw new Error("noteIdsToCount: type error"); throw new Error("noteIdsToCount: type error");
@ -50,7 +55,7 @@ function getNeighbors(note: BNote, depth: number): string[] {
return []; return [];
} }
const retNoteIds = []; const retNoteIds: string[] = [];
function isIgnoredRelation(relation: BAttribute) { function isIgnoredRelation(relation: BAttribute) {
return ["relationMapLink", "template", "inherit", "image", "ancestor"].includes(relation.name); return ["relationMapLink", "template", "inherit", "image", "ancestor"].includes(relation.name);
@ -196,7 +201,7 @@ function getTreeMap(req: Request) {
const noteIds = new Set<string>(); const noteIds = new Set<string>();
notes.forEach(([noteId]) => noteId && noteIds.add(noteId)); notes.forEach(([noteId]) => noteId && noteIds.add(noteId));
const links = []; const links: TreeLink[] = [];
for (const { parentNoteId, childNoteId } of subtree.relationships) { for (const { parentNoteId, childNoteId } of subtree.relationships) {
if (!noteIds.has(parentNoteId) || !noteIds.has(childNoteId)) { if (!noteIds.has(parentNoteId) || !noteIds.has(childNoteId)) {
@ -246,7 +251,7 @@ function findExcerpts(sourceNote: BNote, referencedNoteId: string) {
const html = sourceNote.getContent(); const html = sourceNote.getContent();
const document = new JSDOM(html).window.document; const document = new JSDOM(html).window.document;
const excerpts = []; const excerpts: string[] = [];
removeImages(document); removeImages(document);

View File

@ -9,6 +9,12 @@ import { changeLanguage, getLocales } from "../../services/i18n.js";
import type { OptionNames } from "@triliumnext/commons"; import type { OptionNames } from "@triliumnext/commons";
import config from "../../services/config.js"; import config from "../../services/config.js";
interface UserTheme {
val: string; // value of the theme, used in the URL
title: string; // title of the theme, displayed in the UI
noteId: string; // ID of the note containing the theme
}
// options allowed to be updated directly in the Options dialog // options allowed to be updated directly in the Options dialog
const ALLOWED_OPTIONS = new Set<OptionNames>([ const ALLOWED_OPTIONS = new Set<OptionNames>([
"eraseEntitiesAfterTimeInSeconds", "eraseEntitiesAfterTimeInSeconds",
@ -177,7 +183,7 @@ function update(name: string, value: string) {
function getUserThemes() { function getUserThemes() {
const notes = searchService.searchNotes("#appTheme", { ignoreHoistedNote: true }); const notes = searchService.searchNotes("#appTheme", { ignoreHoistedNote: true });
const ret = []; const ret: UserTheme[] = [];
for (const note of notes) { for (const note of notes) {
let value = note.getOwnedLabelValue("appTheme"); let value = note.getOwnedLabelValue("appTheme");

View File

@ -21,7 +21,7 @@ interface RecentChangeRow {
function getRecentChanges(req: Request) { function getRecentChanges(req: Request) {
const { ancestorNoteId } = req.params; const { ancestorNoteId } = req.params;
let recentChanges = []; let recentChanges: RecentChangeRow[] = [];
const revisionRows = sql.getRows<RecentChangeRow>(` const revisionRows = sql.getRows<RecentChangeRow>(`
SELECT SELECT

View File

@ -1,6 +1,6 @@
"use strict"; "use strict";
import scriptService from "../../services/script.js"; import scriptService, { type Bundle } from "../../services/script.js";
import attributeService from "../../services/attributes.js"; import attributeService from "../../services/attributes.js";
import becca from "../../becca/becca.js"; import becca from "../../becca/becca.js";
import syncService from "../../services/sync.js"; import syncService from "../../services/sync.js";
@ -54,7 +54,7 @@ function run(req: Request) {
function getBundlesWithLabel(label: string, value?: string) { function getBundlesWithLabel(label: string, value?: string) {
const notes = attributeService.getNotesWithLabel(label, value); const notes = attributeService.getNotesWithLabel(label, value);
const bundles = []; const bundles: Bundle[] = [];
for (const note of notes) { for (const note of notes) {
const bundle = scriptService.getScriptBundleForFrontend(note); const bundle = scriptService.getScriptBundleForFrontend(note);
@ -97,7 +97,7 @@ function getRelationBundles(req: Request) {
const targetNoteIds = filtered.map((relation) => relation.value); const targetNoteIds = filtered.map((relation) => relation.value);
const uniqueNoteIds = Array.from(new Set(targetNoteIds)); const uniqueNoteIds = Array.from(new Set(targetNoteIds));
const bundles = []; const bundles: Bundle[] = [];
for (const noteId of uniqueNoteIds) { for (const noteId of uniqueNoteIds) {
const note = becca.getNoteOrThrow(noteId); const note = becca.getNoteOrThrow(noteId);

View File

@ -6,9 +6,14 @@ import type { Request } from "express";
import ValidationError from "../../errors/validation_error.js"; import ValidationError from "../../errors/validation_error.js";
import { safeExtractMessageAndStackFromError } from "../../services/utils.js"; import { safeExtractMessageAndStackFromError } from "../../services/utils.js";
interface Table {
name: string;
columns: unknown[];
}
function getSchema() { function getSchema() {
const tableNames = sql.getColumn(/*sql*/`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`); const tableNames = sql.getColumn<string>(/*sql*/`SELECT name FROM sqlite_master WHERE type='table' AND name NOT LIKE 'sqlite_%' ORDER BY name`);
const tables = []; const tables: Table[] = [];
for (const tableName of tableNames) { for (const tableName of tableNames) {
tables.push({ tables.push({
@ -31,7 +36,7 @@ function execute(req: Request) {
const queries = content.split("\n---"); const queries = content.split("\n---");
try { try {
const results = []; const results: unknown[] = [];
for (let query of queries) { for (let query of queries) {
query = query.trim(); query = query.trim();

View File

@ -5,6 +5,7 @@ import log from "../../services/log.js";
import NotFoundError from "../../errors/not_found_error.js"; import NotFoundError from "../../errors/not_found_error.js";
import type { Request } from "express"; import type { Request } from "express";
import type BNote from "../../becca/entities/bnote.js"; import type BNote from "../../becca/entities/bnote.js";
import type { AttributeRow, BranchRow, NoteRow } from "@triliumnext/commons";
function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set<string>) { function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set<string>) {
const noteIds = new Set(_noteIds); const noteIds = new Set(_noteIds);
@ -53,7 +54,7 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set<string>) {
collectEntityIds(note); collectEntityIds(note);
} }
const notes = []; const notes: NoteRow[] = [];
for (const noteId of collectedNoteIds) { for (const noteId of collectedNoteIds) {
const note = becca.notes[noteId]; const note = becca.notes[noteId];
@ -68,7 +69,7 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set<string>) {
}); });
} }
const branches = []; const branches: BranchRow[] = [];
if (noteIds.has("root")) { if (noteIds.has("root")) {
branches.push({ branches.push({
@ -99,7 +100,7 @@ function getNotesAndBranchesAndAttributes(_noteIds: string[] | Set<string>) {
}); });
} }
const attributes = []; const attributes: AttributeRow[] = [];
for (const attributeId of collectedAttributeIds) { for (const attributeId of collectedAttributeIds) {
const attribute = becca.attributes[attributeId]; const attribute = becca.attributes[attributeId];

View File

@ -7,6 +7,11 @@ import eraseService from "./erase.js";
type SectorHash = Record<string, string>; type SectorHash = Record<string, string>;
interface FailedCheck {
entityName: string;
sector: string[1];
}
function getEntityHashes() { function getEntityHashes() {
// blob erasure is not synced, we should check before each sync if there's some blob to erase // blob erasure is not synced, we should check before each sync if there's some blob to erase
eraseService.eraseUnusedBlobs(); eraseService.eraseUnusedBlobs();
@ -56,7 +61,7 @@ function getEntityHashes() {
function checkContentHashes(otherHashes: Record<string, SectorHash>) { function checkContentHashes(otherHashes: Record<string, SectorHash>) {
const entityHashes = getEntityHashes(); const entityHashes = getEntityHashes();
const failedChecks = []; const failedChecks: FailedCheck[] = [];
for (const entityName in entityHashes) { for (const entityName in entityHashes) {
const thisSectorHashes: SectorHash = entityHashes[entityName] || {}; const thisSectorHashes: SectorHash = entityHashes[entityName] || {};

View File

@ -160,7 +160,7 @@ function extractJsStructure(content: string): string {
} }
// Look for class declarations // Look for class declarations
const classes = []; const classes: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('class ') || line.includes(' class ')) { if (line.startsWith('class ') || line.includes(' class ')) {
@ -173,7 +173,7 @@ function extractJsStructure(content: string): string {
} }
// Look for function declarations // Look for function declarations
const functions = []; const functions: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('function ') || if (line.startsWith('function ') ||
@ -212,7 +212,7 @@ function extractPythonStructure(content: string): string {
} }
// Look for class declarations // Look for class declarations
const classes = []; const classes: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('class ')) { if (line.startsWith('class ')) {
@ -225,7 +225,7 @@ function extractPythonStructure(content: string): string {
} }
// Look for function declarations // Look for function declarations
const functions = []; const functions: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('def ')) { if (line.startsWith('def ')) {
@ -263,7 +263,7 @@ function extractClassBasedStructure(content: string): string {
} }
// Look for class declarations // Look for class declarations
const classes = []; const classes: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.match(/^(public|private|protected)?\s*(class|interface|enum)\s+\w+/)) { if (line.match(/^(public|private|protected)?\s*(class|interface|enum)\s+\w+/)) {
@ -276,7 +276,7 @@ function extractClassBasedStructure(content: string): string {
} }
// Look for method declarations // Look for method declarations
const methods = []; const methods: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.match(/^(public|private|protected)?\s*(static)?\s*[\w<>[\]]+\s+\w+\s*\(/)) { if (line.match(/^(public|private|protected)?\s*(static)?\s*[\w<>[\]]+\s+\w+\s*\(/)) {
@ -319,7 +319,7 @@ function extractGoStructure(content: string): string {
} }
// Look for type declarations (structs, interfaces) // Look for type declarations (structs, interfaces)
const types = []; const types: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('type ') && (line.includes(' struct ') || line.includes(' interface '))) { if (line.startsWith('type ') && (line.includes(' struct ') || line.includes(' interface '))) {
@ -332,7 +332,7 @@ function extractGoStructure(content: string): string {
} }
// Look for function declarations // Look for function declarations
const functions = []; const functions: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('func ')) { if (line.startsWith('func ')) {
@ -366,7 +366,7 @@ function extractRustStructure(content: string): string {
} }
// Look for struct/enum/trait declarations // Look for struct/enum/trait declarations
const types = []; const types: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();
if (line.startsWith('struct ') || line.startsWith('enum ') || line.startsWith('trait ')) { if (line.startsWith('struct ') || line.startsWith('enum ') || line.startsWith('trait ')) {
@ -379,8 +379,8 @@ function extractRustStructure(content: string): string {
} }
// Look for function/impl declarations // Look for function/impl declarations
const functions = []; const functions: string[] = [];
const impls = []; const impls: string[] = [];
for (let i = 0; i < lines.length; i++) { for (let i = 0; i < lines.length; i++) {
const line = lines[i].trim(); const line = lines[i].trim();

View File

@ -198,7 +198,7 @@ export async function semanticChunking(
// Try to split on headers first // Try to split on headers first
const headerPattern = /#{1,6}\s+.+|<h[1-6][^>]*>.*?<\/h[1-6]>/g; const headerPattern = /#{1,6}\s+.+|<h[1-6][^>]*>.*?<\/h[1-6]>/g;
const sections = []; const sections: string[] = [];
let lastIndex = 0; let lastIndex = 0;
let match; let match;

View File

@ -439,7 +439,7 @@ export class QueryDecompositionTool {
// If no pattern match, try to extract noun phrases // If no pattern match, try to extract noun phrases
const words = query.split(/\s+/); const words = query.split(/\s+/);
const potentialEntities = []; const potentialEntities: string[] = [];
let currentPhrase = ''; let currentPhrase = '';
for (const word of words) { for (const word of words) {

View File

@ -246,7 +246,7 @@ export abstract class BaseEmbeddingProvider {
*/ */
protected generateNoteContextText(context: NoteEmbeddingContext): string { protected generateNoteContextText(context: NoteEmbeddingContext): string {
// Build a relationship-focused summary first // Build a relationship-focused summary first
const relationshipSummary = []; const relationshipSummary: string[] = [];
// Summarize the note's place in the hierarchy // Summarize the note's place in the hierarchy
if (context.parentTitles.length > 0) { if (context.parentTitles.length > 0) {

View File

@ -13,6 +13,21 @@ import indexService from '../index_service.js';
// Track which notes are currently being processed // Track which notes are currently being processed
const notesInProcess = new Set<string>(); const notesInProcess = new Set<string>();
interface FailedItemRow {
noteId: string;
operation: string;
attempts: number;
lastAttempt: string;
error: string | null;
failed: number;
}
interface FailedItemWithTitle extends FailedItemRow {
title?: string;
failureType: 'chunks' | 'full';
isPermanent: boolean;
}
/** /**
* Queues a note for embedding update * Queues a note for embedding update
*/ */
@ -77,17 +92,17 @@ export async function queueNoteForEmbedding(noteId: string, operation = 'UPDATE'
*/ */
export async function getFailedEmbeddingNotes(limit: number = 100): Promise<any[]> { export async function getFailedEmbeddingNotes(limit: number = 100): Promise<any[]> {
// Get notes with failed embedding attempts or permanently failed flag // Get notes with failed embedding attempts or permanently failed flag
const failedQueueItems = await sql.getRows(` const failedQueueItems = sql.getRows<FailedItemRow>(`
SELECT noteId, operation, attempts, lastAttempt, error, failed SELECT noteId, operation, attempts, lastAttempt, error, failed
FROM embedding_queue FROM embedding_queue
WHERE attempts > 0 OR failed = 1 WHERE attempts > 0 OR failed = 1
ORDER BY failed DESC, attempts DESC, lastAttempt DESC ORDER BY failed DESC, attempts DESC, lastAttempt DESC
LIMIT ?`, LIMIT ?`,
[limit] [limit]
) as {noteId: string, operation: string, attempts: number, lastAttempt: string, error: string, failed: number}[]; );
// Add titles to the failed notes // Add titles to the failed notes
const failedNotesWithTitles = []; const failedNotesWithTitles: FailedItemWithTitle[] = [];
for (const item of failedQueueItems) { for (const item of failedQueueItems) {
const note = becca.getNote(item.noteId); const note = becca.getNote(item.noteId);
if (note) { if (note) {

View File

@ -95,7 +95,7 @@ export class ModelSelectionStage extends BasePipelineStage<ModelSelectionInput,
const providerPrecedence = await options.getOption('aiProviderPrecedence'); const providerPrecedence = await options.getOption('aiProviderPrecedence');
if (providerPrecedence) { if (providerPrecedence) {
// Parse provider precedence list // Parse provider precedence list
let providers = []; let providers: string[] = [];
if (providerPrecedence.includes(',')) { if (providerPrecedence.includes(',')) {
providers = providerPrecedence.split(',').map(p => p.trim()); providers = providerPrecedence.split(',').map(p => p.trim());
} else if (providerPrecedence.startsWith('[') && providerPrecedence.endsWith(']')) { } else if (providerPrecedence.startsWith('[') && providerPrecedence.endsWith(']')) {

View File

@ -52,7 +52,7 @@ class NoteFlatTextExp extends Expression {
return; return;
} }
const foundAttrTokens = []; const foundAttrTokens: string[] = [];
for (const token of remainingTokens) { for (const token of remainingTokens) {
if (note.type.includes(token) || note.mime.includes(token)) { if (note.type.includes(token) || note.mime.includes(token)) {
@ -73,7 +73,7 @@ class NoteFlatTextExp extends Expression {
for (const parentNote of note.parents) { for (const parentNote of note.parents) {
const title = normalize(beccaService.getNoteTitle(note.noteId, parentNote.noteId)); const title = normalize(beccaService.getNoteTitle(note.noteId, parentNote.noteId));
const foundTokens = foundAttrTokens.slice(); const foundTokens: string[] = foundAttrTokens.slice();
for (const token of remainingTokens) { for (const token of remainingTokens) {
if (title.includes(token)) { if (title.includes(token)) {
@ -100,7 +100,7 @@ class NoteFlatTextExp extends Expression {
continue; continue;
} }
const foundAttrTokens = []; const foundAttrTokens: string[] = [];
for (const token of this.tokens) { for (const token of this.tokens) {
if (note.type.includes(token) || note.mime.includes(token)) { if (note.type.includes(token) || note.mime.includes(token)) {
@ -153,7 +153,7 @@ class NoteFlatTextExp extends Expression {
* Returns noteIds which have at least one matching tokens * Returns noteIds which have at least one matching tokens
*/ */
getCandidateNotes(noteSet: NoteSet): BNote[] { getCandidateNotes(noteSet: NoteSet): BNote[] {
const candidateNotes = []; const candidateNotes: BNote[] = [];
for (const note of noteSet.notes) { for (const note of noteSet.notes) {
for (const token of this.tokens) { for (const token of this.tokens) {

View File

@ -126,17 +126,17 @@ export type NoteType = (typeof ALLOWED_NOTE_TYPES)[number];
export interface NoteRow { export interface NoteRow {
noteId: string; noteId: string;
deleteId: string; deleteId?: string;
title: string; title: string;
type: NoteType; type: NoteType;
mime: string; mime: string;
isProtected: boolean; isProtected?: boolean;
isDeleted: boolean; isDeleted?: boolean;
blobId: string; blobId?: string;
dateCreated: string; dateCreated?: string;
dateModified: string; dateModified?: string;
utcDateCreated: string; utcDateCreated?: string;
utcDateModified: string; utcDateModified?: string;
content?: string | Buffer; content?: string | Buffer;
} }