refactor: enable TypeScript strict mode and fix memory leak

- tsconfig.json: strict: true 활성화 (noImplicitAny, strictNullChecks를 대체)
- main.ts: definite assignment assertions (!) 추가 — Obsidian Plugin은 onload()에서 초기화
- settings-tab.ts: strictFunctionTypes 호환을 위해 onChange 타입 캐스트
- settings-tab.ts: hide() 오버라이드로 debounceTimer 정리 (메모리 누수 수정)

Closes #38
This commit is contained in:
uppinote 2026-03-13 17:00:15 +09:00
parent fc9c68ae44
commit 3b8f6b972e
3 changed files with 23 additions and 17 deletions

View file

@ -21,23 +21,23 @@ import { AutoNoteImporterSettingTab } from './ui';
* Main plugin class for Auto Note Importer.
*/
export default class AutoNoteImporterPlugin extends Plugin {
settings: AutoNoteImporterSettings;
settings!: AutoNoteImporterSettings;
private intervalId: number | null = null;
private settingTab: AutoNoteImporterSettingTab;
private settingTab!: AutoNoteImporterSettingTab;
// Services
private airtableClient: AirtableClient;
private fieldCache: FieldCache;
private rateLimiter: RateLimiter;
// Services (initialized in onload → initializeServices)
private airtableClient!: AirtableClient;
private fieldCache!: FieldCache;
private rateLimiter!: RateLimiter;
// Core
private syncQueue: SyncQueue;
private conflictResolver: ConflictResolver;
private syncOrchestrator: SyncOrchestrator;
private syncQueue!: SyncQueue;
private conflictResolver!: ConflictResolver;
private syncOrchestrator!: SyncOrchestrator;
// File Operations
private frontmatterParser: FrontmatterParser;
private fileWatcher: FileWatcher;
private frontmatterParser!: FrontmatterParser;
private fileWatcher!: FileWatcher;
async onload() {
await this.loadSettings();

View file

@ -53,6 +53,13 @@ export class AutoNoteImporterSettingTab extends PluginSettingTab {
});
}
hide(): void {
if (this.debounceTimer) {
clearTimeout(this.debounceTimer);
this.debounceTimer = null;
}
}
display(): void {
const { containerEl } = this;
containerEl.empty();
@ -309,8 +316,8 @@ export class AutoNoteImporterSettingTab extends PluginSettingTab {
.addOption('synced-folder', 'Inside synced folder')
.addOption('custom', 'Custom path')
.setValue(this.plugin.settings.basesFileLocation)
.onChange(async (value: BasesFileLocation) => {
this.plugin.settings.basesFileLocation = value;
.onChange(async (value) => {
this.plugin.settings.basesFileLocation = value as BasesFileLocation;
await this.plugin.saveSettings();
this.debounceDisplay();
}));
@ -366,8 +373,8 @@ export class AutoNoteImporterSettingTab extends PluginSettingTab {
.addOption('obsidian-wins', 'Obsidian wins (overwrite Airtable)')
.addOption('airtable-wins', 'Airtable wins (overwrite Obsidian)')
.setValue(this.plugin.settings.conflictResolution)
.onChange(async (value: ConflictResolutionMode) => {
this.plugin.settings.conflictResolution = value;
.onChange(async (value) => {
this.plugin.settings.conflictResolution = value as ConflictResolutionMode;
await this.plugin.saveSettings();
}));

View file

@ -6,11 +6,10 @@
"module": "ESNext",
"target": "ES6",
"allowJs": true,
"noImplicitAny": true,
"strict": true,
"moduleResolution": "node",
"importHelpers": true,
"isolatedModules": true,
"strictNullChecks": true,
"lib": [
"DOM",
"ES5",