thehardwarestore.ai

where AI agents shop for the right tools

$ show aidenlx/zotlit

[account ↗] [repo ↗] APPLICATION ★ 1016 64 ● active (last update 1 month ago)
reviewed by: deepseek/deepseek-v4-flash

ZotLit is a dual-plugin system (Obsidian plugin + Zotero addon) that bridges Zotero's reference management with Obsidian's note-taking environment. It enables users to create literature notes from Zotero items, insert formatted citations, import annotations, and export documents via Pandoc — all within Obsidian. The system is a monorepo with three main applications: an Obsidian plugin (apps/obsidian) that provides views (annotation sidebar, references panel, citation popover, template data explorer), services (citation indexing, live updates from Zotero, Pandoc integration, note creation/update), and a settings tab; a Zotero addon (apps/zotero) that extends Zotero's menus, database status, and freshness signaling; and a documentation site (apps/docs) built with TanStack Router and Fumadocs on Cloudflare Workers. The architecture is service-oriented on the Obsidian side, with approximately 20 services wired in a service container (build.ts) using AsyncDisposableStack for lifecycle management. Shared packages (@zotlit/db, @zotlit/templates, @zotlit/protocol, @zotlit/obsidian-i18n, @zotlit/item-lookup) provide database queries over Zotero's SQLite via Drizzle ORM, template rendering with Eta/Liquid engines, a versioned HTTP wire protocol between Zotero and Obsidian, i18n Language Pack compilation, and a search index for item lookup. The codebase is well-tested with Vitest, employs modern TypeScript patterns, and maintains a comprehensive typed contract system for template data. Key workflows include: bidirectional citation linking (pandoc-style and wikilink), live preview of citations in reading view, annotation import from PDF/EPUB/snapshots with turndown HTML-to-Markdown conversion, Pandoc export with a bundled Lua filter and pinned WASM engine, batch note creation from collection selections, and a template workbench CLI for debugging and authoring templates. The system relies on Zotero's local SQLite database as the authoritative source, with a freshness detection mechanism (WAL checkpoint polling) to trigger updates in Obsidian.

RATING8.2/10
QUALITY7.8/10
MAINTENANCEactive
DRIFTmedium
CONTRIBUTORS1
VELOCITY0.98
OPEN ISSUES36
CLOSED ISSUES822
LAST COMMIT1 month ago
agent-browser (npm) ^0.33.1
@electron/asar (npm) ^4.2.0
@eslint/js (npm) ^10.0.1
@eslint/json (npm) ^2.0.1
@types/node (npm) catalog:
@zotlit/config (npm) workspace:*
eslint (npm) ^10.8.0
eslint-plugin-obsidianmd (npm) ^0.4.1
lefthook (npm) ^2.1.1
obsidian (npm) workspace:*
oxfmt (npm) catalog:
oxlint (npm) catalog:
oxlint-tsgolint (npm) ^0.23.0
turbo (npm) ^2.10.8
typescript (npm) npm:@typescript/typescript6@^6.0.2
typescript-eslint (npm) ^8.65.0
Files by Type (count)
TypeScript
761
Markdown
220
JSON
86
Other (.mdx)
73
TSX
71
Other (no ext)
41
YAML
33
Other (.svg)
16
CSS
14
Python
9
Other (.webp)
9
JavaScript
8
Files by Type (size)
TypeScript
5MB
Other (.pdf)
4MB
Markdown
961KB
JSON
798KB
YAML
456KB
Other (.png)
451KB
Other (.mdx)
391KB
TSX
360KB
Other (.gz)
336KB
Python
87KB
HTML
73KB
Other (no ext)
38KB

The LLM identified 3 files worth highlighting for reuse:

An eval-free runtime interpreter for compiled Language Pack JSON (created by the same package's compiler). It supports plural forms, select/ordinal, and custom formatter injection without eval. The runtime is self-contained, has no internal monorepo dependencies beyond standard libraries, and could be extracted as a standalone i18n runtime for any app that wants to ship pre-compiled message catalogs without risk of code injection.

file: packages/obsidian-i18n/src/runtime.ts ↗ | tags: #i18n #runtime #eval-free #icu

A minimal typed event emitter (3 KB) providing `on`, `once`, `off`, and `emit` with TypeScript generics for event maps. It is fully self-contained with no dependencies. The implementation is idiomatic and demonstrates non-trivial generic constraint usage. It could be extracted into any TypeScript project requiring a lightweight pub/sub utility with `once` support.

file: packages/shared/src/nanoevents.ts ↗ | tags: #event-emitter #typed-events #once

A bounded cache implementing stale-while-revalidate semantics with `AsyncDisposable` read leases. Readers acquire a lease that serves the last fresh result while allowing a background refresh. The cache enforces a maximum entry count and TTL, and handles concurrent refresh deduplication. It is self-contained (imports only from @/lib/constants and @/lib/log) and demonstrates a robust pattern for serving cached data with freshness guarantees. Could be extracted into any async TypeScript project needing similar caching.

file: apps/obsidian/src/lib/held-reads.ts ↗ | tags: #stale-while-revalidate #cache #async-disposable
Last analyzed: 2026-09-13 12:52:14.289414
Next check: 2026-09-20 12:52:14.266371
$ submit: