@nitpicker/crawler 0.8.0 → 0.11.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (92) hide show
  1. package/lib/archive/archive-accessor.d.ts +87 -14
  2. package/lib/archive/archive-accessor.js +162 -36
  3. package/lib/archive/archive.d.ts +147 -24
  4. package/lib/archive/archive.js +252 -86
  5. package/lib/archive/database.d.ts +209 -25
  6. package/lib/archive/database.js +928 -108
  7. package/lib/archive/filesystem/peek-tar-top-dir.d.ts +28 -0
  8. package/lib/archive/filesystem/peek-tar-top-dir.js +65 -0
  9. package/lib/archive/init-schema.d.ts +53 -2
  10. package/lib/archive/init-schema.js +247 -15
  11. package/lib/archive/meta/assert-compatible-version.d.ts +39 -0
  12. package/lib/archive/meta/assert-compatible-version.js +72 -0
  13. package/lib/archive/meta/classify-jsonld-type.d.ts +23 -0
  14. package/lib/archive/meta/classify-jsonld-type.js +43 -0
  15. package/lib/archive/meta/compare-semver.d.ts +23 -0
  16. package/lib/archive/meta/compare-semver.js +51 -0
  17. package/lib/archive/meta/compute-page-denormalized.d.ts +21 -0
  18. package/lib/archive/meta/compute-page-denormalized.js +35 -0
  19. package/lib/archive/meta/derive-flat-from-meta.d.ts +35 -0
  20. package/lib/archive/meta/derive-flat-from-meta.js +158 -0
  21. package/lib/archive/meta/derive-meta-extras.d.ts +20 -0
  22. package/lib/archive/meta/derive-meta-extras.js +23 -0
  23. package/lib/archive/meta/extract-tags-for-archive.d.ts +18 -0
  24. package/lib/archive/meta/extract-tags-for-archive.js +36 -0
  25. package/lib/archive/meta/summarize-jsonld.d.ts +17 -0
  26. package/lib/archive/meta/summarize-jsonld.js +29 -0
  27. package/lib/archive/meta/summarize-tags.d.ts +16 -0
  28. package/lib/archive/meta/summarize-tags.js +33 -0
  29. package/lib/archive/meta/types.d.ts +207 -0
  30. package/lib/archive/meta/types.js +33 -0
  31. package/lib/archive/migrate-crawl-errors.d.ts +20 -0
  32. package/lib/archive/migrate-crawl-errors.js +38 -0
  33. package/lib/archive/migrate-html-blob-tables.d.ts +24 -0
  34. package/lib/archive/migrate-html-blob-tables.js +53 -0
  35. package/lib/archive/migrate-page-errors.d.ts +16 -0
  36. package/lib/archive/migrate-page-errors.js +35 -0
  37. package/lib/archive/migrate-pages-resources-source.d.ts +16 -0
  38. package/lib/archive/migrate-pages-resources-source.js +46 -0
  39. package/lib/archive/page.d.ts +187 -49
  40. package/lib/archive/page.js +258 -63
  41. package/lib/archive/peek-archive-lock.d.ts +40 -0
  42. package/lib/archive/peek-archive-lock.js +62 -0
  43. package/lib/archive/resolve-redirect-chain.d.ts +33 -0
  44. package/lib/archive/resolve-redirect-chain.js +27 -0
  45. package/lib/archive/types.d.ts +135 -26
  46. package/lib/crawler/close-browser-safely.d.ts +64 -0
  47. package/lib/crawler/close-browser-safely.js +73 -0
  48. package/lib/crawler/crawler.d.ts +4 -1
  49. package/lib/crawler/crawler.js +290 -32
  50. package/lib/crawler/create-change-phase-handler.d.ts +54 -0
  51. package/lib/crawler/create-change-phase-handler.js +44 -0
  52. package/lib/crawler/derive-page-source.d.ts +23 -0
  53. package/lib/crawler/derive-page-source.js +28 -0
  54. package/lib/crawler/derive-resource-source.d.ts +23 -0
  55. package/lib/crawler/derive-resource-source.js +26 -0
  56. package/lib/crawler/drain-phase-errors.d.ts +48 -0
  57. package/lib/crawler/drain-phase-errors.js +35 -0
  58. package/lib/crawler/fetch-destination.js +38 -2
  59. package/lib/crawler/format-crawl-progress.d.ts +12 -3
  60. package/lib/crawler/format-crawl-progress.js +14 -6
  61. package/lib/crawler/handle-browser-close.d.ts +29 -0
  62. package/lib/crawler/handle-browser-close.js +28 -0
  63. package/lib/crawler/is-html-content-type.d.ts +17 -0
  64. package/lib/crawler/is-html-content-type.js +19 -0
  65. package/lib/crawler/is-likely-html-url.d.ts +22 -0
  66. package/lib/crawler/is-likely-html-url.js +65 -0
  67. package/lib/crawler/kill-process-tree.d.ts +94 -0
  68. package/lib/crawler/kill-process-tree.js +178 -0
  69. package/lib/crawler/link-list.js +2 -1
  70. package/lib/crawler/link-to-page-data.d.ts +13 -5
  71. package/lib/crawler/link-to-page-data.js +26 -5
  72. package/lib/crawler/log-undrained-phase-errors.d.ts +37 -0
  73. package/lib/crawler/log-undrained-phase-errors.js +34 -0
  74. package/lib/crawler/normalize-content-type.d.ts +14 -0
  75. package/lib/crawler/normalize-content-type.js +20 -0
  76. package/lib/crawler/partition-urls-by-html.d.ts +16 -0
  77. package/lib/crawler/partition-urls-by-html.js +23 -0
  78. package/lib/crawler/redirect-dest-key.d.ts +19 -0
  79. package/lib/crawler/redirect-dest-key.js +27 -0
  80. package/lib/crawler/resource-to-page-data.d.ts +28 -0
  81. package/lib/crawler/resource-to-page-data.js +59 -0
  82. package/lib/crawler/types.d.ts +122 -1
  83. package/lib/crawler-orchestrator.d.ts +93 -1
  84. package/lib/crawler-orchestrator.js +389 -12
  85. package/lib/crawler.d.ts +5 -0
  86. package/lib/crawler.js +3 -0
  87. package/lib/resource-row-to-lookup-result.d.ts +13 -0
  88. package/lib/resource-row-to-lookup-result.js +20 -0
  89. package/lib/types.d.ts +11 -1
  90. package/lib/utils/object/parse-response-headers.d.ts +12 -0
  91. package/lib/utils/object/parse-response-headers.js +26 -0
  92. package/package.json +4 -4
