From 245d790f0d250b6f8974f5118e284d10e674e19f Mon Sep 17 00:00:00 2001 From: aria Date: Wed, 18 Dec 2024 12:36:45 -0600 Subject: [PATCH] chore: refactor project structure --- src/Backgrounder/Backgrounder.ts | 49 +++++++++ .../BackgrounderLane.ts} | 101 ++---------------- src/Backgrounder/index.ts | 2 + src/Backgrounder/types.ts | 46 ++++++++ src/ImagePicker.ts | 6 +- src/{backend => Indexer}/Indexer.ts | 51 ++------- src/Indexer/IndexerDB.ts | 18 ++++ src/Indexer/index.ts | 2 + src/Indexer/types.ts | 24 +++++ src/client/ImagePickerContext.tsx | 2 +- .../ImagePickerView/ImagePickerView.tsx | 2 +- src/client/Thumbnail.tsx | 2 +- src/utils.ts | 2 +- 13 files changed, 165 insertions(+), 142 deletions(-) create mode 100644 src/Backgrounder/Backgrounder.ts rename src/{backend/Backgrounder.ts => Backgrounder/BackgrounderLane.ts} (52%) create mode 100644 src/Backgrounder/index.ts create mode 100644 src/Backgrounder/types.ts rename src/{backend => Indexer}/Indexer.ts (84%) create mode 100644 src/Indexer/IndexerDB.ts create mode 100644 src/Indexer/index.ts create mode 100644 src/Indexer/types.ts diff --git a/src/Backgrounder/Backgrounder.ts b/src/Backgrounder/Backgrounder.ts new file mode 100644 index 0000000..0cdbbc4 --- /dev/null +++ b/src/Backgrounder/Backgrounder.ts @@ -0,0 +1,49 @@ +import { ImagePicker } from '../ImagePicker' + +import { BackgrounderLane } from './BackgrounderLane' +import { BackgrounderLaneProps } from './types' + +/** + * General purpose background job runner :) + * + * This is used mostly to alleviate the main thread from + * doing too much work at once. Things like indexing, + * image processing, or other long-running tasks can be + * run in the background. + * + * It's a FIFO queue, so jobs are run in the order they + * are enqueued. + */ +export class Backgrounder { + public lanes: Record = {} + + constructor(public plugin: ImagePicker) {} + + log = (...args: unknown[]) => { + this.plugin.log('Backgrounder -> ', ...args) + } + + createLane = (lane: Omit) => { + this.lanes[lane.type] = new BackgrounderLane(this.plugin, lane) + } + + deleteLane = (type: string) => { + delete this.lanes[type] + } + + stop = (type: string) => { + if (this.lanes[type]) { + this.lanes[type].clear() + this.log('Stopped lane:', type) + } else { + this.log('Lane not found:', type) + } + } + + stopAll = () => { + for (const lane of Object.values(this.lanes)) { + lane.clear() + } + this.log('Stopped all lanes') + } +} diff --git a/src/backend/Backgrounder.ts b/src/Backgrounder/BackgrounderLane.ts similarity index 52% rename from src/backend/Backgrounder.ts rename to src/Backgrounder/BackgrounderLane.ts index 989f9fd..ed3b975 100644 --- a/src/backend/Backgrounder.ts +++ b/src/Backgrounder/BackgrounderLane.ts @@ -1,53 +1,11 @@ +import ImagePicker from 'src/main' import { v4 } from 'uuid' -import { ImagePicker } from '../ImagePicker' - -export interface BackgrounderJob { - /** - * Internally used UUID for the job - */ - id: string - /** - * The type of job, in a small string. - * - * This is used as a "unique" identifier for the job. - * If you run it in a lane with `unique: true`, only - * one job of this type will be in the queue at a time. - */ - type: string - /** - * The action that will be run when the job is executed - */ - action: () => void | Promise - /** - * If true, the job will be run immediately if the lane is free - */ - eager?: boolean -} - -export type BackgrounderQueue = BackgrounderJob[] - -export interface BackgrounderLaneProps { - type: string - queue: BackgrounderQueue - /** - * The time to wait between jobs in milliseconds - */ - sleep: number - /** - * If true, only one job of this type can be in the queue at a time - */ - unique: boolean - /** - * Determines which job to keep when enqueuing a unique job - * - * 'first' keeps the existing job and ignores the new one - * 'last' keeps the new job and removes the existing one - * - * @default 'first' - */ - uniqueKeep: 'first' | 'last' -} +import { + BackgrounderQueue, + BackgrounderLaneProps, + BackgrounderJob, +} from './types' export class BackgrounderLane { private plugin: ImagePicker @@ -58,7 +16,7 @@ export class BackgrounderLane { private queue: BackgrounderQueue private sleepTime: number = 0 - log = (...args: any[]) => { + log = (...args: unknown[]) => { this.plugin.log(`Lane [${this.type}] -> `, ...args) } @@ -152,48 +110,3 @@ export class BackgrounderLane { this.log('Cleared queue') } } - -/** - * General purpose background job runner :) - * - * This is used mostly to alleviate the main thread from - * doing too much work at once. Things like indexing, - * image processing, or other long-running tasks can be - * run in the background. - * - * It's a FIFO queue, so jobs are run in the order they - * are enqueued. - */ -export class Backgrounder { - public lanes: Record = {} - - constructor(public plugin: ImagePicker) {} - - log = (...args: any[]) => { - this.plugin.log('Backgrounder -> ', ...args) - } - - createLane = (lane: Omit) => { - this.lanes[lane.type] = new BackgrounderLane(this.plugin, lane) - } - - deleteLane = (type: string) => { - delete this.lanes[type] - } - - stop = (type: string) => { - if (this.lanes[type]) { - this.lanes[type].clear() - this.log('Stopped lane:', type) - } else { - this.log('Lane not found:', type) - } - } - - stopAll = () => { - for (const lane of Object.values(this.lanes)) { - lane.clear() - } - this.log('Stopped all lanes') - } -} diff --git a/src/Backgrounder/index.ts b/src/Backgrounder/index.ts new file mode 100644 index 0000000..abf35f8 --- /dev/null +++ b/src/Backgrounder/index.ts @@ -0,0 +1,2 @@ +export * from './Backgrounder' +export * from './types' diff --git a/src/Backgrounder/types.ts b/src/Backgrounder/types.ts new file mode 100644 index 0000000..32bc05c --- /dev/null +++ b/src/Backgrounder/types.ts @@ -0,0 +1,46 @@ +export interface BackgrounderJob { + /** + * Internally used UUID for the job + */ + id: string + /** + * The type of job, in a small string. + * + * This is used as a "unique" identifier for the job. + * If you run it in a lane with `unique: true`, only + * one job of this type will be in the queue at a time. + */ + type: string + /** + * The action that will be run when the job is executed + */ + action: () => void | Promise + /** + * If true, the job will be run immediately if the lane is free + */ + eager?: boolean +} + +export type BackgrounderQueue = BackgrounderJob[] + +export interface BackgrounderLaneProps { + type: string + queue: BackgrounderQueue + /** + * The time to wait between jobs in milliseconds + */ + sleep: number + /** + * If true, only one job of this type can be in the queue at a time + */ + unique: boolean + /** + * Determines which job to keep when enqueuing a unique job + * + * 'first' keeps the existing job and ignores the new one + * 'last' keeps the new job and removes the existing one + * + * @default 'first' + */ + uniqueKeep: 'first' | 'last' +} diff --git a/src/ImagePicker.ts b/src/ImagePicker.ts index 743aff1..5b1ffbe 100644 --- a/src/ImagePicker.ts +++ b/src/ImagePicker.ts @@ -1,7 +1,7 @@ import { App, Plugin, PluginManifest, TFile, WorkspaceLeaf } from 'obsidian' import { pick } from 'lodash' -import { Indexer } from './backend/Indexer' +import { Indexer } from './Indexer' import { ImagePickerSettings, ImagePickerSettingTab, @@ -12,7 +12,7 @@ import { VALID_IMAGE_EXTENSIONS, VIEW_TYPE_IMAGE_PICKER, } from './constants' -import { Backgrounder } from './backend/Backgrounder' +import { Backgrounder } from './Backgrounder' export class ImagePicker extends Plugin { settings: ImagePickerSettings @@ -27,7 +27,7 @@ export class ImagePicker extends Plugin { super(app, manifest) } - log = (...args: any[]) => { + log = (...args: unknown[]) => { if (this.settings?.debugMode) { console.log('ImagePicker -> ', ...args) } diff --git a/src/backend/Indexer.ts b/src/Indexer/Indexer.ts similarity index 84% rename from src/backend/Indexer.ts rename to src/Indexer/Indexer.ts index 660552f..b588b0e 100644 --- a/src/backend/Indexer.ts +++ b/src/Indexer/Indexer.ts @@ -1,7 +1,5 @@ -import { TFile } from 'obsidian' import { debounce, merge } from 'lodash' import { v4 } from 'uuid' -import Dexie from 'dexie' import { fetchImageFile, @@ -9,45 +7,16 @@ import { imageToArrayBuffer, makeThumbnail, } from '../utils' -import ImagePicker from '../main' +import { ImagePicker } from '../ImagePicker' -export interface IndexerRoot { - [path: string]: IndexerNode -} - -export interface IndexerNode - extends Pick { - uri: string - thumbnail?: string -} - -export interface AbstractIndexerRoot { - [path: string]: AbstractIndexerNode -} - -export interface AbstractIndexerNode extends Omit { - thumbnail: Thumbnail -} - -export interface Thumbnail { - id: string - data: string -} - -class IndexerDB extends Dexie { - index: Dexie.Table - thumbnails: Dexie.Table - - constructor() { - super('IndexerDB') - this.version(1).stores({ - index: 'path', - thumbnails: 'id', - }) - this.index = this.table('index') - this.thumbnails = this.table('thumbnails') - } -} +import { + IndexerNode, + Thumbnail, + IndexerRoot, + AbstractIndexerRoot, + AbstractIndexerNode, +} from './types' +import { IndexerDB } from './IndexerDB' export class Indexer { private memory: IndexerRoot = {} @@ -77,7 +46,7 @@ export class Indexer { this.db = new IndexerDB() } - log = (...args: any[]) => { + log = (...args: unknown[]) => { this.plugin.log('Indexer -> ', ...args) } diff --git a/src/Indexer/IndexerDB.ts b/src/Indexer/IndexerDB.ts new file mode 100644 index 0000000..6cae214 --- /dev/null +++ b/src/Indexer/IndexerDB.ts @@ -0,0 +1,18 @@ +import Dexie from 'dexie' + +import { IndexerNode, Thumbnail } from './types' + +export class IndexerDB extends Dexie { + index: Dexie.Table + thumbnails: Dexie.Table + + constructor() { + super('ImagePicker') + this.version(1).stores({ + index: 'path', + thumbnails: 'id', + }) + this.index = this.table('index') + this.thumbnails = this.table('thumbnails') + } +} diff --git a/src/Indexer/index.ts b/src/Indexer/index.ts new file mode 100644 index 0000000..052ecc9 --- /dev/null +++ b/src/Indexer/index.ts @@ -0,0 +1,2 @@ +export * from './Indexer' +export * from './types' diff --git a/src/Indexer/types.ts b/src/Indexer/types.ts new file mode 100644 index 0000000..d8a7c9f --- /dev/null +++ b/src/Indexer/types.ts @@ -0,0 +1,24 @@ +import { type TFile } from 'obsidian' + +export interface IndexerRoot { + [path: string]: IndexerNode +} + +export interface IndexerNode + extends Pick { + uri: string + thumbnail?: string +} + +export interface AbstractIndexerRoot { + [path: string]: AbstractIndexerNode +} + +export interface AbstractIndexerNode extends Omit { + thumbnail: Thumbnail +} + +export interface Thumbnail { + id: string + data: string +} diff --git a/src/client/ImagePickerContext.tsx b/src/client/ImagePickerContext.tsx index c68df8c..d05dee8 100644 --- a/src/client/ImagePickerContext.tsx +++ b/src/client/ImagePickerContext.tsx @@ -2,7 +2,7 @@ import { createContext, useContext } from 'react' import { App } from 'obsidian' import ImagePicker from '../main' -import { IndexerNode } from '../backend/Indexer' +import { IndexerNode } from '../Indexer' export interface ImagePickerContextType { app: App diff --git a/src/client/ImagePickerView/ImagePickerView.tsx b/src/client/ImagePickerView/ImagePickerView.tsx index 1235b5e..ead8699 100644 --- a/src/client/ImagePickerView/ImagePickerView.tsx +++ b/src/client/ImagePickerView/ImagePickerView.tsx @@ -16,7 +16,7 @@ import { setGridHeight, tokenizeSearchQuery, } from '../../utils' -import { AbstractIndexerNode, IndexerNode } from '../../backend/Indexer' +import { AbstractIndexerNode, IndexerNode } from '../../Indexer' import { useApp, useFiles, usePlugin } from '../ImagePickerContext' import { Thumbnail } from '../Thumbnail' diff --git a/src/client/Thumbnail.tsx b/src/client/Thumbnail.tsx index a79687b..6abdbe4 100644 --- a/src/client/Thumbnail.tsx +++ b/src/client/Thumbnail.tsx @@ -1,6 +1,6 @@ import React, { FC, useCallback, useEffect, useRef, useState } from 'react' -import { AbstractIndexerNode, IndexerNode } from '../backend/Indexer' +import { AbstractIndexerNode, IndexerNode } from '../Indexer' import { usePlugin } from './ImagePickerContext' diff --git a/src/utils.ts b/src/utils.ts index 99f5646..ae91ab6 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -1,6 +1,6 @@ import { readAndCompressImage } from 'browser-image-resizer' -import { AbstractIndexerNode, IndexerNode } from './backend/Indexer' +import { AbstractIndexerNode, IndexerNode } from './Indexer' import { queryTokens, ROW_HEIGHT } from './constants' export const getSizeInKb = (size: number): number => {