Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/arverma/Bihar-Police-Notebook/llms.txt

Use this file to discover all available pages before exploring further.

Bihar Police Notebook runs entirely in your browser — there is no application server that receives or stores your documents. Every letter and FIR case diary you write is automatically persisted in your browser’s IndexedDB, a structured client-side database that survives page refreshes and browser restarts. This page explains how that storage is organised, when saves happen, and what happens when you delete a document.

Database structure

The app opens an IndexedDB database named bp-writing-tool at schema version 2 (defined in editor/js/store.js). Inside it, two object stores hold documents side by side:
Object storeWhat it holdsKey
letterHindi letter documentsAuto-increment integer id
diaryFIR case diary documentsAuto-increment integer id
Both stores share the same field schema and carry two indexes:
  • filename — non-unique, lets the app look up documents by display name.
  • uuid — unique, the stable identifier used to match local documents with their counterpart on Google Drive.

Document fields

Every row in either object store has the following fields:
FieldTypeMeaning
idnumberAuto-incremented primary key, local to this browser
filenamestringDisplay name shown in the History sidebar (often a date)
contentstring | objectLetter: raw text string. Diary: JSON object { header, pages }
type"letter" | "diary"Discriminator — mirrors which object store the row lives in
uuidstringStable cross-device identifier generated with crypto.randomUUID()
created_atstringISO 8601 timestamp set once when the document is first created
updated_atstringISO 8601 timestamp refreshed on every save
driveFileIdstring | nullGoogle Drive file ID once the document has been backed up
syncedAtstring | nullISO 8601 timestamp of the last successful Drive sync
syncErrorstring | nullError message from the last failed Drive sync attempt, if any
deletedAtstring | nullISO 8601 timestamp set when the document is soft-deleted; null for live documents

Autosave sequence

The editor does not require you to press a save button. Changes are written to IndexedDB automatically via a 600 ms debounce:
1

User edits the document

Typing or any content change fires an onChange event in the letter or diary sheet component.
2

scheduleSave debounces the write

main.js schedules a deferred save. If another change arrives within 600 ms, the timer resets — preventing a write on every keystroke.
3

flushSave triggers the store

Once 600 ms elapse without further changes, flushSave calls saveDocumentById in store.js.
4

saveDocumentById writes to IndexedDB

The function opens a readwrite transaction on the appropriate object store, sets updated_at to the current ISO timestamp, clears any previous syncError, and issues an IDBObjectStore.put(). If no id is present yet (new document), it calls add() instead and also assigns a fresh uuid.
// Simplified view of the save path in store.js
export async function saveDocumentById(type, doc) {
  const db = await openDb();                        // opens bp-writing-tool v2
  // ... readwrite transaction on `type` store
  existing.updated_at = new Date().toISOString();   // refreshes timestamp
  existing.syncError  = null;                       // clears stale errors
  store.put(existing);                              // persists to IndexedDB
}

Delete modes

The app uses two different deletion strategies depending on whether a Drive backup exists.
When a document has ever been synced to Drive (i.e., driveFileId is set), deleting it sets deletedAt to the current timestamp rather than removing the row. The document disappears from the History sidebar immediately, but its row remains as a tombstone so the next Drive sync can upload the deletion signal and have it reflected on all devices.Once the tombstone has been successfully pushed to Drive, hardDeleteById is called automatically to clean up the local row.
// store.js — soft delete
row.deletedAt = new Date().toISOString();
row.updated_at = row.deletedAt;
row.syncError  = null;
store.put(row);   // row stays; deletedAt marks it as gone

Preferences storage

UI and feature flags — such as the Drive connection state, the dictation language, and toggle positions — are not stored in IndexedDB. They live in the browser’s localStorage under keys prefixed with bpnt. (managed by editor/js/prefs.js):
// prefs.js key examples
"bpnt.drive.connected"        // boolean — is Drive currently linked?
"bpnt.drive.email"            // string  — connected Google account
"bpnt.dictation.lang"         // string  — selected dictation language
"bpnt.dictation.onboarded"    // boolean — has the user seen the intro?
These preference values are separate from documents. Clearing IndexedDB does not erase preferences, and vice versa.

Origin scope and data loss

IndexedDB is origin-scoped by the browser. All documents are stored under the origin bpdiary.arverma.dev. Clearing your browser’s site data for that origin (via browser settings, “Clear browsing data”, or clearing cookies/storage) permanently removes every document unless they were previously synced to Google Drive.

Data stays on your device

No letter or diary content is ever transmitted to an application server. The only time data leaves your device is when you explicitly connect Google Drive and run a sync.

Portable across tabs

Because IndexedDB is scoped to the origin, the same documents are visible across any tab open to bpdiary.arverma.dev in the same browser profile.

Private browser mode

In private/incognito mode, IndexedDB is still available but is wiped when the private session ends. Preference to use private mode for confidential drafts.

No cross-device sync without Drive

Documents do not automatically appear on other devices or browsers. Enable Google Drive backup to access documents from a second device.
If you work across multiple browsers or devices, set up Google Drive Backup so that your documents are always recoverable even after clearing local storage.

Build docs developers (and LLMs) love