@@ -1,4 +1,5 @@
1
- import type { Config, DatabaseOption, DB_Anchor, DB_Page, DB_Redirect, DB_Referrer, DB_Resource, DatabaseEvent, PageFilter } from './types.js';
1
+ import type { JsonLdRow, TagRow } from './meta/types.js';
2
+ import type { Config, DatabaseOption, DB_Anchor, DB_Page, DB_Redirect, DB_Referrer, DB_Resource, DatabaseEvent, PageFilter, PageSource } from './types.js';
2
3
  import type { PageData, Resource } from '../utils/types/types.js';
3
4
  import type { ExURL, ParseURLOptions } from '@d-zero/shared/parse-url';
4
5
  import type { Knex } from 'knex';
@@ -6,10 +7,11 @@ import { TypedAwaitEventEmitter as EventEmitter } from '@d-zero/shared/typed-awa
6
7
  /**
7
8
  * Low-level database abstraction layer for the archive's SQLite database.
8
9
  *
9
- * Manages the `pages`, `anchors`, `images`, `resources`, and `resources-referrers`
10
- * tables. All public methods that perform database queries use the `@retryable`
11
- * decorator for automatic retry on transient failures, and `@ErrorEmitter` to
12
- * propagate errors as events.
10
+ * Public methods that perform database queries use the `@retryable`
11
+ * decorator for automatic retry on transient failures, and `@ErrorEmitter`
12
+ * to propagate errors as events. The set of tables this layer manages is
13
+ * defined by `init-schema.ts` (the source of truth — query that file for
14
+ * the canonical list).
13
15
  *
14
16
  * Use the static {@link Database.connect} factory method to create instances.
15
17
  * The constructor is private.
@@ -30,12 +32,6 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
30
32
  * This ensures the database is fully self-contained in `db.sqlite` before archiving.
31
33
  */
