Insurgently

Obsidian plugin· Active · beta · not yet released

Books & Shelves

Shelves across Obsidian, Calibre and Audible, as an Obsidian plugin over the shelf engine.

API reference

Every declaration in Books & Shelves's API for other plugins, generated from the code. API version 0.2.0.

For tools and coding agentsbooks-and-shelves-api.d.tsapi.json

BooksApi

version

readonly version: string

Semantic version of this API. Check it with isCompatible (or use getBooks).

listBooks

listBooks(which: number[] | {
    shelf: string;
}): Promise<BookSummary[]>

Books by Calibre id (in the order asked), or a shelf's books (by Calibre id). Works from the Content Server, or read-only from the library file when the server is off and a library folder is set. Rejects with book-missing naming any id Calibre doesn't have.

bookFile

bookFile(id: number, format: BookFormat, opts?: BookFileOptions): Promise<ArrayBuffer | null>

A book file's bytes, through the Content Server. With { convert: true }, an EPUB the book lacks is made from its AZW3 or MOBI after the user agrees (null if they decline). Rejects with server-off when the server is off, even if the library file is readable.

pdfText

pdfText(id: number): Promise<string>

A PDF's text, page by page (pages separated by a blank line), through Obsidian's PDF.js.

shelfMembers

shelfMembers(shelf: string): Promise<number[]>

The Calibre ids of the books on a shelf, ascending: by the shelf's rule, pinned, not excluded (the same test as the shelf's Base). A shelf is named by its collection_id, or its note's name or path. Book notes without a calibre_id aren't included.

calibreChecks

calibreChecks(): Promise<CalibreChecks>

The Calibre settings Books & Shelves depends on, checked against the Content Server now: that it answers, that any login works, that the library exists, and that it allows changes (needed to convert a book or write to it). Each check that fails says how to set it right in Calibre. Never rejects: a server that doesn't answer is a failed check. Since 0.2.

Functions

isCompatible

declare function isCompatible(actual: string, wanted: string): boolean;

True when a consumer built against wanted can use an API at actual: same major and a minor at least as new. Before 1.0, minors break by default, so 0.x serves only the minors it promises (0.1 and up). The same rule as Model Hub's, used for both directions: this plugin's API, and the Hub API this plugin asks for.

getBooks

declare function getBooks(app: unknown, wanted: string): GetBooksResult;

Finds Books & Shelves in this vault and checks its API version against the one you built for.

onBooksReady

declare function onBooksReady(app: unknown, plugin: {
    registerEvent(ref: unknown): void;
}, wanted: string, cb: (books: BooksApi) => void): void;

Runs cb with the API now if Books & Shelves is loaded (and compatible with wanted), and again each time it loads: it fires books-and-shelves:ready on the workspace at the end of its onload. The listener is registered on your plugin, so it stops when your plugin unloads.

onBooksReady(this.app, this, '0.1.0', (books) => (this.books = books));

Constants

BOOKS_API_VERSION

declare const BOOKS_API_VERSION = "0.2.0";

Semantic version of Books & Shelves' public API. Consumers check it before calling anything else.

BOOKS_PLUGIN_ID

declare const BOOKS_PLUGIN_ID = "books-and-shelves";

BOOKS_READY_EVENT

declare const BOOKS_READY_EVENT = "books-and-shelves:ready";

The workspace event Books & Shelves fires each time it loads, with its API: at startup, and when the user disables and enables it again. onBooksReady listens for it.

Types

Select a type to see its members.

BookFileOptions interface
interface BookFileOptions
  • convert?: boolean

    For an EPUB the book doesn't have: when it has an AZW3 or MOBI, ask the user to convert it in Calibre. The conversion adds an EPUB to the book in their Calibre library, so the user is always asked first; bookFile resolves null when they decline. Without this, a missing EPUB rejects with format-missing.

BookFormat type

The formats bookFile returns. Other formats (AZW3, MOBI…) are listed in formats but not served.

type BookFormat = "EPUB" | "PDF";
BooksErrorCode type

Why a call failed: - server-off: Calibre's Content Server isn't set or doesn't answer (and, for listBooks/shelfMembers, no library folder is set to read the library file instead). bookFile and pdfText always need the server. - server-error: the server answered with an error (a login it asks for, a refused change, a failure). - book-missing: Calibre has no book with that id. - format-missing: the book has no file in that format (and none to convert from, or convert wasn't asked). - shelf-missing: no shelf note has that id or name. - conversion-failed: Calibre tried to convert the book and couldn't. - no-text: the PDF has no text layer (a scan). - invalid-request: the arguments are malformed (an id that isn't a number, an unknown format).

type BooksErrorCode = "server-off" | "server-error" | "book-missing" | "format-missing" | "shelf-missing" | "conversion-failed" | "no-text" | "invalid-request";
BookSummary interface

One Calibre book, as listBooks gives it.

interface BookSummary
  • id: number

    The Calibre id.

  • title: string
  • authors: string[]
  • formats: string[]

    Calibre's formats for the book, upper case: EPUB, PDF, AZW3…

  • notePath: string | null

    The book's note in the library folder (by its calibre_id or calibre_ids), or null when it has none.

CalibreCheck interface

One Calibre setting as checked.

interface CalibreCheck
  • id: "server" | "login" | "library" | "changes"
  • name: string

    The setting in a word or two: "Content Server", "Login", "Library", "Changes".

  • state: CalibreCheckState

    off: not checked, because an earlier check failed.

  • text: string

    What was found.

  • fix?: string

    Where to set it right in Calibre, when state is bad.

CalibreChecks interface
interface CalibreChecks
  • ok: boolean

    Every check passed.

  • reads: boolean

    The server answers and the library exists: books can be read.

  • writes: boolean

    The server allows changes.

  • checks: CalibreCheck[]
CalibreCheckState type
type CalibreCheckState = "ok" | "bad" | "off";
GetBooksResult type
type GetBooksResult = {
    books: BooksApi;
} | {
    books: null;
    reason: "missing" | "incompatible";
    message: string;
    version?: string;
};