@shotkit/shotium 0.2.0 → 0.3.1

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.
package/dist/index.d.ts CHANGED
@@ -27,6 +27,75 @@ interface Viewport {
27
27
  /** CSS pixels. Default 720. */
28
28
  height?: number;
29
29
  }
30
+ /**
31
+ * What a capture may do with the HTTP cache, spelled the way `fetch` spells
32
+ * it.
33
+ *
34
+ * - `default`: ordinary HTTP semantics. A fresh entry is used without asking,
35
+ * a stale one is revalidated, and the response updates the cache.
36
+ * - `reload`: read nothing, write everything -- the browser's reload button.
37
+ * The next capture is fast again.
38
+ * - `no-store`: neither read nor write. For a page that should not be left on
39
+ * this machine's disk, which an authenticated one usually should not.
40
+ * - `only-if-cached`: the network may not be touched and a miss is an error.
41
+ * Useful for a deterministic re-render of something already fetched.
42
+ */
43
+ type CacheMode = 'default' | 'reload' | 'no-store' | 'only-if-cached';
44
+ /** Where the milliseconds went. */
45
+ interface CaptureTiming {
46
+ /**
47
+ * Fetching the top-level document. For a cold `https:` URL this is DNS, TCP,
48
+ * TLS and a round trip, and it is routinely larger than everything below --
49
+ * which is the single most useful thing this object says.
50
+ */
51
+ fetch: number;
52
+ /** Parse, subresources, style, layout, prepaint, paint. */
53
+ render: number;
54
+ /** Page/frame creation and synchronous document installation. */
55
+ setup: number;
56
+ /** Waiting for parsing, load completion and subresources. */
57
+ wait: number;
58
+ /** Capture selection plus style/layout/lifecycle advancement. */
59
+ lifecycle: number;
60
+ /** Extracting Blink's paint record. */
61
+ paint: number;
62
+ /** Raster-surface preparation and paint-record replay. */
63
+ raster: number;
64
+ encode: number;
65
+ /** Wall clock for the whole capture, so the phases above can be checked. */
66
+ total: number;
67
+ }
68
+ /** What one capture cost, and where its bytes came from. */
69
+ interface CaptureStats {
70
+ /** Every resource the document asked for, itself included. */
71
+ requests: number;
72
+ /**
73
+ * Answered from the HTTP cache -- the body came from disk.
74
+ *
75
+ * Not the same as "no network was touched". A stale entry that can be
76
+ * revalidated costs a conditional request and a 304, and counts here too;
77
+ * what the cache saved is the download rather than the round trip. That is
78
+ * why `timing.fetch` can be tens of milliseconds with this set.
79
+ */
80
+ fromCache: number;
81
+ failed: number;
82
+ /** Decoded body bytes, summed -- not the transfer size. */
83
+ bytes: number;
84
+ /** The document's own status. 0 for a `file:` URL. */
85
+ httpStatus: number;
86
+ /** After redirects, which is what relative URLs resolved against. */
87
+ finalUrl: string;
88
+ timing: CaptureTiming;
89
+ }
90
+ /** One screenshot, and what taking it cost. */
91
+ interface ScreenshotResult {
92
+ /**
93
+ * The encoded image, or `null` when `path` was given: the engine wrote the
94
+ * file itself and there is nothing left to hand back.
95
+ */
96
+ image: Buffer | null;
97
+ stats: CaptureStats;
98
+ }
30
99
  interface ScreenshotOptions {
31
100
  /** An http/https/file URL, or a local path. */
32
101
  file: string;
@@ -62,14 +131,47 @@ interface ScreenshotOptions {
62
131
  * is rendered on.
63
132
  */
64
133
  allowFileAccess?: boolean;
134
+ /**
135
+ * What this capture may do with the HTTP cache. Default `default`.
136
+ *
137
+ * It applies to the subresources as well as the document: a `reload` that
138
+ * refreshed the HTML and reused yesterday's stylesheet would be a confusing
139
+ * thing to have asked for.
140
+ */
141
+ cache?: CacheMode;
142
+ /**
143
+ * Extra request headers, sent with the document and with the subresources
144
+ * that are same-origin with it.
145
+ *
146
+ * Same-origin is the whole rule and it is not configurable. A caller passing
147
+ * `Authorization` or `Cookie` means it for the site being photographed; a
148
+ * page that pulls a script from a CDN must not have the credential
149
+ * forwarded there.
150
+ */
151
+ headers?: Record<string, string>;
65
152
  }
66
153
  interface StartOptions {
67
154
  /**
68
- * Root of the HTTP disk cache. `null` disables caching entirely, which is
69
- * the default: a program holding the engine is often short-lived, and a
70
- * cache it never reads twice is a directory it leaves behind.
155
+ * Root of the HTTP disk cache. `null` disables caching entirely.
156
+ *
157
+ * The default is a per-project directory under the system temporary
158
+ * directory -- see `cache.getDir()`. Caching is on by default because the
159
+ * alternative turned out to be worse: without it every capture of an
160
+ * `https:` URL pays for DNS, TLS and a round trip, which for a small page is
161
+ * most of the time the call takes and all of the time the caller did not
162
+ * expect to spend.
71
163
  */
72
164
  cacheDir?: string | null;
165
+ /**
166
+ * Ceiling on the cache directory, in bytes. Default 256 MB.
167
+ *
168
+ * Zero is not "unlimited" -- it hands the decision to the backend, which
169
+ * sizes itself against the volume's free space. That was a reasonable
170
+ * default when every user of the cache had named a directory on purpose; for
171
+ * one that appears by default under `~/.shotium` because somebody imported a
172
+ * library, a number somebody chose is better than a number nobody did.
173
+ */
174
+ cacheMaxBytes?: number;
73
175
  /** Overrides the built-in user agent string. */
74
176
  userAgent?: string;
75
177
  /**
@@ -78,6 +180,35 @@ interface StartOptions {
78
180
  */
79
181
  resourceDir?: string;
80
182
  }
183
+ /** What `start()` reports about the engine it brought up. */
184
+ interface StartResult {
185
+ /**
186
+ * Whether this lifecycle is started.
187
+ *
188
+ * A process has at most one engine, so `false` here does not mean there is
189
+ * nothing running -- it means this `Runtime` is stood down. `cacheDir` below
190
+ * is still answered from the engine, because a stood-down engine keeps its
191
+ * cache directory and reporting `null` would say the cache had gone away
192
+ * when what went away was the willingness to render.
193
+ */
194
+ running: boolean;
195
+ /** The directory in use, or `null` when caching is off. */
196
+ cacheDir: string | null;
197
+ /**
198
+ * Whether that directory is actually being cached into.
199
+ *
200
+ * A directory that cannot be created or written to costs nothing visible:
201
+ * the engine renders exactly as well without a cache, only slower, and every
202
+ * capture pays for the network again for a reason nothing reports. `false`
203
+ * with a `cacheDir` set means the open failed; `false` with `cacheDir: null`
204
+ * means no cache was asked for.
205
+ *
206
+ * It is not about sharing. Several processes may use one directory and all
207
+ * of them cache -- the backend takes no cross-process lock -- so `true` in
208
+ * two processes at once is the ordinary answer.
209
+ */
210
+ cacheActive: boolean;
211
+ }
81
212
  interface DaemonOptions extends StartOptions {
82
213
  /**
83
214
  * Address the daemon by name instead of by configuration. Without it the
@@ -123,7 +254,16 @@ interface DaemonStatus {
123
254
  idleTimeoutMs: number;
124
255
  version: string;
125
256
  }
126
- interface PurgeOptions {
257
+ /**
258
+ * Options for `releaseMemory()`.
259
+ *
260
+ * Named for what it does rather than for `purge`, which it was called until
261
+ * 0.3. With `cache.clear()` in the API the old name reads as though it clears
262
+ * the cache, and it does not: it hands back blink's heap, skia's caches and
263
+ * PartitionAlloc's free lists, all of which the engine rebuilds on demand.
264
+ * Nothing on disk is touched.
265
+ */
266
+ interface ReleaseMemoryOptions {
127
267
  /**
128
268
  * Also ask the OS to take the engine's pages back. The next screenshot pays
129
269
  * them back in soft page faults -- a few milliseconds -- so this is for when
@@ -131,6 +271,150 @@ interface PurgeOptions {
131
271
  */
132
272
  releaseWorkingSet?: boolean;
133
273
  }
274
+ /** Which cache directory an operation is about. */
275
+ interface CacheTarget {
276
+ /**
277
+ * `current` (the default) is this project's directory, `all` is every
278
+ * directory shotium has created under the shared root -- `~/.shotium/cache`
279
+ * -- and a string is either an absolute path or one project hash as
280
+ * `getDir()` reports it.
281
+ *
282
+ * The absolute path is there because `start({cacheDir})` accepts any
283
+ * directory: without it, a caller who chose their own cache would have the
284
+ * one cache these methods could not see.
285
+ *
286
+ * `all` exists because the directories are per-project by default, so
287
+ * "clear shotium's caches" is otherwise something a caller cannot express
288
+ * without already knowing where the other projects were.
289
+ */
290
+ target?: 'current' | 'all' | (string & {});
291
+ }
292
+ /** One resource the cache is holding. */
293
+ interface CacheEntry {
294
+ /** The resource, not the backend's key -- see `cache.getFiles()`. */
295
+ url: string;
296
+ /** Milliseconds since the Unix epoch. */
297
+ lastUsedMs: number;
298
+ bytes: number;
299
+ /** Which cache directory it was found in. */
300
+ dir: string;
301
+ }
302
+ interface CacheClearOptions extends CacheTarget {
303
+ /**
304
+ * Glob patterns matched against entry URLs -- not against filenames, which
305
+ * are hashes and would match nothing anybody would think to write.
306
+ *
307
+ * Supports `*` (within a path segment), `**` (across segments), `?` and
308
+ * `{a,b}`. Matching happens here rather than in the engine: the entries come
309
+ * back first, the patterns are applied to their URLs, and the ones that
310
+ * matched are what gets removed.
311
+ */
312
+ glob?: string[];
313
+ /**
314
+ * Remove entries not used for this many seconds. `0`, the default, means no
315
+ * age limit.
316
+ */
317
+ maxAge?: number;
318
+ /**
319
+ * Evict least-recently-used entries until the directory is at or below this
320
+ * many bytes. `0`, the default, means no size limit.
321
+ */
322
+ maxSize?: number;
323
+ }
324
+ interface CacheClearResult {
325
+ /**
326
+ * How many entries went. `-1` when the whole directory was dropped in one
327
+ * operation, which the backend does without counting them.
328
+ */
329
+ removed: number;
330
+ bytesBefore: number;
331
+ bytesAfter: number;
332
+ /** Which directory this result is for. */
333
+ dir: string;
334
+ }
335
+ //#endregion
336
+ //#region src/lib/binding.d.ts
337
+ /**
338
+ * The engine handle the addon hands back. Opaque on purpose: everything that
339
+ * can be done with it is a call on the binding below.
340
+ */
341
+ type Engine = unknown;
342
+ //#endregion
343
+ //#region src/lib/cache.d.ts
344
+ /**
345
+ * The cache, from the outside.
346
+ *
347
+ * Every method takes the engine handle if there is one, and that is not an
348
+ * optimisation. Within one process a cache directory has one backend: asking
349
+ * for a second one on the directory the engine holds waits for the engine's to
350
+ * go away, which it will not do while the engine is up. Borrowing is the only
351
+ * thing that returns.
352
+ *
353
+ * "If there is one" means the process, not the lifecycle. `stop()` stands the
354
+ * engine down without tearing it down, so an engine that has been stopped
355
+ * still holds its directory and still has to be borrowed from -- which is also
356
+ * what makes the cache survive a stop, and outlive one, and be worth having.
357
+ *
358
+ * Across processes there is no such constraint -- several of them may share a
359
+ * directory and all of them cache.
360
+ *
361
+ * The engine is fetched through a callback rather than held, because this
362
+ * object is built once at import time and the engine comes and goes.
363
+ */
364
+ declare class Cache {
365
+ private readonly engineHandle;
366
+ constructor(engineHandle: () => Engine | null);
367
+ /**
368
+ * This project's cache directory, absolute and with forward slashes.
369
+ *
370
+ * It exists whether or not anything has been written to it -- the answer is
371
+ * "where the cache goes", not "where a cache is".
372
+ */
373
+ getDir(options?: CacheTarget): string;
374
+ /** Every directory the target names. `all` can be several; the rest, one. */
375
+ getDirs(options?: CacheTarget): string[];
376
+ /**
377
+ * What the cache is holding, by URL.
378
+ *
379
+ * Named `getFiles` for the operation callers reach for, and deliberately not
380
+ * returning filenames: the files in a cache directory are called things like
381
+ * `5349fbae98c6d9a1_0`, because the name is a hash of the entry key. A list
382
+ * of those answers no question anybody has. The URLs are what the entries
383
+ * are, and they are what `clear({glob})` matches against.
384
+ *
385
+ * This opens every entry to read its key and size, so it is a diagnostic
386
+ * rather than something to put on a request path.
387
+ */
388
+ getFiles(options?: CacheTarget): Promise<CacheEntry[]>;
389
+ /**
390
+ * Removes what the options select. With no options, everything.
391
+ *
392
+ * The three filters compose, and `glob` is applied here rather than in the
393
+ * engine: the entries are listed, their URLs are matched, and the ones that
394
+ * matched are what the engine is asked to remove. That keeps the pattern
395
+ * dialect in the layer whose users have opinions about pattern dialects, and
396
+ * keeps the engine's interface to exact URLs.
397
+ *
398
+ * Removal goes through the cache backend, never through the filesystem.
399
+ * Deleting the files directly would leave the backend's index naming entries
400
+ * that are no longer there, and the next process to open the directory
401
+ * either rebuilds the index from disk or, having found it inconsistent,
402
+ * discards it. That is the difference between clearing a cache and
403
+ * corrupting one.
404
+ */
405
+ clear(options?: CacheClearOptions): Promise<CacheClearResult[]>;
406
+ /**
407
+ * The engine handle, when there is an engine.
408
+ *
409
+ * Passed for every directory and not only the engine's own. It is never
410
+ * wrong to pass it -- the engine's thread can open any directory, and for
411
+ * the one it already has open, borrowing its backend is the only thing that
412
+ * returns. It is passing `null` while an engine is up that hangs, which is
413
+ * why this is conditional on neither the directory asked for nor on whether
414
+ * the engine is currently accepting captures.
415
+ */
416
+ private handleFor;
417
+ }
134
418
  //#endregion
135
419
  //#region src/lib/client.d.ts
136
420
  interface ClientReply {
@@ -138,6 +422,7 @@ interface ClientReply {
138
422
  ok?: boolean;
139
423
  error?: string;
140
424
  path?: string;
425
+ stats?: CaptureStats;
141
426
  }
142
427
  interface ClientResult {
143
428
  header: ClientReply;
@@ -157,8 +442,13 @@ declare class DaemonClient extends EventEmitter {
157
442
  private settle;
158
443
  private failAll;
159
444
  send(message: Record<string, unknown>): Promise<ClientResult>;
160
- /** Resolves to the image, or to null when `path` was given. */
161
- screenshot(options: ScreenshotOptions): Promise<Buffer | null>;
445
+ /**
446
+ * One screenshot, and what taking it cost.
447
+ *
448
+ * The same shape the in-process engine returns, so that moving a program
449
+ * between the two is an import change and nothing else.
450
+ */
451
+ screenshot(options: ScreenshotOptions): Promise<ScreenshotResult>;
162
452
  status(): Promise<DaemonStatus>;
163
453
  shutdown(): Promise<{
164
454
  ok: boolean;
@@ -174,7 +464,7 @@ interface Daemon {
174
464
  /** One screenshot through the daemon, connection and all. */
175
465
  screenshot(options: ScreenshotOptions & {
176
466
  daemon?: DaemonOptions;
177
- }): Promise<Buffer | null>;
467
+ }): Promise<ScreenshotResult>;
178
468
  /** Starts one if it is not up, and reports what is there either way. */
179
469
  start(options?: DaemonOptions): Promise<DaemonStatus & {
180
470
  spawned: boolean;
@@ -193,9 +483,11 @@ interface Daemon {
193
483
  *
194
484
  * import shotium from '@shotkit/shotium';
195
485
  *
196
- * shotium.runtime.start();
197
- * const png = await shotium.screenshot({file: 'https://example.com'});
198
- * await shotium.runtime.stop();
486
+ * shotium.start();
487
+ * const {image, stats} = await shotium.screenshot({
488
+ * file: 'https://example.com',
489
+ * });
490
+ * await shotium.stop();
199
491
  *
200
492
  * `start` and `stop` are explicit because starting Blink is the expensive part
201
493
  * -- tens of milliseconds and a working set that stays resident -- and only
@@ -204,11 +496,24 @@ interface Daemon {
204
496
  * What they buy is control over when that cost is paid, and the certainty that
205
497
  * it has been given back.
206
498
  *
207
- * `runtime` below is the singleton because there is nothing else it could be:
208
- * Blink starts once per process and cannot be restarted, so a second Runtime
209
- * in the same process has no engine to have. Construct one directly only to
210
- * own the lifecycle yourself instead of using `runtime`. Parallelism is more
211
- * processes, not more Runtimes.
499
+ * Neither is rationed, either. They may be called in any order and as often as
500
+ * a program likes: `stop()` stands the engine down and `start()` picks the
501
+ * same one back up, warm cache and all. What cannot happen is a *second*
502
+ * engine -- Blink is initialised once per process and there is no undo -- but
503
+ * that is a fact about how many there are, not about how many times the one
504
+ * may be asked for.
505
+ *
506
+ * The methods are on the module rather than under a `runtime` namespace, which
507
+ * they were until 0.3. There was never anything else to start, so the word
508
+ * carried nothing; and `runtime.cache` would have been the wrong place for the
509
+ * cache besides, since a cache directory outlives every engine that writes to
510
+ * it and can be read when no engine is running at all.
511
+ *
512
+ * `Runtime` is still exported for a caller who wants to own a lifecycle rather
513
+ * than share the module's. It is a lifecycle and not an engine: there is one
514
+ * engine per process, and a second Runtime that starts adopts the same one
515
+ * rather than building another. Parallelism is more processes, not more
516
+ * Runtimes.
212
517
  *
213
518
  * `daemon` is the same engine in a process of its own, behind a socket, for
214
519
  * callers whose own process does not live long enough to be worth starting
@@ -216,53 +521,119 @@ interface Daemon {
216
521
  */
217
522
  declare class Runtime {
218
523
  private engine;
524
+ /**
525
+ * The HTTP cache: where it is, what is in it, and how to empty it.
526
+ *
527
+ * On the Runtime as well as on the module because a caller holding their own
528
+ * Runtime needs the engine handle to reach a directory that engine has open:
529
+ * within one process a directory has one backend, so borrowing is the only
530
+ * way in.
531
+ */
532
+ readonly cache: Cache;
219
533
  get running(): boolean;
220
534
  /**
221
- * Starts the engine. Safe to call twice; the second call is a no-op, so that
222
- * library code can call it defensively. Not safe after `stop()` -- see there.
535
+ * Starts the engine, or picks the running one back up.
536
+ *
537
+ * Callable as often as you like, in any order with `stop()`; library code
538
+ * can call it defensively. The first call in a process builds the engine and
539
+ * every later one adopts it -- the same engine, the same warm cache. The one
540
+ * thing it will refuse is a *different* configuration: the options below are
541
+ * fixed when the engine is built, and there is no second build, so naming
542
+ * one that disagrees with what is running throws rather than rendering with
543
+ * a value you did not ask for.
223
544
  *
224
- * Every option has a default. `cacheDir` is the HTTP disk cache and `null`
225
- * disables it; `resourceDir` is where `shotium_data.pak` and
545
+ * Every option has a default. `cacheDir` is the HTTP disk cache and defaults
546
+ * to a per-project directory under `~/.shotium/cache`, and not under the
547
+ * temporary directory, which is defined by not surviving. `null` turns it
548
+ * off. `resourceDir` is where `shotium_data.pak` and
226
549
  * `shotium_strings.pak` are, and defaults to the directory the engine was
227
550
  * loaded from, which is where they ship.
551
+ *
552
+ * The return value is worth reading once. `cacheActive: false` with a
553
+ * `cacheDir` set means the directory could not be opened and this engine is
554
+ * running without a cache -- correctly, silently, and a round trip slower on
555
+ * everything.
228
556
  */
229
- start(options?: StartOptions): this;
557
+ start(options?: StartOptions): StartResult;
558
+ /** What `start()` returned, asked again. */
559
+ status(): StartResult;
230
560
  /**
231
- * Stops the engine, after whatever is queued.
561
+ * Stands the engine down, after whatever is queued.
232
562
  *
233
- * Final for this process. Blink writes process-wide state that it has no
234
- * path to undo, so starting again -- here or on another Runtime -- throws
235
- * rather than quietly handing back something that cannot render. A program
236
- * that wants another screenshot later should stay started and `purge()`.
563
+ * The queue drains, the memory the engine can rebuild goes back to the OS,
564
+ * and `running` becomes false. Blink itself stays initialised, because there
565
+ * is no way to un-initialise it -- so the disk cache stays where it is, and
566
+ * `start()` or the next `screenshot()` picks the same engine back up.
567
+ *
568
+ * Which makes this a caller saying they are done for now rather than a
569
+ * destructor. It does the same work as `releaseMemory({releaseWorkingSet:
570
+ * true})` and additionally stops accepting captures.
237
571
  */
238
572
  stop(): Promise<void>;
239
573
  /**
240
- * Hands back what the engine is holding but can rebuild. Worth calling when
241
- * a batch has ended and the next one may be a while away.
574
+ * Hands back what the engine is holding but can rebuild: Blink's heap,
575
+ * skia's caches, PartitionAlloc's free lists. Worth calling when a batch has
576
+ * ended and the next one may be a while away.
577
+ *
578
+ * This is memory and nothing else. It was called `purge()` until 0.3, which
579
+ * next to `cache.clear()` read as though it emptied the HTTP cache; it does
580
+ * not touch the disk at all.
242
581
  */
243
- purge(options?: PurgeOptions): void;
582
+ releaseMemory(options?: ReleaseMemoryOptions): void;
244
583
  /**
245
- * Renders one screenshot. Resolves to the encoded image, or to `null` when
246
- * `path` was given and the engine wrote the file itself.
584
+ * Renders one screenshot, and reports what it cost.
585
+ *
586
+ * `image` is the encoded bytes, or `null` when `path` was given and the
587
+ * engine wrote the file itself. `stats` says how many resources were
588
+ * fetched, how many came from the cache, and where the milliseconds went --
589
+ * which for an `https:` URL is usually the answer to "why did this take so
590
+ * long", because a cold connection costs more than the render does.
247
591
  */
248
- screenshot(options: ScreenshotOptions): Promise<Buffer | null>;
592
+ screenshot(options: ScreenshotOptions): Promise<ScreenshotResult>;
249
593
  }
250
594
  /** The shared engine: one per process, started on first use. */
251
595
  declare const runtime: Runtime;
252
596
  /** One screenshot through the shared engine, starting it if it is not up. */
253
- declare const screenshot: (options: ScreenshotOptions) => Promise<Buffer | null>;
597
+ declare const screenshot: (options: ScreenshotOptions) => Promise<ScreenshotResult>;
598
+ declare const start: (options?: StartOptions) => StartResult;
599
+ declare const status: () => StartResult;
600
+ declare const stop: () => Promise<void>;
601
+ declare const releaseMemory: (options?: ReleaseMemoryOptions) => void;
602
+ /**
603
+ * The HTTP cache.
604
+ *
605
+ * At the top level rather than under the engine because it outlives one: the
606
+ * directory is on disk whether or not anything is running, `getDir()` answers
607
+ * before the first `start()`, and clearing it is something a program may want
608
+ * to do without bringing Blink up at all. When an engine *is* up, these
609
+ * borrow its cache backend, because within one process a directory has one
610
+ * backend and that is the only way in.
611
+ */
612
+ declare const cache: Cache;
254
613
  /**
255
614
  * The resident engine: a process that outlives the one that started it,
256
615
  * reachable over a named pipe on Windows and a unix socket elsewhere. For
257
616
  * callers that are short-lived themselves. See lib/daemon.ts.
617
+ *
618
+ * It has no `cache` of its own. A daemon's cache directory is reported by
619
+ * `daemon.status()`, and clearing it is done by pointing `cache.clear()` at
620
+ * that directory or by stopping the daemon -- a cross-process cache protocol
621
+ * would be a second implementation of this module for something nobody does on
622
+ * a request path.
258
623
  */
259
624
  declare const daemon: Daemon;
260
625
  declare const _default: {
261
626
  Runtime: typeof Runtime;
262
- runtime: Runtime;
263
- screenshot: (options: ScreenshotOptions) => Promise<Buffer | null>;
627
+ cache: Cache;
264
628
  daemon: Daemon;
629
+ releaseMemory: (options?: ReleaseMemoryOptions) => void;
630
+ runtime: Runtime;
631
+ screenshot: (options: ScreenshotOptions) => Promise<ScreenshotResult>;
632
+ start: (options?: StartOptions) => StartResult;
633
+ status: () => StartResult;
634
+ stop: () => Promise<void>;
635
+ readonly running: boolean;
265
636
  };
266
637
  //#endregion
267
- export { type Clip, Daemon, type DaemonClient, type DaemonOptions, type DaemonStatus, type PageGotoParams, type PurgeOptions, Runtime, type ScreenshotOptions, type StartOptions, type Viewport, daemon, _default as default, runtime, screenshot };
638
+ export { Cache, type CacheClearOptions, type CacheClearResult, type CacheEntry, type CacheMode, type CacheTarget, type CaptureStats, type CaptureTiming, type Clip, Daemon, type DaemonClient, type DaemonOptions, type DaemonStatus, type PageGotoParams, type ReleaseMemoryOptions, Runtime, type ScreenshotOptions, type ScreenshotResult, type StartOptions, type StartResult, type Viewport, cache, daemon, _default as default, releaseMemory, runtime, screenshot, start, status, stop };
268
639
  //# sourceMappingURL=index.d.ts.map