32
34
  checkpoint(): Promise<void>;
33
- /**
34
- * Clears the HTML snapshot path for a page.
35
- * Used to roll back the snapshot reference when the snapshot file write fails.
36
- * @param pageId - The database ID of the page whose HTML path should be cleared.
37
- */
38
- clearHtmlPath(pageId: number): Promise<void>;
39
35
  /**
40
36
  * Destroys the database connection, releasing all pooled resources.
41
37
  */
@@ -69,11 +65,51 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
69
65
  pending: string[];
70
66
  }>;
71
67
  /**
72
- * Retrieves the HTML snapshot file path for a specific page.
68
+ * Return the subset of `urls` that already exist in the `pages` table.
69
+ * Chunked into batches so SQLite's `IN (?, ?, …)` parameter limit
70
+ * (`SQLITE_MAX_VARIABLE_NUMBER`, default 999) cannot be hit even when the
71
+ * inventory list contains tens of thousands of URLs.
72
+ *
73
+ * Read-only — no transaction, no lock contention with the crawler write
74
+ * pipeline (callers run this BEFORE the `<archive>.bak` is taken and the
75
+ * crawl is started).
76
+ * @param urls - URL strings to probe (already in `withoutHashAndAuth` form).
77
+ * @returns URLs found in `pages`. Order is not preserved.
78
+ */
79
+ getExistingPageUrls(urls: readonly string[]): Promise<string[]>;
80
+ /**
81
+ * Return the subset of `urls` that already exist in the `resources` table.
82
+ * See {@link Database.getExistingPageUrls} — same chunking strategy.
83
+ * @param urls - URL strings to probe.
84
+ * @returns URLs found in `resources`.
85
+ */
86
+ getExistingResourceUrls(urls: readonly string[]): Promise<string[]>;
87
+ /**
88
+ * Reads the HTML snapshot stored as a zstd-compressed BLOB for the given page.
89
+ *
90
+ * Joins `page_html_ref` → `page_html_blobs` and decompresses inline. Returns
91
+ * `null` when the page has no stored body (a non-HTML resource, a redirect
92
+ * source, a degraded render). Read works identically on read-only / stub
93
+ * connections — the special-cased "do we have a loose dir vs zip?" branching
94
+ * the previous file-backed layout required is gone.
95
+ *
96
+ * Tables `page_html_ref` and `page_html_blobs` are created by `initSchema`.
97
+ * Older `.nitpicker` archives that predate this migration must be passed
98
+ * through `scripts/migrate-to-0.10.mjs` before they can be read.
73
99
  * @param pageId - The database ID of the page.
74
- * @returns The relative file path to the HTML snapshot, or null if not saved.
100
+ * @returns The decompressed HTML string, or `null` if no snapshot is stored.
101
+ */
102
+ getHtmlOfPageById(pageId: number): Promise<string | null>;
103
+ /**
104
+ * Retrieves all `page_jsonld` rows for the given page id, parsed back into
105
+ * {@link JsonLdRow} shape (with `parsed` deserialised from its JSON column).
106
+ *
107
+ * Read-side counterpart to `#insertJsonLd`. Returns rows in insertion order
108
+ * by `id` so the order observed by `get-page-jsonld` matches the order the
109
+ * scraper saw them.
110
+ * @param pageId
75
111
  */
76
- getHtmlPathOnPage(pageId: number): Promise<any>;
112
+ getJsonLdOfPage(pageId: number): Promise<JsonLdRow[]>;
77
113
  /**
78
114
  * Returns the underlying Knex query builder instance for direct SQL access.
79
115
  * This enables advanced queries (GROUP BY, HAVING, JOINs) at the database
@@ -122,6 +158,14 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
122
158
  getRedirectsForPages(pageIds: number[]): Promise<DB_Redirect[]>;
123
159
  /**
124
160
  * Retrieves pages that link to a specific page (incoming links / referrers).
161
+ *
162
+ * Incoming links are resolved **through redirects**: an anchor pointing at a
163
+ * redirect source (e.g. `http://x` that 301s to `https://x`) counts as a
164
+ * referrer of the redirect's final destination, not of the source. This keeps
165
+ * backlinks merged on the canonical page instead of splitting them across the
166
+ * `http`/`https` (or any redirect source/dest) pair. The resolution mirrors
167
+ * `redirectTable()` — `redirectDestId` is pre-flattened to the final
168
+ * destination, so `COALESCE(target.redirectDestId, target.id)` is a single hop.
125
169
  * @param pageId - The database ID of the target page.
126
170
  * @returns An array of referrer records with URL, hash, and text content.
127
171
  */
@@ -132,6 +176,22 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
132
176
  * @returns An array of page URL strings that reference the resource.
133
177
  */
134
178
  getReferrersOfResource(id: number): Promise<string[]>;
179
+ /**
180
+ * Retrieves a single sub-resource from the `resources` table by its URL.
181
+ *
182
+ * Accepts multiple URL candidates because the stored key is the resource's
183
+ * `href` while callers may only know the hash-stripped form; the first match
184
+ * wins.
185
+ *
186
+ * Deliberately NOT decorated with `@ErrorEmitter`: the only caller (the
187
+ * crawler's resource-reuse hook) has a full fallback (the HEAD pre-flight),
188
+ * so a read failure here must not surface as a database `error` event —
189
+ * the orchestrator aborts the whole crawl on that event, which is the
190
+ * correct reaction to write failures but not to a recoverable read.
191
+ * @param urls - URL candidates to match against the `url` column.
192
+ * @returns The raw {@link DB_Resource} row, or `null` if none match.
193
+ */
194
+ getResourceByUrl(urls: readonly string[]): Promise<DB_Resource | null>;
135
195
  /**
136
196
  * Retrieves all sub-resources from the `resources` table.
137
197
  * @returns An array of raw {@link DB_Resource} rows.
@@ -142,12 +202,73 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
142
202
  * @returns An array of resource URL strings.
143
203
  */
144
204
  getResourceUrlList(): Promise<any[]>;
205
+ /**
206
+ * Counts pages that were scraped as crawl targets (full HTML render).
207
+ *
208
+ * Used by the crawler to seed its `pagesScraped` counter on resume so the
209
+ * progress display reflects all browser-rendered HTML pages across sessions,
210
+ * not just the current one.
211
+ *
212
+ * "HTML page" is guaranteed by `contentType = 'text/html'`, NOT by `isTarget`
213
+ * alone: `isTarget` means "in-scope crawl target" and is set for in-scope
214
+ * non-HTML resources too (e.g. a PDF reached via the HEAD pre-flight is
215
+ * `isTarget = 1`). Counting those would over-report the HTML page total, so
216
+ * page-ness is asserted at the read layer here rather than by trusting
217
+ * `isTarget`.
218
+ * @returns The number of `text/html` rows with `isTarget = 1` and `scraped = 1`.
219
+ */
220
+ getScrapedHtmlPageCount(): Promise<number>;
221
+ /**
222
+ * Retrieves all `page_tags` rows for the given page id, parsed back into
223
+ * {@link TagRow} shape (with `categories` and `sources` JSON columns
224
+ * deserialised).
225
+ *
226
+ * Read-side counterpart to `#insertTags`.
227
+ * @param pageId
228
+ */
229
+ getTagsOfPage(pageId: number): Promise<TagRow[]>;
230
+ /**
231
+ * Records a crawler-level (`error` channel) failure into `crawl_errors`.
232
+ *
233
+ * Unlike {@link insertPageError} this is not tied to a scraped page: `url`
234
+ * may be an external link that never became a page row, or `null` for a
235
+ * process-level error. The cause is intentionally not stored — it is derived
236
+ * on read so that older archives (which only have `error.log`) and freshly
237
+ * captured rows classify identically.
238
+ * @param url - The URL the error is about, or `null` for a process-level error.
239
+ * @param message - The error message (one line is enough for classification).
240
+ * @param isExternal - Whether the URL is external to the crawl scope.
241
+ */
242
+ insertCrawlError(url: string | null, message: string, isExternal?: boolean): Promise<void>;
243
+ /**
244
+ * Records a partial scrape failure against the page identified by `url`.
245
+ *
246
+ * The page row is resolved (or inserted as a stub) via
247
+ * {@link Database.#getIdByUrl} so the error can be recorded even before
248
+ * `setPage` has run — useful when the failure fires during scraping
249
+ * (e.g. mid-`scrapeStart`) and the orchestrator enqueues this write
250
+ * before the success write for the same URL.
251
+ *
252
+ * A single page can have multiple `page_errors` rows (e.g. both
253
+ * `desktop-compact` and `mobile-small` viewports failing).
254
+ * @param url - URL of the page being scraped.
255
+ * @param phase - Scrape phase name (typically `'retryExhausted'`).
256
+ * @param message - Human-readable failure message.
257
+ * @param isExternal - Whether the URL is external. Defaults to `false`.
258
+ */
259
+ insertPageError(url: string, phase: string, message: string, isExternal?: boolean): Promise<void>;
145
260
  /**
146
261
  * Inserts a sub-resource into the `resources` table.
147
262
  * Ignores duplicate URLs (uses `ON CONFLICT IGNORE`).
263
+ *
264
+ * The `source` provenance label is written ONLY on insert; an
265
+ * `ON CONFLICT IGNORE` collision leaves an existing row's source untouched
266
+ * (this is what makes a second `crawl --inventory` non-destructive — see
267
+ * the inventory plan).
148
268
  * @param resource - The resource data to insert.
269
+ * @param source - Provenance label for new rows. `undefined` leaves the DB DEFAULT (`'crawled'`).
149
270
  */
150
- insertResource(resource: Resource): Promise<void>;
271
+ insertResource(resource: Resource, source?: PageSource): Promise<void>;
151
272
  /**
152
273
  * Inserts a referrer relationship between a resource and a page into the
153
274
  * `resources-referrers` table. Silently skips if the resource is not found.
@@ -155,6 +276,25 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
155
276
  * @param pageUrl - The URL of the page that references the resource.
156
277
  */
157
278
  insertResourceReferrers(src: string, pageUrl: string): Promise<void>;
279
+ /**
280
+ * Records a redirect edge (source → destination) **without** re-storing the
281
+ * destination's content.
282
+ *
283
+ * The crawler renders a many-to-one redirect destination exactly once. For
284
+ * every subsequent source URL that redirects to that already-rendered
285
+ * destination, it calls this instead of {@link updatePage} (#73). Routing a
286
+ * content-less HEAD result through `updatePage` would funnel it into
287
+ * `#insertPage` and overwrite the destination's good title / meta with empty
288
+ * values, so the dedicated edge-only path is required.
289
+ *
290
+ * The destination row is resolved (created on demand if a concurrent in-flight
291
+ * render has not committed it yet) so the edge always points at a valid id;
292
+ * the single render fills in the destination's content under that same id.
293
+ * The destination's existing anchors / images are never touched here.
294
+ * @param page - HEAD-resolved page data carrying the redirect chain. Its
295
+ * `anchorList` / `imageList` are ignored (a redirect source owns no content).
296
+ */
297
+ recordRedirect(page: PageData): Promise<void>;
158
298
  /**
159
299
  * Promote previously-external pages whose URL falls under any of the new scope
160
300
  * entries back to a "needs scraping" state so that the next crawl picks them up
@@ -174,6 +314,35 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
174
314
  * @returns The URLs of the pages that were promoted.
175
315
  */
176
316
  repromoteExternalPages(scopes: ReadonlyMap<string, readonly ExURL[]>, options?: ParseURLOptions): Promise<string[]>;
317
+ /**
318
+ * Reset previously-attempted pages that ended in a recoverable failure so a
319
+ * follow-up crawl can re-fetch them from scratch.
320
+ *
321
+ * A page qualifies as a recoverable failure when it was already scraped
322
+ * (`scraped = 1`), is not a redirect source (`redirectDestId IS NULL`), was
323
+ * not intentionally skipped (`isSkipped` is not `1`), and one of the
324
+ * following holds:
325
+ *
326
+ * - `status = -1` — the sentinel a hard scrape failure (network error,
327
+ * timeout, browser crash) is recorded with (see `handle-scrape-error.ts`);
328
+ * - `status IS NULL` — no status was ever stored for the row;
329
+ * - `contentType IS NULL` — the content type could not be determined;
330
+ * - `status` is in the `5xx` range — a (frequently transient) server error.
331
+ *
332
+ * Definitive `4xx` responses are intentionally excluded: re-fetching a 404
333
+ * almost always yields the same answer. Matching rows — internal and
334
+ * external alike — are demoted back to pending (`scraped = 0`) and have their
335
+ * stale scrape metadata cleared. The page row itself is kept (id preserved)
336
+ * so existing `anchors.hrefId` referrers stay valid, and `isExternal` is left
337
+ * untouched so the next pass re-classifies each page from the crawl scope.
338
+ * Related `anchors`, `images`, `resources-referrers`, and `page_errors` rows
339
+ * are deleted so the re-scrape can re-insert fresh data without duplicates.
340
+ *
341
+ * SELECT and UPDATE/DELETE statements are chunked to stay below SQLite's
342
+ * `SQLITE_LIMIT_VARIABLE_NUMBER`.
343
+ * @returns The URLs of the pages that were reset to pending.
344
+ */
345
+ resetFailedPages(): Promise<string[]>;
177
346
  /**
178
347
  * Stores the crawl configuration in the `info` table.
179
348
  * Only fields in {@link INFO_COLUMN_ALLOWLIST} are forwarded — any extra
@@ -212,27 +381,42 @@ export declare class Database extends EventEmitter<DatabaseEvent> {
212
381
  updateConfig(patch: Partial<Config>): Promise<void>;
213
382
  /**
214
383
  * Inserts or updates a crawled page in the database, including its redirect chain,
215
- * anchors, and images. Optionally creates an HTML snapshot file path entry.
384
+ * anchors, images, and (when `writeHtml`) its compressed HTML snapshot BLOB.
216
385
  *
217
386
  * Self-redirects (where the source URL equals the destination URL after normalization)
218
387
  * are skipped to avoid marking a page as redirected to itself — a situation caused by
219
388
  * authentication challenges (e.g. Basic Auth 302) that would otherwise exclude the page
220
389
  * from reports via the `whereNull('redirectDestId')` filter.
221
390
  * @param page - The page data to store.
222
- * @param snapshotDir - The directory for saving HTML snapshots, or null to skip snapshots.
391
+ * @param writeHtml - When `true`, this call is allowed to insert (or clear)
392
+ * the page's HTML blob. `setExternalPage` passes `false` because external
393
+ * metadata-only scrapes never carry HTML and must not perturb an already
394
+ * stored body.
223
395
  * @param isTarget - Whether this page is a crawl target.
224
- * @returns An object with the optional `html` snapshot file path and the page's database `pageId`.
396
+ * @param source - Provenance label written ONLY when the row is freshly
397
+ * inserted. Existing rows keep their original `source` (this is why a
398
+ * second `crawl --inventory` does not "demote" an `'inventory-seed'` row
399
+ * that was discovered earlier).
400
+ * @returns The database `pageId` of the inserted/updated row.
225
401
  */
226
- updatePage(page: PageData, snapshotDir: string | null, isTarget: boolean): Promise<{
227
- html?: string | undefined;
228
- pageId: number;
229
- }>;
402
+ updatePage(page: PageData, writeHtml: boolean, isTarget: boolean, source?: PageSource): Promise<number>;
230
403
  /**
231
404
  * Creates and initializes a new Database instance.
232
- * Creates the parent directory for the database file if needed,
233
- * establishes the connection, and initializes tables if they do not exist.
234
- * @param options - Database connection options (working directory + SQLite file path).
405
+ *
406
+ * **Writer mode (default)**: creates the parent directory for the
407
+ * database file if needed, establishes the connection, and initializes
408
+ * the schema + migrations.
409
+ *
410
+ * **Read-only mode** (`options.readOnly`): refuses to resurrect a
411
+ * missing parent directory or db file — throws if either is absent at
412
+ * the time of the call. Skips schema init and migrations entirely so
413
+ * the user's tmpDir is never modified. Required by viewer / MCP
414
+ * stub-mode opens, where a TOCTOU window between classification and
415
+ * `connect()` could otherwise leave behind a phantom empty tmpDir.
416
+ * @param options - Database connection options.
235
417
  * @returns A fully initialized Database instance.
418
+ * @throws {Error} In read-only mode, if the parent directory or db
419
+ * file does not exist when `connect()` runs.
236
420
  */
237
421
  static connect(options: DatabaseOption): Promise<Database>;
238
422
  }